1 //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements the RISCVDisassembler class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MCTargetDesc/RISCVMCTargetDesc.h" 14 #include "TargetInfo/RISCVTargetInfo.h" 15 #include "Utils/RISCVBaseInfo.h" 16 #include "llvm/CodeGen/Register.h" 17 #include "llvm/MC/MCContext.h" 18 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 19 #include "llvm/MC/MCFixedLenDisassembler.h" 20 #include "llvm/MC/MCInst.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/Support/Endian.h" 24 #include "llvm/Support/TargetRegistry.h" 25 26 using namespace llvm; 27 28 #define DEBUG_TYPE "riscv-disassembler" 29 30 typedef MCDisassembler::DecodeStatus DecodeStatus; 31 32 namespace { 33 class RISCVDisassembler : public MCDisassembler { 34 35 public: 36 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 37 : MCDisassembler(STI, Ctx) {} 38 39 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 40 ArrayRef<uint8_t> Bytes, uint64_t Address, 41 raw_ostream &VStream, 42 raw_ostream &CStream) const override; 43 }; 44 } // end anonymous namespace 45 46 static MCDisassembler *createRISCVDisassembler(const Target &T, 47 const MCSubtargetInfo &STI, 48 MCContext &Ctx) { 49 return new RISCVDisassembler(STI, Ctx); 50 } 51 52 extern "C" void LLVMInitializeRISCVDisassembler() { 53 // Register the disassembler for each target. 54 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(), 55 createRISCVDisassembler); 56 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(), 57 createRISCVDisassembler); 58 } 59 60 static const Register GPRDecoderTable[] = { 61 RISCV::X0, RISCV::X1, RISCV::X2, RISCV::X3, 62 RISCV::X4, RISCV::X5, RISCV::X6, RISCV::X7, 63 RISCV::X8, RISCV::X9, RISCV::X10, RISCV::X11, 64 RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15, 65 RISCV::X16, RISCV::X17, RISCV::X18, RISCV::X19, 66 RISCV::X20, RISCV::X21, RISCV::X22, RISCV::X23, 67 RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27, 68 RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31 69 }; 70 71 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 72 uint64_t Address, 73 const void *Decoder) { 74 const FeatureBitset &FeatureBits = 75 static_cast<const MCDisassembler *>(Decoder) 76 ->getSubtargetInfo() 77 .getFeatureBits(); 78 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E]; 79 80 if (RegNo > array_lengthof(GPRDecoderTable) || (IsRV32E && RegNo > 15)) 81 return MCDisassembler::Fail; 82 83 // We must define our own mapping from RegNo to register identifier. 84 // Accessing index RegNo in the register class will work in the case that 85 // registers were added in ascending order, but not in general. 86 Register Reg = GPRDecoderTable[RegNo]; 87 Inst.addOperand(MCOperand::createReg(Reg)); 88 return MCDisassembler::Success; 89 } 90 91 static const Register FPR32DecoderTable[] = { 92 RISCV::F0_32, RISCV::F1_32, RISCV::F2_32, RISCV::F3_32, 93 RISCV::F4_32, RISCV::F5_32, RISCV::F6_32, RISCV::F7_32, 94 RISCV::F8_32, RISCV::F9_32, RISCV::F10_32, RISCV::F11_32, 95 RISCV::F12_32, RISCV::F13_32, RISCV::F14_32, RISCV::F15_32, 96 RISCV::F16_32, RISCV::F17_32, RISCV::F18_32, RISCV::F19_32, 97 RISCV::F20_32, RISCV::F21_32, RISCV::F22_32, RISCV::F23_32, 98 RISCV::F24_32, RISCV::F25_32, RISCV::F26_32, RISCV::F27_32, 99 RISCV::F28_32, RISCV::F29_32, RISCV::F30_32, RISCV::F31_32 100 }; 101 102 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 103 uint64_t Address, 104 const void *Decoder) { 105 if (RegNo > array_lengthof(FPR32DecoderTable)) 106 return MCDisassembler::Fail; 107 108 // We must define our own mapping from RegNo to register identifier. 109 // Accessing index RegNo in the register class will work in the case that 110 // registers were added in ascending order, but not in general. 111 Register Reg = FPR32DecoderTable[RegNo]; 112 Inst.addOperand(MCOperand::createReg(Reg)); 113 return MCDisassembler::Success; 114 } 115 116 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo, 117 uint64_t Address, 118 const void *Decoder) { 119 if (RegNo > 8) { 120 return MCDisassembler::Fail; 121 } 122 Register Reg = FPR32DecoderTable[RegNo + 8]; 123 Inst.addOperand(MCOperand::createReg(Reg)); 124 return MCDisassembler::Success; 125 } 126 127 static const Register FPR64DecoderTable[] = { 128 RISCV::F0_64, RISCV::F1_64, RISCV::F2_64, RISCV::F3_64, 129 RISCV::F4_64, RISCV::F5_64, RISCV::F6_64, RISCV::F7_64, 130 RISCV::F8_64, RISCV::F9_64, RISCV::F10_64, RISCV::F11_64, 131 RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64, 132 RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64, 133 RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64, 134 RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64, 135 RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64 136 }; 137 138 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 139 uint64_t Address, 140 const void *Decoder) { 141 if (RegNo > array_lengthof(FPR64DecoderTable)) 142 return MCDisassembler::Fail; 143 144 // We must define our own mapping from RegNo to register identifier. 145 // Accessing index RegNo in the register class will work in the case that 146 // registers were added in ascending order, but not in general. 147 Register Reg = FPR64DecoderTable[RegNo]; 148 Inst.addOperand(MCOperand::createReg(Reg)); 149 return MCDisassembler::Success; 150 } 151 152 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo, 153 uint64_t Address, 154 const void *Decoder) { 155 if (RegNo > 8) { 156 return MCDisassembler::Fail; 157 } 158 Register Reg = FPR64DecoderTable[RegNo + 8]; 159 Inst.addOperand(MCOperand::createReg(Reg)); 160 return MCDisassembler::Success; 161 } 162 163 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, 164 uint64_t Address, 165 const void *Decoder) { 166 if (RegNo == 0) { 167 return MCDisassembler::Fail; 168 } 169 170 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 171 } 172 173 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, 174 uint64_t Address, 175 const void *Decoder) { 176 if (RegNo == 2) { 177 return MCDisassembler::Fail; 178 } 179 180 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); 181 } 182 183 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 184 uint64_t Address, 185 const void *Decoder) { 186 if (RegNo > 8) 187 return MCDisassembler::Fail; 188 189 Register Reg = GPRDecoderTable[RegNo + 8]; 190 Inst.addOperand(MCOperand::createReg(Reg)); 191 return MCDisassembler::Success; 192 } 193 194 // Add implied SP operand for instructions *SP compressed instructions. The SP 195 // operand isn't explicitly encoded in the instruction. 196 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) { 197 if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP || 198 Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP || 199 Inst.getOpcode() == RISCV::C_FLWSP || 200 Inst.getOpcode() == RISCV::C_FSWSP || 201 Inst.getOpcode() == RISCV::C_FLDSP || 202 Inst.getOpcode() == RISCV::C_FSDSP || 203 Inst.getOpcode() == RISCV::C_ADDI4SPN) { 204 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 205 } 206 if (Inst.getOpcode() == RISCV::C_ADDI16SP) { 207 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 208 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 209 } 210 } 211 212 template <unsigned N> 213 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 214 int64_t Address, const void *Decoder) { 215 assert(isUInt<N>(Imm) && "Invalid immediate"); 216 addImplySP(Inst, Address, Decoder); 217 Inst.addOperand(MCOperand::createImm(Imm)); 218 return MCDisassembler::Success; 219 } 220 221 template <unsigned N> 222 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm, 223 int64_t Address, 224 const void *Decoder) { 225 if (Imm == 0) 226 return MCDisassembler::Fail; 227 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder); 228 } 229 230 template <unsigned N> 231 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 232 int64_t Address, const void *Decoder) { 233 assert(isUInt<N>(Imm) && "Invalid immediate"); 234 addImplySP(Inst, Address, Decoder); 235 // Sign-extend the number in the bottom N bits of Imm 236 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 237 return MCDisassembler::Success; 238 } 239 240 template <unsigned N> 241 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm, 242 int64_t Address, 243 const void *Decoder) { 244 if (Imm == 0) 245 return MCDisassembler::Fail; 246 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder); 247 } 248 249 template <unsigned N> 250 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, 251 int64_t Address, 252 const void *Decoder) { 253 assert(isUInt<N>(Imm) && "Invalid immediate"); 254 // Sign-extend the number in the bottom N bits of Imm after accounting for 255 // the fact that the N bit immediate is stored in N-1 bits (the LSB is 256 // always zero) 257 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); 258 return MCDisassembler::Success; 259 } 260 261 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm, 262 int64_t Address, 263 const void *Decoder) { 264 assert(isUInt<6>(Imm) && "Invalid immediate"); 265 if (Imm > 31) { 266 Imm = (SignExtend64<6>(Imm) & 0xfffff); 267 } 268 Inst.addOperand(MCOperand::createImm(Imm)); 269 return MCDisassembler::Success; 270 } 271 272 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, 273 int64_t Address, 274 const void *Decoder) { 275 assert(isUInt<3>(Imm) && "Invalid immediate"); 276 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm)) 277 return MCDisassembler::Fail; 278 279 Inst.addOperand(MCOperand::createImm(Imm)); 280 return MCDisassembler::Success; 281 } 282 283 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn, 284 uint64_t Address, const void *Decoder); 285 286 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn, 287 uint64_t Address, const void *Decoder); 288 289 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn, 290 uint64_t Address, 291 const void *Decoder); 292 293 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn, 294 uint64_t Address, const void *Decoder); 295 296 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn, 297 uint64_t Address, 298 const void *Decoder); 299 300 #include "RISCVGenDisassemblerTables.inc" 301 302 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn, 303 uint64_t Address, const void *Decoder) { 304 uint64_t SImm6 = 305 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 306 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder); 307 (void)Result; 308 assert(Result == MCDisassembler::Success && "Invalid immediate"); 309 return MCDisassembler::Success; 310 } 311 312 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn, 313 uint64_t Address, 314 const void *Decoder) { 315 DecodeGPRRegisterClass(Inst, 0, Address, Decoder); 316 uint64_t SImm6 = 317 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 318 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder); 319 (void)Result; 320 assert(Result == MCDisassembler::Success && "Invalid immediate"); 321 return MCDisassembler::Success; 322 } 323 324 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn, 325 uint64_t Address, 326 const void *Decoder) { 327 DecodeGPRRegisterClass(Inst, 0, Address, Decoder); 328 Inst.addOperand(Inst.getOperand(0)); 329 uint64_t UImm6 = 330 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 331 DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder); 332 (void)Result; 333 assert(Result == MCDisassembler::Success && "Invalid immediate"); 334 return MCDisassembler::Success; 335 } 336 337 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn, 338 uint64_t Address, const void *Decoder) { 339 unsigned Rd = fieldFromInstruction(Insn, 7, 5); 340 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5); 341 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder); 342 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 343 return MCDisassembler::Success; 344 } 345 346 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn, 347 uint64_t Address, 348 const void *Decoder) { 349 unsigned Rd = fieldFromInstruction(Insn, 7, 5); 350 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5); 351 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder); 352 Inst.addOperand(Inst.getOperand(0)); 353 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 354 return MCDisassembler::Success; 355 } 356 357 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 358 ArrayRef<uint8_t> Bytes, 359 uint64_t Address, 360 raw_ostream &OS, 361 raw_ostream &CS) const { 362 // TODO: This will need modification when supporting instruction set 363 // extensions with instructions > 32-bits (up to 176 bits wide). 364 uint32_t Insn; 365 DecodeStatus Result; 366 367 // It's a 32 bit instruction if bit 0 and 1 are 1. 368 if ((Bytes[0] & 0x3) == 0x3) { 369 if (Bytes.size() < 4) { 370 Size = 0; 371 return MCDisassembler::Fail; 372 } 373 Insn = support::endian::read32le(Bytes.data()); 374 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n"); 375 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 376 Size = 4; 377 } else { 378 if (Bytes.size() < 2) { 379 Size = 0; 380 return MCDisassembler::Fail; 381 } 382 Insn = support::endian::read16le(Bytes.data()); 383 384 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) { 385 LLVM_DEBUG( 386 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n"); 387 // Calling the auto-generated decoder function. 388 Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address, 389 this, STI); 390 if (Result != MCDisassembler::Fail) { 391 Size = 2; 392 return Result; 393 } 394 } 395 396 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n"); 397 // Calling the auto-generated decoder function. 398 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 399 Size = 2; 400 } 401 402 return Result; 403 } 404