Coverage Report

Created: 2026-02-26 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/capstonenext/arch/RISCV/RISCVDisassembler.c
Line
Count
Source
1
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
2
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2022, */
3
/*    Rot127 <unisono@quyllur.org> 2022-2023 */
4
/* Automatically translated source file from LLVM. */
5
6
/* LLVM-commit: <commit> */
7
/* LLVM-tag: <tag> */
8
9
/* Only small edits allowed. */
10
/* For multiple similar edits, please create a Patch for the translator. */
11
12
/* Capstone's C++ file translator: */
13
/* https://github.com/capstone-engine/capstone/tree/next/suite/auto-sync */
14
15
//===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===//
16
//
17
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
18
// See https://llvm.org/LICENSE.txt for license information.
19
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
20
//
21
//===----------------------------------------------------------------------===//
22
//
23
// This file implements the RISCVDisassembler class.
24
//
25
//===----------------------------------------------------------------------===//
26
27
#include <stdio.h>
28
#include <string.h>
29
#include <stdlib.h>
30
#include <capstone/platform.h>
31
32
#include "../../MCInst.h"
33
#include "../../MathExtras.h"
34
#include "../../MCInstPrinter.h"
35
#include "../../MCDisassembler.h"
36
#include "../../MCFixedLenDisassembler.h"
37
#include "../../cs_priv.h"
38
#include "../../utils.h"
39
#include "RISCVDisassemblerExtension.h"
40
#include "RISCVBaseInfo.h"
41
42
#define GET_SUBTARGETINFO_ENUM
43
#include "RISCVGenSubtargetInfo.inc"
44
45
#define GET_REGINFO_ENUM
46
#include "RISCVGenRegisterInfo.inc"
47
48
#define GET_INSTRINFO_ENUM
49
#define GET_INSTRINFO_MC_DESC
50
#include "RISCVGenInstrInfo.inc"
51
52
9.41k
#define CONCAT(a, b) CONCAT_(a, b)
53
9.41k
#define CONCAT_(a, b) a##_##b
54
55
#define DEBUG_TYPE "riscv-disassembler"
56
57
DecodeStatus RISCV_getInstruction(MCInst *Instr, uint16_t *Size,
58
          const uint8_t *Bytes, size_t BytesLen,
59
          uint64_t Address, SStream *CStream);
60
void addSPOperands(MCInst *MI);
61
;
62
// end anonymous namespace
63
64
static DecodeStatus DecodeGPRRegisterClass(MCInst *Inst, uint32_t RegNo,
65
             uint64_t Address,
66
             const void *Decoder)
67
54.9k
{
68
54.9k
  bool IsRVE = RISCV_getFeatureBits(Inst->csh->mode, RISCV_FeatureRVE);
69
70
54.9k
  if (RegNo >= 32 || (IsRVE && RegNo >= 16))
71
0
    return MCDisassembler_Fail;
72
73
54.9k
  MCRegister Reg = RISCV_X0 + RegNo;
74
54.9k
  MCOperand_CreateReg0(Inst, (Reg));
75
54.9k
  return MCDisassembler_Success;
76
54.9k
}
77
78
static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst *Inst, uint32_t RegNo,
79
                 uint64_t Address,
80
                 const void *Decoder)
81
0
{
82
0
  MCRegister Reg = RISCV_X0 + RegNo;
83
0
  if (Reg != RISCV_X1 && Reg != RISCV_X5)
84
0
    return MCDisassembler_Fail;
85
86
0
  MCOperand_CreateReg0(Inst, (Reg));
87
0
  return MCDisassembler_Success;
88
0
}
89
90
static DecodeStatus DecodeFPR16RegisterClass(MCInst *Inst, uint32_t RegNo,
91
               uint64_t Address,
92
               const void *Decoder)
93
4.89k
{
94
4.89k
  if (RegNo >= 32)
95
0
    return MCDisassembler_Fail;
96
97
4.89k
  MCRegister Reg = RISCV_F0_H + RegNo;
98
4.89k
  MCOperand_CreateReg0(Inst, (Reg));
99
4.89k
  return MCDisassembler_Success;
100
4.89k
}
101
102
static DecodeStatus DecodeFPR32RegisterClass(MCInst *Inst, uint32_t RegNo,
103
               uint64_t Address,
104
               const void *Decoder)
105
2.87k
{
106
2.87k
  if (RegNo >= 32)
107
0
    return MCDisassembler_Fail;
108
109
2.87k
  MCRegister Reg = RISCV_F0_F + RegNo;
110
2.87k
  MCOperand_CreateReg0(Inst, (Reg));
111
2.87k
  return MCDisassembler_Success;
112
2.87k
}
113
114
static DecodeStatus DecodeFPR32CRegisterClass(MCInst *Inst, uint32_t RegNo,
115
                uint64_t Address,
116
                const void *Decoder)
117
0
{
118
0
  if (RegNo >= 8) {
119
0
    return MCDisassembler_Fail;
120
0
  }
121
0
  MCRegister Reg = RISCV_F8_F + RegNo;
122
0
  MCOperand_CreateReg0(Inst, (Reg));
123
0
  return MCDisassembler_Success;
124
0
}
125
126
static DecodeStatus DecodeFPR64RegisterClass(MCInst *Inst, uint32_t RegNo,
127
               uint64_t Address,
128
               const void *Decoder)
