18ab4a969SAlex Bradbury //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===//
28ab4a969SAlex Bradbury //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68ab4a969SAlex Bradbury //
78ab4a969SAlex Bradbury //===----------------------------------------------------------------------===//
88ab4a969SAlex Bradbury //
98ab4a969SAlex Bradbury // This file implements the RISCVDisassembler class.
108ab4a969SAlex Bradbury //
118ab4a969SAlex Bradbury //===----------------------------------------------------------------------===//
128ab4a969SAlex Bradbury
13387d3c24SCraig Topper #include "MCTargetDesc/RISCVBaseInfo.h"
148ab4a969SAlex Bradbury #include "MCTargetDesc/RISCVMCTargetDesc.h"
1551fc56d6SRichard Trieu #include "TargetInfo/RISCVTargetInfo.h"
168ab4a969SAlex Bradbury #include "llvm/MC/MCContext.h"
17*c644488aSSheng #include "llvm/MC/MCDecoderOps.h"
188ab4a969SAlex Bradbury #include "llvm/MC/MCDisassembler/MCDisassembler.h"
198ab4a969SAlex Bradbury #include "llvm/MC/MCInst.h"
2066da87dcSHsiangkai Wang #include "llvm/MC/MCInstrInfo.h"
218ab4a969SAlex Bradbury #include "llvm/MC/MCRegisterInfo.h"
228ab4a969SAlex Bradbury #include "llvm/MC/MCSubtargetInfo.h"
2389b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
248ab4a969SAlex Bradbury #include "llvm/Support/Endian.h"
258ab4a969SAlex Bradbury
268ab4a969SAlex Bradbury using namespace llvm;
278ab4a969SAlex Bradbury
288ab4a969SAlex Bradbury #define DEBUG_TYPE "riscv-disassembler"
298ab4a969SAlex Bradbury
308ab4a969SAlex Bradbury typedef MCDisassembler::DecodeStatus DecodeStatus;
318ab4a969SAlex Bradbury
328ab4a969SAlex Bradbury namespace {
338ab4a969SAlex Bradbury class RISCVDisassembler : public MCDisassembler {
3466da87dcSHsiangkai Wang std::unique_ptr<MCInstrInfo const> const MCII;
358ab4a969SAlex Bradbury
368ab4a969SAlex Bradbury public:
RISCVDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,MCInstrInfo const * MCII)3766da87dcSHsiangkai Wang RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
3866da87dcSHsiangkai Wang MCInstrInfo const *MCII)
3966da87dcSHsiangkai Wang : MCDisassembler(STI, Ctx), MCII(MCII) {}
408ab4a969SAlex Bradbury
418ab4a969SAlex Bradbury DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
428ab4a969SAlex Bradbury ArrayRef<uint8_t> Bytes, uint64_t Address,
438ab4a969SAlex Bradbury raw_ostream &CStream) const override;
448ab4a969SAlex Bradbury };
458ab4a969SAlex Bradbury } // end anonymous namespace
468ab4a969SAlex Bradbury
createRISCVDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)478ab4a969SAlex Bradbury static MCDisassembler *createRISCVDisassembler(const Target &T,
488ab4a969SAlex Bradbury const MCSubtargetInfo &STI,
498ab4a969SAlex Bradbury MCContext &Ctx) {
5066da87dcSHsiangkai Wang return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());
518ab4a969SAlex Bradbury }
528ab4a969SAlex Bradbury
LLVMInitializeRISCVDisassembler()530dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {
548ab4a969SAlex Bradbury // Register the disassembler for each target.
558ab4a969SAlex Bradbury TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
568ab4a969SAlex Bradbury createRISCVDisassembler);
578ab4a969SAlex Bradbury TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
588ab4a969SAlex Bradbury createRISCVDisassembler);
598ab4a969SAlex Bradbury }
608ab4a969SAlex Bradbury
DecodeGPRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)618ab4a969SAlex Bradbury static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
628ab4a969SAlex Bradbury uint64_t Address,
634ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
64dab1f6fcSAlex Bradbury const FeatureBitset &FeatureBits =
654ae9745aSMaksim Panchenko Decoder->getSubtargetInfo().getFeatureBits();
66dab1f6fcSAlex Bradbury bool IsRV32E = FeatureBits[RISCV::FeatureRV32E];
67dab1f6fcSAlex Bradbury
68aae97bfdSLuis Marques if (RegNo >= 32 || (IsRV32E && RegNo >= 16))
698ab4a969SAlex Bradbury return MCDisassembler::Fail;
708ab4a969SAlex Bradbury
710add5f91SCraig Topper MCRegister Reg = RISCV::X0 + RegNo;
728ab4a969SAlex Bradbury Inst.addOperand(MCOperand::createReg(Reg));
738ab4a969SAlex Bradbury return MCDisassembler::Success;
748ab4a969SAlex Bradbury }
758ab4a969SAlex Bradbury
DecodeFPR16RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)76f7bc7c29SHsiangkai Wang static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint64_t RegNo,
77f7bc7c29SHsiangkai Wang uint64_t Address,
784ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
79f7bc7c29SHsiangkai Wang if (RegNo >= 32)
80f7bc7c29SHsiangkai Wang return MCDisassembler::Fail;
81f7bc7c29SHsiangkai Wang
82f7bc7c29SHsiangkai Wang MCRegister Reg = RISCV::F0_H + RegNo;
83f7bc7c29SHsiangkai Wang Inst.addOperand(MCOperand::createReg(Reg));
84f7bc7c29SHsiangkai Wang return MCDisassembler::Success;
85f7bc7c29SHsiangkai Wang }
86f7bc7c29SHsiangkai Wang
DecodeFPR32RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)870d6cf906SAlex Bradbury static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
880d6cf906SAlex Bradbury uint64_t Address,
894ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
90aae97bfdSLuis Marques if (RegNo >= 32)
910d6cf906SAlex Bradbury return MCDisassembler::Fail;
920d6cf906SAlex Bradbury
930add5f91SCraig Topper MCRegister Reg = RISCV::F0_F + RegNo;
940d6cf906SAlex Bradbury Inst.addOperand(MCOperand::createReg(Reg));
950d6cf906SAlex Bradbury return MCDisassembler::Success;
960d6cf906SAlex Bradbury }
970d6cf906SAlex Bradbury
DecodeFPR32CRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)9860714f98SAlex Bradbury static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
9960714f98SAlex Bradbury uint64_t Address,
1004ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
101aae97bfdSLuis Marques if (RegNo >= 8) {
10260714f98SAlex Bradbury return MCDisassembler::Fail;
10360714f98SAlex Bradbury }
1040add5f91SCraig Topper MCRegister Reg = RISCV::F8_F + RegNo;
10560714f98SAlex Bradbury Inst.addOperand(MCOperand::createReg(Reg));
10660714f98SAlex Bradbury return MCDisassembler::Success;
10760714f98SAlex Bradbury }
10860714f98SAlex Bradbury
DecodeFPR64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1097bc2a95bSAlex Bradbury static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
1107bc2a95bSAlex Bradbury uint64_t Address,
1114ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
112aae97bfdSLuis Marques if (RegNo >= 32)
1137bc2a95bSAlex Bradbury return MCDisassembler::Fail;
1147bc2a95bSAlex Bradbury
1150add5f91SCraig Topper MCRegister Reg = RISCV::F0_D + RegNo;
1167bc2a95bSAlex Bradbury Inst.addOperand(MCOperand::createReg(Reg));
1177bc2a95bSAlex Bradbury return MCDisassembler::Success;
1187bc2a95bSAlex Bradbury }
1197bc2a95bSAlex Bradbury
DecodeFPR64CRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)12060714f98SAlex Bradbury static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
12160714f98SAlex Bradbury uint64_t Address,
1224ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
123aae97bfdSLuis Marques if (RegNo >= 8) {
12460714f98SAlex Bradbury return MCDisassembler::Fail;
12560714f98SAlex Bradbury }
1260add5f91SCraig Topper MCRegister Reg = RISCV::F8_D + RegNo;
12760714f98SAlex Bradbury Inst.addOperand(MCOperand::createReg(Reg));
12860714f98SAlex Bradbury return MCDisassembler::Success;
12960714f98SAlex Bradbury }
13060714f98SAlex Bradbury
DecodeGPRNoX0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1319f6aec4bSAlex Bradbury static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
1329f6aec4bSAlex Bradbury uint64_t Address,
1334ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
1349f6aec4bSAlex Bradbury if (RegNo == 0) {
1359f6aec4bSAlex Bradbury return MCDisassembler::Fail;
1369f6aec4bSAlex Bradbury }
1379f6aec4bSAlex Bradbury
1389f6aec4bSAlex Bradbury return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
1399f6aec4bSAlex Bradbury }
1409f6aec4bSAlex Bradbury
1414ae9745aSMaksim Panchenko static DecodeStatus
DecodeGPRNoX0X2RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1424ae9745aSMaksim Panchenko DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
1434ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
14460714f98SAlex Bradbury if (RegNo == 2) {
14560714f98SAlex Bradbury return MCDisassembler::Fail;
14660714f98SAlex Bradbury }
14760714f98SAlex Bradbury
14860714f98SAlex Bradbury return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
14960714f98SAlex Bradbury }
15060714f98SAlex Bradbury
DecodeGPRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1519f6aec4bSAlex Bradbury static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1529f6aec4bSAlex Bradbury uint64_t Address,
1534ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
154aae97bfdSLuis Marques if (RegNo >= 8)
1559f6aec4bSAlex Bradbury return MCDisassembler::Fail;
1569f6aec4bSAlex Bradbury
1570add5f91SCraig Topper MCRegister Reg = RISCV::X8 + RegNo;
1589f6aec4bSAlex Bradbury Inst.addOperand(MCOperand::createReg(Reg));
1599f6aec4bSAlex Bradbury return MCDisassembler::Success;
1609f6aec4bSAlex Bradbury }
1619f6aec4bSAlex Bradbury
DecodeGPRPF64RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1620e38b295SShao-Ce SUN static DecodeStatus DecodeGPRPF64RegisterClass(MCInst &Inst, uint64_t RegNo,
1630e38b295SShao-Ce SUN uint64_t Address,
1644ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
1650e38b295SShao-Ce SUN if (RegNo >= 32 || RegNo & 1)
1660e38b295SShao-Ce SUN return MCDisassembler::Fail;
1670e38b295SShao-Ce SUN
1680e38b295SShao-Ce SUN MCRegister Reg = RISCV::X0 + RegNo;
1690e38b295SShao-Ce SUN Inst.addOperand(MCOperand::createReg(Reg));
1700e38b295SShao-Ce SUN return MCDisassembler::Success;
1710e38b295SShao-Ce SUN }
1720e38b295SShao-Ce SUN
DecodeVRRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)17366da87dcSHsiangkai Wang static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo,
17466da87dcSHsiangkai Wang uint64_t Address,
1754ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
17666da87dcSHsiangkai Wang if (RegNo >= 32)
17766da87dcSHsiangkai Wang return MCDisassembler::Fail;
17866da87dcSHsiangkai Wang
1790add5f91SCraig Topper MCRegister Reg = RISCV::V0 + RegNo;
18066da87dcSHsiangkai Wang Inst.addOperand(MCOperand::createReg(Reg));
18166da87dcSHsiangkai Wang return MCDisassembler::Success;
18266da87dcSHsiangkai Wang }
18366da87dcSHsiangkai Wang
DecodeVRM2RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)184a2d19badSHsiangkai Wang static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint64_t RegNo,
185a2d19badSHsiangkai Wang uint64_t Address,
1864ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
187a2d19badSHsiangkai Wang if (RegNo >= 32)
188a2d19badSHsiangkai Wang return MCDisassembler::Fail;
189a2d19badSHsiangkai Wang
190a2d19badSHsiangkai Wang if (RegNo % 2)
191a2d19badSHsiangkai Wang return MCDisassembler::Fail;
192a2d19badSHsiangkai Wang
193a2d19badSHsiangkai Wang const RISCVDisassembler *Dis =
194a2d19badSHsiangkai Wang static_cast<const RISCVDisassembler *>(Decoder);
195a2d19badSHsiangkai Wang const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
196a2d19badSHsiangkai Wang MCRegister Reg =
197a2d19badSHsiangkai Wang RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
198a2d19badSHsiangkai Wang &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);
199a2d19badSHsiangkai Wang
200a2d19badSHsiangkai Wang Inst.addOperand(MCOperand::createReg(Reg));
201a2d19badSHsiangkai Wang return MCDisassembler::Success;
202a2d19badSHsiangkai Wang }
203a2d19badSHsiangkai Wang
DecodeVRM4RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)204a2d19badSHsiangkai Wang static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint64_t RegNo,
205a2d19badSHsiangkai Wang uint64_t Address,
2064ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
207a2d19badSHsiangkai Wang if (RegNo >= 32)
208a2d19badSHsiangkai Wang return MCDisassembler::Fail;
209a2d19badSHsiangkai Wang
210a2d19badSHsiangkai Wang if (RegNo % 4)
211a2d19badSHsiangkai Wang return MCDisassembler::Fail;
212a2d19badSHsiangkai Wang
213a2d19badSHsiangkai Wang const RISCVDisassembler *Dis =
214a2d19badSHsiangkai Wang static_cast<const RISCVDisassembler *>(Decoder);
215a2d19badSHsiangkai Wang const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
216a2d19badSHsiangkai Wang MCRegister Reg =
217a2d19badSHsiangkai Wang RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
218a2d19badSHsiangkai Wang &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);
219a2d19badSHsiangkai Wang
220a2d19badSHsiangkai Wang Inst.addOperand(MCOperand::createReg(Reg));
221a2d19badSHsiangkai Wang return MCDisassembler::Success;
222a2d19badSHsiangkai Wang }
223a2d19badSHsiangkai Wang
DecodeVRM8RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)224a2d19badSHsiangkai Wang static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint64_t RegNo,
225a2d19badSHsiangkai Wang uint64_t Address,
2264ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
227a2d19badSHsiangkai Wang if (RegNo >= 32)
228a2d19badSHsiangkai Wang return MCDisassembler::Fail;
229a2d19badSHsiangkai Wang
230a2d19badSHsiangkai Wang if (RegNo % 8)
231a2d19badSHsiangkai Wang return MCDisassembler::Fail;
232a2d19badSHsiangkai Wang
233a2d19badSHsiangkai Wang const RISCVDisassembler *Dis =
234a2d19badSHsiangkai Wang static_cast<const RISCVDisassembler *>(Decoder);
235a2d19badSHsiangkai Wang const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();
236a2d19badSHsiangkai Wang MCRegister Reg =
237a2d19badSHsiangkai Wang RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,
238a2d19badSHsiangkai Wang &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);
239a2d19badSHsiangkai Wang
240a2d19badSHsiangkai Wang Inst.addOperand(MCOperand::createReg(Reg));
241a2d19badSHsiangkai Wang return MCDisassembler::Success;
242a2d19badSHsiangkai Wang }
243a2d19badSHsiangkai Wang
decodeVMaskReg(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)24466da87dcSHsiangkai Wang static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo,
2454ae9745aSMaksim Panchenko uint64_t Address,
2464ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
2470add5f91SCraig Topper MCRegister Reg = RISCV::NoRegister;
24866da87dcSHsiangkai Wang switch (RegNo) {
24966da87dcSHsiangkai Wang default:
25066da87dcSHsiangkai Wang return MCDisassembler::Fail;
25166da87dcSHsiangkai Wang case 0:
25266da87dcSHsiangkai Wang Reg = RISCV::V0;
25366da87dcSHsiangkai Wang break;
25466da87dcSHsiangkai Wang case 1:
25566da87dcSHsiangkai Wang break;
25666da87dcSHsiangkai Wang }
25766da87dcSHsiangkai Wang Inst.addOperand(MCOperand::createReg(Reg));
25866da87dcSHsiangkai Wang return MCDisassembler::Success;
25966da87dcSHsiangkai Wang }
26066da87dcSHsiangkai Wang
2619f6aec4bSAlex Bradbury // Add implied SP operand for instructions *SP compressed instructions. The SP
2629f6aec4bSAlex Bradbury // operand isn't explicitly encoded in the instruction.
addImplySP(MCInst & Inst,int64_t Address,const MCDisassembler * Decoder)2634ae9745aSMaksim Panchenko static void addImplySP(MCInst &Inst, int64_t Address,
2644ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
26519c9314aSAlex Bradbury if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
26619c9314aSAlex Bradbury Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
26719c9314aSAlex Bradbury Inst.getOpcode() == RISCV::C_FLWSP ||
26819c9314aSAlex Bradbury Inst.getOpcode() == RISCV::C_FSWSP ||
26919c9314aSAlex Bradbury Inst.getOpcode() == RISCV::C_FLDSP ||
27019c9314aSAlex Bradbury Inst.getOpcode() == RISCV::C_FSDSP ||
27119c9314aSAlex Bradbury Inst.getOpcode() == RISCV::C_ADDI4SPN) {
27260714f98SAlex Bradbury DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
27360714f98SAlex Bradbury }
27419c9314aSAlex Bradbury if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
27560714f98SAlex Bradbury DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
2769f6aec4bSAlex Bradbury DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
2779f6aec4bSAlex Bradbury }
2789f6aec4bSAlex Bradbury }
2799f6aec4bSAlex Bradbury
2808ab4a969SAlex Bradbury template <unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)2818ab4a969SAlex Bradbury static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
2824ae9745aSMaksim Panchenko int64_t Address,
2834ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
2848ab4a969SAlex Bradbury assert(isUInt<N>(Imm) && "Invalid immediate");
2859f6aec4bSAlex Bradbury addImplySP(Inst, Address, Decoder);
2868ab4a969SAlex Bradbury Inst.addOperand(MCOperand::createImm(Imm));
2878ab4a969SAlex Bradbury return MCDisassembler::Success;
2888ab4a969SAlex Bradbury }
2898ab4a969SAlex Bradbury
2908ab4a969SAlex Bradbury template <unsigned N>
decodeUImmNonZeroOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)291b0799ddaSAna Pazos static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
292b0799ddaSAna Pazos int64_t Address,
2934ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
294b0799ddaSAna Pazos if (Imm == 0)
295b0799ddaSAna Pazos return MCDisassembler::Fail;
296b0799ddaSAna Pazos return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);
297b0799ddaSAna Pazos }
298b0799ddaSAna Pazos
299b0799ddaSAna Pazos template <unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)3008ab4a969SAlex Bradbury static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
3014ae9745aSMaksim Panchenko int64_t Address,
3024ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
3038ab4a969SAlex Bradbury assert(isUInt<N>(Imm) && "Invalid immediate");
30460714f98SAlex Bradbury addImplySP(Inst, Address, Decoder);
3058ab4a969SAlex Bradbury // Sign-extend the number in the bottom N bits of Imm
3068ab4a969SAlex Bradbury Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
3078ab4a969SAlex Bradbury return MCDisassembler::Success;
3088ab4a969SAlex Bradbury }
3098ab4a969SAlex Bradbury
3108ab4a969SAlex Bradbury template <unsigned N>
decodeSImmNonZeroOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)311b0799ddaSAna Pazos static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm,
312b0799ddaSAna Pazos int64_t Address,
3134ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
314b0799ddaSAna Pazos if (Imm == 0)
315b0799ddaSAna Pazos return MCDisassembler::Fail;
316b0799ddaSAna Pazos return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);
317b0799ddaSAna Pazos }
318b0799ddaSAna Pazos
319b0799ddaSAna Pazos template <unsigned N>
decodeSImmOperandAndLsl1(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)3208ab4a969SAlex Bradbury static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
3218ab4a969SAlex Bradbury int64_t Address,
3224ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
3238ab4a969SAlex Bradbury assert(isUInt<N>(Imm) && "Invalid immediate");
3248ab4a969SAlex Bradbury // Sign-extend the number in the bottom N bits of Imm after accounting for
3258ab4a969SAlex Bradbury // the fact that the N bit immediate is stored in N-1 bits (the LSB is
3268ab4a969SAlex Bradbury // always zero)
3278ab4a969SAlex Bradbury Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
3288ab4a969SAlex Bradbury return MCDisassembler::Success;
3298ab4a969SAlex Bradbury }
3308ab4a969SAlex Bradbury
decodeCLUIImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)3317c17242bSShiva Chen static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
3327c17242bSShiva Chen int64_t Address,
3334ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
3347c17242bSShiva Chen assert(isUInt<6>(Imm) && "Invalid immediate");
3357c17242bSShiva Chen if (Imm > 31) {
3367c17242bSShiva Chen Imm = (SignExtend64<6>(Imm) & 0xfffff);
3377c17242bSShiva Chen }
3387c17242bSShiva Chen Inst.addOperand(MCOperand::createImm(Imm));
3397c17242bSShiva Chen return MCDisassembler::Success;
3407c17242bSShiva Chen }
3417c17242bSShiva Chen
decodeFRMArg(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)3424ae9745aSMaksim Panchenko static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, int64_t Address,
3434ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
344b2ed11a0SAna Pazos assert(isUInt<3>(Imm) && "Invalid immediate");
345b2ed11a0SAna Pazos if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))
346b2ed11a0SAna Pazos return MCDisassembler::Fail;
347b2ed11a0SAna Pazos
348b2ed11a0SAna Pazos Inst.addOperand(MCOperand::createImm(Imm));
349b2ed11a0SAna Pazos return MCDisassembler::Success;
350b2ed11a0SAna Pazos }
351b2ed11a0SAna Pazos
352c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
3534ae9745aSMaksim Panchenko uint64_t Address,
3544ae9745aSMaksim Panchenko const MCDisassembler *Decoder);
355c3bf3d14SLuis Marques
356c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
3574ae9745aSMaksim Panchenko uint64_t Address,
3584ae9745aSMaksim Panchenko const MCDisassembler *Decoder);
359c3bf3d14SLuis Marques
360c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
361c3bf3d14SLuis Marques uint64_t Address,
3624ae9745aSMaksim Panchenko const MCDisassembler *Decoder);
363c3bf3d14SLuis Marques
364c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
3654ae9745aSMaksim Panchenko uint64_t Address,
3664ae9745aSMaksim Panchenko const MCDisassembler *Decoder);
367c3bf3d14SLuis Marques
368c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
369c3bf3d14SLuis Marques uint64_t Address,
3704ae9745aSMaksim Panchenko const MCDisassembler *Decoder);
371c3bf3d14SLuis Marques
3728ab4a969SAlex Bradbury #include "RISCVGenDisassemblerTables.inc"
3738ab4a969SAlex Bradbury
decodeRVCInstrSImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)374c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn,
3754ae9745aSMaksim Panchenko uint64_t Address,
3764ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
377c3bf3d14SLuis Marques uint64_t SImm6 =
378c3bf3d14SLuis Marques fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
3794f488b59SLuis Marques DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
3804f488b59SLuis Marques (void)Result;
3814f488b59SLuis Marques assert(Result == MCDisassembler::Success && "Invalid immediate");
382c3bf3d14SLuis Marques return MCDisassembler::Success;
383c3bf3d14SLuis Marques }
384c3bf3d14SLuis Marques
decodeRVCInstrRdSImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)385c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn,
386c3bf3d14SLuis Marques uint64_t Address,
3874ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
388c3bf3d14SLuis Marques DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
389c3bf3d14SLuis Marques uint64_t SImm6 =
390c3bf3d14SLuis Marques fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
3914f488b59SLuis Marques DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);
3924f488b59SLuis Marques (void)Result;
3934f488b59SLuis Marques assert(Result == MCDisassembler::Success && "Invalid immediate");
394c3bf3d14SLuis Marques return MCDisassembler::Success;
395c3bf3d14SLuis Marques }
396c3bf3d14SLuis Marques
decodeRVCInstrRdRs1UImm(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)397c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn,
398c3bf3d14SLuis Marques uint64_t Address,
3994ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
400c3bf3d14SLuis Marques DecodeGPRRegisterClass(Inst, 0, Address, Decoder);
401c3bf3d14SLuis Marques Inst.addOperand(Inst.getOperand(0));
402c3bf3d14SLuis Marques uint64_t UImm6 =
403c3bf3d14SLuis Marques fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);
4044f488b59SLuis Marques DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);
4054f488b59SLuis Marques (void)Result;
4064f488b59SLuis Marques assert(Result == MCDisassembler::Success && "Invalid immediate");
407c3bf3d14SLuis Marques return MCDisassembler::Success;
408c3bf3d14SLuis Marques }
409c3bf3d14SLuis Marques
decodeRVCInstrRdRs2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)410c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn,
4114ae9745aSMaksim Panchenko uint64_t Address,
4124ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
413c3bf3d14SLuis Marques unsigned Rd = fieldFromInstruction(Insn, 7, 5);
414c3bf3d14SLuis Marques unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
415c3bf3d14SLuis Marques DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
416c3bf3d14SLuis Marques DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
417c3bf3d14SLuis Marques return MCDisassembler::Success;
418c3bf3d14SLuis Marques }
419c3bf3d14SLuis Marques
decodeRVCInstrRdRs1Rs2(MCInst & Inst,unsigned Insn,uint64_t Address,const MCDisassembler * Decoder)420c3bf3d14SLuis Marques static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn,
421c3bf3d14SLuis Marques uint64_t Address,
4224ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
423c3bf3d14SLuis Marques unsigned Rd = fieldFromInstruction(Insn, 7, 5);
424c3bf3d14SLuis Marques unsigned Rs2 = fieldFromInstruction(Insn, 2, 5);
425c3bf3d14SLuis Marques DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);
426c3bf3d14SLuis Marques Inst.addOperand(Inst.getOperand(0));
427c3bf3d14SLuis Marques DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);
428c3bf3d14SLuis Marques return MCDisassembler::Success;
429c3bf3d14SLuis Marques }
430c3bf3d14SLuis Marques
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const4318ab4a969SAlex Bradbury DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
4328ab4a969SAlex Bradbury ArrayRef<uint8_t> Bytes,
4338ab4a969SAlex Bradbury uint64_t Address,
4348ab4a969SAlex Bradbury raw_ostream &CS) const {
4359f6aec4bSAlex Bradbury // TODO: This will need modification when supporting instruction set
4369f6aec4bSAlex Bradbury // extensions with instructions > 32-bits (up to 176 bits wide).
4379f6aec4bSAlex Bradbury uint32_t Insn;
4389f6aec4bSAlex Bradbury DecodeStatus Result;
4399f6aec4bSAlex Bradbury
4409f6aec4bSAlex Bradbury // It's a 32 bit instruction if bit 0 and 1 are 1.
4419f6aec4bSAlex Bradbury if ((Bytes[0] & 0x3) == 0x3) {
442b97d1894SAna Pazos if (Bytes.size() < 4) {
443b97d1894SAna Pazos Size = 0;
444b97d1894SAna Pazos return MCDisassembler::Fail;
445b97d1894SAna Pazos }
4469f6aec4bSAlex Bradbury Insn = support::endian::read32le(Bytes.data());
4470e38b295SShao-Ce SUN if (STI.getFeatureBits()[RISCV::FeatureStdExtZdinx] &&
4480e38b295SShao-Ce SUN !STI.getFeatureBits()[RISCV::Feature64Bit]) {
4490e38b295SShao-Ce SUN LLVM_DEBUG(dbgs() << "Trying RV32Zdinx table (Double in Integer and"
4500e38b295SShao-Ce SUN "rv32)\n");
4510e38b295SShao-Ce SUN Result = decodeInstruction(DecoderTableRV32Zdinx32, MI, Insn, Address,
4520e38b295SShao-Ce SUN this, STI);
4530e38b295SShao-Ce SUN if (Result != MCDisassembler::Fail) {
4540e38b295SShao-Ce SUN Size = 4;
4550e38b295SShao-Ce SUN return Result;
4560e38b295SShao-Ce SUN }
4570e38b295SShao-Ce SUN }
4580e38b295SShao-Ce SUN
4590e38b295SShao-Ce SUN if (STI.getFeatureBits()[RISCV::FeatureStdExtZfinx]) {
4600e38b295SShao-Ce SUN LLVM_DEBUG(dbgs() << "Trying RVZfinx table (Float in Integer):\n");
4610e38b295SShao-Ce SUN Result = decodeInstruction(DecoderTableRVZfinx32, MI, Insn, Address, this,
4620e38b295SShao-Ce SUN STI);
4630e38b295SShao-Ce SUN if (Result != MCDisassembler::Fail) {
4640e38b295SShao-Ce SUN Size = 4;
4650e38b295SShao-Ce SUN return Result;
4660e38b295SShao-Ce SUN }
4670e38b295SShao-Ce SUN }
468d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
4699f6aec4bSAlex Bradbury Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
4708ab4a969SAlex Bradbury Size = 4;
4719f6aec4bSAlex Bradbury } else {
472b97d1894SAna Pazos if (Bytes.size() < 2) {
473b97d1894SAna Pazos Size = 0;
474b97d1894SAna Pazos return MCDisassembler::Fail;
475b97d1894SAna Pazos }
4769f6aec4bSAlex Bradbury Insn = support::endian::read16le(Bytes.data());
47760714f98SAlex Bradbury
47860714f98SAlex Bradbury if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
479d34e60caSNicola Zaghen LLVM_DEBUG(
480d34e60caSNicola Zaghen dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
48160714f98SAlex Bradbury // Calling the auto-generated decoder function.
48260714f98SAlex Bradbury Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
48360714f98SAlex Bradbury this, STI);
48460714f98SAlex Bradbury if (Result != MCDisassembler::Fail) {
48560714f98SAlex Bradbury Size = 2;
48660714f98SAlex Bradbury return Result;
48760714f98SAlex Bradbury }
48860714f98SAlex Bradbury }
48960714f98SAlex Bradbury
490d34e60caSNicola Zaghen LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
4919f6aec4bSAlex Bradbury // Calling the auto-generated decoder function.
4929f6aec4bSAlex Bradbury Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
4939f6aec4bSAlex Bradbury Size = 2;
4948ab4a969SAlex Bradbury }
4958ab4a969SAlex Bradbury
4969f6aec4bSAlex Bradbury return Result;
4978ab4a969SAlex Bradbury }
498