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/MCDecoder.h"
18#include "llvm/MC/MCDecoderOps.h"
19#include "llvm/MC/MCDisassembler/MCDisassembler.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstrInfo.h"
22#include "llvm/MC/MCRegisterInfo.h"
23#include "llvm/MC/MCSubtargetInfo.h"
24#include "llvm/MC/TargetRegistry.h"
25#include "llvm/Support/Compiler.h"
26#include "llvm/Support/Endian.h"
27
28using namespace llvm;
29using namespace llvm::MCD;
30
31#define DEBUG_TYPE "riscv-disassembler"
32
33typedef MCDisassembler::DecodeStatus DecodeStatus;
34
35namespace {
36class RISCVDisassembler : public MCDisassembler {
37 std::unique_ptr<MCInstrInfo const> const MCII;
38
39public:
40 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
41 MCInstrInfo const *MCII)
42 : MCDisassembler(STI, Ctx), MCII(MCII) {}
43
44 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
45 ArrayRef<uint8_t> Bytes, uint64_t Address,
46 raw_ostream &CStream) const override;
47
48private:
49 DecodeStatus getInstruction48(MCInst &Instr, uint64_t &Size,
50 ArrayRef<uint8_t> Bytes, uint64_t Address,
51 raw_ostream &CStream) const;
52
53 DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,
54 ArrayRef<uint8_t> Bytes, uint64_t Address,
55 raw_ostream &CStream) const;
56 DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size,
57 ArrayRef<uint8_t> Bytes, uint64_t Address,
58 raw_ostream &CStream) const;
59};
60} // end anonymous namespace
61
62static MCDisassembler *createRISCVDisassembler(const Target &T,
63 const MCSubtargetInfo &STI,
64 MCContext &Ctx) {
65 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
66}
67
68static MCSymbolizer *
69createRISCVMCSymbolizer(const Triple &TT, LLVMOpInfoCallback GetOpInfo,
70 LLVMSymbolLookupCallback /*SymbolLookUp*/,
71 void *DisInfo, MCContext *Ctx,
72 std::unique_ptr<MCRelocationInfo> &&RelInfo) {
73 // RISC-V only asks MCSymbolizer to decode HI20/LO12 address fragments. They
74 // require relocation information and cannot be looked up as absolute
75 // addresses when GetOpInfo fails.
76 return llvm::createMCSymbolizer(TT, GetOpInfo, /*SymbolLookUp=*/nullptr,
77 DisInfo, Ctx, RelInfo: std::move(RelInfo));
78}
79
80extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void
81LLVMInitializeRISCVDisassembler() {
82 // Register the disassembler for each target.
83 TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV32Target(),
84 Fn: createRISCVDisassembler);
85 TargetRegistry::RegisterMCSymbolizer(T&: getTheRISCV32Target(),
86 Fn: createRISCVMCSymbolizer);
87 TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV64Target(),
88 Fn: createRISCVDisassembler);
89 TargetRegistry::RegisterMCSymbolizer(T&: getTheRISCV64Target(),
90 Fn: createRISCVMCSymbolizer);
91 TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV32beTarget(),
92 Fn: createRISCVDisassembler);
93 TargetRegistry::RegisterMCSymbolizer(T&: getTheRISCV32beTarget(),
94 Fn: createRISCVMCSymbolizer);
95 TargetRegistry::RegisterMCDisassembler(T&: getTheRISCV64beTarget(),
96 Fn: createRISCVDisassembler);
97 TargetRegistry::RegisterMCSymbolizer(T&: getTheRISCV64beTarget(),
98 Fn: createRISCVMCSymbolizer);
99}
100
101template <unsigned FirstReg, unsigned NumRegsInClass, unsigned RVELimit = 0>
102static DecodeStatus DecodeSimpleRegisterClass(MCInst &Inst, uint32_t RegNo,
103 uint64_t Address,
104 const MCDisassembler *Decoder) {
105 bool CheckRVE = RVELimit != 0 &&
106 Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
107
108 if (RegNo >= NumRegsInClass || (CheckRVE && RegNo >= RVELimit))
109 return MCDisassembler::Fail;
110
111 MCRegister Reg = FirstReg + RegNo;
112 Inst.addOperand(Op: MCOperand::createReg(Reg));
113 return MCDisassembler::Success;
114}
115
116template <unsigned PhysReg, unsigned Encoding>
117static DecodeStatus DecodeSingleRegister(MCInst &Inst, uint32_t RegNo,
118 uint64_t Address,
119 const MCDisassembler *Decoder) {
120 assert(RegNo == Encoding);
121 Inst.addOperand(Op: MCOperand::createReg(Reg: PhysReg));
122 return MCDisassembler::Success;
123}
124
125template <unsigned PhysReg, unsigned Encoding>
126static DecodeStatus DecodeSingleRegister(MCInst &Inst,
127 const MCDisassembler *Decoder) {
128 Inst.addOperand(Op: MCOperand::createReg(Reg: PhysReg));
129 return MCDisassembler::Success;
130}
131
132constexpr auto DecodeGPRRegisterClass =
133 DecodeSimpleRegisterClass<RISCV::X0, 32, /*RVELimit=*/16>;
134
135template <auto DecodeFn, auto PredicateFn>
136static DecodeStatus DecodeFilteredRegisterClass(MCInst &Inst, uint32_t RegNo,
137 uint64_t Address,
138 const MCDisassembler *Decoder) {
139 if (!PredicateFn(RegNo))
140 return MCDisassembler::Fail;
141 return DecodeFn(Inst, RegNo, Address, Decoder);
142}
143
144constexpr bool PredNoX0(uint32_t RegNo) { return RegNo != 0; }
145constexpr bool PredNoX2(uint32_t RegNo) { return RegNo != 2; }
146constexpr bool PredNoX31(uint32_t RegNo) { return RegNo != 31; }
147constexpr bool PredX1OrX5(uint32_t RegNo) { return RegNo == 1 || RegNo == 5; }
148
149constexpr auto DecodeGPRNoX0RegisterClass =
150 DecodeFilteredRegisterClass<DecodeGPRRegisterClass, PredNoX0>;
151constexpr auto DecodeGPRNoX2RegisterClass =
152 DecodeFilteredRegisterClass<DecodeGPRRegisterClass, PredNoX2>;
153constexpr auto DecodeGPRNoX31RegisterClass =
154 DecodeFilteredRegisterClass<DecodeGPRRegisterClass, PredNoX31>;
155constexpr auto DecodeGPRX1X5RegisterClass =
156 DecodeFilteredRegisterClass<DecodeGPRRegisterClass, PredX1OrX5>;
157
158static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,
159 uint64_t Address,
160 const MCDisassembler *Decoder) {
161 if (RegNo >= 32 || RegNo % 2)
162 return MCDisassembler::Fail;
163
164 const RISCVDisassembler *Dis =
165 static_cast<const RISCVDisassembler *>(Decoder);
166 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
167 MCRegister Reg = RI->getMatchingSuperReg(
168 Reg: RISCV::X0 + RegNo, SubIdx: RISCV::sub_gpr_even,
169 RC: &getRISCVMCRegisterClass(RC: RISCV::GPRPairRegClassID));
170 Inst.addOperand(Op: MCOperand::createReg(Reg));
171 return MCDisassembler::Success;
172}
173
174constexpr auto DecodeGPRPairNoX0RegisterClass =
175 DecodeFilteredRegisterClass<DecodeGPRPairRegisterClass, PredNoX0>;
176
177static DecodeStatus DecodeGPRPairCRegisterClass(MCInst &Inst, uint32_t RegNo,
178 uint64_t Address,
179 const MCDisassembler *Decoder) {
180 if (RegNo >= 8 || RegNo % 2)
181 return MCDisassembler::Fail;
182
183 return DecodeGPRPairRegisterClass(Inst, RegNo: RegNo + 8, Address, Decoder);
184}
185
186static DecodeStatus DecodeGPRS07RegisterClass(MCInst &Inst, uint32_t RegNo,
187 uint64_t Address,
188 const void *Decoder) {
189 if (RegNo >= 8)
190 return MCDisassembler::Fail;
191
192 MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
193 Inst.addOperand(Op: MCOperand::createReg(Reg));
194 return MCDisassembler::Success;
195}
196
197template <unsigned RegisterClass, unsigned NumRegsInClass, unsigned LMul>
198static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, uint32_t RegNo,
199 uint64_t Address,
200 const MCDisassembler *Decoder) {
201 if (RegNo >= NumRegsInClass || RegNo % LMul)
202 return MCDisassembler::Fail;
203
204 const RISCVDisassembler *Dis =
205 static_cast<const RISCVDisassembler *>(Decoder);
206 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
207 MCRegister Reg =
208 RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0,
209 RC: &getRISCVMCRegisterClass(RC: RegisterClass));
210
211 Inst.addOperand(Op: MCOperand::createReg(Reg));
212 return MCDisassembler::Success;
213}
214
215static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
216 uint64_t Address,
217 const MCDisassembler *Decoder) {
218 if (RegNo > 15 || RegNo % 2)
219 return MCDisassembler::Fail;
220
221 MCRegister Reg = RISCV::T0 + RegNo;
222 Inst.addOperand(Op: MCOperand::createReg(Reg));
223 return MCDisassembler::Success;
224}
225
226static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
227 uint64_t Address,
228 const MCDisassembler *Decoder) {
229 if (RegNo > 15 || RegNo % 4)
230 return MCDisassembler::Fail;
231
232 MCRegister Reg = RISCV::T0 + RegNo;
233 Inst.addOperand(Op: MCOperand::createReg(Reg));
234 return MCDisassembler::Success;
235}
236
237static DecodeStatus DecodeYBNDSWImm(MCInst &Inst, uint64_t Imm, int64_t Address,
238 const MCDisassembler *Decoder) {
239 assert(isUInt<9>(Imm) && "Invalid immediate");
240 uint64_t Result;
241 if (Imm == 0) {
242 // If imm[8:0] == 0, result is 4096.
243 Result = 4096;
244 } else if (Imm <= 255) {
245 // If imm[8] == 0 and imm[7:0] != 0, result is imm[7:0].
246 Result = Imm;
247 } else {
248 uint64_t Imm7To0 = Imm & 0xFF;
249 if (Imm7To0 <= 31) {
250 // If imm[8] == 1 and imm[7:5] == 0 (i.e. imm[7:0] <= 31), result is
251 // `256 | (imm[3:0] << 4) | (imm[4] << 3)`.
252 Result = 256 + ((Imm & 0xF) << 4) + (((Imm >> 4) & 1) << 3);
253 } else {
254 // Otherwise, result is imm[7:0] << 4.
255 Result = Imm7To0 << 4;
256 }
257 }
258 Inst.addOperand(Op: MCOperand::createImm(Val: Result));
259 return MCDisassembler::Success;
260}
261
262static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,
263 uint64_t Address,
264 const MCDisassembler *Decoder) {
265 if (RegNo >= 2)
266 return MCDisassembler::Fail;
267
268 MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;
269
270 Inst.addOperand(Op: MCOperand::createReg(Reg));
271 return MCDisassembler::Success;
272}
273
274template <int64_t Imm>
275static DecodeStatus decodeFixedImmOperand(MCInst &Inst,
276 const MCDisassembler *Decoder) {
277 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
278 return MCDisassembler::Success;
279}
280
281template <unsigned N, unsigned LowerBound = 0>
282static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
283 int64_t Address,
284 const MCDisassembler *Decoder) {
285 assert(isUInt<N>(Imm) && "Invalid immediate");
286
287 if (Imm < LowerBound)
288 return MCDisassembler::Fail;
289
290 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
291 return MCDisassembler::Success;
292}
293
294static DecodeStatus decodeUImmSlistOperand(MCInst &Inst, uint32_t Imm,
295 int64_t Address,
296 const MCDisassembler *Decoder) {
297 assert(isUInt<3>(Imm) && "Invalid Slist immediate");
298 const uint8_t Slist[] = {0, 1, 2, 4, 8, 16, 15, 31};
299 Inst.addOperand(Op: MCOperand::createImm(Val: Slist[Imm]));
300 return MCDisassembler::Success;
301}
302
303static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm,
304 int64_t Address,
305 const MCDisassembler *Decoder) {
306 assert(isUInt<6>(Imm) && "Invalid immediate");
307
308 if (!Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::Feature64Bit) &&
309 !isUInt<5>(x: Imm))
310 return MCDisassembler::Fail;
311
312 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
313 return MCDisassembler::Success;
314}
315
316static DecodeStatus decodeUImm7EqXLenOperand(MCInst &Inst, uint32_t Imm,
317 int64_t Address,
318 const MCDisassembler *Decoder) {
319 assert(isUInt<7>(Imm) && "Invalid immediate");
320
321 uint32_t ExpectedValue =
322 Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::Feature64Bit) ? 64 : 32;
323 if (Imm != ExpectedValue)
324 return MCDisassembler::Fail;
325
326 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
327 return MCDisassembler::Success;
328}
329
330template <unsigned N>
331static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
332 int64_t Address,
333 const MCDisassembler *Decoder) {
334 if (Imm == 0)
335 return MCDisassembler::Fail;
336 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
337}
338
339static DecodeStatus
340decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address,
341 const MCDisassembler *Decoder) {
342 if (Imm == 0)
343 return MCDisassembler::Fail;
344 return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder);
345}
346
347template <unsigned N, unsigned LowerBound = 1>
348static DecodeStatus decodeUImmPlus1Operand(MCInst &Inst, uint32_t Imm,
349 int64_t Address,
350 const MCDisassembler *Decoder) {
351 assert(isUInt<N>(Imm) && "Invalid immediate");
352
353 if ((Imm + 1) < LowerBound)
354 return MCDisassembler::Fail;
355
356 Inst.addOperand(Op: MCOperand::createImm(Val: Imm + 1));
357 return MCDisassembler::Success;
358}
359
360static DecodeStatus decodeImmZibiOperand(MCInst &Inst, uint32_t Imm,
361 int64_t Address,
362 const MCDisassembler *Decoder) {
363 assert(isUInt<5>(Imm) && "Invalid immediate");
364 Inst.addOperand(Op: MCOperand::createImm(Val: Imm ? Imm : -1LL));
365 return MCDisassembler::Success;
366}
367
368template <unsigned N>
369static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
370 int64_t Address,
371 const MCDisassembler *Decoder) {
372 assert(isUInt<N>(Imm) && "Invalid immediate");
373 // Sign-extend the number in the bottom N bits of Imm
374 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<N>(Imm)));
375 return MCDisassembler::Success;
376}
377
378static DecodeStatus decodeSImm12LoOperand(MCInst &Inst, uint32_t Imm,
379 int64_t Address,
380 const MCDisassembler *Decoder) {
381 assert(isUInt<12>(Imm) && "Invalid immediate");
382 const int64_t Value = SignExtend64<12>(x: Imm);
383 if (!Decoder->tryAddingSymbolicOperand(Inst, Value, Address,
384 /*IsBranch=*/false,
385 /*Offset=*/0, /*OpSize=*/4,
386 /*InstSize=*/4))
387 Inst.addOperand(Op: MCOperand::createImm(Val: Value));
388 return MCDisassembler::Success;
389}
390
391static DecodeStatus decodeUImm20Operand(MCInst &Inst, uint32_t Imm,
392 int64_t Address,
393 const MCDisassembler *Decoder) {
394 assert(isUInt<20>(Imm) && "Invalid immediate");
395 const int64_t Value = SignExtend64<32>(x: Imm << 12);
396 if (!Decoder->tryAddingSymbolicOperand(Inst, Value, Address,
397 /*IsBranch=*/false,
398 /*Offset=*/0, /*OpSize=*/4,
399 /*InstSize=*/4))
400 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
401 return MCDisassembler::Success;
402}
403
404template <unsigned N>
405static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
406 int64_t Address,
407 const MCDisassembler *Decoder) {
408 if (Imm == 0)
409 return MCDisassembler::Fail;
410 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
411}
412
413template <unsigned T, unsigned N>
414static DecodeStatus decodeSImmOperandAndLslN(MCInst &Inst, uint32_t Imm,
415 int64_t Address,
416 const MCDisassembler *Decoder) {
417 assert(isUInt<T - N + 1>(Imm) && "Invalid immediate");
418 // Sign-extend the number in the bottom T bits of Imm after accounting for
419 // the fact that the T bit immediate is stored in T-N bits (the LSB is
420 // always zero)
421 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<T>(Imm << N)));
422 return MCDisassembler::Success;
423}
424
425static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
426 int64_t Address,
427 const MCDisassembler *Decoder) {
428 assert(isUInt<6>(Imm) && "Invalid immediate");
429 if (Imm == 0)
430 return MCDisassembler::Fail;
431 Imm = SignExtend64<6>(x: Imm) & 0xfffff;
432 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
433 return MCDisassembler::Success;
434}
435
436static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
437 const MCDisassembler *Decoder) {
438 assert(isUInt<3>(Imm) && "Invalid immediate");
439 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Mode: Imm))
440 return MCDisassembler::Fail;
441
442 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
443 return MCDisassembler::Success;
444}
445
446static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
447 uint64_t Address,
448 const MCDisassembler *Decoder) {
449 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
450 if (Imm < RISCVZC::RA || (IsRVE && Imm >= RISCVZC::RA_S0_S2))
451 return MCDisassembler::Fail;
452 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
453 return MCDisassembler::Success;
454}
455
456static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,
457 uint64_t Address,
458 const MCDisassembler *Decoder) {
459 if (Imm < RISCVZC::RA_S0)
460 return MCDisassembler::Fail;
461 return decodeZcmpRlist(Inst, Imm, Address, Decoder);
462}
463
464#include "RISCVGenDisassemblerTables.inc"
465
466namespace {
467
468struct DecoderListEntry {
469 const uint8_t *Table;
470 FeatureBitset ContainedFeatures;
471 const char *Desc;
472
473 bool haveContainedFeatures(const FeatureBitset &ActiveFeatures) const {
474 return ContainedFeatures.none() ||
475 (ContainedFeatures & ActiveFeatures).any();
476 }
477};
478
479} // end anonymous namespace
480
481static constexpr FeatureBitset XCVFeatureGroup = {
482 RISCV::FeatureVendorXCVbitmanip, RISCV::FeatureVendorXCVelw,
483 RISCV::FeatureVendorXCVmac, RISCV::FeatureVendorXCVmem,
484 RISCV::FeatureVendorXCValu, RISCV::FeatureVendorXCVsimd,
485 RISCV::FeatureVendorXCVbi};
486
487static constexpr FeatureBitset XqciFeatureGroup = {
488 RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
489 RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
490 RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
491 RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
492 RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio,
493 RISCV::FeatureVendorXqcilb, RISCV::FeatureVendorXqcili,
494 RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
495 RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
496 RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync,
497};
498
499static constexpr FeatureBitset XSfVectorGroup = {
500 RISCV::FeatureVendorXSfvcp, RISCV::FeatureVendorXSfvqmaccdod,
501 RISCV::FeatureVendorXSfvqmaccqoq, RISCV::FeatureVendorXSfvfwmaccqqq,
502 RISCV::FeatureVendorXSfvfnrclipxfqf, RISCV::FeatureVendorXSfmmbase,
503 RISCV::FeatureVendorXSfvfexpa, RISCV::FeatureVendorXSfvfexpa64e,
504 RISCV::FeatureVendorXSfvfbfexp16e, RISCV::FeatureVendorXSfvfexp16e,
505 RISCV::FeatureVendorXSfvfexp32e};
506static constexpr FeatureBitset XSfSystemGroup = {
507 RISCV::FeatureVendorXSiFivecdiscarddlone,
508 RISCV::FeatureVendorXSiFivecflushdlone,
509};
510
511static constexpr FeatureBitset XMIPSGroup = {
512 RISCV::FeatureVendorXMIPSLSP,
513 RISCV::FeatureVendorXMIPSCMov,
514 RISCV::FeatureVendorXMIPSCBOP,
515 RISCV::FeatureVendorXMIPSEXECTL,
516};
517
518static constexpr FeatureBitset XTHeadGroup = {
519 RISCV::FeatureVendorXTHeadBa, RISCV::FeatureVendorXTHeadBb,
520 RISCV::FeatureVendorXTHeadBs, RISCV::FeatureVendorXTHeadCondMov,
521 RISCV::FeatureVendorXTHeadCmo, RISCV::FeatureVendorXTHeadFMemIdx,
522 RISCV::FeatureVendorXTHeadMac, RISCV::FeatureVendorXTHeadMemIdx,
523 RISCV::FeatureVendorXTHeadMemPair, RISCV::FeatureVendorXTHeadSync,
524 RISCV::FeatureVendorXTHeadVdot};
525
526static constexpr FeatureBitset XAndesGroup = {
527 RISCV::FeatureVendorXAndesPerf, RISCV::FeatureVendorXAndesBFHCvt,
528 RISCV::FeatureVendorXAndesVBFHCvt, RISCV::FeatureVendorXAndesVSIntH,
529 RISCV::FeatureVendorXAndesVSIntLoad, RISCV::FeatureVendorXAndesVPackFPH,
530 RISCV::FeatureVendorXAndesVDot};
531
532static constexpr FeatureBitset XSMTGroup = {RISCV::FeatureVendorXSMTVDot,
533 RISCV::FeatureVendorXSMTVDotII};
534
535static constexpr FeatureBitset XAIFGroup = {RISCV::FeatureVendorXAIFET};
536
537static constexpr DecoderListEntry DecoderList32[]{
538 // Vendor Extensions
539 {.Table: DecoderTableXCV32, .ContainedFeatures: XCVFeatureGroup, .Desc: "CORE-V extensions"},
540 {.Table: DecoderTableXqci32, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC Extensions"},
541 {.Table: DecoderTableXTHead32, .ContainedFeatures: XTHeadGroup, .Desc: "T-Head extensions"},
542 {.Table: DecoderTableXSfvector32, .ContainedFeatures: XSfVectorGroup, .Desc: "SiFive vector extensions"},
543 {.Table: DecoderTableXSfsystem32, .ContainedFeatures: XSfSystemGroup, .Desc: "SiFive system extensions"},
544 {.Table: DecoderTableXSfcease32, .ContainedFeatures: {RISCV::FeatureVendorXSfcease}, .Desc: "SiFive sf.cease"},
545 {.Table: DecoderTableXMIPS32, .ContainedFeatures: XMIPSGroup, .Desc: "Mips extensions"},
546 {.Table: DecoderTableXAndes32, .ContainedFeatures: XAndesGroup, .Desc: "Andes extensions"},
547 {.Table: DecoderTableXSMT32, .ContainedFeatures: XSMTGroup, .Desc: "SpacemiT extensions"},
548 {.Table: DecoderTableXAIF32, .ContainedFeatures: XAIFGroup, .Desc: "AI Foundry extensions"},
549 // Standard Extensions
550 {.Table: DecoderTable32, .ContainedFeatures: {}, .Desc: "standard 32-bit instructions"},
551 {.Table: DecoderTableRV32Only32, .ContainedFeatures: {}, .Desc: "RV32-only standard 32-bit instructions"},
552 {.Table: DecoderTableZfinx32, .ContainedFeatures: {}, .Desc: "Zfinx (Float in Integer)"},
553 {.Table: DecoderTableZdinxRV32Only32, .ContainedFeatures: {}, .Desc: "RV32-only Zdinx (Double in Integer)"},
554};
555
556namespace {
557// Define bitwidths for various types used to instantiate the decoder.
558template <> constexpr uint32_t InsnBitWidth<uint16_t> = 16;
559template <> constexpr uint32_t InsnBitWidth<uint32_t> = 32;
560// Use uint64_t to represent 48 bit instructions.
561template <> constexpr uint32_t InsnBitWidth<uint64_t> = 48;
562} // namespace
563
564DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
565 ArrayRef<uint8_t> Bytes,
566 uint64_t Address,
567 raw_ostream &CS) const {
568 if (Bytes.size() < 4) {
569 Size = 0;
570 return MCDisassembler::Fail;
571 }
572 Size = 4;
573
574 uint32_t Insn = support::endian::read32le(P: Bytes.data());
575
576 for (const DecoderListEntry &Entry : DecoderList32) {
577 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
578 continue;
579
580 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
581 DecodeStatus Result =
582 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
583 if (Result == MCDisassembler::Fail)
584 continue;
585
586 return Result;
587 }
588
589 return MCDisassembler::Fail;
590}
591
592static constexpr DecoderListEntry DecoderList16[]{
593 // Vendor Extensions
594 {.Table: DecoderTableXqci16, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC 16-bit"},
595 {.Table: DecoderTableXqccmp16,
596 .ContainedFeatures: {RISCV::FeatureVendorXqccmp},
597 .Desc: "Xqccmp (Qualcomm 16-bit Push/Pop & Double Move Instructions)"},
598 {.Table: DecoderTableXqccmt16,
599 .ContainedFeatures: {RISCV::FeatureVendorXqccmt},
600 .Desc: "Xqccmt (Qualcomm 16-bit Table Jump Instructions)"},
601 {.Table: DecoderTableXwchc16, .ContainedFeatures: {RISCV::FeatureVendorXwchc}, .Desc: "WCH QingKe XW"},
602 // Standard Extensions
603 {.Table: DecoderTable16, .ContainedFeatures: {}, .Desc: "standard 16-bit instructions"},
604 {.Table: DecoderTableRV32Only16, .ContainedFeatures: {}, .Desc: "RV32-only 16-bit instructions"},
605 // Zc* instructions incompatible with Zcf or Zcd
606 {.Table: DecoderTableZcOverlap16,
607 .ContainedFeatures: {},
608 .Desc: "ZcOverlap (16-bit Instructions overlapping with Zcf/Zcd)"},
609};
610
611DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
612 ArrayRef<uint8_t> Bytes,
613 uint64_t Address,
614 raw_ostream &CS) const {
615 if (Bytes.size() < 2) {
616 Size = 0;
617 return MCDisassembler::Fail;
618 }
619 Size = 2;
620
621 uint16_t Insn = support::endian::read16le(P: Bytes.data());
622
623 for (const DecoderListEntry &Entry : DecoderList16) {
624 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
625 continue;
626
627 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
628 DecodeStatus Result =
629 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
630 if (Result != MCDisassembler::Fail)
631 return Result;
632 }
633
634 return MCDisassembler::Fail;
635}
636
637static constexpr DecoderListEntry DecoderList48[]{
638 {.Table: DecoderTableXqci48, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC 48bit"},
639};
640
641DecodeStatus RISCVDisassembler::getInstruction48(MCInst &MI, uint64_t &Size,
642 ArrayRef<uint8_t> Bytes,
643 uint64_t Address,
644 raw_ostream &CS) const {
645 if (Bytes.size() < 6) {
646 Size = 0;
647 return MCDisassembler::Fail;
648 }
649 Size = 6;
650
651 uint64_t Insn = 0;
652 for (size_t i = Size; i-- != 0;)
653 Insn += (static_cast<uint64_t>(Bytes[i]) << 8 * i);
654
655 for (const DecoderListEntry &Entry : DecoderList48) {
656 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
657 continue;
658
659 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
660 DecodeStatus Result =
661 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
662 if (Result == MCDisassembler::Fail)
663 continue;
664
665 return Result;
666 }
667
668 return MCDisassembler::Fail;
669}
670
671DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
672 ArrayRef<uint8_t> Bytes,
673 uint64_t Address,
674 raw_ostream &CS) const {
675 CommentStream = &CS;
676 // It's a 16 bit instruction if bit 0 and 1 are not 0b11.
677 if ((Bytes[0] & 0b11) != 0b11)
678 return getInstruction16(MI, Size, Bytes, Address, CS);
679
680 // Try to decode as a 32-bit instruction first.
681 DecodeStatus Result = getInstruction32(MI, Size, Bytes, Address, CS);
682 if (Result != MCDisassembler::Fail)
683 return Result;
684
685 // If bits [4:2] are 0b111 this might be a 48-bit or larger instruction,
686 // otherwise assume it's an unknown 32-bit instruction.
687 if ((Bytes[0] & 0b1'1100) != 0b1'1100) {
688 Size = Bytes.size() >= 4 ? 4 : 0;
689 return MCDisassembler::Fail;
690 }
691
692 // 48-bit instructions are encoded as 0bxx011111.
693 if ((Bytes[0] & 0b11'1111) == 0b01'1111)
694 return getInstruction48(MI, Size, Bytes, Address, CS);
695
696 // 64-bit instructions are encoded as 0x0111111.
697 if ((Bytes[0] & 0b111'1111) == 0b011'1111) {
698 Size = Bytes.size() >= 8 ? 8 : 0;
699 return MCDisassembler::Fail;
700 }
701
702 // Remaining cases need to check a second byte.
703 if (Bytes.size() < 2) {
704 Size = 0;
705 return MCDisassembler::Fail;
706 }
707
708 // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.
709 // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.
710 unsigned nnn = (Bytes[1] >> 4) & 0b111;
711 if (nnn != 0b111) {
712 Size = 10 + (nnn * 2);
713 if (Bytes.size() < Size)
714 Size = 0;
715 return MCDisassembler::Fail;
716 }
717
718 // Remaining encodings are reserved for > 176-bit instructions.
719 Size = 0;
720 return MCDisassembler::Fail;
721}
722