xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
106c3fb27SDimitry Andric //===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the RISCVDisassembler class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
13e8d8bef9SDimitry Andric #include "MCTargetDesc/RISCVBaseInfo.h"
140b57cec5SDimitry Andric #include "MCTargetDesc/RISCVMCTargetDesc.h"
150b57cec5SDimitry Andric #include "TargetInfo/RISCVTargetInfo.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
1781ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
205ffd83dbSDimitry Andric #include "llvm/MC/MCInstrInfo.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
23349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
240b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric using namespace llvm;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric #define DEBUG_TYPE "riscv-disassembler"
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric namespace {
330b57cec5SDimitry Andric class RISCVDisassembler : public MCDisassembler {
345ffd83dbSDimitry Andric   std::unique_ptr<MCInstrInfo const> const MCII;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric public:
375ffd83dbSDimitry Andric   RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
385ffd83dbSDimitry Andric                     MCInstrInfo const *MCII)
395ffd83dbSDimitry Andric       : MCDisassembler(STI, Ctx), MCII(MCII) {}
400b57cec5SDimitry Andric 
410b57cec5SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
420b57cec5SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
430b57cec5SDimitry Andric                               raw_ostream &CStream) const override;
4406c3fb27SDimitry Andric 
4506c3fb27SDimitry Andric private:
4606c3fb27SDimitry Andric   void addSPOperands(MCInst &MI) const;
47*0fca6ea1SDimitry Andric 
48*0fca6ea1SDimitry Andric   DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,
49*0fca6ea1SDimitry Andric                                 ArrayRef<uint8_t> Bytes, uint64_t Address,
50*0fca6ea1SDimitry Andric                                 raw_ostream &CStream) const;
51*0fca6ea1SDimitry Andric   DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size,
52*0fca6ea1SDimitry Andric                                 ArrayRef<uint8_t> Bytes, uint64_t Address,
53*0fca6ea1SDimitry Andric                                 raw_ostream &CStream) const;
540b57cec5SDimitry Andric };
550b57cec5SDimitry Andric } // end anonymous namespace
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric static MCDisassembler *createRISCVDisassembler(const Target &T,
580b57cec5SDimitry Andric                                                const MCSubtargetInfo &STI,
590b57cec5SDimitry Andric                                                MCContext &Ctx) {
605ffd83dbSDimitry Andric   return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
63480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
640b57cec5SDimitry Andric   // Register the disassembler for each target.
650b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
660b57cec5SDimitry Andric                                          createRISCVDisassembler);
670b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
680b57cec5SDimitry Andric                                          createRISCVDisassembler);
690b57cec5SDimitry Andric }
700b57cec5SDimitry Andric 
7106c3fb27SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,
720b57cec5SDimitry Andric                                            uint64_t Address,
7381ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
74*0fca6ea1SDimitry Andric   bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);
750b57cec5SDimitry Andric 
7606c3fb27SDimitry Andric   if (RegNo >= 32 || (IsRVE && RegNo >= 16))
770b57cec5SDimitry Andric     return MCDisassembler::Fail;
780b57cec5SDimitry Andric 
79e8d8bef9SDimitry Andric   MCRegister Reg = RISCV::X0 + RegNo;
80e8d8bef9SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
81e8d8bef9SDimitry Andric   return MCDisassembler::Success;
82e8d8bef9SDimitry Andric }
83e8d8bef9SDimitry Andric 
84647cbc5dSDimitry Andric static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,
85647cbc5dSDimitry Andric                                                uint64_t Address,
86647cbc5dSDimitry Andric                                                const MCDisassembler *Decoder) {
87647cbc5dSDimitry Andric   MCRegister Reg = RISCV::X0 + RegNo;
88647cbc5dSDimitry Andric   if (Reg != RISCV::X1 && Reg != RISCV::X5)
89647cbc5dSDimitry Andric     return MCDisassembler::Fail;
90647cbc5dSDimitry Andric 
91647cbc5dSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
92647cbc5dSDimitry Andric   return MCDisassembler::Success;
93647cbc5dSDimitry Andric }
94647cbc5dSDimitry Andric 
9506c3fb27SDimitry Andric static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo,
96e8d8bef9SDimitry Andric                                              uint64_t Address,
9781ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
98e8d8bef9SDimitry Andric   if (RegNo >= 32)
99e8d8bef9SDimitry Andric     return MCDisassembler::Fail;
100e8d8bef9SDimitry Andric 
101e8d8bef9SDimitry Andric   MCRegister Reg = RISCV::F0_H + RegNo;
1020b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1030b57cec5SDimitry Andric   return MCDisassembler::Success;
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
10606c3fb27SDimitry Andric static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo,
1070b57cec5SDimitry Andric                                              uint64_t Address,
10881ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
1098bcb0991SDimitry Andric   if (RegNo >= 32)
1100b57cec5SDimitry Andric     return MCDisassembler::Fail;
1110b57cec5SDimitry Andric 
112e8d8bef9SDimitry Andric   MCRegister Reg = RISCV::F0_F + RegNo;
1130b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1140b57cec5SDimitry Andric   return MCDisassembler::Success;
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric 
11706c3fb27SDimitry Andric static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo,
1180b57cec5SDimitry Andric                                               uint64_t Address,
11981ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
1208bcb0991SDimitry Andric   if (RegNo >= 8) {
1210b57cec5SDimitry Andric     return MCDisassembler::Fail;
1220b57cec5SDimitry Andric   }
123e8d8bef9SDimitry Andric   MCRegister Reg = RISCV::F8_F + RegNo;
1240b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1250b57cec5SDimitry Andric   return MCDisassembler::Success;
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric 
12806c3fb27SDimitry Andric static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo,
1290b57cec5SDimitry Andric                                              uint64_t Address,
13081ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
1318bcb0991SDimitry Andric   if (RegNo >= 32)
1320b57cec5SDimitry Andric     return MCDisassembler::Fail;
1330b57cec5SDimitry Andric 
134e8d8bef9SDimitry Andric   MCRegister Reg = RISCV::F0_D + RegNo;
1350b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1360b57cec5SDimitry Andric   return MCDisassembler::Success;
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
13906c3fb27SDimitry Andric static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,
1400b57cec5SDimitry Andric                                               uint64_t Address,
14181ad6265SDimitry Andric                                               const MCDisassembler *Decoder) {
1428bcb0991SDimitry Andric   if (RegNo >= 8) {
1430b57cec5SDimitry Andric     return MCDisassembler::Fail;
1440b57cec5SDimitry Andric   }
145e8d8bef9SDimitry Andric   MCRegister Reg = RISCV::F8_D + RegNo;
1460b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1470b57cec5SDimitry Andric   return MCDisassembler::Success;
1480b57cec5SDimitry Andric }
1490b57cec5SDimitry Andric 
15006c3fb27SDimitry Andric static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,
1510b57cec5SDimitry Andric                                                uint64_t Address,
15281ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1530b57cec5SDimitry Andric   if (RegNo == 0) {
1540b57cec5SDimitry Andric     return MCDisassembler::Fail;
1550b57cec5SDimitry Andric   }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric 
16081ad6265SDimitry Andric static DecodeStatus
16106c3fb27SDimitry Andric DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address,
16281ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
1630b57cec5SDimitry Andric   if (RegNo == 2) {
1640b57cec5SDimitry Andric     return MCDisassembler::Fail;
1650b57cec5SDimitry Andric   }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
17006c3fb27SDimitry Andric static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo,
1710b57cec5SDimitry Andric                                             uint64_t Address,
17281ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
1738bcb0991SDimitry Andric   if (RegNo >= 8)
1740b57cec5SDimitry Andric     return MCDisassembler::Fail;
1750b57cec5SDimitry Andric 
176e8d8bef9SDimitry Andric   MCRegister Reg = RISCV::X8 + RegNo;
1770b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1780b57cec5SDimitry Andric   return MCDisassembler::Success;
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric 
181297eecfbSDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,
182d56accc7SDimitry Andric                                                uint64_t Address,
18381ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
184d56accc7SDimitry Andric   if (RegNo >= 32 || RegNo & 1)
185d56accc7SDimitry Andric     return MCDisassembler::Fail;
186d56accc7SDimitry Andric 
187d56accc7SDimitry Andric   MCRegister Reg = RISCV::X0 + RegNo;
188d56accc7SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
189d56accc7SDimitry Andric   return MCDisassembler::Success;
190d56accc7SDimitry Andric }
191d56accc7SDimitry Andric 
192*0fca6ea1SDimitry Andric static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo,
19306c3fb27SDimitry Andric                                             uint64_t Address,
19406c3fb27SDimitry Andric                                             const void *Decoder) {
19506c3fb27SDimitry Andric   if (RegNo >= 8)
19606c3fb27SDimitry Andric     return MCDisassembler::Fail;
19706c3fb27SDimitry Andric 
19806c3fb27SDimitry Andric   MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);
19906c3fb27SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
20006c3fb27SDimitry Andric   return MCDisassembler::Success;
20106c3fb27SDimitry Andric }
20206c3fb27SDimitry Andric 
20306c3fb27SDimitry Andric static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,
2045ffd83dbSDimitry Andric                                           uint64_t Address,
20581ad6265SDimitry Andric                                           const MCDisassembler *Decoder) {
2065ffd83dbSDimitry Andric   if (RegNo >= 32)
2075ffd83dbSDimitry Andric     return MCDisassembler::Fail;
2085ffd83dbSDimitry Andric 
209e8d8bef9SDimitry Andric   MCRegister Reg = RISCV::V0 + RegNo;
2105ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2115ffd83dbSDimitry Andric   return MCDisassembler::Success;
2125ffd83dbSDimitry Andric }
2135ffd83dbSDimitry Andric 
21406c3fb27SDimitry Andric static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,
215fe6060f1SDimitry Andric                                             uint64_t Address,
21681ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
2175f757f3fSDimitry Andric   if (RegNo >= 32 || RegNo % 2)
218fe6060f1SDimitry Andric     return MCDisassembler::Fail;
219fe6060f1SDimitry Andric 
220fe6060f1SDimitry Andric   const RISCVDisassembler *Dis =
221fe6060f1SDimitry Andric       static_cast<const RISCVDisassembler *>(Decoder);
222fe6060f1SDimitry Andric   const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
223fe6060f1SDimitry Andric   MCRegister Reg =
224fe6060f1SDimitry Andric       RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
225fe6060f1SDimitry Andric                               &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
226fe6060f1SDimitry Andric 
227fe6060f1SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
228fe6060f1SDimitry Andric   return MCDisassembler::Success;
229fe6060f1SDimitry Andric }
230fe6060f1SDimitry Andric 
23106c3fb27SDimitry Andric static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo,
232fe6060f1SDimitry Andric                                             uint64_t Address,
23381ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
2345f757f3fSDimitry Andric   if (RegNo >= 32 || RegNo % 4)
235fe6060f1SDimitry Andric     return MCDisassembler::Fail;
236fe6060f1SDimitry Andric 
237fe6060f1SDimitry Andric   const RISCVDisassembler *Dis =
238fe6060f1SDimitry Andric       static_cast<const RISCVDisassembler *>(Decoder);
239fe6060f1SDimitry Andric   const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
240fe6060f1SDimitry Andric   MCRegister Reg =
241fe6060f1SDimitry Andric       RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
242fe6060f1SDimitry Andric                               &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
243fe6060f1SDimitry Andric 
244fe6060f1SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
245fe6060f1SDimitry Andric   return MCDisassembler::Success;
246fe6060f1SDimitry Andric }
247fe6060f1SDimitry Andric 
24806c3fb27SDimitry Andric static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,
249fe6060f1SDimitry Andric                                             uint64_t Address,
25081ad6265SDimitry Andric                                             const MCDisassembler *Decoder) {
2515f757f3fSDimitry Andric   if (RegNo >= 32 || RegNo % 8)
252fe6060f1SDimitry Andric     return MCDisassembler::Fail;
253fe6060f1SDimitry Andric 
254fe6060f1SDimitry Andric   const RISCVDisassembler *Dis =
255fe6060f1SDimitry Andric       static_cast<const RISCVDisassembler *>(Decoder);
256fe6060f1SDimitry Andric   const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
257fe6060f1SDimitry Andric   MCRegister Reg =
258fe6060f1SDimitry Andric       RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
259fe6060f1SDimitry Andric                               &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
260fe6060f1SDimitry Andric 
261fe6060f1SDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
262fe6060f1SDimitry Andric   return MCDisassembler::Success;
263fe6060f1SDimitry Andric }
264fe6060f1SDimitry Andric 
265*0fca6ea1SDimitry Andric static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,
26681ad6265SDimitry Andric                                    uint64_t Address,
26781ad6265SDimitry Andric                                    const MCDisassembler *Decoder) {
268*0fca6ea1SDimitry Andric   if (RegNo >= 2)
2695ffd83dbSDimitry Andric     return MCDisassembler::Fail;
270*0fca6ea1SDimitry Andric 
2715f757f3fSDimitry Andric   MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;
2725f757f3fSDimitry Andric 
2735ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
2745ffd83dbSDimitry Andric   return MCDisassembler::Success;
2755ffd83dbSDimitry Andric }
2765ffd83dbSDimitry Andric 
2770b57cec5SDimitry Andric template <unsigned N>
27806c3fb27SDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,
27981ad6265SDimitry Andric                                       int64_t Address,
28081ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
2810b57cec5SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
2820b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
2830b57cec5SDimitry Andric   return MCDisassembler::Success;
2840b57cec5SDimitry Andric }
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric template <unsigned N>
28706c3fb27SDimitry Andric static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
2880b57cec5SDimitry Andric                                              int64_t Address,
28981ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
2900b57cec5SDimitry Andric   if (Imm == 0)
2910b57cec5SDimitry Andric     return MCDisassembler::Fail;
2920b57cec5SDimitry Andric   return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
2930b57cec5SDimitry Andric }
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric template <unsigned N>
29606c3fb27SDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,
29781ad6265SDimitry Andric                                       int64_t Address,
29881ad6265SDimitry Andric                                       const MCDisassembler *Decoder) {
2990b57cec5SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
3000b57cec5SDimitry Andric   // Sign-extend the number in the bottom N bits of Imm
3010b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
3020b57cec5SDimitry Andric   return MCDisassembler::Success;
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric template <unsigned N>
30606c3fb27SDimitry Andric static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,
3070b57cec5SDimitry Andric                                              int64_t Address,
30881ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
3090b57cec5SDimitry Andric   if (Imm == 0)
3100b57cec5SDimitry Andric     return MCDisassembler::Fail;
3110b57cec5SDimitry Andric   return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric template <unsigned N>
31506c3fb27SDimitry Andric static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm,
3160b57cec5SDimitry Andric                                              int64_t Address,
31781ad6265SDimitry Andric                                              const MCDisassembler *Decoder) {
3180b57cec5SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
3190b57cec5SDimitry Andric   // Sign-extend the number in the bottom N bits of Imm after accounting for
3200b57cec5SDimitry Andric   // the fact that the N bit immediate is stored in N-1 bits (the LSB is
3210b57cec5SDimitry Andric   // always zero)
3220b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
3230b57cec5SDimitry Andric   return MCDisassembler::Success;
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric 
32606c3fb27SDimitry Andric static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,
3270b57cec5SDimitry Andric                                          int64_t Address,
32881ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
3290b57cec5SDimitry Andric   assert(isUInt<6>(Imm) && "Invalid immediate");
3300b57cec5SDimitry Andric   if (Imm > 31) {
3310b57cec5SDimitry Andric     Imm = (SignExtend64<6>(Imm) & 0xfffff);
3320b57cec5SDimitry Andric   }
3330b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
3340b57cec5SDimitry Andric   return MCDisassembler::Success;
3350b57cec5SDimitry Andric }
3360b57cec5SDimitry Andric 
33706c3fb27SDimitry Andric static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,
33881ad6265SDimitry Andric                                  const MCDisassembler *Decoder) {
3390b57cec5SDimitry Andric   assert(isUInt<3>(Imm) && "Invalid immediate");
3400b57cec5SDimitry Andric   if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
3410b57cec5SDimitry Andric     return MCDisassembler::Fail;
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
3440b57cec5SDimitry Andric   return MCDisassembler::Success;
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric 
34706c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
34881ad6265SDimitry Andric                                                uint64_t Address,
34981ad6265SDimitry Andric                                                const MCDisassembler *Decoder);
3508bcb0991SDimitry Andric 
35106c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
35281ad6265SDimitry Andric                                          uint64_t Address,
35381ad6265SDimitry Andric                                          const MCDisassembler *Decoder);
3548bcb0991SDimitry Andric 
35506c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
3568bcb0991SDimitry Andric                                             uint64_t Address,
35781ad6265SDimitry Andric                                             const MCDisassembler *Decoder);
3588bcb0991SDimitry Andric 
35906c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
36081ad6265SDimitry Andric                                         uint64_t Address,
36181ad6265SDimitry Andric                                         const MCDisassembler *Decoder);
3628bcb0991SDimitry Andric 
36306c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
3648bcb0991SDimitry Andric                                            uint64_t Address,
36581ad6265SDimitry Andric                                            const MCDisassembler *Decoder);
3668bcb0991SDimitry Andric 
36706c3fb27SDimitry Andric static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
36806c3fb27SDimitry Andric                                         uint64_t Address,
36906c3fb27SDimitry Andric                                         const MCDisassembler *Decoder);
37006c3fb27SDimitry Andric 
371*0fca6ea1SDimitry Andric static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
37206c3fb27SDimitry Andric                                     uint64_t Address, const void *Decoder);
37306c3fb27SDimitry Andric 
3745f757f3fSDimitry Andric static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
3755f757f3fSDimitry Andric                                  const MCDisassembler *Decoder);
3765f757f3fSDimitry Andric 
377*0fca6ea1SDimitry Andric static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
37806c3fb27SDimitry Andric                                     uint64_t Address, const void *Decoder);
37906c3fb27SDimitry Andric 
380647cbc5dSDimitry Andric static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
381647cbc5dSDimitry Andric                                         uint64_t Address,
382647cbc5dSDimitry Andric                                         const MCDisassembler *Decoder);
383647cbc5dSDimitry Andric 
3840b57cec5SDimitry Andric #include "RISCVGenDisassemblerTables.inc"
3850b57cec5SDimitry Andric 
38606c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,
38781ad6265SDimitry Andric                                                uint64_t Address,
38881ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
38906c3fb27SDimitry Andric   uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
390*0fca6ea1SDimitry Andric   [[maybe_unused]] DecodeStatus Result =
391*0fca6ea1SDimitry Andric       DecodeGPRNoX0RegisterClass(Inst, Rd, Address, Decoder);
39206c3fb27SDimitry Andric   assert(Result == MCDisassembler::Success && "Invalid register");
3938bcb0991SDimitry Andric   Inst.addOperand(Inst.getOperand(0));
39406c3fb27SDimitry Andric   Inst.addOperand(MCOperand::createImm(0));
39506c3fb27SDimitry Andric   return MCDisassembler::Success;
39606c3fb27SDimitry Andric }
39706c3fb27SDimitry Andric 
398647cbc5dSDimitry Andric static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,
399647cbc5dSDimitry Andric                                         uint64_t Address,
400647cbc5dSDimitry Andric                                         const MCDisassembler *Decoder) {
401647cbc5dSDimitry Andric   uint32_t Rs1 = fieldFromInstruction(Insn, 7, 5);
402*0fca6ea1SDimitry Andric   [[maybe_unused]] DecodeStatus Result =
403*0fca6ea1SDimitry Andric       DecodeGPRX1X5RegisterClass(Inst, Rs1, Address, Decoder);
404647cbc5dSDimitry Andric   assert(Result == MCDisassembler::Success && "Invalid register");
405647cbc5dSDimitry Andric   return MCDisassembler::Success;
406647cbc5dSDimitry Andric }
407647cbc5dSDimitry Andric 
40806c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,
40906c3fb27SDimitry Andric                                          uint64_t Address,
41006c3fb27SDimitry Andric                                          const MCDisassembler *Decoder) {
41106c3fb27SDimitry Andric   Inst.addOperand(MCOperand::createReg(RISCV::X0));
41206c3fb27SDimitry Andric   uint32_t SImm6 =
41306c3fb27SDimitry Andric       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
414*0fca6ea1SDimitry Andric   [[maybe_unused]] DecodeStatus Result =
415*0fca6ea1SDimitry Andric       decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
41606c3fb27SDimitry Andric   assert(Result == MCDisassembler::Success && "Invalid immediate");
41706c3fb27SDimitry Andric   return MCDisassembler::Success;
41806c3fb27SDimitry Andric }
41906c3fb27SDimitry Andric 
42006c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,
42106c3fb27SDimitry Andric                                             uint64_t Address,
42206c3fb27SDimitry Andric                                             const MCDisassembler *Decoder) {
42306c3fb27SDimitry Andric   Inst.addOperand(MCOperand::createReg(RISCV::X0));
42406c3fb27SDimitry Andric   Inst.addOperand(Inst.getOperand(0));
42506c3fb27SDimitry Andric   uint32_t UImm6 =
4268bcb0991SDimitry Andric       fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
427*0fca6ea1SDimitry Andric   [[maybe_unused]] DecodeStatus Result =
428*0fca6ea1SDimitry Andric       decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
4298bcb0991SDimitry Andric   assert(Result == MCDisassembler::Success && "Invalid immediate");
4308bcb0991SDimitry Andric   return MCDisassembler::Success;
4318bcb0991SDimitry Andric }
4328bcb0991SDimitry Andric 
43306c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,
43481ad6265SDimitry Andric                                         uint64_t Address,
43581ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
43606c3fb27SDimitry Andric   uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
43706c3fb27SDimitry Andric   uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);
4388bcb0991SDimitry Andric   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
4398bcb0991SDimitry Andric   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
4408bcb0991SDimitry Andric   return MCDisassembler::Success;
4418bcb0991SDimitry Andric }
4428bcb0991SDimitry Andric 
44306c3fb27SDimitry Andric static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,
4448bcb0991SDimitry Andric                                            uint64_t Address,
44581ad6265SDimitry Andric                                            const MCDisassembler *Decoder) {
44606c3fb27SDimitry Andric   uint32_t Rd = fieldFromInstruction(Insn, 7, 5);
44706c3fb27SDimitry Andric   uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);
4488bcb0991SDimitry Andric   DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
4498bcb0991SDimitry Andric   Inst.addOperand(Inst.getOperand(0));
4508bcb0991SDimitry Andric   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
4518bcb0991SDimitry Andric   return MCDisassembler::Success;
4528bcb0991SDimitry Andric }
4538bcb0991SDimitry Andric 
45406c3fb27SDimitry Andric static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,
45506c3fb27SDimitry Andric                                         uint64_t Address,
45606c3fb27SDimitry Andric                                         const MCDisassembler *Decoder) {
45706c3fb27SDimitry Andric   uint32_t Rd1 = fieldFromInstruction(Insn, 7, 5);
45806c3fb27SDimitry Andric   uint32_t Rs1 = fieldFromInstruction(Insn, 15, 5);
45906c3fb27SDimitry Andric   uint32_t Rd2 = fieldFromInstruction(Insn, 20, 5);
46006c3fb27SDimitry Andric   uint32_t UImm2 = fieldFromInstruction(Insn, 25, 2);
46106c3fb27SDimitry Andric   DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder);
46206c3fb27SDimitry Andric   DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder);
46306c3fb27SDimitry Andric   DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
464*0fca6ea1SDimitry Andric   [[maybe_unused]] DecodeStatus Result =
465*0fca6ea1SDimitry Andric       decodeUImmOperand<2>(Inst, UImm2, Address, Decoder);
46606c3fb27SDimitry Andric   assert(Result == MCDisassembler::Success && "Invalid immediate");
46706c3fb27SDimitry Andric 
46806c3fb27SDimitry Andric   // Disassemble the final operand which is implicit.
46906c3fb27SDimitry Andric   unsigned Opcode = Inst.getOpcode();
47006c3fb27SDimitry Andric   bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD ||
47106c3fb27SDimitry Andric                    Opcode == RISCV::TH_SWD);
47206c3fb27SDimitry Andric   if (IsWordOp)
47306c3fb27SDimitry Andric     Inst.addOperand(MCOperand::createImm(3));
47406c3fb27SDimitry Andric   else
47506c3fb27SDimitry Andric     Inst.addOperand(MCOperand::createImm(4));
47606c3fb27SDimitry Andric 
47706c3fb27SDimitry Andric   return MCDisassembler::Success;
47806c3fb27SDimitry Andric }
47906c3fb27SDimitry Andric 
480*0fca6ea1SDimitry Andric static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,
48106c3fb27SDimitry Andric                                     uint64_t Address, const void *Decoder) {
48206c3fb27SDimitry Andric   if (Imm <= 3)
48306c3fb27SDimitry Andric     return MCDisassembler::Fail;
48406c3fb27SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
48506c3fb27SDimitry Andric   return MCDisassembler::Success;
48606c3fb27SDimitry Andric }
48706c3fb27SDimitry Andric 
4885f757f3fSDimitry Andric static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,
4895f757f3fSDimitry Andric                                  const MCDisassembler *Decoder) {
4905f757f3fSDimitry Andric   uint32_t Rs1 = fieldFromInstruction(Insn, 0, 5);
4915f757f3fSDimitry Andric   uint32_t Rs2 = fieldFromInstruction(Insn, 5, 5);
4925f757f3fSDimitry Andric   DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);
4935f757f3fSDimitry Andric   DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
4945f757f3fSDimitry Andric   return MCDisassembler::Success;
4955f757f3fSDimitry Andric }
4965f757f3fSDimitry Andric 
497*0fca6ea1SDimitry Andric static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,
49806c3fb27SDimitry Andric                                     uint64_t Address, const void *Decoder) {
49906c3fb27SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
50006c3fb27SDimitry Andric   return MCDisassembler::Success;
50106c3fb27SDimitry Andric }
50206c3fb27SDimitry Andric 
50306c3fb27SDimitry Andric // Add implied SP operand for C.*SP compressed instructions. The SP operand
50406c3fb27SDimitry Andric // isn't explicitly encoded in the instruction.
50506c3fb27SDimitry Andric void RISCVDisassembler::addSPOperands(MCInst &MI) const {
50606c3fb27SDimitry Andric   const MCInstrDesc &MCID = MCII->get(MI.getOpcode());
50706c3fb27SDimitry Andric   for (unsigned i = 0; i < MCID.getNumOperands(); i++)
50806c3fb27SDimitry Andric     if (MCID.operands()[i].RegClass == RISCV::SPRegClassID)
50906c3fb27SDimitry Andric       MI.insert(MI.begin() + i, MCOperand::createReg(RISCV::X2));
51006c3fb27SDimitry Andric }
51106c3fb27SDimitry Andric 
51206c3fb27SDimitry Andric #define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, \
51306c3fb27SDimitry Andric                                                 DESC, ADDITIONAL_OPERATION)    \
51406c3fb27SDimitry Andric   do {                                                                         \
51506c3fb27SDimitry Andric     if (FEATURE_CHECKS) {                                                      \
51606c3fb27SDimitry Andric       LLVM_DEBUG(dbgs() << "Trying " DESC ":\n");                              \
517*0fca6ea1SDimitry Andric       DecodeStatus Result =                                                    \
518*0fca6ea1SDimitry Andric           decodeInstruction(DECODER_TABLE, MI, Insn, Address, this, STI);      \
51906c3fb27SDimitry Andric       if (Result != MCDisassembler::Fail) {                                    \
52006c3fb27SDimitry Andric         ADDITIONAL_OPERATION;                                                  \
52106c3fb27SDimitry Andric         return Result;                                                         \
52206c3fb27SDimitry Andric       }                                                                        \
52306c3fb27SDimitry Andric     }                                                                          \
52406c3fb27SDimitry Andric   } while (false)
52506c3fb27SDimitry Andric #define TRY_TO_DECODE_AND_ADD_SP(FEATURE_CHECKS, DECODER_TABLE, DESC)          \
52606c3fb27SDimitry Andric   TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
52706c3fb27SDimitry Andric                                           addSPOperands(MI))
52806c3fb27SDimitry Andric #define TRY_TO_DECODE(FEATURE_CHECKS, DECODER_TABLE, DESC)                     \
52906c3fb27SDimitry Andric   TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \
53006c3fb27SDimitry Andric                                           (void)nullptr)
53106c3fb27SDimitry Andric #define TRY_TO_DECODE_FEATURE(FEATURE, DECODER_TABLE, DESC)                    \
53206c3fb27SDimitry Andric   TRY_TO_DECODE(STI.hasFeature(FEATURE), DECODER_TABLE, DESC)
53306c3fb27SDimitry Andric 
534*0fca6ea1SDimitry Andric DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,
535*0fca6ea1SDimitry Andric                                                  ArrayRef<uint8_t> Bytes,
536*0fca6ea1SDimitry Andric                                                  uint64_t Address,
537*0fca6ea1SDimitry Andric                                                  raw_ostream &CS) const {
5380b57cec5SDimitry Andric   if (Bytes.size() < 4) {
5390b57cec5SDimitry Andric     Size = 0;
5400b57cec5SDimitry Andric     return MCDisassembler::Fail;
5410b57cec5SDimitry Andric   }
54206c3fb27SDimitry Andric   Size = 4;
54306c3fb27SDimitry Andric 
544*0fca6ea1SDimitry Andric   uint32_t Insn = support::endian::read32le(Bytes.data());
54506c3fb27SDimitry Andric 
54606c3fb27SDimitry Andric   TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZdinx) &&
54706c3fb27SDimitry Andric                     !STI.hasFeature(RISCV::Feature64Bit),
54806c3fb27SDimitry Andric                 DecoderTableRV32Zdinx32,
54906c3fb27SDimitry Andric                 "RV32Zdinx table (Double in Integer and rv32)");
550297eecfbSDimitry Andric   TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZacas) &&
551297eecfbSDimitry Andric                     !STI.hasFeature(RISCV::Feature64Bit),
552297eecfbSDimitry Andric                 DecoderTableRV32Zacas32,
553297eecfbSDimitry Andric                 "RV32Zacas table (Compare-And-Swap and rv32)");
55406c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZfinx, DecoderTableRVZfinx32,
55506c3fb27SDimitry Andric                         "RVZfinx table (Float in Integer)");
55606c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXVentanaCondOps,
5575f757f3fSDimitry Andric                         DecoderTableXVentana32, "Ventana custom opcode table");
5585f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBa, DecoderTableXTHeadBa32,
55906c3fb27SDimitry Andric                         "XTHeadBa custom opcode table");
5605f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBb, DecoderTableXTHeadBb32,
56106c3fb27SDimitry Andric                         "XTHeadBb custom opcode table");
5625f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBs, DecoderTableXTHeadBs32,
56306c3fb27SDimitry Andric                         "XTHeadBs custom opcode table");
56406c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCondMov,
5655f757f3fSDimitry Andric                         DecoderTableXTHeadCondMov32,
56606c3fb27SDimitry Andric                         "XTHeadCondMov custom opcode table");
5675f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCmo, DecoderTableXTHeadCmo32,
56806c3fb27SDimitry Andric                         "XTHeadCmo custom opcode table");
56906c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadFMemIdx,
5705f757f3fSDimitry Andric                         DecoderTableXTHeadFMemIdx32,
57106c3fb27SDimitry Andric                         "XTHeadFMemIdx custom opcode table");
5725f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMac, DecoderTableXTHeadMac32,
57306c3fb27SDimitry Andric                         "XTHeadMac custom opcode table");
57406c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemIdx,
5755f757f3fSDimitry Andric                         DecoderTableXTHeadMemIdx32,
57606c3fb27SDimitry Andric                         "XTHeadMemIdx custom opcode table");
57706c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemPair,
5785f757f3fSDimitry Andric                         DecoderTableXTHeadMemPair32,
57906c3fb27SDimitry Andric                         "XTHeadMemPair custom opcode table");
58006c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadSync,
5815f757f3fSDimitry Andric                         DecoderTableXTHeadSync32,
58206c3fb27SDimitry Andric                         "XTHeadSync custom opcode table");
583*0fca6ea1SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadVdot,
584*0fca6ea1SDimitry Andric                         DecoderTableXTHeadVdot32,
58506c3fb27SDimitry Andric                         "XTHeadVdot custom opcode table");
58606c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfvcp, DecoderTableXSfvcp32,
58706c3fb27SDimitry Andric                         "SiFive VCIX custom opcode table");
5885f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(
5895f757f3fSDimitry Andric       RISCV::FeatureVendorXSfvqmaccdod, DecoderTableXSfvqmaccdod32,
5905f757f3fSDimitry Andric       "SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table");
5915f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(
5925f757f3fSDimitry Andric       RISCV::FeatureVendorXSfvqmaccqoq, DecoderTableXSfvqmaccqoq32,
5935f757f3fSDimitry Andric       "SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table");
5945f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(
5955f757f3fSDimitry Andric       RISCV::FeatureVendorXSfvfwmaccqqq, DecoderTableXSfvfwmaccqqq32,
5965f757f3fSDimitry Andric       "SiFive Matrix Multiplication Instruction opcode table");
5975f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(
5985f757f3fSDimitry Andric       RISCV::FeatureVendorXSfvfnrclipxfqf, DecoderTableXSfvfnrclipxfqf32,
5995f757f3fSDimitry Andric       "SiFive FP32-to-int8 Ranged Clip Instructions opcode table");
600*0fca6ea1SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecdiscarddlone,
601*0fca6ea1SDimitry Andric                         DecoderTableXSiFivecdiscarddlone32,
602*0fca6ea1SDimitry Andric                         "SiFive sf.cdiscard.d.l1 custom opcode table");
603*0fca6ea1SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecflushdlone,
604*0fca6ea1SDimitry Andric                         DecoderTableXSiFivecflushdlone32,
605*0fca6ea1SDimitry Andric                         "SiFive sf.cflush.d.l1 custom opcode table");
606*0fca6ea1SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcease, DecoderTableXSfcease32,
607*0fca6ea1SDimitry Andric                         "SiFive sf.cease custom opcode table");
60806c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,
60906c3fb27SDimitry Andric                         DecoderTableXCVbitmanip32,
61006c3fb27SDimitry Andric                         "CORE-V Bit Manipulation custom opcode table");
6115f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32,
6125f757f3fSDimitry Andric                         "CORE-V Event load custom opcode table");
61306c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32,
61406c3fb27SDimitry Andric                         "CORE-V MAC custom opcode table");
6155f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32,
6165f757f3fSDimitry Andric                         "CORE-V MEM custom opcode table");
6175f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32,
6185f757f3fSDimitry Andric                         "CORE-V ALU custom opcode table");
6195f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32,
6205f757f3fSDimitry Andric                         "CORE-V SIMD extensions custom opcode table");
6215f757f3fSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,
6225f757f3fSDimitry Andric                         "CORE-V Immediate Branching custom opcode table");
62306c3fb27SDimitry Andric   TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");
62406c3fb27SDimitry Andric 
62506c3fb27SDimitry Andric   return MCDisassembler::Fail;
626d56accc7SDimitry Andric }
627d56accc7SDimitry Andric 
628*0fca6ea1SDimitry Andric DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,
629*0fca6ea1SDimitry Andric                                                  ArrayRef<uint8_t> Bytes,
630*0fca6ea1SDimitry Andric                                                  uint64_t Address,
631*0fca6ea1SDimitry Andric                                                  raw_ostream &CS) const {
6320b57cec5SDimitry Andric   if (Bytes.size() < 2) {
6330b57cec5SDimitry Andric     Size = 0;
6340b57cec5SDimitry Andric     return MCDisassembler::Fail;
6350b57cec5SDimitry Andric   }
63606c3fb27SDimitry Andric   Size = 2;
63706c3fb27SDimitry Andric 
638*0fca6ea1SDimitry Andric   uint32_t Insn = support::endian::read16le(Bytes.data());
63906c3fb27SDimitry Andric   TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit),
64006c3fb27SDimitry Andric                            DecoderTableRISCV32Only_16,
64106c3fb27SDimitry Andric                            "RISCV32Only_16 table (16-bit Instruction)");
642647cbc5dSDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZicfiss, DecoderTableZicfiss16,
643647cbc5dSDimitry Andric                         "RVZicfiss table (Shadow Stack)");
64406c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16,
64506c3fb27SDimitry Andric                         "Zcmt table (16-bit Table Jump Instructions)");
64606c3fb27SDimitry Andric   TRY_TO_DECODE_FEATURE(
64706c3fb27SDimitry Andric       RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,
64806c3fb27SDimitry Andric       "Zcmp table (16-bit Push/Pop & Double Move Instructions)");
649*0fca6ea1SDimitry Andric   TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),
650*0fca6ea1SDimitry Andric                            DecoderTableXwchc16,
651*0fca6ea1SDimitry Andric                            "WCH QingKe XW custom opcode table");
65206c3fb27SDimitry Andric   TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16,
65306c3fb27SDimitry Andric                            "RISCV_C table (16-bit Instruction)");
6540b57cec5SDimitry Andric 
65506c3fb27SDimitry Andric   return MCDisassembler::Fail;
6560b57cec5SDimitry Andric }
657*0fca6ea1SDimitry Andric 
658*0fca6ea1SDimitry Andric DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
659*0fca6ea1SDimitry Andric                                                ArrayRef<uint8_t> Bytes,
660*0fca6ea1SDimitry Andric                                                uint64_t Address,
661*0fca6ea1SDimitry Andric                                                raw_ostream &CS) const {
662*0fca6ea1SDimitry Andric   // It's a 16 bit instruction if bit 0 and 1 are not 0b11.
663*0fca6ea1SDimitry Andric   if ((Bytes[0] & 0b11) != 0b11)
664*0fca6ea1SDimitry Andric     return getInstruction16(MI, Size, Bytes, Address, CS);
665*0fca6ea1SDimitry Andric 
666*0fca6ea1SDimitry Andric   // It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2
667*0fca6ea1SDimitry Andric   // are not 0b111.
668*0fca6ea1SDimitry Andric   if ((Bytes[0] & 0b1'1100) != 0b1'1100)
669*0fca6ea1SDimitry Andric     return getInstruction32(MI, Size, Bytes, Address, CS);
670*0fca6ea1SDimitry Andric 
671*0fca6ea1SDimitry Andric   // 48-bit instructions are encoded as 0bxx011111.
672*0fca6ea1SDimitry Andric   if ((Bytes[0] & 0b11'1111) == 0b01'1111) {
673*0fca6ea1SDimitry Andric     Size = Bytes.size() >= 6 ? 6 : 0;
674*0fca6ea1SDimitry Andric     return MCDisassembler::Fail;
675*0fca6ea1SDimitry Andric   }
676*0fca6ea1SDimitry Andric 
677*0fca6ea1SDimitry Andric   // 64-bit instructions are encoded as 0x0111111.
678*0fca6ea1SDimitry Andric   if ((Bytes[0] & 0b111'1111) == 0b011'1111) {
679*0fca6ea1SDimitry Andric     Size = Bytes.size() >= 8 ? 8 : 0;
680*0fca6ea1SDimitry Andric     return MCDisassembler::Fail;
681*0fca6ea1SDimitry Andric   }
682*0fca6ea1SDimitry Andric 
683*0fca6ea1SDimitry Andric   // Remaining cases need to check a second byte.
684*0fca6ea1SDimitry Andric   if (Bytes.size() < 2) {
685*0fca6ea1SDimitry Andric     Size = 0;
686*0fca6ea1SDimitry Andric     return MCDisassembler::Fail;
687*0fca6ea1SDimitry Andric   }
688*0fca6ea1SDimitry Andric 
689*0fca6ea1SDimitry Andric   // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.
690*0fca6ea1SDimitry Andric   // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.
691*0fca6ea1SDimitry Andric   unsigned nnn = (Bytes[1] >> 4) & 0b111;
692*0fca6ea1SDimitry Andric   if (nnn != 0b111) {
693*0fca6ea1SDimitry Andric     Size = 10 + (nnn * 2);
694*0fca6ea1SDimitry Andric     if (Bytes.size() < Size)
695*0fca6ea1SDimitry Andric       Size = 0;
696*0fca6ea1SDimitry Andric     return MCDisassembler::Fail;
697*0fca6ea1SDimitry Andric   }
698*0fca6ea1SDimitry Andric 
699*0fca6ea1SDimitry Andric   // Remaining encodings are reserved for > 176-bit instructions.
700*0fca6ea1SDimitry Andric   Size = 0;
701*0fca6ea1SDimitry Andric   return MCDisassembler::Fail;
702*0fca6ea1SDimitry Andric }
703