1//===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the RISCVDisassembler class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "MCTargetDesc/RISCVBaseInfo.h"
14#include "MCTargetDesc/RISCVMCTargetDesc.h"
15#include "TargetInfo/RISCVTargetInfo.h"
16#include "llvm/MC/MCContext.h"
17#include "llvm/MC/MCDecoderOps.h"
18#include "llvm/MC/MCDisassembler/MCDisassembler.h"
19#include "llvm/MC/MCInst.h"
20#include "llvm/MC/MCInstrInfo.h"
21#include "llvm/MC/MCRegisterInfo.h"
22#include "llvm/MC/MCSubtargetInfo.h"
23#include "llvm/MC/TargetRegistry.h"
24#include "llvm/Support/Endian.h"
25
26using namespace llvm;
27
28#define DEBUG_TYPE "riscv-disassembler"
29
30typedef MCDisassembler::DecodeStatus DecodeStatus;
31
32namespace {
33class RISCVDisassembler : public MCDisassembler {
34 std::unique_ptr<MCInstrInfo const> const MCII;
35
36public:
37 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
38 MCInstrInfo const *MCII)
39 : MCDisassembler(STI, Ctx), MCII(MCII) {}
40
41 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
42 ArrayRef<uint8_t> Bytes, uint64_t Address,
43 raw_ostream &CStream) const override;
44
45private:
46 void addSPOperands(MCInst &MI) const;
47
48 DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,
49 ArrayRef<uint8_t> Bytes, uint64_t Address,
50 raw_ostream &CStream) const;
51 DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size,
52 ArrayRef<uint8_t> Bytes, uint64_t Address,
53 raw_ostream &CStream) const;
54};
55} // end anonymous namespace
56
57static MCDisassembler *createRISCVDisassembler(const Target &T,
58 const MCSubtargetInfo &STI,
59 MCContext &Ctx) {
60 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
61}
62
63extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
64 // Register the disassembler for each target.
65 TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV32Target(),
66 Fn: createRISCVDisassembler);
67 TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV64Target(),
68 Fn: createRISCVDisassembler);
69}
70
71static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
72 uint64_t Address,
73 const MCDisassembler *Decoder) {
74 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
75
76 if (RegNo >= 32 || (IsRVE && RegNo >= 16))
77 return MCDisassembler::Fail;
78
79 MCRegister Reg = RISCV::X0 + RegNo;
80 Inst.addOperand(Op: MCOperand::createReg(Reg));
81 return MCDisassembler::Success;
82}
83
84static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,
85 uint64_t Address,
86 const MCDisassembler *Decoder) {
87 MCRegister Reg = RISCV::X0 + RegNo;
88 if (Reg != RISCV::X1 && Reg != RISCV::X5)
89 return MCDisassembler::Fail;
90
91 Inst.addOperand(Op: MCOperand::createReg(Reg));
92 return MCDisassembler::Success;
93}
94
95static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo,
96 uint64_t Address,
97 const MCDisassembler *Decoder) {
98 if (RegNo >= 32)
99 return MCDisassembler::Fail;
100
101 MCRegister Reg = RISCV::F0_H + RegNo;
102 Inst.addOperand(Op: MCOperand::createReg(Reg));
103 return MCDisassembler::Success;
104}
105
106static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo,
107 uint64_t Address,
108 const MCDisassembler *Decoder) {
109 if (RegNo >= 32)
110 return MCDisassembler::Fail;
111
112 MCRegister Reg = RISCV::F0_F + RegNo;
113 Inst.addOperand(Op: MCOperand::createReg(Reg));
114 return MCDisassembler::Success;
115}
116
117static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo,
118 uint64_t Address,
119 const MCDisassembler *Decoder) {
120 if (RegNo >= 8) {
121 return MCDisassembler::Fail;
122 }
123 MCRegister Reg = RISCV::F8_F + RegNo;
124 Inst.addOperand(Op: MCOperand::createReg(Reg));
125 return MCDisassembler::Success;
126}
127
128static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo,
129 uint64_t Address,
130 const MCDisassembler *Decoder) {
131 if (RegNo >= 32)
132 return MCDisassembler::Fail;
133
134 MCRegister Reg = RISCV::F0_D + RegNo;
135 Inst.addOperand(Op: MCOperand::createReg(Reg));
136 return MCDisassembler::Success;
137}
138
139static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,
140 uint64_t Address,
141 const MCDisassembler *Decoder) {
142 if (RegNo >= 8) {
143 return MCDisassembler::Fail;
144 }
145 MCRegister Reg = RISCV::F8_D + RegNo;
146 Inst.addOperand(Op: MCOperand::createReg(Reg));
147 return MCDisassembler::Success;
148}
149
150static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,
151 uint64_t Address,
152 const MCDisassembler *Decoder) {
153 if (RegNo == 0) {
154 return MCDisassembler::Fail;
155 }
156
157 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
158}
159
160static DecodeStatus
161DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address,
162 const MCDisassembler *Decoder) {
163 if (RegNo == 2) {
164 return MCDisassembler::Fail;
165 }
166
167 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
168}
169
170static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo,
171 uint64_t Address,
172 const MCDisassembler *Decoder) {
173 if (RegNo >= 8)
174 return MCDisassembler::Fail;
175
176 MCRegister Reg = RISCV::X8 + RegNo;
177 Inst.addOperand(Op: MCOperand::createReg(Reg));
178 return MCDisassembler::Success;
179}
180
181static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,
182 uint64_t Address,
183 const MCDisassembler *Decoder) {
184 if (RegNo >= 32 || RegNo & 1)
185 return MCDisassembler::Fail;
186
187 MCRegister Reg = RISCV::X0 + RegNo;
188 Inst.addOperand(Op: MCOperand::createReg(Reg));
189 return MCDisassembler::Success;
190}
191
192static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo,
193 uint64_t Address,
194 const void *Decoder) {
195 if (RegNo >= 8)
196 return MCDisassembler::Fail;
197
198 MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
199 Inst.addOperand(Op: MCOperand::createReg(Reg));
200 return MCDisassembler::Success;
201}
202
203static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,
204 uint64_t Address,
205 const MCDisassembler *Decoder) {
206 if (RegNo >= 32)
207 return MCDisassembler::Fail;
208
209 MCRegister Reg = RISCV::V0 + RegNo;
210 Inst.addOperand(Op: MCOperand::createReg(Reg));
211 return MCDisassembler::Success;
212}
213
214static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
215 uint64_t Address,
216 const MCDisassembler *Decoder) {
217 if (RegNo >= 32 || RegNo % 2)
218 return MCDisassembler::Fail;
219
220 const RISCVDisassembler *Dis =
221 static_cast<const RISCVDisassembler *>(Decoder);
222 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
223 MCRegister Reg =
224 RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0,
225 RC: &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
226
227 Inst.addOperand(Op: MCOperand::createReg(Reg));
228 return MCDisassembler::Success;
229}
230
231static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
232 uint64_t Address,
233 const MCDisassembler *Decoder) {
234 if (RegNo >= 32 || RegNo % 4)
235 return MCDisassembler::Fail;
236
237 const RISCVDisassembler *Dis =
238 static_cast<const RISCVDisassembler *>(Decoder);
239 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
240 MCRegister Reg =
241 RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0,
242 RC: &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
243
244 Inst.addOperand(Op: MCOperand::createReg(Reg));
245 return MCDisassembler::Success;
246}
247
248static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,
249 uint64_t Address,
250 const MCDisassembler *Decoder) {
251 if (RegNo >= 32 || RegNo % 8)
252 return MCDisassembler::Fail;
253
254 const RISCVDisassembler *Dis =
255 static_cast<const RISCVDisassembler *>(Decoder);
256 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
257 MCRegister Reg =
258 RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0,
259 RC: &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
260
261 Inst.addOperand(Op: MCOperand::createReg(Reg));
262 return MCDisassembler::Success;
263}
264
265static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,
266 uint64_t Address,
267 const MCDisassembler *Decoder) {
268 if (RegNo >= 2)
269 return MCDisassembler::Fail;
270
271 MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;
272
273 Inst.addOperand(Op: MCOperand::createReg(Reg));
274 return MCDisassembler::Success;
275}
276
277template <unsigned N>
278static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
279 int64_t Address,
280 const MCDisassembler *Decoder) {
281 assert(isUInt<N>(Imm) && "Invalid immediate");
282 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
283 return MCDisassembler::Success;
284}
285
286template <unsigned N>
287static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
288 int64_t Address,
289 const MCDisassembler *Decoder) {
290 if (Imm == 0)
291 return MCDisassembler::Fail;
292 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
293}
294
295template <unsigned N>
296static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
297 int64_t Address,
298 const MCDisassembler *Decoder) {
299 assert(isUInt<N>(Imm) && "Invalid immediate");
300 // Sign-extend the number in the bottom N bits of Imm
301 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<N>(Imm)));
302 return MCDisassembler::Success;
303}
304
305template <unsigned N>
306static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
307 int64_t Address,
308 const MCDisassembler *Decoder) {
309 if (Imm == 0)
310 return MCDisassembler::Fail;
311 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
312}
313
314template <unsigned N>
315static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm,
316 int64_t Address,
317 const MCDisassembler *Decoder) {
318 assert(isUInt<N>(Imm) && "Invalid immediate");
319 // Sign-extend the number in the bottom N bits of Imm after accounting for
320 // the fact that the N bit immediate is stored in N-1 bits (the LSB is
321 // always zero)
322 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<N>(Imm << 1)));
323 return MCDisassembler::Success;
324}
325
326static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
327 int64_t Address,
328 const MCDisassembler *Decoder) {
329 assert(isUInt<6>(Imm) && "Invalid immediate");
330 if (Imm > 31) {
331 Imm = (SignExtend64<6>(x: Imm) & 0xfffff);
332 }
333 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
334 return MCDisassembler::Success;
335}
336
337static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
338 const MCDisassembler *Decoder) {
339 assert(isUInt<3>(Imm) && "Invalid immediate");
340 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Mode: Imm))
341 return MCDisassembler::Fail;
342
343 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
344 return MCDisassembler::Success;
345}
346
347static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
348 uint64_t Address,
349 const MCDisassembler *Decoder);
350
351static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
352 uint64_t Address,
353 const MCDisassembler *Decoder);
354
355static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
356 uint64_t Address,
357 const MCDisassembler *Decoder);
358
359static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
360 uint64_t Address,
361 const MCDisassembler *Decoder);
362
363static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
364 uint64_t Address,
365 const MCDisassembler *Decoder);
366
367static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
368 uint64_t Address,
369 const MCDisassembler *Decoder);
370
371static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
372 uint64_t Address, const void *Decoder);
373
374static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
375 const MCDisassembler *Decoder);
376
377static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
378 uint64_t Address, const void *Decoder);
379
380static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
381 uint64_t Address,
382 const MCDisassembler *Decoder);
383
384#include "RISCVGenDisassemblerTables.inc"
385
386static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
387 uint64_t Address,
388 const MCDisassembler *Decoder) {
389 uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
390 [[maybe_unused]] DecodeStatus Result =
391 DecodeGPRNoX0RegisterClass(Inst, RegNo: Rd, Address, Decoder);
392 assert(Result == MCDisassembler::Success && "Invalid register");
393 Inst.addOperand(Op: Inst.getOperand(i: 0));
394 Inst.addOperand(Op: MCOperand::createImm(Val: 0));
395 return MCDisassembler::Success;
396}
397
398static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
399 uint64_t Address,
400 const MCDisassembler *Decoder) {
401 uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
402 [[maybe_unused]] DecodeStatus Result =
403 DecodeGPRX1X5RegisterClass(Inst, RegNo: Rs1, Address, Decoder);
404 assert(Result == MCDisassembler::Success && "Invalid register");
405 return MCDisassembler::Success;
406}
407
408static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
409 uint64_t Address,
410 const MCDisassembler *Decoder) {
411 Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0));
412 uint32_t SImm6 =
413 fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
414 [[maybe_unused]] DecodeStatus Result =
415 decodeSImmOperand<6>(Inst, Imm: SImm6, Address, Decoder);
416 assert(Result == MCDisassembler::Success && "Invalid immediate");
417 return MCDisassembler::Success;
418}
419
420static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
421 uint64_t Address,
422 const MCDisassembler *Decoder) {
423 Inst.addOperand(Op: MCOperand::createReg(Reg: RISCV::X0));
424 Inst.addOperand(Op: Inst.getOperand(i: 0));
425 uint32_t UImm6 =
426 fieldFromInstruction(insn: Insn, startBit: 12, numBits: 1) << 5 | fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
427 [[maybe_unused]] DecodeStatus Result =
428 decodeUImmOperand<6>(Inst, Imm: UImm6, Address, Decoder);
429 assert(Result == MCDisassembler::Success && "Invalid immediate");
430 return MCDisassembler::Success;
431}
432
433static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
434 uint64_t Address,
435 const MCDisassembler *Decoder) {
436 uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
437 uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
438 DecodeGPRRegisterClass(Inst, RegNo: Rd, Address, Decoder);
439 DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder);
440 return MCDisassembler::Success;
441}
442
443static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
444 uint64_t Address,
445 const MCDisassembler *Decoder) {
446 uint32_t Rd = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
447 uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 2, numBits: 5);
448 DecodeGPRRegisterClass(Inst, RegNo: Rd, Address, Decoder);
449 Inst.addOperand(Op: Inst.getOperand(i: 0));
450 DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder);
451 return MCDisassembler::Success;
452}
453
454static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
455 uint64_t Address,
456 const MCDisassembler *Decoder) {
457 uint32_t Rd1 = fieldFromInstruction(insn: Insn, startBit: 7, numBits: 5);
458 uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 15, numBits: 5);
459 uint32_t Rd2 = fieldFromInstruction(insn: Insn, startBit: 20, numBits: 5);
460 uint32_t UImm2 = fieldFromInstruction(insn: Insn, startBit: 25, numBits: 2);
461 DecodeGPRRegisterClass(Inst, RegNo: Rd1, Address, Decoder);
462 DecodeGPRRegisterClass(Inst, RegNo: Rd2, Address, Decoder);
463 DecodeGPRRegisterClass(Inst, RegNo: Rs1, Address, Decoder);
464 [[maybe_unused]] DecodeStatus Result =
465 decodeUImmOperand<2>(Inst, Imm: UImm2, Address, Decoder);
466 assert(Result == MCDisassembler::Success && "Invalid immediate");
467
468 // Disassemble the final operand which is implicit.
469 unsigned Opcode = Inst.getOpcode();
470 bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD ||
471 Opcode == RISCV::TH_SWD);
472 if (IsWordOp)
473 Inst.addOperand(Op: MCOperand::createImm(Val: 3));
474 else
475 Inst.addOperand(Op: MCOperand::createImm(Val: 4));
476
477 return MCDisassembler::Success;
478}
479
480static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
481 uint64_t Address, const void *Decoder) {
482 if (Imm <= 3)
483 return MCDisassembler::Fail;
484 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
485 return MCDisassembler::Success;
486}
487
488static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
489 const MCDisassembler *Decoder) {
490 uint32_t Rs1 = fieldFromInstruction(insn: Insn, startBit: 0, numBits: 5);
491 uint32_t Rs2 = fieldFromInstruction(insn: Insn, startBit: 5, numBits: 5);
492 DecodeGPRRegisterClass(Inst, RegNo: Rs1, Address, Decoder);
493 DecodeGPRRegisterClass(Inst, RegNo: Rs2, Address, Decoder);
494 return MCDisassembler::Success;
495}
496
497static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
498 uint64_t Address, const void *Decoder) {
499 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
500 return MCDisassembler::Success;
501}
502
503// Add implied SP operand for C.*SP compressed instructions. The SP operand
504// isn't explicitly encoded in the instruction.
505void RISCVDisassembler::addSPOperands(MCInst &MI) const {
506 const MCInstrDesc &MCID = MCII->get(Opcode: MI.getOpcode());
507 for (unsigned i = 0; i < MCID.getNumOperands(); i++)
508 if (MCID.operands()[i].RegClass == RISCV::SPRegClassID)
509 MI.insert(I: MI.begin() + i, Op: MCOperand::createReg(Reg: RISCV::X2));
510}
511
512#define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, \
513 DESC, ADDITIONAL_OPERATION) \
514 do { \
515 if (FEATURE_CHECKS) { \
516 LLVM_DEBUG(dbgs() << "Trying " DESC ":\n"); \
517 DecodeStatus Result = \
518 decodeInstruction(DECODER_TABLE, MI, Insn, Address, this, STI); \
519 if (Result != MCDisassembler::Fail) { \
520 ADDITIONAL_OPERATION; \
521 return Result; \
522 } \
523 } \
524 } while (false)
525#define TRY_TO_DECODE_AND_ADD_SP(FEATURE_CHECKS, DECODER_TABLE, DESC) \
526 TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
527 addSPOperands(MI))
528#define TRY_TO_DECODE(FEATURE_CHECKS, DECODER_TABLE, DESC) \
529 TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
530 (void)nullptr)
531#define TRY_TO_DECODE_FEATURE(FEATURE, DECODER_TABLE, DESC) \
532 TRY_TO_DECODE(STI.hasFeature(FEATURE), DECODER_TABLE, DESC)
533
534DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
535 ArrayRef<uint8_t> Bytes,
536 uint64_t Address,
537 raw_ostream &CS) const {
538 if (Bytes.size() < 4) {
539 Size = 0;
540 return MCDisassembler::Fail;
541 }
542 Size = 4;
543
544 uint32_t Insn = support::endian::read32le(P: Bytes.data());
545
546 TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZdinx) &&
547 !STI.hasFeature(RISCV::Feature64Bit),
548 DecoderTableRV32Zdinx32,
549 "RV32Zdinx table (Double in Integer and rv32)");
550 TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZacas) &&
551 !STI.hasFeature(RISCV::Feature64Bit),
552 DecoderTableRV32Zacas32,
553 "RV32Zacas table (Compare-And-Swap and rv32)");
554 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZfinx, DecoderTableRVZfinx32,
555 "RVZfinx table (Float in Integer)");
556 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXVentanaCondOps,
557 DecoderTableXVentana32, "Ventana custom opcode table");
558 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBa, DecoderTableXTHeadBa32,
559 "XTHeadBa custom opcode table");
560 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBb, DecoderTableXTHeadBb32,
561 "XTHeadBb custom opcode table");
562 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBs, DecoderTableXTHeadBs32,
563 "XTHeadBs custom opcode table");
564 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCondMov,
565 DecoderTableXTHeadCondMov32,
566 "XTHeadCondMov custom opcode table");
567 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCmo, DecoderTableXTHeadCmo32,
568 "XTHeadCmo custom opcode table");
569 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadFMemIdx,
570 DecoderTableXTHeadFMemIdx32,
571 "XTHeadFMemIdx custom opcode table");
572 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMac, DecoderTableXTHeadMac32,
573 "XTHeadMac custom opcode table");
574 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemIdx,
575 DecoderTableXTHeadMemIdx32,
576 "XTHeadMemIdx custom opcode table");
577 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemPair,
578 DecoderTableXTHeadMemPair32,
579 "XTHeadMemPair custom opcode table");
580 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadSync,
581 DecoderTableXTHeadSync32,
582 "XTHeadSync custom opcode table");
583 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadVdot,
584 DecoderTableXTHeadVdot32,
585 "XTHeadVdot custom opcode table");
586 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfvcp, DecoderTableXSfvcp32,
587 "SiFive VCIX custom opcode table");
588 TRY_TO_DECODE_FEATURE(
589 RISCV::FeatureVendorXSfvqmaccdod, DecoderTableXSfvqmaccdod32,
590 "SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table");
591 TRY_TO_DECODE_FEATURE(
592 RISCV::FeatureVendorXSfvqmaccqoq, DecoderTableXSfvqmaccqoq32,
593 "SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table");
594 TRY_TO_DECODE_FEATURE(
595 RISCV::FeatureVendorXSfvfwmaccqqq, DecoderTableXSfvfwmaccqqq32,
596 "SiFive Matrix Multiplication Instruction opcode table");
597 TRY_TO_DECODE_FEATURE(
598 RISCV::FeatureVendorXSfvfnrclipxfqf, DecoderTableXSfvfnrclipxfqf32,
599 "SiFive FP32-to-int8 Ranged Clip Instructions opcode table");
600 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecdiscarddlone,
601 DecoderTableXSiFivecdiscarddlone32,
602 "SiFive sf.cdiscard.d.l1 custom opcode table");
603 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecflushdlone,
604 DecoderTableXSiFivecflushdlone32,
605 "SiFive sf.cflush.d.l1 custom opcode table");
606 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcease, DecoderTableXSfcease32,
607 "SiFive sf.cease custom opcode table");
608 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,
609 DecoderTableXCVbitmanip32,
610 "CORE-V Bit Manipulation custom opcode table");
611 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32,
612 "CORE-V Event load custom opcode table");
613 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32,
614 "CORE-V MAC custom opcode table");
615 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32,
616 "CORE-V MEM custom opcode table");
617 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32,
618 "CORE-V ALU custom opcode table");
619 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32,
620 "CORE-V SIMD extensions custom opcode table");
621 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
622 "CORE-V Immediate Branching custom opcode table");
623 TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
624
625 return MCDisassembler::Fail;
626}
627
628DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
629 ArrayRef<uint8_t> Bytes,
630 uint64_t Address,
631 raw_ostream &CS) const {
632 if (Bytes.size() < 2) {
633 Size = 0;
634 return MCDisassembler::Fail;
635 }
636 Size = 2;
637
638 uint32_t Insn = support::endian::read16le(P: Bytes.data());
639 TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit),
640 DecoderTableRISCV32Only_16,
641 "RISCV32Only_16 table (16-bit Instruction)");
642 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZicfiss, DecoderTableZicfiss16,
643 "RVZicfiss table (Shadow Stack)");
644 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16,
645 "Zcmt table (16-bit Table Jump Instructions)");
646 TRY_TO_DECODE_FEATURE(
647 RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,
648 "Zcmp table (16-bit Push/Pop & Double Move Instructions)");
649 TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
650 DecoderTableXwchc16,
651 "WCH QingKe XW custom opcode table");
652 TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16,
653 "RISCV_C table (16-bit Instruction)");
654
655 return MCDisassembler::Fail;
656}
657
658DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
659 ArrayRef<uint8_t> Bytes,
660 uint64_t Address,
661 raw_ostream &CS) const {
662 // It's a 16 bit instruction if bit 0 and 1 are not 0b11.
663 if ((Bytes[0] & 0b11) != 0b11)
664 return getInstruction16(MI, Size, Bytes, Address, CS);
665
666 // It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2
667 // are not 0b111.
668 if ((Bytes[0] & 0b1'1100) != 0b1'1100)
669 return getInstruction32(MI, Size, Bytes, Address, CS);
670
671 // 48-bit instructions are encoded as 0bxx011111.
672 if ((Bytes[0] & 0b11'1111) == 0b01'1111) {
673 Size = Bytes.size() >= 6 ? 6 : 0;
674 return MCDisassembler::Fail;
675 }
676
677 // 64-bit instructions are encoded as 0x0111111.
678 if ((Bytes[0] & 0b111'1111) == 0b011'1111) {
679 Size = Bytes.size() >= 8 ? 8 : 0;
680 return MCDisassembler::Fail;
681 }
682
683 // Remaining cases need to check a second byte.
684 if (Bytes.size() < 2) {
685 Size = 0;
686 return MCDisassembler::Fail;
687 }
688
689 // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.
690 // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.
691 unsigned nnn = (Bytes[1] >> 4) & 0b111;
692 if (nnn != 0b111) {
693 Size = 10 + (nnn * 2);
694 if (Bytes.size() < Size)
695 Size = 0;
696 return MCDisassembler::Fail;
697 }
698
699 // Remaining encodings are reserved for > 176-bit instructions.
700 Size = 0;
701 return MCDisassembler::Fail;
702}
703