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:
RISCVDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)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
createRISCVDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)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
LLVMInitializeRISCVDisassembler()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
DecodeGPRRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeGPRX1X5RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeFPR16RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeFPR32RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeFPR32CRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeFPR64RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeFPR64CRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeGPRNoX0RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeGPRNoX0X2RegisterClass(MCInst & Inst,uint64_t RegNo,uint32_t Address,const MCDisassembler * Decoder)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
DecodeGPRCRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeGPRPairRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeSR07RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const void * Decoder)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
DecodeVRRegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeVRM2RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeVRM4RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
DecodeVRM8RegisterClass(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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
decodeVMaskReg(MCInst & Inst,uint32_t RegNo,uint64_t Address,const MCDisassembler * Decoder)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>
decodeUImmOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)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>
decodeUImmNonZeroOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)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>
decodeSImmOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)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>
decodeSImmNonZeroOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)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>
decodeSImmOperandAndLsl1(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeCLUIImmOperand(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeFRMArg(MCInst & Inst,uint32_t Imm,int64_t Address,const MCDisassembler * Decoder)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
decodeRVCInstrRdRs1ImmZero(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)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
decodeCSSPushPopchk(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)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
decodeRVCInstrRdSImm(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)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
decodeRVCInstrRdRs1UImm(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)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
decodeRVCInstrRdRs2(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)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
decodeRVCInstrRdRs1Rs2(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)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
decodeXTHeadMemPair(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)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
decodeZcmpRlist(MCInst & Inst,uint32_t Imm,uint64_t Address,const void * Decoder)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
decodeRegReg(MCInst & Inst,uint32_t Insn,uint64_t Address,const MCDisassembler * Decoder)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
decodeZcmpSpimm(MCInst & Inst,uint32_t Imm,uint64_t Address,const void * Decoder)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.
addSPOperands(MCInst & MI) const50506c3fb27SDimitry 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
getInstruction32(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const534*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
getInstruction16(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const628*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
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const658*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