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 decodeTHMemIdxRs1Operand(MCInst &Inst, uint32_t RegNo,
159 uint64_t Address,
160 const MCDisassembler *Decoder) {
161 const DecodeStatus Result =
162 DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
163 if (Result != MCDisassembler::Success)
164 return Result;
165 const MCRegister Rd = Inst.getOperand(i: 0).getReg();
166 const MCRegister Rs1 = Inst.getOperand(i: Inst.getNumOperands() - 1).getReg();
167 if (Rd == Rs1)
168 return MCDisassembler::Fail;
169 return Result;
170}
171
172static DecodeStatus decodeTHMemPairRs1Operand(MCInst &Inst, uint32_t RegNo,
173 uint64_t Address,
174 const MCDisassembler *Decoder) {
175 const DecodeStatus Result =
176 DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
177 if (Result != MCDisassembler::Success)
178 return Result;
179 const MCRegister Rd1 = Inst.getOperand(i: 0).getReg();
180 const MCRegister Rd2 = Inst.getOperand(i: 1).getReg();
181 const MCRegister Rs1 = Inst.getOperand(i: Inst.getNumOperands() - 1).getReg();
182 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2)
183 return MCDisassembler::Fail;
184 return Result;
185}
186
187static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,
188 uint64_t Address,
189 const MCDisassembler *Decoder) {
190 if (RegNo >= 32 || RegNo % 2)
191 return MCDisassembler::Fail;
192
193 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
194 if (IsRVE && RegNo >= 16)
195 return MCDisassembler::Fail;
196
197 const RISCVDisassembler *Dis =
198 static_cast<const RISCVDisassembler *>(Decoder);
199 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
200 MCRegister Reg = RI->getMatchingSuperReg(
201 Reg: RISCV::X0 + RegNo, SubIdx: RISCV::sub_gpr_even,
202 RC: &getRISCVMCRegisterClass(RC: RISCV::GPRPairRegClassID));
203 Inst.addOperand(Op: MCOperand::createReg(Reg));
204 return MCDisassembler::Success;
205}
206
207constexpr auto DecodeGPRPairNoX0RegisterClass =
208 DecodeFilteredRegisterClass<DecodeGPRPairRegisterClass, PredNoX0>;
209
210static DecodeStatus DecodeGPRPairCRegisterClass(MCInst &Inst, uint32_t RegNo,
211 uint64_t Address,
212 const MCDisassembler *Decoder) {
213 if (RegNo >= 8 || RegNo % 2)
214 return MCDisassembler::Fail;
215
216 return DecodeGPRPairRegisterClass(Inst, RegNo: RegNo + 8, Address, Decoder);
217}
218
219static DecodeStatus DecodeGPRS07RegisterClass(MCInst &Inst, uint32_t RegNo,
220 uint64_t Address,
221 const MCDisassembler *Decoder) {
222 // Only s0 and s1 exist on RVE, so sreg values above 1 are reserved.
223 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
224 if (RegNo >= 8 || (IsRVE && RegNo > 1))
225 return MCDisassembler::Fail;
226
227 MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
228 Inst.addOperand(Op: MCOperand::createReg(Reg));
229 return MCDisassembler::Success;
230}
231
232template <unsigned RegisterClass, unsigned NumRegsInClass, unsigned LMul>
233static DecodeStatus DecodeVectorRegisterClass(MCInst &Inst, uint32_t RegNo,
234 uint64_t Address,
235 const MCDisassembler *Decoder) {
236 if (RegNo >= NumRegsInClass || RegNo % LMul)
237 return MCDisassembler::Fail;
238
239 const RISCVDisassembler *Dis =
240 static_cast<const RISCVDisassembler *>(Decoder);
241 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
242 MCRegister Reg =
243 RI->getMatchingSuperReg(Reg: RISCV::V0 + RegNo, SubIdx: RISCV::sub_vrm1_0,
244 RC: &getRISCVMCRegisterClass(RC: RegisterClass));
245
246 Inst.addOperand(Op: MCOperand::createReg(Reg));
247 return MCDisassembler::Success;
248}
249
250static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
251 uint64_t Address,
252 const MCDisassembler *Decoder) {
253 if (RegNo > 15 || RegNo % 2)
254 return MCDisassembler::Fail;
255
256 MCRegister Reg = RISCV::T0 + RegNo;
257 Inst.addOperand(Op: MCOperand::createReg(Reg));
258 return MCDisassembler::Success;
259}
260
261static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
262 uint64_t Address,
263 const MCDisassembler *Decoder) {
264 if (RegNo > 15 || RegNo % 4)
265 return MCDisassembler::Fail;
266
267 MCRegister Reg = RISCV::T0 + RegNo;
268 Inst.addOperand(Op: MCOperand::createReg(Reg));
269 return MCDisassembler::Success;
270}
271
272static DecodeStatus DecodeYBNDSWImm(MCInst &Inst, uint64_t Imm, int64_t Address,
273 const MCDisassembler *Decoder) {
274 assert(isUInt<9>(Imm) && "Invalid immediate");
275 uint64_t Result;
276 if (Imm == 0) {
277 // If imm[8:0] == 0, result is 4096.
278 Result = 4096;
279 } else if (Imm <= 255) {
280 // If imm[8] == 0 and imm[7:0] != 0, result is imm[7:0].
281 Result = Imm;
282 } else {
283 uint64_t Imm7To0 = Imm & 0xFF;
284 if (Imm7To0 <= 31) {
285 // If imm[8] == 1 and imm[7:5] == 0 (i.e. imm[7:0] <= 31), result is
286 // `256 | (imm[3:0] << 4) | (imm[4] << 3)`.
287 Result = 256 + ((Imm & 0xF) << 4) + (((Imm >> 4) & 1) << 3);
288 } else {
289 // Otherwise, result is imm[7:0] << 4.
290 Result = Imm7To0 << 4;
291 }
292 }
293 Inst.addOperand(Op: MCOperand::createImm(Val: Result));
294 return MCDisassembler::Success;
295}
296
297static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,
298 uint64_t Address,
299 const MCDisassembler *Decoder) {
300 if (RegNo >= 2)
301 return MCDisassembler::Fail;
302
303 MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;
304
305 Inst.addOperand(Op: MCOperand::createReg(Reg));
306 return MCDisassembler::Success;
307}
308
309template <int64_t Imm>
310static DecodeStatus decodeFixedImmOperand(MCInst &Inst,
311 const MCDisassembler *Decoder) {
312 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
313 return MCDisassembler::Success;
314}
315
316template <unsigned N, unsigned LowerBound = 0>
317static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
318 int64_t Address,
319 const MCDisassembler *Decoder) {
320 assert(isUInt<N>(Imm) && "Invalid immediate");
321
322 if (Imm < LowerBound)
323 return MCDisassembler::Fail;
324
325 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
326 return MCDisassembler::Success;
327}
328
329static DecodeStatus decodeUImmSlistOperand(MCInst &Inst, uint32_t Imm,
330 int64_t Address,
331 const MCDisassembler *Decoder) {
332 assert(isUInt<3>(Imm) && "Invalid Slist immediate");
333 const uint8_t Slist[] = {0, 1, 2, 4, 8, 16, 15, 31};
334 Inst.addOperand(Op: MCOperand::createImm(Val: Slist[Imm]));
335 return MCDisassembler::Success;
336}
337
338static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm,
339 int64_t Address,
340 const MCDisassembler *Decoder) {
341 assert(isUInt<6>(Imm) && "Invalid immediate");
342
343 if (!Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::Feature64Bit) &&
344 !isUInt<5>(x: Imm))
345 return MCDisassembler::Fail;
346
347 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
348 return MCDisassembler::Success;
349}
350
351template <unsigned N>
352static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
353 int64_t Address,
354 const MCDisassembler *Decoder) {
355 if (Imm == 0)
356 return MCDisassembler::Fail;
357 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
358}
359
360static DecodeStatus
361decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address,
362 const MCDisassembler *Decoder) {
363 if (Imm == 0)
364 return MCDisassembler::Fail;
365 return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder);
366}
367
368template <unsigned N, unsigned LowerBound = 1>
369static DecodeStatus decodeUImmPlus1Operand(MCInst &Inst, uint32_t Imm,
370 int64_t Address,
371 const MCDisassembler *Decoder) {
372 assert(isUInt<N>(Imm) && "Invalid immediate");
373
374 if ((Imm + 1) < LowerBound)
375 return MCDisassembler::Fail;
376
377 Inst.addOperand(Op: MCOperand::createImm(Val: Imm + 1));
378 return MCDisassembler::Success;
379}
380
381static DecodeStatus decodeImmZibiOperand(MCInst &Inst, uint32_t Imm,
382 int64_t Address,
383 const MCDisassembler *Decoder) {
384 assert(isUInt<5>(Imm) && "Invalid immediate");
385 Inst.addOperand(Op: MCOperand::createImm(Val: Imm ? Imm : -1LL));
386 return MCDisassembler::Success;
387}
388
389template <unsigned N>
390static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
391 int64_t Address,
392 const MCDisassembler *Decoder) {
393 assert(isUInt<N>(Imm) && "Invalid immediate");
394 // Sign-extend the number in the bottom N bits of Imm
395 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<N>(Imm)));
396 return MCDisassembler::Success;
397}
398
399static DecodeStatus decodeSImm12LoOperand(MCInst &Inst, uint32_t Imm,
400 int64_t Address,
401 const MCDisassembler *Decoder) {
402 assert(isUInt<12>(Imm) && "Invalid immediate");
403 const int64_t Value = SignExtend64<12>(x: Imm);
404 if (!Decoder->tryAddingSymbolicOperand(Inst, Value, Address,
405 /*IsBranch=*/false,
406 /*Offset=*/0, /*OpSize=*/4,
407 /*InstSize=*/4))
408 Inst.addOperand(Op: MCOperand::createImm(Val: Value));
409 return MCDisassembler::Success;
410}
411
412static DecodeStatus decodeUImm20Operand(MCInst &Inst, uint32_t Imm,
413 int64_t Address,
414 const MCDisassembler *Decoder) {
415 assert(isUInt<20>(Imm) && "Invalid immediate");
416 const int64_t Value = SignExtend64<32>(x: Imm << 12);
417 if (!Decoder->tryAddingSymbolicOperand(Inst, Value, Address,
418 /*IsBranch=*/false,
419 /*Offset=*/0, /*OpSize=*/4,
420 /*InstSize=*/4))
421 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
422 return MCDisassembler::Success;
423}
424
425template <unsigned N>
426static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
427 int64_t Address,
428 const MCDisassembler *Decoder) {
429 if (Imm == 0)
430 return MCDisassembler::Fail;
431 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
432}
433
434template <unsigned T, unsigned N>
435static DecodeStatus decodeSImmOperandAndLslN(MCInst &Inst, uint32_t Imm,
436 int64_t Address,
437 const MCDisassembler *Decoder) {
438 assert(isUInt<T - N + 1>(Imm) && "Invalid immediate");
439 // Sign-extend the number in the bottom T bits of Imm after accounting for
440 // the fact that the T bit immediate is stored in T-N bits (the LSB is
441 // always zero)
442 Inst.addOperand(Op: MCOperand::createImm(Val: SignExtend64<T>(Imm << N)));
443 return MCDisassembler::Success;
444}
445
446static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
447 int64_t Address,
448 const MCDisassembler *Decoder) {
449 assert(isUInt<6>(Imm) && "Invalid immediate");
450 if (Imm == 0)
451 return MCDisassembler::Fail;
452 Imm = SignExtend64<6>(x: Imm) & 0xfffff;
453 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
454 return MCDisassembler::Success;
455}
456
457static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
458 const MCDisassembler *Decoder) {
459 assert(isUInt<3>(Imm) && "Invalid immediate");
460 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Mode: Imm))
461 return MCDisassembler::Fail;
462
463 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
464 return MCDisassembler::Success;
465}
466
467static DecodeStatus decodeCVInsertIs2Operand(MCInst &Inst, uint32_t Imm,
468 int64_t Address,
469 const MCDisassembler *Decoder) {
470 const int64_t Is3 = Inst.getOperand(i: Inst.getNumOperands() - 1).getImm();
471 if (Is3 + Imm >= 32)
472 return MCDisassembler::Fail;
473 return decodeUImmOperand<5>(Inst, Imm, Address, Decoder);
474}
475
476static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
477 uint64_t Address,
478 const MCDisassembler *Decoder) {
479 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(Feature: RISCV::FeatureStdExtE);
480 if (Imm < RISCVZC::RA || (IsRVE && Imm >= RISCVZC::RA_S0_S2))
481 return MCDisassembler::Fail;
482 Inst.addOperand(Op: MCOperand::createImm(Val: Imm));
483 return MCDisassembler::Success;
484}
485
486static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,
487 uint64_t Address,
488 const MCDisassembler *Decoder) {
489 if (Imm < RISCVZC::RA_S0)
490 return MCDisassembler::Fail;
491 return decodeZcmpRlist(Inst, Imm, Address, Decoder);
492}
493
494static DecodeStatus decodeMvsa01Rs2Operand(MCInst &Inst, uint32_t RegNo,
495 uint64_t Address,
496 const MCDisassembler *Decoder) {
497 const DecodeStatus Result =
498 DecodeGPRS07RegisterClass(Inst, RegNo, Address, Decoder);
499 if (Result != MCDisassembler::Success)
500 return Result;
501 if (Inst.getOperand(i: 0).getReg() == Inst.getOperand(i: 1).getReg())
502 return MCDisassembler::Fail;
503 return MCDisassembler::Success;
504}
505
506#include "RISCVGenDisassemblerTables.inc"
507
508namespace {
509
510struct DecoderListEntry {
511 const uint8_t *Table;
512 FeatureBitset ContainedFeatures;
513 const char *Desc;
514
515 bool haveContainedFeatures(const FeatureBitset &ActiveFeatures) const {
516 return ContainedFeatures.none() ||
517 (ContainedFeatures & ActiveFeatures).any();
518 }
519};
520
521} // end anonymous namespace
522
523static constexpr FeatureBitset XCVFeatureGroup = {
524 RISCV::FeatureVendorXCVbitmanip, RISCV::FeatureVendorXCVelw,
525 RISCV::FeatureVendorXCVmac, RISCV::FeatureVendorXCVmem,
526 RISCV::FeatureVendorXCValu, RISCV::FeatureVendorXCVsimd,
527 RISCV::FeatureVendorXCVbi};
528
529static constexpr FeatureBitset XqciFeatureGroup = {
530 RISCV::FeatureVendorXqcia, RISCV::FeatureVendorXqciac,
531 RISCV::FeatureVendorXqcibi, RISCV::FeatureVendorXqcibm,
532 RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,
533 RISCV::FeatureVendorXqcics, RISCV::FeatureVendorXqcicsr,
534 RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio,
535 RISCV::FeatureVendorXqcilb, RISCV::FeatureVendorXqcili,
536 RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,
537 RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,
538 RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync,
539};
540
541static constexpr FeatureBitset XSfVectorGroup = {
542 RISCV::FeatureVendorXSfvcp, RISCV::FeatureVendorXSfvqmaccdod,
543 RISCV::FeatureVendorXSfvqmaccqoq, RISCV::FeatureVendorXSfvfwmaccqqq,
544 RISCV::FeatureVendorXSfvfnrclipxfqf, RISCV::FeatureVendorXSfmmbase,
545 RISCV::FeatureVendorXSfvfexpa, RISCV::FeatureVendorXSfvfexpa64e,
546 RISCV::FeatureVendorXSfvfbfexp16e, RISCV::FeatureVendorXSfvfexp16e,
547 RISCV::FeatureVendorXSfvfexp32e};
548static constexpr FeatureBitset XSfSystemGroup = {
549 RISCV::FeatureVendorXSiFivecdiscarddlone,
550 RISCV::FeatureVendorXSiFivecflushdlone,
551};
552
553static constexpr FeatureBitset XMIPSGroup = {
554 RISCV::FeatureVendorXMIPSLSP,
555 RISCV::FeatureVendorXMIPSCMov,
556 RISCV::FeatureVendorXMIPSCBOP,
557 RISCV::FeatureVendorXMIPSEXECTL,
558};
559
560static constexpr FeatureBitset XTHeadGroup = {
561 RISCV::FeatureVendorXTHeadBa, RISCV::FeatureVendorXTHeadBb,
562 RISCV::FeatureVendorXTHeadBs, RISCV::FeatureVendorXTHeadCondMov,
563 RISCV::FeatureVendorXTHeadCmo, RISCV::FeatureVendorXTHeadFMemIdx,
564 RISCV::FeatureVendorXTHeadMac, RISCV::FeatureVendorXTHeadMemIdx,
565 RISCV::FeatureVendorXTHeadMemPair, RISCV::FeatureVendorXTHeadSync,
566 RISCV::FeatureVendorXTHeadVdot};
567
568static constexpr FeatureBitset XAndesGroup = {
569 RISCV::FeatureVendorXAndesPerf, RISCV::FeatureVendorXAndesBFHCvt,
570 RISCV::FeatureVendorXAndesVBFHCvt, RISCV::FeatureVendorXAndesVSIntH,
571 RISCV::FeatureVendorXAndesVSIntLoad, RISCV::FeatureVendorXAndesVPackFPH,
572 RISCV::FeatureVendorXAndesVDot};
573
574static constexpr FeatureBitset XSMTGroup = {RISCV::FeatureVendorXSMTVDot,
575 RISCV::FeatureVendorXSMTVDotII};
576
577static constexpr FeatureBitset XAIFGroup = {RISCV::FeatureVendorXAIFET};
578
579static constexpr DecoderListEntry DecoderList32[]{
580 // Vendor Extensions
581 {.Table: DecoderTableXCV32, .ContainedFeatures: XCVFeatureGroup, .Desc: "CORE-V extensions"},
582 {.Table: DecoderTableXqci32, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC Extensions"},
583 {.Table: DecoderTableXTHead32, .ContainedFeatures: XTHeadGroup, .Desc: "T-Head extensions"},
584 {.Table: DecoderTableXSfvector32, .ContainedFeatures: XSfVectorGroup, .Desc: "SiFive vector extensions"},
585 {.Table: DecoderTableXSfsystem32, .ContainedFeatures: XSfSystemGroup, .Desc: "SiFive system extensions"},
586 {.Table: DecoderTableXSfcease32, .ContainedFeatures: {RISCV::FeatureVendorXSfcease}, .Desc: "SiFive sf.cease"},
587 {.Table: DecoderTableXMIPS32, .ContainedFeatures: XMIPSGroup, .Desc: "Mips extensions"},
588 {.Table: DecoderTableXAndes32, .ContainedFeatures: XAndesGroup, .Desc: "Andes extensions"},
589 {.Table: DecoderTableXSMT32, .ContainedFeatures: XSMTGroup, .Desc: "SpacemiT extensions"},
590 {.Table: DecoderTableXAIF32, .ContainedFeatures: XAIFGroup, .Desc: "AI Foundry extensions"},
591 // Standard Extensions
592 {.Table: DecoderTable32, .ContainedFeatures: {}, .Desc: "standard 32-bit instructions"},
593 {.Table: DecoderTableRV32Only32, .ContainedFeatures: {}, .Desc: "RV32-only standard 32-bit instructions"},
594 {.Table: DecoderTableZfinx32, .ContainedFeatures: {}, .Desc: "Zfinx (Float in Integer)"},
595 {.Table: DecoderTableZdinxRV32Only32, .ContainedFeatures: {}, .Desc: "RV32-only Zdinx (Double in Integer)"},
596};
597
598namespace {
599// Define bitwidths for various types used to instantiate the decoder.
600template <> constexpr uint32_t InsnBitWidth<uint16_t> = 16;
601template <> constexpr uint32_t InsnBitWidth<uint32_t> = 32;
602// Use uint64_t to represent 48 bit instructions.
603template <> constexpr uint32_t InsnBitWidth<uint64_t> = 48;
604} // namespace
605
606DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
607 ArrayRef<uint8_t> Bytes,
608 uint64_t Address,
609 raw_ostream &CS) const {
610 if (Bytes.size() < 4) {
611 Size = 0;
612 return MCDisassembler::Fail;
613 }
614 Size = 4;
615
616 uint32_t Insn = support::endian::read32le(P: Bytes.data());
617
618 for (const DecoderListEntry &Entry : DecoderList32) {
619 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
620 continue;
621
622 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
623 DecodeStatus Result =
624 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
625 if (Result == MCDisassembler::Fail)
626 continue;
627
628 return Result;
629 }
630
631 return MCDisassembler::Fail;
632}
633
634static constexpr DecoderListEntry DecoderList16[]{
635 // Vendor Extensions
636 {.Table: DecoderTableXqci16, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC 16-bit"},
637 {.Table: DecoderTableXqccmp16,
638 .ContainedFeatures: {RISCV::FeatureVendorXqccmp},
639 .Desc: "Xqccmp (Qualcomm 16-bit Push/Pop & Double Move Instructions)"},
640 {.Table: DecoderTableXqccmi16,
641 .ContainedFeatures: {RISCV::FeatureVendorXqccmi},
642 .Desc: "Xqccmi (Qualcomm 16-bit Instruction Lookup Table)"},
643 {.Table: DecoderTableXqccmt16,
644 .ContainedFeatures: {RISCV::FeatureVendorXqccmt},
645 .Desc: "Xqccmt (Qualcomm 16-bit Table Jump Instructions)"},
646 {.Table: DecoderTableXwchc16, .ContainedFeatures: {RISCV::FeatureVendorXwchc}, .Desc: "WCH QingKe XW"},
647 // Standard Extensions
648 {.Table: DecoderTable16, .ContainedFeatures: {}, .Desc: "standard 16-bit instructions"},
649 {.Table: DecoderTableRV32Only16, .ContainedFeatures: {}, .Desc: "RV32-only 16-bit instructions"},
650 // Zc* instructions incompatible with Zcf or Zcd
651 {.Table: DecoderTableZcOverlap16,
652 .ContainedFeatures: {},
653 .Desc: "ZcOverlap (16-bit Instructions overlapping with Zcf/Zcd)"},
654};
655
656DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
657 ArrayRef<uint8_t> Bytes,
658 uint64_t Address,
659 raw_ostream &CS) const {
660 if (Bytes.size() < 2) {
661 Size = 0;
662 return MCDisassembler::Fail;
663 }
664 Size = 2;
665
666 uint16_t Insn = support::endian::read16le(P: Bytes.data());
667
668 for (const DecoderListEntry &Entry : DecoderList16) {
669 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
670 continue;
671
672 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
673 DecodeStatus Result =
674 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
675 if (Result != MCDisassembler::Fail)
676 return Result;
677 }
678
679 return MCDisassembler::Fail;
680}
681
682static constexpr DecoderListEntry DecoderList48[]{
683 {.Table: DecoderTableXqci48, .ContainedFeatures: XqciFeatureGroup, .Desc: "Qualcomm uC 48bit"},
684};
685
686DecodeStatus RISCVDisassembler::getInstruction48(MCInst &MI, uint64_t &Size,
687 ArrayRef<uint8_t> Bytes,
688 uint64_t Address,
689 raw_ostream &CS) const {
690 if (Bytes.size() < 6) {
691 Size = 0;
692 return MCDisassembler::Fail;
693 }
694 Size = 6;
695
696 uint64_t Insn = 0;
697 for (size_t i = Size; i-- != 0;)
698 Insn += (static_cast<uint64_t>(Bytes[i]) << 8 * i);
699
700 for (const DecoderListEntry &Entry : DecoderList48) {
701 if (!Entry.haveContainedFeatures(ActiveFeatures: STI.getFeatureBits()))
702 continue;
703
704 LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");
705 DecodeStatus Result =
706 decodeInstruction(DecodeTable: Entry.Table, MI, insn: Insn, Address, DisAsm: this, STI);
707 if (Result == MCDisassembler::Fail)
708 continue;
709
710 return Result;
711 }
712
713 return MCDisassembler::Fail;
714}
715
716DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
717 ArrayRef<uint8_t> Bytes,
718 uint64_t Address,
719 raw_ostream &CS) const {
720 CommentStream = &CS;
721 // It's a 16 bit instruction if bit 0 and 1 are not 0b11.
722 if ((Bytes[0] & 0b11) != 0b11)
723 return getInstruction16(MI, Size, Bytes, Address, CS);
724
725 // Try to decode as a 32-bit instruction first.
726 DecodeStatus Result = getInstruction32(MI, Size, Bytes, Address, CS);
727 if (Result != MCDisassembler::Fail)
728 return Result;
729
730 // If bits [4:2] are 0b111 this might be a 48-bit or larger instruction,
731 // otherwise assume it's an unknown 32-bit instruction.
732 if ((Bytes[0] & 0b1'1100) != 0b1'1100) {
733 Size = Bytes.size() >= 4 ? 4 : 0;
734 return MCDisassembler::Fail;
735 }
736
737 // 48-bit instructions are encoded as 0bxx011111.
738 if ((Bytes[0] & 0b11'1111) == 0b01'1111)
739 return getInstruction48(MI, Size, Bytes, Address, CS);
740
741 // 64-bit instructions are encoded as 0x0111111.
742 if ((Bytes[0] & 0b111'1111) == 0b011'1111) {
743 Size = Bytes.size() >= 8 ? 8 : 0;
744 return MCDisassembler::Fail;
745 }
746
747 // Remaining cases need to check a second byte.
748 if (Bytes.size() < 2) {
749 Size = 0;
750 return MCDisassembler::Fail;
751 }
752
753 // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.
754 // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.
755 unsigned nnn = (Bytes[1] >> 4) & 0b111;
756 if (nnn != 0b111) {
757 Size = 10 + (nnn * 2);
758 if (Bytes.size() < Size)
759 Size = 0;
760 return MCDisassembler::Fail;
761 }
762
763 // Remaining encodings are reserved for > 176-bit instructions.
764 Size = 0;
765 return MCDisassembler::Fail;
766}
767