129
0
{
130
0
  if (RegNo >= 32)
131
0
    return MCDisassembler_Fail;
132
133
0
  MCRegister Reg = RISCV_F0_D + RegNo;
134
0
  MCOperand_CreateReg0(Inst, (Reg));
135
0
  return MCDisassembler_Success;
136
0
}
137
138
static DecodeStatus DecodeFPR64CRegisterClass(MCInst *Inst, uint32_t RegNo,
139
                uint64_t Address,
140
                const void *Decoder)
141
0
{
142
0
  if (RegNo >= 8) {
143
0
    return MCDisassembler_Fail;
144
0
  }
145
0
  MCRegister Reg = RISCV_F8_D + RegNo;
146
0
  MCOperand_CreateReg0(Inst, (Reg));
147
0
  return MCDisassembler_Success;
148
0
}
149
150
static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst *Inst, uint32_t RegNo,
151
                 uint64_t Address,
152
                 const void *Decoder)
153
23.6k
{
154
23.6k
  if (RegNo == 0) {
155
7
    return MCDisassembler_Fail;
156
7
  }
157
158
23.6k
  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
159
23.6k
}
160
161
static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst *Inst, uint64_t RegNo,
162
             uint32_t Address,
163
             const void *Decoder)
164
1.58k
{
165
1.58k
  if (RegNo == 2) {
166
0
    return MCDisassembler_Fail;
167
0
  }
168
169
1.58k
  return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
170
1.58k
}
171
172
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint32_t RegNo,
173
              uint64_t Address,
174
              const void *Decoder)
175
35.8k
{
176
35.8k
  if (RegNo >= 8)
177
0
    return MCDisassembler_Fail;
178
179
35.8k
  MCRegister Reg = RISCV_X8 + RegNo;
180
35.8k
  MCOperand_CreateReg0(Inst, (Reg));
181
35.8k
  return MCDisassembler_Success;
182
35.8k
}
183
184
static DecodeStatus DecodeGPRPairRegisterClass(MCInst *Inst, uint32_t RegNo,
185
                 uint64_t Address,
186
                 const void *Decoder)
187
416
{
188
416
  if (RegNo >= 32 || RegNo & 1)
189
3
    return MCDisassembler_Fail;
190
191
413
  MCRegister Reg = RISCV_X0 + RegNo;
192
413
  MCOperand_CreateReg0(Inst, (Reg));
193
413
  return MCDisassembler_Success;
194
416
}
195
196
static DecodeStatus DecodeSR07RegisterClass(MCInst *Inst, uint64_t RegNo,
197
              uint64_t Address,
198
              const void *Decoder)
199
0
{
200
0
  if (RegNo >= 8)
201
0
    return MCDisassembler_Fail;
202
203
0
  MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV_X8) :
204
0
               (RegNo - 2 + RISCV_X18);
205
0
  MCOperand_CreateReg0(Inst, (Reg));
206
0
  return MCDisassembler_Success;
207
0
}
208
209
static DecodeStatus DecodeVRRegisterClass(MCInst *Inst, uint32_t RegNo,
210
            uint64_t Address, const void *Decoder)
211
12.8k
{
212
12.8k
  if (RegNo >= 32)
213
0
    return MCDisassembler_Fail;
214
215
12.8k
  MCRegister Reg = RISCV_V0 + RegNo;
216
12.8k
  MCOperand_CreateReg0(Inst, (Reg));
217
12.8k
  return MCDisassembler_Success;
218
12.8k
}
219
220
static DecodeStatus DecodeVRM2RegisterClass(MCInst *Inst, uint32_t RegNo,
221
              uint64_t Address,
222
              const void *Decoder)
223
647
{
224
647
  if (RegNo >= 32 || RegNo % 2)
225
3
    return MCDisassembler_Fail;
226
227
644
  MCRegister Reg = MCRegisterInfo_getMatchingSuperReg(
228
644
    Inst->MRI, RISCV_V0 + RegNo, RISCV_sub_vrm1_0,
229
644
    MCRegisterInfo_getRegClass(Inst->MRI, RISCV_VRM2RegClassID));
230
231
644
  MCOperand_CreateReg0(Inst, (Reg));
232
644
  return MCDisassembler_Success;
233
647
}
234
235
static DecodeStatus DecodeVRM4RegisterClass(MCInst *Inst, uint32_t RegNo,
236
              uint64_t Address,
237
              const void *Decoder)
238
274
{
239
274
  if (RegNo >= 32 || RegNo % 4)
240
5
    return MCDisassembler_Fail;
241
242
269
  MCRegister Reg = MCRegisterInfo_getMatchingSuperReg(
243
269
    Inst->MRI, RISCV_V0 + RegNo, RISCV_sub_vrm1_0,
244
269
    MCRegisterInfo_getRegClass(Inst->MRI, RISCV_VRM4RegClassID));
245
246
269
  MCOperand_CreateReg0(Inst, (Reg));
247
269
  return MCDisassembler_Success;
248
274
}
249
250
static DecodeStatus DecodeVRM8RegisterClass(MCInst *Inst, uint32_t RegNo,
251
              uint64_t Address,
252
              const void *Decoder)
