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