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 DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo, 109 uint64_t Address, 110 const void *Decoder) { 111 if (RegNo > 8) { 112 return MCDisassembler::Fail; 113 } 114 unsigned Reg = FPR32DecoderTable[RegNo + 8]; 115 Inst.addOperand(MCOperand::createReg(Reg)); 116 return MCDisassembler::Success; 117 } 118 119 static const unsigned FPR64DecoderTable[] = { 120 RISCV::F0_64, RISCV::F1_64, RISCV::F2_64, RISCV::F3_64, 121 RISCV::F4_64, RISCV::F5_64, RISCV::F6_64, RISCV::F7_64, 122 RISCV::F8_64, RISCV::F9_64, RISCV::F10_64, RISCV::F11_64, 123 RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64, 124 RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64, 125 RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64, 126 RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64, 127 RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64 128 }; 129 130 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 131 uint64_t Address, 132 const void *Decoder) { 133 if (RegNo > sizeof(FPR64DecoderTable)) 134 return MCDisassembler::Fail; 135 136 // We must define our own mapping from RegNo to register identifier. 137 // Accessing index RegNo in the register class will work in the case that 138 // registers were added in ascending order, but not in general. 139 unsigned Reg = FPR64DecoderTable[RegNo]; 140 Inst.addOperand(MCOperand::createReg(Reg)); 141 return MCDisassembler::Success; 142 } 143 144 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo, 145 uint64_t Address, 146 const void *Decoder) { 147 if (RegNo > 8) { 148 return MCDisassembler::Fail; 149 } 150 unsigned Reg = FPR64DecoderTable[RegNo + 8]; 151 Inst.addOperand(MCOperand::createReg(Reg)); 152 return MCDisassembler::Success; 153 } 154 155 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, 156 uint64_t Address, 157 const void *Decoder) { 158 if (RegNo == 0) { 159 return MCDisassembler::Fail; 160 } 161 162 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 163 } 164 165 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, 166 uint64_t Address, 167 const void *Decoder) { 168 if (RegNo == 2) { 169 return MCDisassembler::Fail; 170 } 171 172 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); 173 } 174 175 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 176 uint64_t Address, 177 const void *Decoder) { 178 if (RegNo > 8) 179 return MCDisassembler::Fail; 180 181 unsigned Reg = GPRDecoderTable[RegNo + 8]; 182 Inst.addOperand(MCOperand::createReg(Reg)); 183 return MCDisassembler::Success; 184 } 185 186 // Add implied SP operand for instructions *SP compressed instructions. The SP 187 // operand isn't explicitly encoded in the instruction. 188 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) { 189 if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP || 190 Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP || 191 Inst.getOpcode() == RISCV::C_FLWSP || 192 Inst.getOpcode() == RISCV::C_FSWSP || 193 Inst.getOpcode() == RISCV::C_FLDSP || 194 Inst.getOpcode() == RISCV::C_FSDSP || 195 Inst.getOpcode() == RISCV::C_ADDI4SPN) { 196 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 197 } 198 if (Inst.getOpcode() == RISCV::C_ADDI16SP) { 199 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 200 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 201 } 202 } 203 204 template <unsigned N> 205 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 206 int64_t Address, const void *Decoder) { 207 assert(isUInt<N>(Imm) && "Invalid immediate"); 208 addImplySP(Inst, Address, Decoder); 209 Inst.addOperand(MCOperand::createImm(Imm)); 210 return MCDisassembler::Success; 211 } 212 213 template <unsigned N> 214 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 215 int64_t Address, const void *Decoder) { 216 assert(isUInt<N>(Imm) && "Invalid immediate"); 217 addImplySP(Inst, Address, Decoder); 218 // Sign-extend the number in the bottom N bits of Imm 219 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 220 return MCDisassembler::Success; 221 } 222 223 template <unsigned N> 224 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, 225 int64_t Address, 226 const void *Decoder) { 227 assert(isUInt<N>(Imm) && "Invalid immediate"); 228 // Sign-extend the number in the bottom N bits of Imm after accounting for 229 // the fact that the N bit immediate is stored in N-1 bits (the LSB is 230 // always zero) 231 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); 232 return MCDisassembler::Success; 233 } 234 235 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm, 236 int64_t Address, 237 const void *Decoder) { 238 assert(isUInt<6>(Imm) && "Invalid immediate"); 239 if (Imm > 31) { 240 Imm = (SignExtend64<6>(Imm) & 0xfffff); 241 } 242 Inst.addOperand(MCOperand::createImm(Imm)); 243 return MCDisassembler::Success; 244 } 245 246 #include "RISCVGenDisassemblerTables.inc" 247 248 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 249 ArrayRef<uint8_t> Bytes, 250 uint64_t Address, 251 raw_ostream &OS, 252 raw_ostream &CS) const { 253 // TODO: This will need modification when supporting instruction set 254 // extensions with instructions > 32-bits (up to 176 bits wide). 255 uint32_t Insn; 256 DecodeStatus Result; 257 258 // It's a 32 bit instruction if bit 0 and 1 are 1. 259 if ((Bytes[0] & 0x3) == 0x3) { 260 Insn = support::endian::read32le(Bytes.data()); 261 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n"); 262 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 263 Size = 4; 264 } else { 265 Insn = support::endian::read16le(Bytes.data()); 266 267 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) { 268 LLVM_DEBUG( 269 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n"); 270 // Calling the auto-generated decoder function. 271 Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address, 272 this, STI); 273 if (Result != MCDisassembler::Fail) { 274 Size = 2; 275 return Result; 276 } 277 } 278 279 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n"); 280 // Calling the auto-generated decoder function. 281 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 282 Size = 2; 283 } 284 285 return Result; 286 } 287