253
81
{
254
81
  if (RegNo >= 32 || RegNo % 8)
255
5
    return MCDisassembler_Fail;
256
257
76
  MCRegister Reg = MCRegisterInfo_getMatchingSuperReg(
258
76
    Inst->MRI, RISCV_V0 + RegNo, RISCV_sub_vrm1_0,
259
76
    MCRegisterInfo_getRegClass(Inst->MRI, RISCV_VRM8RegClassID));
260
261
76
  MCOperand_CreateReg0(Inst, (Reg));
262
76
  return MCDisassembler_Success;
263
81
}
264
265
static DecodeStatus decodeVMaskReg(MCInst *Inst, uint64_t RegNo,
266
           uint64_t Address, const void *Decoder)
267
4.46k
{
268
4.46k
  if (RegNo > 2) {
269
0
    return MCDisassembler_Fail;
270
0
  }
271
4.46k
  MCRegister Reg = (RegNo == 0) ? RISCV_V0 : RISCV_NoRegister;
272
273
4.46k
  MCOperand_CreateReg0(Inst, (Reg));
274
4.46k
  return MCDisassembler_Success;
275
4.46k
}
276
277
#define DEFINE_decodeUImmOperand(N) \
278
  static DecodeStatus CONCAT(decodeUImmOperand, \
279
           N)(MCInst * Inst, uint32_t Imm, \
280
              int64_t Address, const void *Decoder) \
281
29.4k
  { \
282
29.4k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
29.4k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
29.4k
    return MCDisassembler_Success; \
285
29.4k
  }
RISCVDisassembler.c:decodeUImmOperand_8
Line
Count
Source
281
5.59k
  { \
282
5.59k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
5.59k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
5.59k
    return MCDisassembler_Success; \
285
5.59k
  }
RISCVDisassembler.c:decodeUImmOperand_9
Line
Count
Source
281
2.87k
  { \
282
2.87k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
2.87k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
2.87k
    return MCDisassembler_Success; \
285
2.87k
  }
RISCVDisassembler.c:decodeUImmOperand_7
Line
Count
Source
281
3.83k
  { \
282
3.83k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
3.83k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
3.83k
    return MCDisassembler_Success; \
285
3.83k
  }
RISCVDisassembler.c:decodeUImmOperand_2
Line
Count
Source
281
1.85k
  { \
282
1.85k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
1.85k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
1.85k
    return MCDisassembler_Success; \
285
1.85k
  }
RISCVDisassembler.c:decodeUImmOperand_4
Line
Count
Source
281
1.12k
  { \
282
1.12k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
1.12k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
1.12k
    return MCDisassembler_Success; \
285
1.12k
  }
RISCVDisassembler.c:decodeUImmOperand_20
Line
Count
Source
281
977
  { \
282
977
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
977
    MCOperand_CreateImm0(Inst, (Imm)); \
284
977
    return MCDisassembler_Success; \
285
977
  }
RISCVDisassembler.c:decodeUImmOperand_5
Line
Count
Source
281
3.46k
  { \
282
3.46k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
3.46k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
3.46k
    return MCDisassembler_Success; \
285
3.46k
  }
RISCVDisassembler.c:decodeUImmOperand_6
Line
Count
Source
281
1.24k
  { \
282
1.24k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
1.24k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
1.24k
    return MCDisassembler_Success; \
285
1.24k
  }
RISCVDisassembler.c:decodeUImmOperand_11
Line
Count
Source
281
687
  { \
282
687
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
687
    MCOperand_CreateImm0(Inst, (Imm)); \
284
687
    return MCDisassembler_Success; \
285
687
  }
RISCVDisassembler.c:decodeUImmOperand_10
Line
Count
Source
281
4.72k
  { \
282
4.72k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
4.72k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
4.72k
    return MCDisassembler_Success; \
285
4.72k
  }
RISCVDisassembler.c:decodeUImmOperand_12
Line
Count
Source
281
2.53k
  { \
282
2.53k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
2.53k
    MCOperand_CreateImm0(Inst, (Imm)); \
284
2.53k
    return MCDisassembler_Success; \
285
2.53k
  }
RISCVDisassembler.c:decodeUImmOperand_3
Line
Count
Source
281
487
  { \
282
487
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
283
487
    MCOperand_CreateImm0(Inst, (Imm)); \
284
487
    return MCDisassembler_Success; \
285
487
  }
Unexecuted instantiation: RISCVDisassembler.c:decodeUImmOperand_1
286
DEFINE_decodeUImmOperand(6);
287
DEFINE_decodeUImmOperand(2);
288
DEFINE_decodeUImmOperand(8);
289
DEFINE_decodeUImmOperand(9);
290
DEFINE_decodeUImmOperand(7);
291
DEFINE_decodeUImmOperand(4);
292
DEFINE_decodeUImmOperand(20);
293
DEFINE_decodeUImmOperand(5);
294
DEFINE_decodeUImmOperand(11);
295
DEFINE_decodeUImmOperand(10);
296
DEFINE_decodeUImmOperand(12);
297
DEFINE_decodeUImmOperand(3);
298
DEFINE_decodeUImmOperand(1);
299
300
#define DEFINE_decodeUImmNonZeroOperand(N) \
301
  static DecodeStatus CONCAT(decodeUImmNonZeroOperand, \
302
           N)(MCInst * Inst, uint32_t Imm, \
303
              int64_t Address, const void *Decoder) \
304
4.44k
  { \
305
4.44k
    if (Imm == 0) \
306
4.44k
      return MCDisassembler_Fail; \
307
4.44k
    return CONCAT(decodeUImmOperand, N)(Inst, Imm, Address, \
308
4.43k
                Decoder); \
309
4.44k
  }
