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