12cab237bSDimitry Andric //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===// 22cab237bSDimitry Andric // 32cab237bSDimitry Andric // The LLVM Compiler Infrastructure 42cab237bSDimitry Andric // 52cab237bSDimitry Andric // This file is distributed under the University of Illinois Open Source 62cab237bSDimitry Andric // License. See LICENSE.TXT for details. 72cab237bSDimitry Andric // 82cab237bSDimitry Andric //===----------------------------------------------------------------------===// 92cab237bSDimitry Andric // 102cab237bSDimitry Andric // This file implements the RISCVDisassembler class. 112cab237bSDimitry Andric // 122cab237bSDimitry Andric //===----------------------------------------------------------------------===// 132cab237bSDimitry Andric 142cab237bSDimitry Andric #include "MCTargetDesc/RISCVMCTargetDesc.h" 152cab237bSDimitry Andric #include "llvm/MC/MCContext.h" 162cab237bSDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h" 172cab237bSDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h" 182cab237bSDimitry Andric #include "llvm/MC/MCInst.h" 192cab237bSDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 202cab237bSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 212cab237bSDimitry Andric #include "llvm/Support/Endian.h" 222cab237bSDimitry Andric #include "llvm/Support/TargetRegistry.h" 232cab237bSDimitry Andric 242cab237bSDimitry Andric using namespace llvm; 252cab237bSDimitry Andric 262cab237bSDimitry Andric #define DEBUG_TYPE "riscv-disassembler" 272cab237bSDimitry Andric 282cab237bSDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus; 292cab237bSDimitry Andric 302cab237bSDimitry Andric namespace { 312cab237bSDimitry Andric class RISCVDisassembler : public MCDisassembler { 322cab237bSDimitry Andric 332cab237bSDimitry Andric public: 342cab237bSDimitry Andric RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 352cab237bSDimitry Andric : MCDisassembler(STI, Ctx) {} 362cab237bSDimitry Andric 372cab237bSDimitry Andric DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 382cab237bSDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address, 392cab237bSDimitry Andric raw_ostream &VStream, 402cab237bSDimitry Andric raw_ostream &CStream) const override; 412cab237bSDimitry Andric }; 422cab237bSDimitry Andric } // end anonymous namespace 432cab237bSDimitry Andric 442cab237bSDimitry Andric static MCDisassembler *createRISCVDisassembler(const Target &T, 452cab237bSDimitry Andric const MCSubtargetInfo &STI, 462cab237bSDimitry Andric MCContext &Ctx) { 472cab237bSDimitry Andric return new RISCVDisassembler(STI, Ctx); 482cab237bSDimitry Andric } 492cab237bSDimitry Andric 502cab237bSDimitry Andric extern "C" void LLVMInitializeRISCVDisassembler() { 512cab237bSDimitry Andric // Register the disassembler for each target. 522cab237bSDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(), 532cab237bSDimitry Andric createRISCVDisassembler); 542cab237bSDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(), 552cab237bSDimitry Andric createRISCVDisassembler); 562cab237bSDimitry Andric } 572cab237bSDimitry Andric 582cab237bSDimitry Andric static const unsigned GPRDecoderTable[] = { 592cab237bSDimitry Andric RISCV::X0, RISCV::X1, RISCV::X2, RISCV::X3, 602cab237bSDimitry Andric RISCV::X4, RISCV::X5, RISCV::X6, RISCV::X7, 612cab237bSDimitry Andric RISCV::X8, RISCV::X9, RISCV::X10, RISCV::X11, 622cab237bSDimitry Andric RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, 632cab237bSDimitry Andric RISCV::X16, RISCV::X17, RISCV::X18, RISCV::X19, 642cab237bSDimitry Andric RISCV::X20, RISCV::X21, RISCV::X22, RISCV::X23, 652cab237bSDimitry Andric RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27, 662cab237bSDimitry Andric RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31 672cab237bSDimitry Andric }; 682cab237bSDimitry Andric 692cab237bSDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 702cab237bSDimitry Andric uint64_t Address, 712cab237bSDimitry Andric const void *Decoder) { 722cab237bSDimitry Andric if (RegNo > sizeof(GPRDecoderTable)) 732cab237bSDimitry Andric return MCDisassembler::Fail; 742cab237bSDimitry Andric 752cab237bSDimitry Andric // We must define our own mapping from RegNo to register identifier. 762cab237bSDimitry Andric // Accessing index RegNo in the register class will work in the case that 772cab237bSDimitry Andric // registers were added in ascending order, but not in general. 782cab237bSDimitry Andric unsigned Reg = GPRDecoderTable[RegNo]; 792cab237bSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg)); 802cab237bSDimitry Andric return MCDisassembler::Success; 812cab237bSDimitry Andric } 822cab237bSDimitry Andric 832cab237bSDimitry Andric static const unsigned FPR32DecoderTable[] = { 842cab237bSDimitry Andric RISCV::F0_32, RISCV::F1_32, RISCV::F2_32, RISCV::F3_32, 852cab237bSDimitry Andric RISCV::F4_32, RISCV::F5_32, RISCV::F6_32, RISCV::F7_32, 862cab237bSDimitry Andric RISCV::F8_32, RISCV::F9_32, RISCV::F10_32, RISCV::F11_32, 872cab237bSDimitry Andric RISCV::F12_32, RISCV::F13_32, RISCV::F14_32, RISCV::F15_32, 882cab237bSDimitry Andric RISCV::F16_32, RISCV::F17_32, RISCV::F18_32, RISCV::F19_32, 892cab237bSDimitry Andric RISCV::F20_32, RISCV::F21_32, RISCV::F22_32, RISCV::F23_32, 902cab237bSDimitry Andric RISCV::F24_32, RISCV::F25_32, RISCV::F26_32, RISCV::F27_32, 912cab237bSDimitry Andric RISCV::F28_32, RISCV::F29_32, RISCV::F30_32, RISCV::F31_32 922cab237bSDimitry Andric }; 932cab237bSDimitry Andric 942cab237bSDimitry Andric static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 952cab237bSDimitry Andric uint64_t Address, 962cab237bSDimitry Andric const void *Decoder) { 972cab237bSDimitry Andric if (RegNo > sizeof(FPR32DecoderTable)) 982cab237bSDimitry Andric return MCDisassembler::Fail; 992cab237bSDimitry Andric 1002cab237bSDimitry Andric // We must define our own mapping from RegNo to register identifier. 1012cab237bSDimitry Andric // Accessing index RegNo in the register class will work in the case that 1022cab237bSDimitry Andric // registers were added in ascending order, but not in general. 1032cab237bSDimitry Andric unsigned Reg = FPR32DecoderTable[RegNo]; 1042cab237bSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg)); 1052cab237bSDimitry Andric return MCDisassembler::Success; 1062cab237bSDimitry Andric } 1072cab237bSDimitry Andric 1082cab237bSDimitry Andric static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo, 1092cab237bSDimitry Andric uint64_t Address, 1102cab237bSDimitry Andric const void *Decoder) { 1112cab237bSDimitry Andric if (RegNo > 8) { 1122cab237bSDimitry Andric return MCDisassembler::Fail; 1132cab237bSDimitry Andric } 1142cab237bSDimitry Andric unsigned Reg = FPR32DecoderTable[RegNo + 8]; 1152cab237bSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg)); 1162cab237bSDimitry Andric return MCDisassembler::Success; 1172cab237bSDimitry Andric } 1182cab237bSDimitry Andric 1192cab237bSDimitry Andric static const unsigned FPR64DecoderTable[] = { 1202cab237bSDimitry Andric RISCV::F0_64, RISCV::F1_64, RISCV::F2_64, RISCV::F3_64, 1212cab237bSDimitry Andric RISCV::F4_64, RISCV::F5_64, RISCV::F6_64, RISCV::F7_64, 1222cab237bSDimitry Andric RISCV::F8_64, RISCV::F9_64, RISCV::F10_64, RISCV::F11_64, 1232cab237bSDimitry Andric RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64, 1242cab237bSDimitry Andric RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64, 1252cab237bSDimitry Andric RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64, 1262cab237bSDimitry Andric RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64, 1272cab237bSDimitry Andric RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64 1282cab237bSDimitry Andric }; 1292cab237bSDimitry Andric 1302cab237bSDimitry Andric static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 1312cab237bSDimitry Andric uint64_t Address, 1322cab237bSDimitry Andric const void *Decoder) { 1332cab237bSDimitry Andric if (RegNo > sizeof(FPR64DecoderTable)) 1342cab237bSDimitry Andric return MCDisassembler::Fail; 1352cab237bSDimitry Andric 1362cab237bSDimitry Andric // We must define our own mapping from RegNo to register identifier. 1372cab237bSDimitry Andric // Accessing index RegNo in the register class will work in the case that 1382cab237bSDimitry Andric // registers were added in ascending order, but not in general. 1392cab237bSDimitry Andric unsigned Reg = FPR64DecoderTable[RegNo]; 1402cab237bSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg)); 1412cab237bSDimitry Andric return MCDisassembler::Success; 1422cab237bSDimitry Andric } 1432cab237bSDimitry Andric 1442cab237bSDimitry Andric static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo, 1452cab237bSDimitry Andric uint64_t Address, 1462cab237bSDimitry Andric const void *Decoder) { 1472cab237bSDimitry Andric if (RegNo > 8) { 1482cab237bSDimitry Andric return MCDisassembler::Fail; 1492cab237bSDimitry Andric } 1502cab237bSDimitry Andric unsigned Reg = FPR64DecoderTable[RegNo + 8]; 1512cab237bSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg)); 1522cab237bSDimitry Andric return MCDisassembler::Success; 1532cab237bSDimitry Andric } 1542cab237bSDimitry Andric 1552cab237bSDimitry Andric static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, 1562cab237bSDimitry Andric uint64_t Address, 1572cab237bSDimitry Andric const void *Decoder) { 1582cab237bSDimitry Andric if (RegNo == 0) { 1592cab237bSDimitry Andric return MCDisassembler::Fail; 1602cab237bSDimitry Andric } 1612cab237bSDimitry Andric 1622cab237bSDimitry Andric return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 1632cab237bSDimitry Andric } 1642cab237bSDimitry Andric 1652cab237bSDimitry Andric static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, 1662cab237bSDimitry Andric uint64_t Address, 1672cab237bSDimitry Andric const void *Decoder) { 1682cab237bSDimitry Andric if (RegNo == 2) { 1692cab237bSDimitry Andric return MCDisassembler::Fail; 1702cab237bSDimitry Andric } 1712cab237bSDimitry Andric 1722cab237bSDimitry Andric return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); 1732cab237bSDimitry Andric } 1742cab237bSDimitry Andric 1752cab237bSDimitry Andric static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 1762cab237bSDimitry Andric uint64_t Address, 1772cab237bSDimitry Andric const void *Decoder) { 1782cab237bSDimitry Andric if (RegNo > 8) 1792cab237bSDimitry Andric return MCDisassembler::Fail; 1802cab237bSDimitry Andric 1812cab237bSDimitry Andric unsigned Reg = GPRDecoderTable[RegNo + 8]; 1822cab237bSDimitry Andric Inst.addOperand(MCOperand::createReg(Reg)); 1832cab237bSDimitry Andric return MCDisassembler::Success; 1842cab237bSDimitry Andric } 1852cab237bSDimitry Andric 1862cab237bSDimitry Andric // Add implied SP operand for instructions *SP compressed instructions. The SP 1872cab237bSDimitry Andric // operand isn't explicitly encoded in the instruction. 1882cab237bSDimitry Andric static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) { 1892cab237bSDimitry Andric if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP || 1902cab237bSDimitry Andric Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP || 1912cab237bSDimitry Andric Inst.getOpcode() == RISCV::C_FLWSP || 1922cab237bSDimitry Andric Inst.getOpcode() == RISCV::C_FSWSP || 1932cab237bSDimitry Andric Inst.getOpcode() == RISCV::C_FLDSP || 1942cab237bSDimitry Andric Inst.getOpcode() == RISCV::C_FSDSP || 1952cab237bSDimitry Andric Inst.getOpcode() == RISCV::C_ADDI4SPN) { 1962cab237bSDimitry Andric DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 1972cab237bSDimitry Andric } 1982cab237bSDimitry Andric if (Inst.getOpcode() == RISCV::C_ADDI16SP) { 1992cab237bSDimitry Andric DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 2002cab237bSDimitry Andric DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 2012cab237bSDimitry Andric } 2022cab237bSDimitry Andric } 2032cab237bSDimitry Andric 2042cab237bSDimitry Andric template <unsigned N> 2052cab237bSDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 2062cab237bSDimitry Andric int64_t Address, const void *Decoder) { 2072cab237bSDimitry Andric assert(isUInt<N>(Imm) && "Invalid immediate"); 2082cab237bSDimitry Andric addImplySP(Inst, Address, Decoder); 2092cab237bSDimitry Andric Inst.addOperand(MCOperand::createImm(Imm)); 2102cab237bSDimitry Andric return MCDisassembler::Success; 2112cab237bSDimitry Andric } 2122cab237bSDimitry Andric 2132cab237bSDimitry Andric template <unsigned N> 2142cab237bSDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 2152cab237bSDimitry Andric int64_t Address, const void *Decoder) { 2162cab237bSDimitry Andric assert(isUInt<N>(Imm) && "Invalid immediate"); 2172cab237bSDimitry Andric addImplySP(Inst, Address, Decoder); 2182cab237bSDimitry Andric // Sign-extend the number in the bottom N bits of Imm 2192cab237bSDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 2202cab237bSDimitry Andric return MCDisassembler::Success; 2212cab237bSDimitry Andric } 2222cab237bSDimitry Andric 2232cab237bSDimitry Andric template <unsigned N> 2242cab237bSDimitry Andric static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, 2252cab237bSDimitry Andric int64_t Address, 2262cab237bSDimitry Andric const void *Decoder) { 2272cab237bSDimitry Andric assert(isUInt<N>(Imm) && "Invalid immediate"); 2282cab237bSDimitry Andric // Sign-extend the number in the bottom N bits of Imm after accounting for 2292cab237bSDimitry Andric // the fact that the N bit immediate is stored in N-1 bits (the LSB is 2302cab237bSDimitry Andric // always zero) 2312cab237bSDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); 2322cab237bSDimitry Andric return MCDisassembler::Success; 2332cab237bSDimitry Andric } 2342cab237bSDimitry Andric 2352cab237bSDimitry Andric #include "RISCVGenDisassemblerTables.inc" 2362cab237bSDimitry Andric 2372cab237bSDimitry Andric DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 2382cab237bSDimitry Andric ArrayRef<uint8_t> Bytes, 2392cab237bSDimitry Andric uint64_t Address, 2402cab237bSDimitry Andric raw_ostream &OS, 2412cab237bSDimitry Andric raw_ostream &CS) const { 2422cab237bSDimitry Andric // TODO: This will need modification when supporting instruction set 2432cab237bSDimitry Andric // extensions with instructions > 32-bits (up to 176 bits wide). 2442cab237bSDimitry Andric uint32_t Insn; 2452cab237bSDimitry Andric DecodeStatus Result; 2462cab237bSDimitry Andric 2472cab237bSDimitry Andric // It's a 32 bit instruction if bit 0 and 1 are 1. 2482cab237bSDimitry Andric if ((Bytes[0] & 0x3) == 0x3) { 2492cab237bSDimitry Andric Insn = support::endian::read32le(Bytes.data()); 2502cab237bSDimitry Andric DEBUG(dbgs() << "Trying RISCV32 table :\n"); 2512cab237bSDimitry Andric Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 2522cab237bSDimitry Andric Size = 4; 2532cab237bSDimitry Andric } else { 2542cab237bSDimitry Andric Insn = support::endian::read16le(Bytes.data()); 2552cab237bSDimitry Andric 2562cab237bSDimitry Andric if (!STI.getFeatureBits()[RISCV::Feature64Bit]) { 2572cab237bSDimitry Andric DEBUG(dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n"); 2582cab237bSDimitry Andric // Calling the auto-generated decoder function. 2592cab237bSDimitry Andric Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address, 2602cab237bSDimitry Andric this, STI); 2612cab237bSDimitry Andric if (Result != MCDisassembler::Fail) { 2622cab237bSDimitry Andric Size = 2; 2632cab237bSDimitry Andric return Result; 2642cab237bSDimitry Andric } 2652cab237bSDimitry Andric } 2662cab237bSDimitry Andric 2672cab237bSDimitry Andric DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n"); 2682cab237bSDimitry Andric // Calling the auto-generated decoder function. 2692cab237bSDimitry Andric Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 2702cab237bSDimitry Andric Size = 2; 2712cab237bSDimitry Andric } 2722cab237bSDimitry Andric 2732cab237bSDimitry Andric return Result; 2742cab237bSDimitry Andric } 275