310
DEFINE_decodeUImmNonZeroOperand(10);
311
312
#define DEFINE_decodeSImmOperand(N) \
313
  static DecodeStatus CONCAT(decodeSImmOperand, \
314
           N)(MCInst * Inst, uint32_t Imm, \
315
              int64_t Address, const void *Decoder) \
316
11.0k
  { \
317
11.0k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
318
11.0k
\
319
11.0k
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
320
11.0k
    return MCDisassembler_Success; \
321
11.0k
  }
RISCVDisassembler.c:decodeSImmOperand_6
Line
Count
Source
316
7.17k
  { \
317
7.17k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
318
7.17k
\
319
7.17k
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
320
7.17k
    return MCDisassembler_Success; \
321
7.17k
  }
RISCVDisassembler.c:decodeSImmOperand_10
Line
Count
Source
316
484
  { \
317
484
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
318
484
\
319
484
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
320
484
    return MCDisassembler_Success; \
321
484
  }
RISCVDisassembler.c:decodeSImmOperand_12
Line
Count
Source
316
3.03k
  { \
317
3.03k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
318
3.03k
\
319
3.03k
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
320
3.03k
    return MCDisassembler_Success; \
321
3.03k
  }
RISCVDisassembler.c:decodeSImmOperand_5
Line
Count
Source
316
338
  { \
317
338
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
318
338
\
319
338
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm), N))); \
320
338
    return MCDisassembler_Success; \
321
338
  }
322
DEFINE_decodeSImmOperand(6);
323
DEFINE_decodeSImmOperand(12);
324
DEFINE_decodeSImmOperand(5);
325
DEFINE_decodeSImmOperand(10);
326
327
#define DEFINE_decodeSImmNonZeroOperand(N) \
328
  static DecodeStatus CONCAT(decodeSImmNonZeroOperand, \
329
           N)(MCInst * Inst, uint32_t Imm, \
330
              int64_t Address, const void *Decoder) \
331
3.75k
  { \
332
3.75k
    if (Imm == 0) \
333
3.75k
      return MCDisassembler_Fail; \
334
3.75k
    return CONCAT(decodeSImmOperand, N)(Inst, Imm, Address, \
335
3.75k
                Decoder); \
336
3.75k
  }
RISCVDisassembler.c:decodeSImmNonZeroOperand_6
Line
Count
Source
331
3.26k
  { \
332
3.26k
    if (Imm == 0) \
333
3.26k
      return MCDisassembler_Fail; \
334
3.26k
    return CONCAT(decodeSImmOperand, N)(Inst, Imm, Address, \
335
3.26k
                Decoder); \
336
3.26k
  }
RISCVDisassembler.c:decodeSImmNonZeroOperand_10
Line
Count
Source
331
485
  { \
332
485
    if (Imm == 0) \
333
485
      return MCDisassembler_Fail; \
334
485
    return CONCAT(decodeSImmOperand, N)(Inst, Imm, Address, \
335
484
                Decoder); \
336
485
  }
337
DEFINE_decodeSImmNonZeroOperand(6);
338
DEFINE_decodeSImmNonZeroOperand(10);
339
340
#define DEFINE_decodeSImmOperandAndLsl1(N) \
341
  static DecodeStatus CONCAT(decodeSImmOperandAndLsl1, \
342
           N)(MCInst * Inst, uint32_t Imm, \
343
              int64_t Address, const void *Decoder) \
344
5.56k
  { \
345
5.56k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
346
5.56k
\
347
5.56k
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 1), N))); \
348
5.56k
    return MCDisassembler_Success; \
349
5.56k
  }
RISCVDisassembler.c:decodeSImmOperandAndLsl1_12
Line
Count
Source
344
1.18k
  { \
345
1.18k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
346
1.18k
\
347
1.18k
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 1), N))); \
348
1.18k
    return MCDisassembler_Success; \
349
1.18k
  }
RISCVDisassembler.c:decodeSImmOperandAndLsl1_9
Line
Count
Source
344
3.40k
  { \
345
3.40k
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
346
3.40k
\
347
3.40k
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 1), N))); \
348
3.40k
    return MCDisassembler_Success; \
349
3.40k
  }
RISCVDisassembler.c:decodeSImmOperandAndLsl1_13
Line
Count
Source
344
451
  { \
345
451
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
346
451
\
347
451
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 1), N))); \
348
451
    return MCDisassembler_Success; \
349
451
  }
RISCVDisassembler.c:decodeSImmOperandAndLsl1_21
Line
Count
Source
344
530
  { \
345
530
    CS_ASSERT(isUIntN(N, Imm) && "Invalid immediate"); \
346
530
\
347
530
    MCOperand_CreateImm0(Inst, (SignExtend64((Imm << 1), N))); \
348
530
    return MCDisassembler_Success; \
349
530
  }
350
DEFINE_decodeSImmOperandAndLsl1(12);
351
DEFINE_decodeSImmOperandAndLsl1(9);
352
DEFINE_decodeSImmOperandAndLsl1(13);
353
DEFINE_decodeSImmOperandAndLsl1(21);
354
355
static DecodeStatus decodeCLUIImmOperand(MCInst *Inst, uint32_t Imm,
356
           int64_t Address, const void *Decoder)
