1 //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the RISCVDisassembler class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "MCTargetDesc/RISCVMCTargetDesc.h" 15 #include "llvm/MC/MCContext.h" 16 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 17 #include "llvm/MC/MCFixedLenDisassembler.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/MC/MCRegisterInfo.h" 20 #include "llvm/MC/MCSubtargetInfo.h" 21 #include "llvm/Support/Endian.h" 22 #include "llvm/Support/TargetRegistry.h" 23 24 using namespace llvm; 25 26 #define DEBUG_TYPE "riscv-disassembler" 27 28 typedef MCDisassembler::DecodeStatus DecodeStatus; 29 30 namespace { 31 class RISCVDisassembler : public MCDisassembler { 32 33 public: 34 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 35 : MCDisassembler(STI, Ctx) {} 36 37 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 38 ArrayRef<uint8_t> Bytes, uint64_t Address, 39 raw_ostream &VStream, 40 raw_ostream &CStream) const override; 41 }; 42 } // end anonymous namespace 43 44 static MCDisassembler *createRISCVDisassembler(const Target &T, 45 const MCSubtargetInfo &STI, 46 MCContext &Ctx) { 47 return new RISCVDisassembler(STI, Ctx); 48 } 49 50 extern "C" void LLVMInitializeRISCVDisassembler() { 51 // Register the disassembler for each target. 52 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(), 53 createRISCVDisassembler); 54 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(), 55 createRISCVDisassembler); 56 } 57 58 static const unsigned GPRDecoderTable[] = { 59 RISCV::X0, RISCV::X1, RISCV::X2, RISCV::X3, 60 RISCV::X4, RISCV::X5, RISCV::X6, RISCV::X7, 61 RISCV::X8, RISCV::X9, RISCV::X10, RISCV::X11, 62 RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, 63 RISCV::X16, RISCV::X17, RISCV::X18, RISCV::X19, 64 RISCV::X20, RISCV::X21, RISCV::X22, RISCV::X23, 65 RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27, 66 RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31 67 }; 68 69 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 70 uint64_t Address, 71 const void *Decoder) { 72 if (RegNo > sizeof(GPRDecoderTable)) 73 return MCDisassembler::Fail; 74 75 // We must define our own mapping from RegNo to register identifier. 76 // Accessing index RegNo in the register class will work in the case that 77 // registers were added in ascending order, but not in general. 78 unsigned Reg = GPRDecoderTable[RegNo]; 79 Inst.addOperand(MCOperand::createReg(Reg)); 80 return MCDisassembler::Success; 81 } 82 83 static const unsigned FPR32DecoderTable[] = { 84 RISCV::F0_32, RISCV::F1_32, RISCV::F2_32, RISCV::F3_32, 85 RISCV::F4_32, RISCV::F5_32, RISCV::F6_32, RISCV::F7_32, 86 RISCV::F8_32, RISCV::F9_32, RISCV::F10_32, RISCV::F11_32, 87 RISCV::F12_32, RISCV::F13_32, RISCV::F14_32, RISCV::F15_32, 88 RISCV::F16_32, RISCV::F17_32, RISCV::F18_32, RISCV::F19_32, 89 RISCV::F20_32, RISCV::F21_32, RISCV::F22_32, RISCV::F23_32, 90 RISCV::F24_32, RISCV::F25_32, RISCV::F26_32, RISCV::F27_32, 91 RISCV::F28_32, RISCV::F29_32, RISCV::F30_32, RISCV::F31_32 92 }; 93 94 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 95 uint64_t Address, 96 const void *Decoder) { 97 if (RegNo > sizeof(FPR32DecoderTable)) 98 return MCDisassembler::Fail; 99 100 // We must define our own mapping from RegNo to register identifier. 101 // Accessing index RegNo in the register class will work in the case that 102 // registers were added in ascending order, but not in general. 103 unsigned Reg = FPR32DecoderTable[RegNo]; 104 Inst.addOperand(MCOperand::createReg(Reg)); 105 return MCDisassembler::Success; 106 } 107 108 static const unsigned FPR64DecoderTable[] = { 109 RISCV::F0_64, RISCV::F1_64, RISCV::F2_64, RISCV::F3_64, 110 RISCV::F4_64, RISCV::F5_64, RISCV::F6_64, RISCV::F7_64, 111 RISCV::F8_64, RISCV::F9_64, RISCV::F10_64, RISCV::F11_64, 112 RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64, 113 RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64, 114 RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64, 115 RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64, 116 RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64 117 }; 118 119 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 120 uint64_t Address, 121 const void *Decoder) { 122 if (RegNo > sizeof(FPR64DecoderTable)) 123 return MCDisassembler::Fail; 124 125 // We must define our own mapping from RegNo to register identifier. 126 // Accessing index RegNo in the register class will work in the case that 127 // registers were added in ascending order, but not in general. 128 unsigned Reg = FPR64DecoderTable[RegNo]; 129 Inst.addOperand(MCOperand::createReg(Reg)); 130 return MCDisassembler::Success; 131 } 132 133 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, 134 uint64_t Address, 135 const void *Decoder) { 136 if (RegNo == 0) { 137 return MCDisassembler::Fail; 138 } 139 140 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 141 } 142 143 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 144 uint64_t Address, 145 const void *Decoder) { 146 if (RegNo > 8) 147 return MCDisassembler::Fail; 148 149 unsigned Reg = GPRDecoderTable[RegNo + 8]; 150 Inst.addOperand(MCOperand::createReg(Reg)); 151 return MCDisassembler::Success; 152 } 153 154 // Add implied SP operand for instructions *SP compressed instructions. The SP 155 // operand isn't explicitly encoded in the instruction. 156 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) { 157 if (Inst.getOpcode() == RISCV::CLWSP || Inst.getOpcode() == RISCV::CSWSP || 158 Inst.getOpcode() == RISCV::CLDSP || Inst.getOpcode() == RISCV::CSDSP) { 159 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 160 } 161 } 162 163 template <unsigned N> 164 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 165 int64_t Address, const void *Decoder) { 166 assert(isUInt<N>(Imm) && "Invalid immediate"); 167 addImplySP(Inst, Address, Decoder); 168 Inst.addOperand(MCOperand::createImm(Imm)); 169 return MCDisassembler::Success; 170 } 171 172 template <unsigned N> 173 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 174 int64_t Address, const void *Decoder) { 175 assert(isUInt<N>(Imm) && "Invalid immediate"); 176 // Sign-extend the number in the bottom N bits of Imm 177 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 178 return MCDisassembler::Success; 179 } 180 181 template <unsigned N> 182 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, 183 int64_t Address, 184 const void *Decoder) { 185 assert(isUInt<N>(Imm) && "Invalid immediate"); 186 // Sign-extend the number in the bottom N bits of Imm after accounting for 187 // the fact that the N bit immediate is stored in N-1 bits (the LSB is 188 // always zero) 189 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); 190 return MCDisassembler::Success; 191 } 192 193 #include "RISCVGenDisassemblerTables.inc" 194 195 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 196 ArrayRef<uint8_t> Bytes, 197 uint64_t Address, 198 raw_ostream &OS, 199 raw_ostream &CS) const { 200 // TODO: This will need modification when supporting instruction set 201 // extensions with instructions > 32-bits (up to 176 bits wide). 202 uint32_t Insn; 203 DecodeStatus Result; 204 205 // It's a 32 bit instruction if bit 0 and 1 are 1. 206 if ((Bytes[0] & 0x3) == 0x3) { 207 Insn = support::endian::read32le(Bytes.data()); 208 DEBUG(dbgs() << "Trying RISCV32 table :\n"); 209 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 210 Size = 4; 211 } else { 212 Insn = support::endian::read16le(Bytes.data()); 213 DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n"); 214 // Calling the auto-generated decoder function. 215 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 216 Size = 2; 217 } 218 219 return Result; 220 } 221