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/MCInstrInfo.h" 22 #include "llvm/MC/MCRegisterInfo.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 #include "llvm/Support/Endian.h" 25 #include "llvm/Support/TargetRegistry.h" 26 27 using namespace llvm; 28 29 #define DEBUG_TYPE "riscv-disassembler" 30 31 typedef MCDisassembler::DecodeStatus DecodeStatus; 32 33 namespace { 34 class RISCVDisassembler : public MCDisassembler { 35 std::unique_ptr<MCInstrInfo const> const MCII; 36 37 public: 38 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 39 MCInstrInfo const *MCII) 40 : MCDisassembler(STI, Ctx), MCII(MCII) {} 41 42 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 43 ArrayRef<uint8_t> Bytes, uint64_t Address, 44 raw_ostream &CStream) const override; 45 }; 46 } // end anonymous namespace 47 48 static MCDisassembler *createRISCVDisassembler(const Target &T, 49 const MCSubtargetInfo &STI, 50 MCContext &Ctx) { 51 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo()); 52 } 53 54 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() { 55 // Register the disassembler for each target. 56 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(), 57 createRISCVDisassembler); 58 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(), 59 createRISCVDisassembler); 60 } 61 62 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 63 uint64_t Address, 64 const void *Decoder) { 65 const FeatureBitset &FeatureBits = 66 static_cast<const MCDisassembler *>(Decoder) 67 ->getSubtargetInfo() 68 .getFeatureBits(); 69 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E]; 70 71 if (RegNo >= 32 || (IsRV32E && RegNo >= 16)) 72 return MCDisassembler::Fail; 73 74 Register Reg = RISCV::X0 + RegNo; 75 Inst.addOperand(MCOperand::createReg(Reg)); 76 return MCDisassembler::Success; 77 } 78 79 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 80 uint64_t Address, 81 const void *Decoder) { 82 if (RegNo >= 32) 83 return MCDisassembler::Fail; 84 85 Register Reg = RISCV::F0_F + RegNo; 86 Inst.addOperand(MCOperand::createReg(Reg)); 87 return MCDisassembler::Success; 88 } 89 90 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo, 91 uint64_t Address, 92 const void *Decoder) { 93 if (RegNo >= 8) { 94 return MCDisassembler::Fail; 95 } 96 Register Reg = RISCV::F8_F + RegNo; 97 Inst.addOperand(MCOperand::createReg(Reg)); 98 return MCDisassembler::Success; 99 } 100 101 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 102 uint64_t Address, 103 const void *Decoder) { 104 if (RegNo >= 32) 105 return MCDisassembler::Fail; 106 107 Register Reg = RISCV::F0_D + RegNo; 108 Inst.addOperand(MCOperand::createReg(Reg)); 109 return MCDisassembler::Success; 110 } 111 112 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo, 113 uint64_t Address, 114 const void *Decoder) { 115 if (RegNo >= 8) { 116 return MCDisassembler::Fail; 117 } 118 Register Reg = RISCV::F8_D + RegNo; 119 Inst.addOperand(MCOperand::createReg(Reg)); 120 return MCDisassembler::Success; 121 } 122 123 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, 124 uint64_t Address, 125 const void *Decoder) { 126 if (RegNo == 0) { 127 return MCDisassembler::Fail; 128 } 129 130 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 131 } 132 133 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, 134 uint64_t Address, 135 const void *Decoder) { 136 if (RegNo == 2) { 137 return MCDisassembler::Fail; 138 } 139 140 return DecodeGPRNoX0RegisterClass(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 Register Reg = RISCV::X8 + RegNo; 150 Inst.addOperand(MCOperand::createReg(Reg)); 151 return MCDisassembler::Success; 152 } 153 154 static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint64_t RegNo, 155 uint64_t Address, 156 const void *Decoder) { 157 if (RegNo >= 32) 158 return MCDisassembler::Fail; 159 160 Register Reg = RISCV::V0 + RegNo; 161 Inst.addOperand(MCOperand::createReg(Reg)); 162 return MCDisassembler::Success; 163 } 164 165 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint64_t RegNo, 166 uint64_t Address, const void *Decoder) { 167 Register Reg = RISCV::NoRegister; 168 switch (RegNo) { 169 default: 170 return MCDisassembler::Fail; 171 case 0: 172 Reg = RISCV::V0; 173 break; 174 case 1: 175 break; 176 } 177 Inst.addOperand(MCOperand::createReg(Reg)); 178 return MCDisassembler::Success; 179 } 180 181 // Add implied SP operand for instructions *SP compressed instructions. The SP 182 // operand isn't explicitly encoded in the instruction. 183 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) { 184 if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP || 185 Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP || 186 Inst.getOpcode() == RISCV::C_FLWSP || 187 Inst.getOpcode() == RISCV::C_FSWSP || 188 Inst.getOpcode() == RISCV::C_FLDSP || 189 Inst.getOpcode() == RISCV::C_FSDSP || 190 Inst.getOpcode() == RISCV::C_ADDI4SPN) { 191 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 192 } 193 if (Inst.getOpcode() == RISCV::C_ADDI16SP) { 194 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 195 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 196 } 197 } 198 199 template <unsigned N> 200 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 201 int64_t Address, const void *Decoder) { 202 assert(isUInt<N>(Imm) && "Invalid immediate"); 203 addImplySP(Inst, Address, Decoder); 204 Inst.addOperand(MCOperand::createImm(Imm)); 205 return MCDisassembler::Success; 206 } 207 208 template <unsigned N> 209 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm, 210 int64_t Address, 211 const void *Decoder) { 212 if (Imm == 0) 213 return MCDisassembler::Fail; 214 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder); 215 } 216 217 template <unsigned N> 218 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 219 int64_t Address, const void *Decoder) { 220 assert(isUInt<N>(Imm) && "Invalid immediate"); 221 addImplySP(Inst, Address, Decoder); 222 // Sign-extend the number in the bottom N bits of Imm 223 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 224 return MCDisassembler::Success; 225 } 226 227 template <unsigned N> 228 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm, 229 int64_t Address, 230 const void *Decoder) { 231 if (Imm == 0) 232 return MCDisassembler::Fail; 233 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder); 234 } 235 236 template <unsigned N> 237 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, 238 int64_t Address, 239 const void *Decoder) { 240 assert(isUInt<N>(Imm) && "Invalid immediate"); 241 // Sign-extend the number in the bottom N bits of Imm after accounting for 242 // the fact that the N bit immediate is stored in N-1 bits (the LSB is 243 // always zero) 244 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); 245 return MCDisassembler::Success; 246 } 247 248 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm, 249 int64_t Address, 250 const void *Decoder) { 251 assert(isUInt<6>(Imm) && "Invalid immediate"); 252 if (Imm > 31) { 253 Imm = (SignExtend64<6>(Imm) & 0xfffff); 254 } 255 Inst.addOperand(MCOperand::createImm(Imm)); 256 return MCDisassembler::Success; 257 } 258 259 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, 260 int64_t Address, 261 const void *Decoder) { 262 assert(isUInt<3>(Imm) && "Invalid immediate"); 263 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm)) 264 return MCDisassembler::Fail; 265 266 Inst.addOperand(MCOperand::createImm(Imm)); 267 return MCDisassembler::Success; 268 } 269 270 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn, 271 uint64_t Address, const void *Decoder); 272 273 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn, 274 uint64_t Address, const void *Decoder); 275 276 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn, 277 uint64_t Address, 278 const void *Decoder); 279 280 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn, 281 uint64_t Address, const void *Decoder); 282 283 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn, 284 uint64_t Address, 285 const void *Decoder); 286 287 #include "RISCVGenDisassemblerTables.inc" 288 289 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn, 290 uint64_t Address, const void *Decoder) { 291 uint64_t SImm6 = 292 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 293 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder); 294 (void)Result; 295 assert(Result == MCDisassembler::Success && "Invalid immediate"); 296 return MCDisassembler::Success; 297 } 298 299 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn, 300 uint64_t Address, 301 const void *Decoder) { 302 DecodeGPRRegisterClass(Inst, 0, Address, Decoder); 303 uint64_t SImm6 = 304 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 305 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder); 306 (void)Result; 307 assert(Result == MCDisassembler::Success && "Invalid immediate"); 308 return MCDisassembler::Success; 309 } 310 311 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn, 312 uint64_t Address, 313 const void *Decoder) { 314 DecodeGPRRegisterClass(Inst, 0, Address, Decoder); 315 Inst.addOperand(Inst.getOperand(0)); 316 uint64_t UImm6 = 317 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 318 DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder); 319 (void)Result; 320 assert(Result == MCDisassembler::Success && "Invalid immediate"); 321 return MCDisassembler::Success; 322 } 323 324 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn, 325 uint64_t Address, const void *Decoder) { 326 unsigned Rd = fieldFromInstruction(Insn, 7, 5); 327 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5); 328 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder); 329 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 330 return MCDisassembler::Success; 331 } 332 333 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn, 334 uint64_t Address, 335 const void *Decoder) { 336 unsigned Rd = fieldFromInstruction(Insn, 7, 5); 337 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5); 338 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder); 339 Inst.addOperand(Inst.getOperand(0)); 340 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 341 return MCDisassembler::Success; 342 } 343 344 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 345 ArrayRef<uint8_t> Bytes, 346 uint64_t Address, 347 raw_ostream &CS) const { 348 // TODO: This will need modification when supporting instruction set 349 // extensions with instructions > 32-bits (up to 176 bits wide). 350 uint32_t Insn; 351 DecodeStatus Result; 352 353 // It's a 32 bit instruction if bit 0 and 1 are 1. 354 if ((Bytes[0] & 0x3) == 0x3) { 355 if (Bytes.size() < 4) { 356 Size = 0; 357 return MCDisassembler::Fail; 358 } 359 Insn = support::endian::read32le(Bytes.data()); 360 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n"); 361 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 362 Size = 4; 363 } else { 364 if (Bytes.size() < 2) { 365 Size = 0; 366 return MCDisassembler::Fail; 367 } 368 Insn = support::endian::read16le(Bytes.data()); 369 370 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) { 371 LLVM_DEBUG( 372 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n"); 373 // Calling the auto-generated decoder function. 374 Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address, 375 this, STI); 376 if (Result != MCDisassembler::Fail) { 377 Size = 2; 378 return Result; 379 } 380 } 381 382 if (STI.getFeatureBits()[RISCV::FeatureExtZbproposedc] && 383 STI.getFeatureBits()[RISCV::FeatureStdExtC]) { 384 LLVM_DEBUG( 385 dbgs() << "Trying RVBC32 table (BitManip 16-bit Instruction):\n"); 386 // Calling the auto-generated decoder function. 387 Result = decodeInstruction(DecoderTableRVBC16, MI, Insn, Address, 388 this, STI); 389 if (Result != MCDisassembler::Fail) { 390 Size = 2; 391 return Result; 392 } 393 } 394 395 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n"); 396 // Calling the auto-generated decoder function. 397 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 398 Size = 2; 399 } 400 401 return Result; 402 } 403