357
1.58k
{
358
1.58k
  CS_ASSERT(isUIntN(6, Imm) && "Invalid immediate");
359
1.58k
  if (Imm > 31) {
360
947
    Imm = (SignExtend64((Imm), 6) & 0xfffff);
361
947
  }
362
1.58k
  MCOperand_CreateImm0(Inst, (Imm));
363
1.58k
  return MCDisassembler_Success;
364
1.58k
}
365
366
static DecodeStatus decodeFRMArg(MCInst *Inst, uint32_t Imm, int64_t Address,
367
         const void *Decoder)
368
2.35k
{
369
2.35k
  CS_ASSERT(isUIntN(3, Imm) && "Invalid immediate");
370
2.35k
  if (!RISCVFPRndMode_isValidRoundingMode(Imm))
371
12
    return MCDisassembler_Fail;
372
373
2.34k
  MCOperand_CreateImm0(Inst, (Imm));
374
2.34k
  return MCDisassembler_Success;
375
2.35k
}
376
377
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst *Inst, uint32_t Insn,
378
                 uint64_t Address,
379
                 const void *Decoder);
380
381
static DecodeStatus decodeRVCInstrRdSImm(MCInst *Inst, uint32_t Insn,
382
           uint64_t Address, const void *Decoder);
383
384
static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst *Inst, uint32_t Insn,
385
              uint64_t Address,
386
              const void *Decoder);
387
388
static DecodeStatus decodeRVCInstrRdRs2(MCInst *Inst, uint32_t Insn,
389
          uint64_t Address, const void *Decoder);
390
391
static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst *Inst, uint32_t Insn,
392
             uint64_t Address,
393
             const void *Decoder);
394
395
static DecodeStatus decodeXTHeadMemPair(MCInst *Inst, uint32_t Insn,
396
          uint64_t Address, const void *Decoder);
397
398
static DecodeStatus decodeZcmpRlist(MCInst *Inst, unsigned Imm,
399
            uint64_t Address, const void *Decoder);
400
401
static DecodeStatus decodeRegReg(MCInst *Inst, uint32_t Insn, uint64_t Address,
402
         const void *Decoder);
403
404
static DecodeStatus decodeZcmpSpimm(MCInst *Inst, unsigned Imm,
405
            uint64_t Address, const void *Decoder);
406
407
static DecodeStatus decodeCSSPushPopchk(MCInst *Inst, uint32_t Insn,
408
          uint64_t Address, const void *Decoder);
409
410
static DecodeStatus decodeUImmLog2XLenOperand(MCInst *Inst, uint32_t Imm,
411
                int64_t Address,
412
                const void *Decoder)
413
3.19k
{
414
3.19k
  CS_ASSERT(isUIntN(6, Imm) && "Invalid immediate");
415
416
3.19k
  if (!RISCV_getFeatureBits(Inst->csh->mode, RISCV_Feature64Bit) &&
417
1.13k
      !isUIntN(5, Imm))
418
12
    return MCDisassembler_Fail;
419
420
3.18k
  MCOperand_CreateImm0(Inst, (Imm));
421
3.18k
  return MCDisassembler_Success;
422
3.19k
}
423
424
static DecodeStatus decodeUImmLog2XLenNonZeroOperand(MCInst *Inst, uint32_t Imm,
425
                 int64_t Address,
426
                 const void *Decoder)
427
3.08k
{
428
3.08k
  if (Imm == 0)
429
0
    return MCDisassembler_Fail;
430
3.08k
  return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder);
431
3.08k
}
432
433
#include "RISCVGenDisassemblerTables.inc"
434
435
static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst *Inst, uint32_t Insn,
436
                 uint64_t Address,
437
                 const void *Decoder)
438
384
{
439
384
  uint32_t Rd = fieldFromInstruction_4(Insn, 7, 5);
440
384
  DecodeStatus Result =
441
384
    DecodeGPRNoX0RegisterClass(Inst, Rd, Address, Decoder);
442
384
  (void)Result;
443
384
  CS_ASSERT(Result == MCDisassembler_Success && "Invalid register");
444
384
  MCInst_addOperand2(Inst, (MCInst_getOperand(Inst, (0))));
445
384
  MCOperand_CreateImm0(Inst, (0));
446
384
  return MCDisassembler_Success;
447
384
}
448
449
static DecodeStatus decodeCSSPushPopchk(MCInst *Inst, uint32_t Insn,
450
          uint64_t Address, const void *Decoder)
451
0
{
452
0
  uint32_t Rs1 = fieldFromInstruction_4(Insn, 7, 5);
453
0
  DecodeStatus Result =
454
0
    DecodeGPRX1X5RegisterClass(Inst, Rs1, Address, Decoder);
455
0
  (void)Result;
456
0
  CS_ASSERT(Result == MCDisassembler_Success && "Invalid register");
457
0
  return MCDisassembler_Success;
458
0
}
459
460
static DecodeStatus decodeRVCInstrRdSImm(MCInst *Inst, uint32_t Insn,
461
           uint64_t Address, const void *Decoder)
