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)
200     return MCDisassembler::Fail;
201 
202   if (RegNo % 2)
203     return MCDisassembler::Fail;
204 
205   const RISCVDisassembler *Dis =
206       static_cast<const RISCVDisassembler *>(Decoder);
207   const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
208   MCRegister Reg =
209       RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
210                               &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
211 
212   Inst.addOperand(MCOperand::createReg(Reg));
213   return MCDisassembler::Success;
214 }
215 
216 static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
217                                             uint64_t Address,
218                                             const MCDisassembler *Decoder) {
219   if (RegNo >= 32)
220     return MCDisassembler::Fail;
221 
222   if (RegNo % 4)
223     return MCDisassembler::Fail;
224 
225   const RISCVDisassembler *Dis =
226       static_cast<const RISCVDisassembler *>(Decoder);
227   const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
228   MCRegister Reg =
229       RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
230                               &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
231 
232   Inst.addOperand(MCOperand::createReg(Reg));
233   return MCDisassembler::Success;
234 }
235 
236 static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,
237                                             uint64_t Address,
238                                             const MCDisassembler *Decoder) {
239   if (RegNo >= 32)
240     return MCDisassembler::Fail;
241 
242   if (RegNo % 8)
243     return MCDisassembler::Fail;
244 
245   const RISCVDisassembler *Dis =
246       static_cast<const RISCVDisassembler *>(Decoder);
247   const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
248   MCRegister Reg =
249       RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
250                               &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
251 
252   Inst.addOperand(MCOperand::createReg(Reg));
253   return MCDisassembler::Success;
254 }
255 
256 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo,
257                                    uint64_t Address,
258                                    const MCDisassembler *Decoder) {
259   MCRegister Reg = RISCV::NoRegister;
260   switch (RegNo) {
261   default:
262     return MCDisassembler::Fail;
263   case 0:
264     Reg = RISCV::V0;
265     break;
266   case 1:
267     break;
268   }
269   Inst.addOperand(MCOperand::createReg(Reg));
270   return MCDisassembler::Success;
271 }
272 
273 template <unsigned N>
274 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
275                                       int64_t Address,
276                                       const MCDisassembler *Decoder) {
277   assert(isUInt<N>(Imm) && "Invalid immediate");
278   Inst.addOperand(MCOperand::createImm(Imm));
279   return MCDisassembler::Success;
280 }
281 
282 template <unsigned N>
283 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
284                                              int64_t Address,
285                                              const MCDisassembler *Decoder) {
286   if (Imm == 0)
287     return MCDisassembler::Fail;
288   return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
289 }
290 
291 template <unsigned N>
292 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
293                                       int64_t Address,
294                                       const MCDisassembler *Decoder) {
295   assert(isUInt<N>(Imm) && "Invalid immediate");
296   // Sign-extend the number in the bottom N bits of Imm
297   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
298   return MCDisassembler::Success;
299 }
300 
301 template <unsigned N>
302 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
303                                              int64_t Address,
304                                              const MCDisassembler *Decoder) {
305   if (Imm == 0)
306     return MCDisassembler::Fail;
307   return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
308 }
309 
310 template <unsigned N>
311 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm,
312                                              int64_t Address,
313                                              const MCDisassembler *Decoder) {
314   assert(isUInt<N>(Imm) && "Invalid immediate");
315   // Sign-extend the number in the bottom N bits of Imm after accounting for
316   // the fact that the N bit immediate is stored in N-1 bits (the LSB is
317   // always zero)
318   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
319   return MCDisassembler::Success;
320 }
321 
322 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
323                                          int64_t Address,
324                                          const MCDisassembler *Decoder) {
325   assert(isUInt<6>(Imm) && "Invalid immediate");
326   if (Imm > 31) {
327     Imm = (SignExtend64<6>(Imm) & 0xfffff);
328   }
329   Inst.addOperand(MCOperand::createImm(Imm));
330   return MCDisassembler::Success;
331 }
332 
333 static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
334                                  const MCDisassembler *Decoder) {
335   assert(isUInt<3>(Imm) && "Invalid immediate");
336   if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
337     return MCDisassembler::Fail;
338 
339   Inst.addOperand(MCOperand::createImm(Imm));
340   return MCDisassembler::Success;
341 }
342 
343 static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
344                                                uint64_t Address,
345                                                const MCDisassembler *Decoder);
346 
347 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
348                                          uint64_t Address,
349                                          const MCDisassembler *Decoder);
350 
351 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
352                                             uint64_t Address,
353                                             const MCDisassembler *Decoder);
354 
355 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
356                                         uint64_t Address,
357                                         const MCDisassembler *Decoder);
358 
359 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
360                                            uint64_t Address,
361                                            const MCDisassembler *Decoder);
362 
363 static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
364                                         uint64_t Address,
365                                         const MCDisassembler *Decoder);
366 
367 static DecodeStatus decodeZcmpRlist(MCInst &Inst, unsigned Imm,
368                                     uint64_t Address, const void *Decoder);
369 
370 static DecodeStatus decodeZcmpSpimm(MCInst &Inst, unsigned Imm,
371                                     uint64_t Address, const void *Decoder);
372 
373 #include "RISCVGenDisassemblerTables.inc"
374 
375 static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
376                                                uint64_t Address,
377                                                const MCDisassembler *Decoder) {
378   uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
379   DecodeStatus Result = DecodeGPRNoX0RegisterClass(Inst, Rd, Address, Decoder);
380   (void)Result;
381   assert(Result == MCDisassembler::Success && "Invalid register");
382   Inst.addOperand(Inst.getOperand(0));
383   Inst.addOperand(MCOperand::createImm(0));
384   return MCDisassembler::Success;
385 }
386 
387 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
388                                          uint64_t Address,
389                                          const MCDisassembler *Decoder) {
390   Inst.addOperand(MCOperand::createReg(RISCV::X0));
391   uint32_t SImm6 =
392       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
393   DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
394   (void)Result;
395   assert(Result == MCDisassembler::Success && "Invalid immediate");
396   return MCDisassembler::Success;
397 }
398 
399 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
400                                             uint64_t Address,
401                                             const MCDisassembler *Decoder) {
402   Inst.addOperand(MCOperand::createReg(RISCV::X0));
403   Inst.addOperand(Inst.getOperand(0));
404   uint32_t UImm6 =
405       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
406   DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
407   (void)Result;
408   assert(Result == MCDisassembler::Success && "Invalid immediate");
409   return MCDisassembler::Success;
410 }
411 
412 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
413                                         uint64_t Address,
414                                         const MCDisassembler *Decoder) {
415   uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
416   uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);
417   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
418   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
419   return MCDisassembler::Success;
420 }
421 
422 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
423                                            uint64_t Address,
424                                            const MCDisassembler *Decoder) {
425   uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
426   uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);
427   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
428   Inst.addOperand(Inst.getOperand(0));
429   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
430   return MCDisassembler::Success;
431 }
432 
433 static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
434                                         uint64_t Address,
435                                         const MCDisassembler *Decoder) {
436   uint32_t Rd1 = fieldFromInstruction(Insn, 7, 5);
437   uint32_t Rs1 = fieldFromInstruction(Insn, 15, 5);
438   uint32_t Rd2 = fieldFromInstruction(Insn, 20, 5);
439   uint32_t UImm2 = fieldFromInstruction(Insn, 25, 2);
440   DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder);
441   DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder);
442   DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
443   DecodeStatus Result = decodeUImmOperand<2>(Inst, UImm2, Address, Decoder);
444   (void)Result;
445   assert(Result == MCDisassembler::Success && "Invalid immediate");
446 
447   // Disassemble the final operand which is implicit.
448   unsigned Opcode = Inst.getOpcode();
449   bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD ||
450                    Opcode == RISCV::TH_SWD);
451   if (IsWordOp)
452     Inst.addOperand(MCOperand::createImm(3));
453   else
454     Inst.addOperand(MCOperand::createImm(4));
455 
456   return MCDisassembler::Success;
457 }
458 
459 static DecodeStatus decodeZcmpRlist(MCInst &Inst, unsigned Imm,
460                                     uint64_t Address, const void *Decoder) {
461   if (Imm <= 3)
462     return MCDisassembler::Fail;
463   Inst.addOperand(MCOperand::createImm(Imm));
464   return MCDisassembler::Success;
465 }
466 
467 // spimm is based on rlist now.
468 static DecodeStatus decodeZcmpSpimm(MCInst &Inst, unsigned Imm,
469                                     uint64_t Address, const void *Decoder) {
470   // TODO: check if spimm matches rlist
471   Inst.addOperand(MCOperand::createImm(Imm));
472   return MCDisassembler::Success;
473 }
474 
475 // Add implied SP operand for C.*SP compressed instructions. The SP operand
476 // isn't explicitly encoded in the instruction.
477 void RISCVDisassembler::addSPOperands(MCInst &MI) const {
478   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
479   for (unsigned i = 0; i < MCID.getNumOperands(); i++)
480     if (MCID.operands()[i].RegClass == RISCV::SPRegClassID)
481       MI.insert(MI.begin() + i, MCOperand::createReg(RISCV::X2));
482 }
483 
484 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
485                                                ArrayRef<uint8_t> Bytes,
486                                                uint64_t Address,
487                                                raw_ostream &CS) const {
488   // TODO: This will need modification when supporting instruction set
489   // extensions with instructions > 32-bits (up to 176 bits wide).
490   uint32_t Insn;
491   DecodeStatus Result;
492 
493 #define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, \
494                                                 DESC, ADDITIONAL_OPERATION)    \
495   do {                                                                         \
496     if (FEATURE_CHECKS) {                                                      \
497       LLVM_DEBUG(dbgs() << "Trying " DESC ":\n");                              \
498       Result = decodeInstruction(DECODER_TABLE, MI, Insn, Address, this, STI); \
499       if (Result != MCDisassembler::Fail) {                                    \
500         ADDITIONAL_OPERATION;                                                  \
501         return Result;                                                         \
502       }                                                                        \
503     }                                                                          \
504   } while (false)
505 #define TRY_TO_DECODE_AND_ADD_SP(FEATURE_CHECKS, DECODER_TABLE, DESC)          \
506   TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
507                                           addSPOperands(MI))
508 #define TRY_TO_DECODE(FEATURE_CHECKS, DECODER_TABLE, DESC)                     \
509   TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
510                                           (void)nullptr)
511 #define TRY_TO_DECODE_FEATURE(FEATURE, DECODER_TABLE, DESC)                    \
512   TRY_TO_DECODE(STI.hasFeature(FEATURE), DECODER_TABLE, DESC)
513 
514   // It's a 32 bit instruction if bit 0 and 1 are 1.
515   if ((Bytes[0] & 0x3) == 0x3) {
516     if (Bytes.size() < 4) {
517       Size = 0;
518       return MCDisassembler::Fail;
519     }
520     Size = 4;
521 
522     Insn = support::endian::read32le(Bytes.data());
523 
524     TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZdinx) &&
525                       !STI.hasFeature(RISCV::Feature64Bit),
526                   DecoderTableRV32Zdinx32,
527                   "RV32Zdinx table (Double in Integer and rv32)");
528     TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZfinx, DecoderTableRVZfinx32,
529                           "RVZfinx table (Float in Integer)");
530     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXVentanaCondOps,
531                           DecoderTableVentana32, "Ventana custom opcode table");
532     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBa, DecoderTableTHeadBa32,
533                           "XTHeadBa custom opcode table");
534     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBb, DecoderTableTHeadBb32,
535                           "XTHeadBb custom opcode table");
536     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBs, DecoderTableTHeadBs32,
537                           "XTHeadBs custom opcode table");
538     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCondMov,
539                           DecoderTableTHeadCondMov32,
540                           "XTHeadCondMov custom opcode table");
541     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCmo, DecoderTableTHeadCmo32,
542                           "XTHeadCmo custom opcode table");
543     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadFMemIdx,
544                           DecoderTableTHeadFMemIdx32,
545                           "XTHeadFMemIdx custom opcode table");
546     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMac, DecoderTableTHeadMac32,
547                           "XTHeadMac custom opcode table");
548     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemIdx,
549                           DecoderTableTHeadMemIdx32,
550                           "XTHeadMemIdx custom opcode table");
551     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemPair,
552                           DecoderTableTHeadMemPair32,
553                           "XTHeadMemPair custom opcode table");
554     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadSync,
555                           DecoderTableTHeadSync32,
556                           "XTHeadSync custom opcode table");
557     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadVdot, DecoderTableTHeadV32,
558                           "XTHeadVdot custom opcode table");
559     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfvcp, DecoderTableXSfvcp32,
560                           "SiFive VCIX custom opcode table");
561     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcie, DecoderTableXSfcie32,
562                           "Sifive CIE custom opcode table");
563     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,
564                           DecoderTableXCVbitmanip32,
565                           "CORE-V Bit Manipulation custom opcode table");
566     TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32,
567                           "CORE-V MAC custom opcode table");
568     TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
569 
570     return MCDisassembler::Fail;
571   }
572 
573   if (Bytes.size() < 2) {
574     Size = 0;
575     return MCDisassembler::Fail;
576   }
577   Size = 2;
578 
579   Insn = support::endian::read16le(Bytes.data());
580   TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit),
581                            DecoderTableRISCV32Only_16,
582                            "RISCV32Only_16 table (16-bit Instruction)");
583   TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16,
584                         "Zcmt table (16-bit Table Jump Instructions)");
585   TRY_TO_DECODE_FEATURE(
586       RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,
587       "Zcmp table (16-bit Push/Pop & Double Move Instructions)");
588   TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16,
589                            "RISCV_C table (16-bit Instruction)");
590 
591   return MCDisassembler::Fail;
592 }
593