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