462
477
{
463
477
  MCOperand_CreateReg0(Inst, (RISCV_X0));
464
477
  uint32_t SImm6 = fieldFromInstruction_4(Insn, 12, 1) << 5 |
465
477
       fieldFromInstruction_4(Insn, 2, 5);
466
477
  DecodeStatus Result =
467
477
    CONCAT(decodeSImmOperand, 6)(Inst, SImm6, Address, Decoder);
468
477
  (void)Result;
469
477
  CS_ASSERT(Result == MCDisassembler_Success && "Invalid immediate");
470
477
  return MCDisassembler_Success;
471
477
}
472
473
static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst *Inst, uint32_t Insn,
474
              uint64_t Address,
475
              const void *Decoder)
476
755
{
477
755
  MCOperand_CreateReg0(Inst, (RISCV_X0));
478
755
  MCInst_addOperand2(Inst, (MCInst_getOperand(Inst, (0))));
479
755
  uint32_t UImm6 = fieldFromInstruction_4(Insn, 12, 1) << 5 |
480
755
       fieldFromInstruction_4(Insn, 2, 5);
481
755
  DecodeStatus Result =
482
755
    CONCAT(decodeUImmOperand, 6)(Inst, UImm6, Address, Decoder);
483
755
  (void)Result;
484
755
  CS_ASSERT(Result == MCDisassembler_Success && "Invalid immediate");
485
755
  return MCDisassembler_Success;
486
755
}
487
488
static DecodeStatus decodeRVCInstrRdRs2(MCInst *Inst, uint32_t Insn,
489
          uint64_t Address, const void *Decoder)
490
99
{
491
99
  uint32_t Rd = fieldFromInstruction_4(Insn, 7, 5);
492
99
  uint32_t Rs2 = fieldFromInstruction_4(Insn, 2, 5);
493
99
  DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
494
99
  DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
495
99
  return MCDisassembler_Success;
496
99
}
497
498
static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst *Inst, uint32_t Insn,
499
             uint64_t Address,
500
             const void *Decoder)
501
139
{
502
139
  uint32_t Rd = fieldFromInstruction_4(Insn, 7, 5);
503
139
  uint32_t Rs2 = fieldFromInstruction_4(Insn, 2, 5);
504
139
  DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
505
139
  MCInst_addOperand2(Inst, (MCInst_getOperand(Inst, (0))));
506
139
  DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
507
139
  return MCDisassembler_Success;
508
139
}
509
510
static DecodeStatus decodeXTHeadMemPair(MCInst *Inst, uint32_t Insn,
511
          uint64_t Address, const void *Decoder)
512
0
{
513
0
  uint32_t Rd1 = fieldFromInstruction_4(Insn, 7, 5);
514
0
  uint32_t Rs1 = fieldFromInstruction_4(Insn, 15, 5);
515
0
  uint32_t Rd2 = fieldFromInstruction_4(Insn, 20, 5);
516
0
  uint32_t UImm2 = fieldFromInstruction_4(Insn, 25, 2);
517
0
  DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder);
518
0
  DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder);
519
0
  DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
520
0
  DecodeStatus Result =
521
0
    CONCAT(decodeUImmOperand, 2)(Inst, UImm2, Address, Decoder);
522
0
  (void)Result;
523
0
  CS_ASSERT(Result == MCDisassembler_Success && "Invalid immediate");
524
525
  // Disassemble the final operand which is implicit.
526
0
  unsigned Opcode = MCInst_getOpcode(Inst);
527
0
  bool IsWordOp = (Opcode == RISCV_TH_LWD || Opcode == RISCV_TH_LWUD ||
528
0
       Opcode == RISCV_TH_SWD);
529
0
  if (IsWordOp)
530
0
    MCOperand_CreateImm0(Inst, (3));
531
0
  else
532
0
    MCOperand_CreateImm0(Inst, (4));
533
534
0
  return MCDisassembler_Success;
535
0
}
536
537
static DecodeStatus decodeZcmpRlist(MCInst *Inst, unsigned Imm,
538
            uint64_t Address, const void *Decoder)
539
0
{
540
0
  if (Imm <= 3)
541
0
    return MCDisassembler_Fail;
542
0
  MCOperand_CreateImm0(Inst, (Imm));
543
0
  return MCDisassembler_Success;
544
0
}
545
546
static DecodeStatus decodeRegReg(MCInst *Inst, uint32_t Insn, uint64_t Address,
547
         const void *Decoder)
548
259
{
549
259
  uint32_t Rs1 = fieldFromInstruction_4(Insn, 0, 5);
550
259
  uint32_t Rs2 = fieldFromInstruction_4(Insn, 5, 5);
551
259
  DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
552
259
  DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
553
259
  return MCDisassembler_Success;
554
259
}
555
556
static DecodeStatus decodeZcmpSpimm(MCInst *Inst, unsigned Imm,
557
            uint64_t Address, const void *Decoder)
558
0
{
559
0
  MCOperand_CreateImm0(Inst, (Imm));
560
0
  return MCDisassembler_Success;
561
0
}
562
563
// Add implied SP operand for C.*SP compressed instructions. The SP operand
564
// isn't explicitly encoded in the instruction.
565
void addSPOperands(MCInst *MI)
566
49.5k
{
567
49.5k
  const MCInstrDesc *MCID = MCInstrDesc_get(MCInst_getOpcode(MI),
568
49.5k
              RISCVDescs.Insts,
569
49.5k
              ARR_SIZE(RISCVDescs.Insts));
570
49.5k
  MCOperand SPReg;
571
49.5k
  SPReg.MachineOperandType = kRegister;
572
49.5k
  SPReg.Kind = kRegister;
573
49.5k
  SPReg.RegVal = RISCV_X2;
574
161k
  for (unsigned i = 0; i < MCID->NumOperands; i++)
575
111k
    if (MCID->OpInfo[i].RegClass == RISCV_SPRegClassID)
576
10.4k
      MCInst_insert0(MI, i, &SPReg);
577
49.5k
}
578
579
DecodeStatus RISCV_getInstruction(MCInst *MI, uint16_t *Size,
580
          const uint8_t *Bytes, size_t BytesLen,
581
          uint64_t Address, SStream *CS)
