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