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 DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 61 uint64_t Address, 62 const void *Decoder) { 63 const FeatureBitset &FeatureBits = 64 static_cast<const MCDisassembler *>(Decoder) 65 ->getSubtargetInfo() 66 .getFeatureBits(); 67 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E]; 68 69 if (RegNo >= 32 || (IsRV32E && RegNo >= 16)) 70 return MCDisassembler::Fail; 71 72 Register Reg = RISCV::X0 + RegNo; 73 Inst.addOperand(MCOperand::createReg(Reg)); 74 return MCDisassembler::Success; 75 } 76 77 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 78 uint64_t Address, 79 const void *Decoder) { 80 if (RegNo >= 32) 81 return MCDisassembler::Fail; 82 83 Register Reg = RISCV::F0_F + RegNo; 84 Inst.addOperand(MCOperand::createReg(Reg)); 85 return MCDisassembler::Success; 86 } 87 88 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo, 89 uint64_t Address, 90 const void *Decoder) { 91 if (RegNo >= 8) { 92 return MCDisassembler::Fail; 93 } 94 Register Reg = RISCV::F8_F + RegNo; 95 Inst.addOperand(MCOperand::createReg(Reg)); 96 return MCDisassembler::Success; 97 } 98 99 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 100 uint64_t Address, 101 const void *Decoder) { 102 if (RegNo >= 32) 103 return MCDisassembler::Fail; 104 105 Register Reg = RISCV::F0_D + RegNo; 106 Inst.addOperand(MCOperand::createReg(Reg)); 107 return MCDisassembler::Success; 108 } 109 110 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo, 111 uint64_t Address, 112 const void *Decoder) { 113 if (RegNo >= 8) { 114 return MCDisassembler::Fail; 115 } 116 Register Reg = RISCV::F8_D + RegNo; 117 Inst.addOperand(MCOperand::createReg(Reg)); 118 return MCDisassembler::Success; 119 } 120 121 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, 122 uint64_t Address, 123 const void *Decoder) { 124 if (RegNo == 0) { 125 return MCDisassembler::Fail; 126 } 127 128 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 129 } 130 131 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, 132 uint64_t Address, 133 const void *Decoder) { 134 if (RegNo == 2) { 135 return MCDisassembler::Fail; 136 } 137 138 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); 139 } 140 141 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 142 uint64_t Address, 143 const void *Decoder) { 144 if (RegNo >= 8) 145 return MCDisassembler::Fail; 146 147 Register Reg = RISCV::X8 + RegNo; 148 Inst.addOperand(MCOperand::createReg(Reg)); 149 return MCDisassembler::Success; 150 } 151 152 // Add implied SP operand for instructions *SP compressed instructions. The SP 153 // operand isn't explicitly encoded in the instruction. 154 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) { 155 if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP || 156 Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP || 157 Inst.getOpcode() == RISCV::C_FLWSP || 158 Inst.getOpcode() == RISCV::C_FSWSP || 159 Inst.getOpcode() == RISCV::C_FLDSP || 160 Inst.getOpcode() == RISCV::C_FSDSP || 161 Inst.getOpcode() == RISCV::C_ADDI4SPN) { 162 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 163 } 164 if (Inst.getOpcode() == RISCV::C_ADDI16SP) { 165 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 166 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 167 } 168 } 169 170 template <unsigned N> 171 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 172 int64_t Address, const void *Decoder) { 173 assert(isUInt<N>(Imm) && "Invalid immediate"); 174 addImplySP(Inst, Address, Decoder); 175 Inst.addOperand(MCOperand::createImm(Imm)); 176 return MCDisassembler::Success; 177 } 178 179 template <unsigned N> 180 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm, 181 int64_t Address, 182 const void *Decoder) { 183 if (Imm == 0) 184 return MCDisassembler::Fail; 185 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder); 186 } 187 188 template <unsigned N> 189 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 190 int64_t Address, const void *Decoder) { 191 assert(isUInt<N>(Imm) && "Invalid immediate"); 192 addImplySP(Inst, Address, Decoder); 193 // Sign-extend the number in the bottom N bits of Imm 194 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 195 return MCDisassembler::Success; 196 } 197 198 template <unsigned N> 199 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm, 200 int64_t Address, 201 const void *Decoder) { 202 if (Imm == 0) 203 return MCDisassembler::Fail; 204 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder); 205 } 206 207 template <unsigned N> 208 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, 209 int64_t Address, 210 const void *Decoder) { 211 assert(isUInt<N>(Imm) && "Invalid immediate"); 212 // Sign-extend the number in the bottom N bits of Imm after accounting for 213 // the fact that the N bit immediate is stored in N-1 bits (the LSB is 214 // always zero) 215 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); 216 return MCDisassembler::Success; 217 } 218 219 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm, 220 int64_t Address, 221 const void *Decoder) { 222 assert(isUInt<6>(Imm) && "Invalid immediate"); 223 if (Imm > 31) { 224 Imm = (SignExtend64<6>(Imm) & 0xfffff); 225 } 226 Inst.addOperand(MCOperand::createImm(Imm)); 227 return MCDisassembler::Success; 228 } 229 230 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, 231 int64_t Address, 232 const void *Decoder) { 233 assert(isUInt<3>(Imm) && "Invalid immediate"); 234 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm)) 235 return MCDisassembler::Fail; 236 237 Inst.addOperand(MCOperand::createImm(Imm)); 238 return MCDisassembler::Success; 239 } 240 241 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn, 242 uint64_t Address, const void *Decoder); 243 244 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn, 245 uint64_t Address, const void *Decoder); 246 247 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn, 248 uint64_t Address, 249 const void *Decoder); 250 251 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn, 252 uint64_t Address, const void *Decoder); 253 254 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn, 255 uint64_t Address, 256 const void *Decoder); 257 258 #include "RISCVGenDisassemblerTables.inc" 259 260 static DecodeStatus decodeRVCInstrSImm(MCInst &Inst, unsigned Insn, 261 uint64_t Address, const void *Decoder) { 262 uint64_t SImm6 = 263 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 264 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder); 265 (void)Result; 266 assert(Result == MCDisassembler::Success && "Invalid immediate"); 267 return MCDisassembler::Success; 268 } 269 270 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, unsigned Insn, 271 uint64_t Address, 272 const void *Decoder) { 273 DecodeGPRRegisterClass(Inst, 0, Address, Decoder); 274 uint64_t SImm6 = 275 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 276 DecodeStatus Result = decodeSImmOperand<6>(Inst, SImm6, Address, Decoder); 277 (void)Result; 278 assert(Result == MCDisassembler::Success && "Invalid immediate"); 279 return MCDisassembler::Success; 280 } 281 282 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, unsigned Insn, 283 uint64_t Address, 284 const void *Decoder) { 285 DecodeGPRRegisterClass(Inst, 0, Address, Decoder); 286 Inst.addOperand(Inst.getOperand(0)); 287 uint64_t UImm6 = 288 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 289 DecodeStatus Result = decodeUImmOperand<6>(Inst, UImm6, Address, Decoder); 290 (void)Result; 291 assert(Result == MCDisassembler::Success && "Invalid immediate"); 292 return MCDisassembler::Success; 293 } 294 295 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, unsigned Insn, 296 uint64_t Address, const void *Decoder) { 297 unsigned Rd = fieldFromInstruction(Insn, 7, 5); 298 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5); 299 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder); 300 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 301 return MCDisassembler::Success; 302 } 303 304 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, unsigned Insn, 305 uint64_t Address, 306 const void *Decoder) { 307 unsigned Rd = fieldFromInstruction(Insn, 7, 5); 308 unsigned Rs2 = fieldFromInstruction(Insn, 2, 5); 309 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder); 310 Inst.addOperand(Inst.getOperand(0)); 311 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 312 return MCDisassembler::Success; 313 } 314 315 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 316 ArrayRef<uint8_t> Bytes, 317 uint64_t Address, 318 raw_ostream &OS, 319 raw_ostream &CS) const { 320 // TODO: This will need modification when supporting instruction set 321 // extensions with instructions > 32-bits (up to 176 bits wide). 322 uint32_t Insn; 323 DecodeStatus Result; 324 325 // It's a 32 bit instruction if bit 0 and 1 are 1. 326 if ((Bytes[0] & 0x3) == 0x3) { 327 if (Bytes.size() < 4) { 328 Size = 0; 329 return MCDisassembler::Fail; 330 } 331 Insn = support::endian::read32le(Bytes.data()); 332 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n"); 333 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 334 Size = 4; 335 } else { 336 if (Bytes.size() < 2) { 337 Size = 0; 338 return MCDisassembler::Fail; 339 } 340 Insn = support::endian::read16le(Bytes.data()); 341 342 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) { 343 LLVM_DEBUG( 344 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n"); 345 // Calling the auto-generated decoder function. 346 Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address, 347 this, STI); 348 if (Result != MCDisassembler::Fail) { 349 Size = 2; 350 return Result; 351 } 352 } 353 354 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n"); 355 // Calling the auto-generated decoder function. 356 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 357 Size = 2; 358 } 359 360 return Result; 361 } 362