582
73.0k
{
583
  // TODO: This will need modification when supporting instruction set
584
  // extensions with instructions > 32-bits (up to 176 bits wide).
585
73.0k
  uint32_t Insn;
586
73.0k
  DecodeStatus Result;
587
588
73.0k
#define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION( \
589
73.0k
  width, FEATURE_CHECKS, DECODER_TABLE, DESC, ADDITIONAL_OPERATION) \
590
868k
  do { \
591
936k
    if (FEATURE_CHECKS) { \
592
244k
      Result = decodeInstruction_##width( \
593
244k
        DECODER_TABLE, MI, Insn, Address, NULL); \
594
244k
      if (Result != MCDisassembler_Fail) { \
595
71.9k
        ADDITIONAL_OPERATION; \
596
71.9k
        return Result; \
597
71.9k
      } \
598
244k
    } \
599
868k
  } while (false)
600
73.0k
#define TRY_TO_DECODE_AND_ADD_SP(width, FEATURE_CHECKS, DECODER_TABLE, DESC) \
601
98.7k
  TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION( \
602
98.7k
    width, FEATURE_CHECKS, DECODER_TABLE, DESC, addSPOperands(MI))
603
73.0k
#define TRY_TO_DECODE(width, FEATURE_CHECKS, DECODER_TABLE, DESC) \
604
769k
  TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION( \
605
769k
    width, FEATURE_CHECKS, DECODER_TABLE, DESC, (void)NULL)
606
73.0k
#define TRY_TO_DECODE_FEATURE(width, FEATURE, DECODER_TABLE, DESC) \
607
704k
  TRY_TO_DECODE(width, RISCV_getFeatureBits(MI->csh->mode, FEATURE), \
608
704k
          DECODER_TABLE, DESC)
609
610
  // It's a 32 bit instruction if bit 0 and 1 are 1.
611
73.0k
  if ((Bytes[0] & 0x3) == 0x3) {
612
23.0k
    if (BytesLen < 4) {
613
242
      *Size = 0;
614
242
      return MCDisassembler_Fail;
615
242
    }
616
22.7k
    *Size = 4;
617
618
22.7k
    Insn = readBytes32(MI, Bytes);
619
620
22.7k
    TRY_TO_DECODE(4,
621
22.7k
            RISCV_getFeatureBits(MI->csh->mode,
622
22.7k
               RISCV_FeatureStdExtZdinx) &&
623
22.7k
              !RISCV_getFeatureBits(MI->csh->mode,
624
22.7k
                  RISCV_Feature64Bit),
625
22.7k
            DecoderTableRV32Zdinx32,
626
22.7k
            "RV32Zdinx table (Double in Integer and rv32)");
627
22.7k
    TRY_TO_DECODE(4,
628
22.7k
            RISCV_getFeatureBits(MI->csh->mode,
629
22.7k
               RISCV_FeatureStdExtZacas) &&
630
22.7k
              !RISCV_getFeatureBits(MI->csh->mode,
631
22.7k
                  RISCV_Feature64Bit),
632
22.7k
            DecoderTableRV32Zacas32,
633
22.7k
            "RV32Zacas table (Compare-And-Swap and rv32)");
634
22.7k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureStdExtZfinx,
635
22.7k
              DecoderTableRVZfinx32,
636
22.7k
              "RVZfinx table (Float in Integer)");
637
22.7k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXVentanaCondOps,
638
22.6k
              DecoderTableXVentana32,
639
22.6k
              "Ventana custom opcode table");
640
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadBa,
641
22.6k
              DecoderTableXTHeadBa32,
642
22.6k
              "XTHeadBa custom opcode table");
643
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadBb,
644
22.6k
              DecoderTableXTHeadBb32,
645
22.6k
              "XTHeadBb custom opcode table");
646
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadBs,
647
22.6k
              DecoderTableXTHeadBs32,
648
22.6k
              "XTHeadBs custom opcode table");
649
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadCondMov,
650
22.6k
              DecoderTableXTHeadCondMov32,
651
22.6k
              "XTHeadCondMov custom opcode table");
652
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadCmo,
653
22.6k
              DecoderTableXTHeadCmo32,
654
22.6k
              "XTHeadCmo custom opcode table");
655
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadFMemIdx,
656
22.6k
              DecoderTableXTHeadFMemIdx32,
657
22.6k
              "XTHeadFMemIdx custom opcode table");
658
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadMac,
659
22.6k
              DecoderTableXTHeadMac32,
660
22.6k
              "XTHeadMac custom opcode table");
661
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadMemIdx,
662
22.6k
              DecoderTableXTHeadMemIdx32,
663
22.6k
              "XTHeadMemIdx custom opcode table");
664
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadMemPair,
665
22.6k
              DecoderTableXTHeadMemPair32,
666
22.6k
              "XTHeadMemPair custom opcode table");
