Path: blob/main/contrib/llvm-project/llvm/lib/Target/RISCV/Disassembler/RISCVDisassembler.cpp
35293 views
//===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the RISCVDisassembler class.9//10//===----------------------------------------------------------------------===//1112#include "MCTargetDesc/RISCVBaseInfo.h"13#include "MCTargetDesc/RISCVMCTargetDesc.h"14#include "TargetInfo/RISCVTargetInfo.h"15#include "llvm/MC/MCContext.h"16#include "llvm/MC/MCDecoderOps.h"17#include "llvm/MC/MCDisassembler/MCDisassembler.h"18#include "llvm/MC/MCInst.h"19#include "llvm/MC/MCInstrInfo.h"20#include "llvm/MC/MCRegisterInfo.h"21#include "llvm/MC/MCSubtargetInfo.h"22#include "llvm/MC/TargetRegistry.h"23#include "llvm/Support/Endian.h"2425using namespace llvm;2627#define DEBUG_TYPE "riscv-disassembler"2829typedef MCDisassembler::DecodeStatus DecodeStatus;3031namespace {32class RISCVDisassembler : public MCDisassembler {33std::unique_ptr<MCInstrInfo const> const MCII;3435public:36RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,37MCInstrInfo const *MCII)38: MCDisassembler(STI, Ctx), MCII(MCII) {}3940DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,41ArrayRef<uint8_t> Bytes, uint64_t Address,42raw_ostream &CStream) const override;4344private:45void addSPOperands(MCInst &MI) const;4647DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,48ArrayRef<uint8_t> Bytes, uint64_t Address,49raw_ostream &CStream) const;50DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size,51ArrayRef<uint8_t> Bytes, uint64_t Address,52raw_ostream &CStream) const;53};54} // end anonymous namespace5556static MCDisassembler *createRISCVDisassembler(const Target &T,57const MCSubtargetInfo &STI,58MCContext &Ctx) {59return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());60}6162extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() {63// Register the disassembler for each target.64TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),65createRISCVDisassembler);66TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),67createRISCVDisassembler);68}6970static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,71uint64_t Address,72const MCDisassembler *Decoder) {73bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);7475if (RegNo >= 32 || (IsRVE && RegNo >= 16))76return MCDisassembler::Fail;7778MCRegister Reg = RISCV::X0 + RegNo;79Inst.addOperand(MCOperand::createReg(Reg));80return MCDisassembler::Success;81}8283static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,84uint64_t Address,85const MCDisassembler *Decoder) {86MCRegister Reg = RISCV::X0 + RegNo;87if (Reg != RISCV::X1 && Reg != RISCV::X5)88return MCDisassembler::Fail;8990Inst.addOperand(MCOperand::createReg(Reg));91return MCDisassembler::Success;92}9394static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo,95uint64_t Address,96const MCDisassembler *Decoder) {97if (RegNo >= 32)98return MCDisassembler::Fail;99100MCRegister Reg = RISCV::F0_H + RegNo;101Inst.addOperand(MCOperand::createReg(Reg));102return MCDisassembler::Success;103}104105static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo,106uint64_t Address,107const MCDisassembler *Decoder) {108if (RegNo >= 32)109return MCDisassembler::Fail;110111MCRegister Reg = RISCV::F0_F + RegNo;112Inst.addOperand(MCOperand::createReg(Reg));113return MCDisassembler::Success;114}115116static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo,117uint64_t Address,118const MCDisassembler *Decoder) {119if (RegNo >= 8) {120return MCDisassembler::Fail;121}122MCRegister Reg = RISCV::F8_F + RegNo;123Inst.addOperand(MCOperand::createReg(Reg));124return MCDisassembler::Success;125}126127static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo,128uint64_t Address,129const MCDisassembler *Decoder) {130if (RegNo >= 32)131return MCDisassembler::Fail;132133MCRegister Reg = RISCV::F0_D + RegNo;134Inst.addOperand(MCOperand::createReg(Reg));135return MCDisassembler::Success;136}137138static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,139uint64_t Address,140const MCDisassembler *Decoder) {141if (RegNo >= 8) {142return MCDisassembler::Fail;143}144MCRegister Reg = RISCV::F8_D + RegNo;145Inst.addOperand(MCOperand::createReg(Reg));146return MCDisassembler::Success;147}148149static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,150uint64_t Address,151const MCDisassembler *Decoder) {152if (RegNo == 0) {153return MCDisassembler::Fail;154}155156return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);157}158159static DecodeStatus160DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address,161const MCDisassembler *Decoder) {162if (RegNo == 2) {163return MCDisassembler::Fail;164}165166return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);167}168169static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo,170uint64_t Address,171const MCDisassembler *Decoder) {172if (RegNo >= 8)173return MCDisassembler::Fail;174175MCRegister Reg = RISCV::X8 + RegNo;176Inst.addOperand(MCOperand::createReg(Reg));177return MCDisassembler::Success;178}179180static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,181uint64_t Address,182const MCDisassembler *Decoder) {183if (RegNo >= 32 || RegNo & 1)184return MCDisassembler::Fail;185186MCRegister Reg = RISCV::X0 + RegNo;187Inst.addOperand(MCOperand::createReg(Reg));188return MCDisassembler::Success;189}190191static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo,192uint64_t Address,193const void *Decoder) {194if (RegNo >= 8)195return MCDisassembler::Fail;196197MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);198Inst.addOperand(MCOperand::createReg(Reg));199return MCDisassembler::Success;200}201202static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,203uint64_t Address,204const MCDisassembler *Decoder) {205if (RegNo >= 32)206return MCDisassembler::Fail;207208MCRegister Reg = RISCV::V0 + RegNo;209Inst.addOperand(MCOperand::createReg(Reg));210return MCDisassembler::Success;211}212213static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,214uint64_t Address,215const MCDisassembler *Decoder) {216if (RegNo >= 32 || RegNo % 2)217return MCDisassembler::Fail;218219const RISCVDisassembler *Dis =220static_cast<const RISCVDisassembler *>(Decoder);221const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();222MCRegister Reg =223RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,224&RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);225226Inst.addOperand(MCOperand::createReg(Reg));227return MCDisassembler::Success;228}229230static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo,231uint64_t Address,232const MCDisassembler *Decoder) {233if (RegNo >= 32 || RegNo % 4)234return MCDisassembler::Fail;235236const RISCVDisassembler *Dis =237static_cast<const RISCVDisassembler *>(Decoder);238const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();239MCRegister Reg =240RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,241&RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);242243Inst.addOperand(MCOperand::createReg(Reg));244return MCDisassembler::Success;245}246247static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,248uint64_t Address,249const MCDisassembler *Decoder) {250if (RegNo >= 32 || RegNo % 8)251return MCDisassembler::Fail;252253const RISCVDisassembler *Dis =254static_cast<const RISCVDisassembler *>(Decoder);255const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();256MCRegister Reg =257RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,258&RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);259260Inst.addOperand(MCOperand::createReg(Reg));261return MCDisassembler::Success;262}263264static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,265uint64_t Address,266const MCDisassembler *Decoder) {267if (RegNo >= 2)268return MCDisassembler::Fail;269270MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;271272Inst.addOperand(MCOperand::createReg(Reg));273return MCDisassembler::Success;274}275276template <unsigned N>277static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,278int64_t Address,279const MCDisassembler *Decoder) {280assert(isUInt<N>(Imm) && "Invalid immediate");281Inst.addOperand(MCOperand::createImm(Imm));282return MCDisassembler::Success;283}284285template <unsigned N>286static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,287int64_t Address,288const MCDisassembler *Decoder) {289if (Imm == 0)290return MCDisassembler::Fail;291return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);292}293294template <unsigned N>295static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,296int64_t Address,297const MCDisassembler *Decoder) {298assert(isUInt<N>(Imm) && "Invalid immediate");299// Sign-extend the number in the bottom N bits of Imm300Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));301return MCDisassembler::Success;302}303304template <unsigned N>305static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,306int64_t Address,307const MCDisassembler *Decoder) {308if (Imm == 0)309return MCDisassembler::Fail;310return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);311}312313template <unsigned N>314static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm,315int64_t Address,316const MCDisassembler *Decoder) {317assert(isUInt<N>(Imm) && "Invalid immediate");318// Sign-extend the number in the bottom N bits of Imm after accounting for319// the fact that the N bit immediate is stored in N-1 bits (the LSB is320// always zero)321Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));322return MCDisassembler::Success;323}324325static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,326int64_t Address,327const MCDisassembler *Decoder) {328assert(isUInt<6>(Imm) && "Invalid immediate");329if (Imm > 31) {330Imm = (SignExtend64<6>(Imm) & 0xfffff);331}332Inst.addOperand(MCOperand::createImm(Imm));333return MCDisassembler::Success;334}335336static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,337const MCDisassembler *Decoder) {338assert(isUInt<3>(Imm) && "Invalid immediate");339if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))340return MCDisassembler::Fail;341342Inst.addOperand(MCOperand::createImm(Imm));343return MCDisassembler::Success;344}345346static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,347uint64_t Address,348const MCDisassembler *Decoder);349350static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,351uint64_t Address,352const MCDisassembler *Decoder);353354static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,355uint64_t Address,356const MCDisassembler *Decoder);357358static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,359uint64_t Address,360const MCDisassembler *Decoder);361362static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,363uint64_t Address,364const MCDisassembler *Decoder);365366static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,367uint64_t Address,368const MCDisassembler *Decoder);369370static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,371uint64_t Address, const void *Decoder);372373static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,374const MCDisassembler *Decoder);375376static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,377uint64_t Address, const void *Decoder);378379static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,380uint64_t Address,381const MCDisassembler *Decoder);382383#include "RISCVGenDisassemblerTables.inc"384385static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn,386uint64_t Address,387const MCDisassembler *Decoder) {388uint32_t Rd = fieldFromInstruction(Insn, 7, 5);389[[maybe_unused]] DecodeStatus Result =390DecodeGPRNoX0RegisterClass(Inst, Rd, Address, Decoder);391assert(Result == MCDisassembler::Success && "Invalid register");392Inst.addOperand(Inst.getOperand(0));393Inst.addOperand(MCOperand::createImm(0));394return MCDisassembler::Success;395}396397static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn,398uint64_t Address,399const MCDisassembler *Decoder) {400uint32_t Rs1 = fieldFromInstruction(Insn, 7, 5);401[[maybe_unused]] DecodeStatus Result =402DecodeGPRX1X5RegisterClass(Inst, Rs1, Address, Decoder);403assert(Result == MCDisassembler::Success && "Invalid register");404return MCDisassembler::Success;405}406407static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn,408uint64_t Address,409const MCDisassembler *Decoder) {410Inst.addOperand(MCOperand::createReg(RISCV::X0));411uint32_t SImm6 =412fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);413[[maybe_unused]] DecodeStatus Result =414decodeSImmOperand<6>(Inst, SImm6, Address, Decoder);415assert(Result == MCDisassembler::Success && "Invalid immediate");416return MCDisassembler::Success;417}418419static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn,420uint64_t Address,421const MCDisassembler *Decoder) {422Inst.addOperand(MCOperand::createReg(RISCV::X0));423Inst.addOperand(Inst.getOperand(0));424uint32_t UImm6 =425fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5);426[[maybe_unused]] DecodeStatus Result =427decodeUImmOperand<6>(Inst, UImm6, Address, Decoder);428assert(Result == MCDisassembler::Success && "Invalid immediate");429return MCDisassembler::Success;430}431432static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn,433uint64_t Address,434const MCDisassembler *Decoder) {435uint32_t Rd = fieldFromInstruction(Insn, 7, 5);436uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);437DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);438DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);439return MCDisassembler::Success;440}441442static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn,443uint64_t Address,444const MCDisassembler *Decoder) {445uint32_t Rd = fieldFromInstruction(Insn, 7, 5);446uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5);447DecodeGPRRegisterClass(Inst, Rd, Address, Decoder);448Inst.addOperand(Inst.getOperand(0));449DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);450return MCDisassembler::Success;451}452453static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn,454uint64_t Address,455const MCDisassembler *Decoder) {456uint32_t Rd1 = fieldFromInstruction(Insn, 7, 5);457uint32_t Rs1 = fieldFromInstruction(Insn, 15, 5);458uint32_t Rd2 = fieldFromInstruction(Insn, 20, 5);459uint32_t UImm2 = fieldFromInstruction(Insn, 25, 2);460DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder);461DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder);462DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);463[[maybe_unused]] DecodeStatus Result =464decodeUImmOperand<2>(Inst, UImm2, Address, Decoder);465assert(Result == MCDisassembler::Success && "Invalid immediate");466467// Disassemble the final operand which is implicit.468unsigned Opcode = Inst.getOpcode();469bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD ||470Opcode == RISCV::TH_SWD);471if (IsWordOp)472Inst.addOperand(MCOperand::createImm(3));473else474Inst.addOperand(MCOperand::createImm(4));475476return MCDisassembler::Success;477}478479static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,480uint64_t Address, const void *Decoder) {481if (Imm <= 3)482return MCDisassembler::Fail;483Inst.addOperand(MCOperand::createImm(Imm));484return MCDisassembler::Success;485}486487static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address,488const MCDisassembler *Decoder) {489uint32_t Rs1 = fieldFromInstruction(Insn, 0, 5);490uint32_t Rs2 = fieldFromInstruction(Insn, 5, 5);491DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder);492DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder);493return MCDisassembler::Success;494}495496static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm,497uint64_t Address, const void *Decoder) {498Inst.addOperand(MCOperand::createImm(Imm));499return MCDisassembler::Success;500}501502// Add implied SP operand for C.*SP compressed instructions. The SP operand503// isn't explicitly encoded in the instruction.504void RISCVDisassembler::addSPOperands(MCInst &MI) const {505const MCInstrDesc &MCID = MCII->get(MI.getOpcode());506for (unsigned i = 0; i < MCID.getNumOperands(); i++)507if (MCID.operands()[i].RegClass == RISCV::SPRegClassID)508MI.insert(MI.begin() + i, MCOperand::createReg(RISCV::X2));509}510511#define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, \512DESC, ADDITIONAL_OPERATION) \513do { \514if (FEATURE_CHECKS) { \515LLVM_DEBUG(dbgs() << "Trying " DESC ":\n"); \516DecodeStatus Result = \517decodeInstruction(DECODER_TABLE, MI, Insn, Address, this, STI); \518if (Result != MCDisassembler::Fail) { \519ADDITIONAL_OPERATION; \520return Result; \521} \522} \523} while (false)524#define TRY_TO_DECODE_AND_ADD_SP(FEATURE_CHECKS, DECODER_TABLE, DESC) \525TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \526addSPOperands(MI))527#define TRY_TO_DECODE(FEATURE_CHECKS, DECODER_TABLE, DESC) \528TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \529(void)nullptr)530#define TRY_TO_DECODE_FEATURE(FEATURE, DECODER_TABLE, DESC) \531TRY_TO_DECODE(STI.hasFeature(FEATURE), DECODER_TABLE, DESC)532533DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,534ArrayRef<uint8_t> Bytes,535uint64_t Address,536raw_ostream &CS) const {537if (Bytes.size() < 4) {538Size = 0;539return MCDisassembler::Fail;540}541Size = 4;542543uint32_t Insn = support::endian::read32le(Bytes.data());544545TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZdinx) &&546!STI.hasFeature(RISCV::Feature64Bit),547DecoderTableRV32Zdinx32,548"RV32Zdinx table (Double in Integer and rv32)");549TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZacas) &&550!STI.hasFeature(RISCV::Feature64Bit),551DecoderTableRV32Zacas32,552"RV32Zacas table (Compare-And-Swap and rv32)");553TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZfinx, DecoderTableRVZfinx32,554"RVZfinx table (Float in Integer)");555TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXVentanaCondOps,556DecoderTableXVentana32, "Ventana custom opcode table");557TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBa, DecoderTableXTHeadBa32,558"XTHeadBa custom opcode table");559TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBb, DecoderTableXTHeadBb32,560"XTHeadBb custom opcode table");561TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBs, DecoderTableXTHeadBs32,562"XTHeadBs custom opcode table");563TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCondMov,564DecoderTableXTHeadCondMov32,565"XTHeadCondMov custom opcode table");566TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCmo, DecoderTableXTHeadCmo32,567"XTHeadCmo custom opcode table");568TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadFMemIdx,569DecoderTableXTHeadFMemIdx32,570"XTHeadFMemIdx custom opcode table");571TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMac, DecoderTableXTHeadMac32,572"XTHeadMac custom opcode table");573TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemIdx,574DecoderTableXTHeadMemIdx32,575"XTHeadMemIdx custom opcode table");576TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemPair,577DecoderTableXTHeadMemPair32,578"XTHeadMemPair custom opcode table");579TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadSync,580DecoderTableXTHeadSync32,581"XTHeadSync custom opcode table");582TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadVdot,583DecoderTableXTHeadVdot32,584"XTHeadVdot custom opcode table");585TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfvcp, DecoderTableXSfvcp32,586"SiFive VCIX custom opcode table");587TRY_TO_DECODE_FEATURE(588RISCV::FeatureVendorXSfvqmaccdod, DecoderTableXSfvqmaccdod32,589"SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table");590TRY_TO_DECODE_FEATURE(591RISCV::FeatureVendorXSfvqmaccqoq, DecoderTableXSfvqmaccqoq32,592"SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table");593TRY_TO_DECODE_FEATURE(594RISCV::FeatureVendorXSfvfwmaccqqq, DecoderTableXSfvfwmaccqqq32,595"SiFive Matrix Multiplication Instruction opcode table");596TRY_TO_DECODE_FEATURE(597RISCV::FeatureVendorXSfvfnrclipxfqf, DecoderTableXSfvfnrclipxfqf32,598"SiFive FP32-to-int8 Ranged Clip Instructions opcode table");599TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecdiscarddlone,600DecoderTableXSiFivecdiscarddlone32,601"SiFive sf.cdiscard.d.l1 custom opcode table");602TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecflushdlone,603DecoderTableXSiFivecflushdlone32,604"SiFive sf.cflush.d.l1 custom opcode table");605TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcease, DecoderTableXSfcease32,606"SiFive sf.cease custom opcode table");607TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip,608DecoderTableXCVbitmanip32,609"CORE-V Bit Manipulation custom opcode table");610TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32,611"CORE-V Event load custom opcode table");612TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32,613"CORE-V MAC custom opcode table");614TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32,615"CORE-V MEM custom opcode table");616TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32,617"CORE-V ALU custom opcode table");618TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32,619"CORE-V SIMD extensions custom opcode table");620TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32,621"CORE-V Immediate Branching custom opcode table");622TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table");623624return MCDisassembler::Fail;625}626627DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,628ArrayRef<uint8_t> Bytes,629uint64_t Address,630raw_ostream &CS) const {631if (Bytes.size() < 2) {632Size = 0;633return MCDisassembler::Fail;634}635Size = 2;636637uint32_t Insn = support::endian::read16le(Bytes.data());638TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit),639DecoderTableRISCV32Only_16,640"RISCV32Only_16 table (16-bit Instruction)");641TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZicfiss, DecoderTableZicfiss16,642"RVZicfiss table (Shadow Stack)");643TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16,644"Zcmt table (16-bit Table Jump Instructions)");645TRY_TO_DECODE_FEATURE(646RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16,647"Zcmp table (16-bit Push/Pop & Double Move Instructions)");648TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc),649DecoderTableXwchc16,650"WCH QingKe XW custom opcode table");651TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16,652"RISCV_C table (16-bit Instruction)");653654return MCDisassembler::Fail;655}656657DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,658ArrayRef<uint8_t> Bytes,659uint64_t Address,660raw_ostream &CS) const {661// It's a 16 bit instruction if bit 0 and 1 are not 0b11.662if ((Bytes[0] & 0b11) != 0b11)663return getInstruction16(MI, Size, Bytes, Address, CS);664665// It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2666// are not 0b111.667if ((Bytes[0] & 0b1'1100) != 0b1'1100)668return getInstruction32(MI, Size, Bytes, Address, CS);669670// 48-bit instructions are encoded as 0bxx011111.671if ((Bytes[0] & 0b11'1111) == 0b01'1111) {672Size = Bytes.size() >= 6 ? 6 : 0;673return MCDisassembler::Fail;674}675676// 64-bit instructions are encoded as 0x0111111.677if ((Bytes[0] & 0b111'1111) == 0b011'1111) {678Size = Bytes.size() >= 8 ? 8 : 0;679return MCDisassembler::Fail;680}681682// Remaining cases need to check a second byte.683if (Bytes.size() < 2) {684Size = 0;685return MCDisassembler::Fail;686}687688// 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.689// Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.690unsigned nnn = (Bytes[1] >> 4) & 0b111;691if (nnn != 0b111) {692Size = 10 + (nnn * 2);693if (Bytes.size() < Size)694Size = 0;695return MCDisassembler::Fail;696}697698// Remaining encodings are reserved for > 176-bit instructions.699Size = 0;700return MCDisassembler::Fail;701}702703704