667
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadSync,
668
22.6k
              DecoderTableXTHeadSync32,
669
22.6k
              "XTHeadSync custom opcode table");
670
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXTHeadVdot,
671
22.6k
              DecoderTableXTHeadVdot32,
672
22.6k
              "XTHeadVdot custom opcode table");
673
22.6k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXSfvcp,
674
22.6k
              DecoderTableXSfvcp32,
675
22.6k
              "SiFive VCIX custom opcode table");
676
22.6k
    TRY_TO_DECODE_FEATURE(
677
22.6k
      4, RISCV_FeatureVendorXSfvqmaccdod,
678
22.6k
      DecoderTableXSfvqmaccdod32,
679
22.6k
      "SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table");
680
22.6k
    TRY_TO_DECODE_FEATURE(
681
22.6k
      4, RISCV_FeatureVendorXSfvqmaccqoq,
682
22.6k
      DecoderTableXSfvqmaccqoq32,
683
22.6k
      "SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table");
684
22.6k
    TRY_TO_DECODE_FEATURE(
685
22.6k
      4, RISCV_FeatureVendorXSfvfwmaccqqq,
686
22.6k
      DecoderTableXSfvfwmaccqqq32,
687
22.6k
      "SiFive Matrix Multiplication Instruction opcode table");
688
22.6k
    TRY_TO_DECODE_FEATURE(
689
22.6k
      4, RISCV_FeatureVendorXSfvfnrclipxfqf,
690
22.6k
      DecoderTableXSfvfnrclipxfqf32,
691
22.6k
      "SiFive FP32-to-int8 Ranged Clip Instructions opcode table");
692
22.6k
    TRY_TO_DECODE_FEATURE(
693
22.0k
      4, RISCV_FeatureVendorXCVbitmanip,
694
22.0k
      DecoderTableXCVbitmanip32,
695
22.0k
      "CORE-V Bit Manipulation custom opcode table");
696
22.0k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXCVelw,
697
22.0k
              DecoderTableXCVelw32,
698
22.0k
              "CORE-V Event load custom opcode table");
699
22.0k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXCVmac,
700
21.5k
              DecoderTableXCVmac32,
701
21.5k
              "CORE-V MAC custom opcode table");
702
21.5k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXCVmem,
703
20.7k
              DecoderTableXCVmem32,
704
20.7k
              "CORE-V MEM custom opcode table");
705
20.7k
    TRY_TO_DECODE_FEATURE(4, RISCV_FeatureVendorXCValu,
706
20.5k
              DecoderTableXCValu32,
707
20.5k
              "CORE-V ALU custom opcode table");
708
20.5k
    TRY_TO_DECODE_FEATURE(
709
19.6k
      4, RISCV_FeatureVendorXCVsimd, DecoderTableXCVsimd32,
710
19.6k
      "CORE-V SIMD extensions custom opcode table");
711
19.6k
    TRY_TO_DECODE_FEATURE(
712
19.4k
      4, RISCV_FeatureVendorXCVbi, DecoderTableXCVbi32,
713
19.4k
      "CORE-V Immediate Branching custom opcode table");
714
19.4k
    TRY_TO_DECODE(4, true, DecoderTable32, "RISCV32 table");
715
716
306
    return MCDisassembler_Fail;
717
19.4k
  }
718
719
50.0k
  if (BytesLen < 2) {
720
266
    *Size = 0;
721
266
    return MCDisassembler_Fail;
722
266
  }
723
49.7k
  *Size = 2;
724
725
49.7k
  Insn = readBytes16(MI, Bytes);
726
49.7k
  TRY_TO_DECODE_AND_ADD_SP(
727
49.0k
    2, !RISCV_getFeatureBits(MI->csh->mode, RISCV_Feature64Bit),
728
49.0k
    DecoderTableRISCV32Only_16,
729
49.0k
    "RISCV32Only_16 table (16-bit Instruction)");
730
49.0k
  TRY_TO_DECODE_FEATURE(2, RISCV_FeatureStdExtZicfiss,
731
49.0k
            DecoderTableZicfiss16,
732
49.0k
            "RVZicfiss table (Shadow Stack)");
733
49.0k
  TRY_TO_DECODE_FEATURE(2, RISCV_FeatureStdExtZcmt, DecoderTableRVZcmt16,
734
49.0k
            "Zcmt table (16-bit Table Jump Instructions)");
735
49.0k
  TRY_TO_DECODE_FEATURE(
736
49.0k
    2, RISCV_FeatureStdExtZcmp, DecoderTableRVZcmp16,
737
49.0k
    "Zcmp table (16-bit Push/Pop & Double Move Instructions)");
738
49.0k
  TRY_TO_DECODE_AND_ADD_SP(2, true, DecoderTable16,
739
245
         "RISCV_C table (16-bit Instruction)");
740
741
245
  return MCDisassembler_Fail;
742
49.0k
}
743
744
bool RISCV_LLVM_getInstruction(csh handle, const uint8_t *Bytes, size_t ByteLen,
745
             MCInst *MI, uint16_t *Size, uint64_t Address,
746
             void *Info)
747
73.0k
{
748
73.0k
  MI->MRI = (MCRegisterInfo *)Info;
749
  return RISCV_getInstruction(MI, Size, Bytes, ByteLen, Address, NULL) !=
750
73.0k
         MCDisassembler_Fail;
751
73.0k
}