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 "Utils/RISCVBaseInfo.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 const FeatureBitset &FeatureBits = 73 static_cast<const MCDisassembler *>(Decoder) 74 ->getSubtargetInfo() 75 .getFeatureBits(); 76 bool IsRV32E = FeatureBits[RISCV::FeatureRV32E]; 77 78 if (RegNo > array_lengthof(GPRDecoderTable) || (IsRV32E && RegNo > 15)) 79 return MCDisassembler::Fail; 80 81 // We must define our own mapping from RegNo to register identifier. 82 // Accessing index RegNo in the register class will work in the case that 83 // registers were added in ascending order, but not in general. 84 unsigned Reg = GPRDecoderTable[RegNo]; 85 Inst.addOperand(MCOperand::createReg(Reg)); 86 return MCDisassembler::Success; 87 } 88 89 static const unsigned FPR32DecoderTable[] = { 90 RISCV::F0_32, RISCV::F1_32, RISCV::F2_32, RISCV::F3_32, 91 RISCV::F4_32, RISCV::F5_32, RISCV::F6_32, RISCV::F7_32, 92 RISCV::F8_32, RISCV::F9_32, RISCV::F10_32, RISCV::F11_32, 93 RISCV::F12_32, RISCV::F13_32, RISCV::F14_32, RISCV::F15_32, 94 RISCV::F16_32, RISCV::F17_32, RISCV::F18_32, RISCV::F19_32, 95 RISCV::F20_32, RISCV::F21_32, RISCV::F22_32, RISCV::F23_32, 96 RISCV::F24_32, RISCV::F25_32, RISCV::F26_32, RISCV::F27_32, 97 RISCV::F28_32, RISCV::F29_32, RISCV::F30_32, RISCV::F31_32 98 }; 99 100 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 101 uint64_t Address, 102 const void *Decoder) { 103 if (RegNo > array_lengthof(FPR32DecoderTable)) 104 return MCDisassembler::Fail; 105 106 // We must define our own mapping from RegNo to register identifier. 107 // Accessing index RegNo in the register class will work in the case that 108 // registers were added in ascending order, but not in general. 109 unsigned Reg = FPR32DecoderTable[RegNo]; 110 Inst.addOperand(MCOperand::createReg(Reg)); 111 return MCDisassembler::Success; 112 } 113 114 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo, 115 uint64_t Address, 116 const void *Decoder) { 117 if (RegNo > 8) { 118 return MCDisassembler::Fail; 119 } 120 unsigned Reg = FPR32DecoderTable[RegNo + 8]; 121 Inst.addOperand(MCOperand::createReg(Reg)); 122 return MCDisassembler::Success; 123 } 124 125 static const unsigned FPR64DecoderTable[] = { 126 RISCV::F0_64, RISCV::F1_64, RISCV::F2_64, RISCV::F3_64, 127 RISCV::F4_64, RISCV::F5_64, RISCV::F6_64, RISCV::F7_64, 128 RISCV::F8_64, RISCV::F9_64, RISCV::F10_64, RISCV::F11_64, 129 RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64, 130 RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64, 131 RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64, 132 RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64, 133 RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64 134 }; 135 136 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 137 uint64_t Address, 138 const void *Decoder) { 139 if (RegNo > array_lengthof(FPR64DecoderTable)) 140 return MCDisassembler::Fail; 141 142 // We must define our own mapping from RegNo to register identifier. 143 // Accessing index RegNo in the register class will work in the case that 144 // registers were added in ascending order, but not in general. 145 unsigned Reg = FPR64DecoderTable[RegNo]; 146 Inst.addOperand(MCOperand::createReg(Reg)); 147 return MCDisassembler::Success; 148 } 149 150 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo, 151 uint64_t Address, 152 const void *Decoder) { 153 if (RegNo > 8) { 154 return MCDisassembler::Fail; 155 } 156 unsigned Reg = FPR64DecoderTable[RegNo + 8]; 157 Inst.addOperand(MCOperand::createReg(Reg)); 158 return MCDisassembler::Success; 159 } 160 161 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo, 162 uint64_t Address, 163 const void *Decoder) { 164 if (RegNo == 0) { 165 return MCDisassembler::Fail; 166 } 167 168 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 169 } 170 171 static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, 172 uint64_t Address, 173 const void *Decoder) { 174 if (RegNo == 2) { 175 return MCDisassembler::Fail; 176 } 177 178 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); 179 } 180 181 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 182 uint64_t Address, 183 const void *Decoder) { 184 if (RegNo > 8) 185 return MCDisassembler::Fail; 186 187 unsigned Reg = GPRDecoderTable[RegNo + 8]; 188 Inst.addOperand(MCOperand::createReg(Reg)); 189 return MCDisassembler::Success; 190 } 191 192 // Add implied SP operand for instructions *SP compressed instructions. The SP 193 // operand isn't explicitly encoded in the instruction. 194 static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) { 195 if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP || 196 Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP || 197 Inst.getOpcode() == RISCV::C_FLWSP || 198 Inst.getOpcode() == RISCV::C_FSWSP || 199 Inst.getOpcode() == RISCV::C_FLDSP || 200 Inst.getOpcode() == RISCV::C_FSDSP || 201 Inst.getOpcode() == RISCV::C_ADDI4SPN) { 202 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 203 } 204 if (Inst.getOpcode() == RISCV::C_ADDI16SP) { 205 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 206 DecodeGPRRegisterClass(Inst, 2, Address, Decoder); 207 } 208 } 209 210 template <unsigned N> 211 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 212 int64_t Address, const void *Decoder) { 213 assert(isUInt<N>(Imm) && "Invalid immediate"); 214 addImplySP(Inst, Address, Decoder); 215 Inst.addOperand(MCOperand::createImm(Imm)); 216 return MCDisassembler::Success; 217 } 218 219 template <unsigned N> 220 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint64_t Imm, 221 int64_t Address, 222 const void *Decoder) { 223 if (Imm == 0) 224 return MCDisassembler::Fail; 225 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder); 226 } 227 228 template <unsigned N> 229 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 230 int64_t Address, const void *Decoder) { 231 assert(isUInt<N>(Imm) && "Invalid immediate"); 232 addImplySP(Inst, Address, Decoder); 233 // Sign-extend the number in the bottom N bits of Imm 234 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 235 return MCDisassembler::Success; 236 } 237 238 template <unsigned N> 239 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint64_t Imm, 240 int64_t Address, 241 const void *Decoder) { 242 if (Imm == 0) 243 return MCDisassembler::Fail; 244 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder); 245 } 246 247 template <unsigned N> 248 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm, 249 int64_t Address, 250 const void *Decoder) { 251 assert(isUInt<N>(Imm) && "Invalid immediate"); 252 // Sign-extend the number in the bottom N bits of Imm after accounting for 253 // the fact that the N bit immediate is stored in N-1 bits (the LSB is 254 // always zero) 255 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); 256 return MCDisassembler::Success; 257 } 258 259 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm, 260 int64_t Address, 261 const void *Decoder) { 262 assert(isUInt<6>(Imm) && "Invalid immediate"); 263 if (Imm > 31) { 264 Imm = (SignExtend64<6>(Imm) & 0xfffff); 265 } 266 Inst.addOperand(MCOperand::createImm(Imm)); 267 return MCDisassembler::Success; 268 } 269 270 static DecodeStatus decodeFRMArg(MCInst &Inst, uint64_t Imm, 271 int64_t Address, 272 const void *Decoder) { 273 assert(isUInt<3>(Imm) && "Invalid immediate"); 274 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm)) 275 return MCDisassembler::Fail; 276 277 Inst.addOperand(MCOperand::createImm(Imm)); 278 return MCDisassembler::Success; 279 } 280 281 #include "RISCVGenDisassemblerTables.inc" 282 283 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 284 ArrayRef<uint8_t> Bytes, 285 uint64_t Address, 286 raw_ostream &OS, 287 raw_ostream &CS) const { 288 // TODO: This will need modification when supporting instruction set 289 // extensions with instructions > 32-bits (up to 176 bits wide). 290 uint32_t Insn; 291 DecodeStatus Result; 292 293 // It's a 32 bit instruction if bit 0 and 1 are 1. 294 if ((Bytes[0] & 0x3) == 0x3) { 295 if (Bytes.size() < 4) { 296 Size = 0; 297 return MCDisassembler::Fail; 298 } 299 Insn = support::endian::read32le(Bytes.data()); 300 LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n"); 301 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 302 Size = 4; 303 } else { 304 if (Bytes.size() < 2) { 305 Size = 0; 306 return MCDisassembler::Fail; 307 } 308 Insn = support::endian::read16le(Bytes.data()); 309 310 if (!STI.getFeatureBits()[RISCV::Feature64Bit]) { 311 LLVM_DEBUG( 312 dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n"); 313 // Calling the auto-generated decoder function. 314 Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address, 315 this, STI); 316 if (Result != MCDisassembler::Fail) { 317 Size = 2; 318 return Result; 319 } 320 } 321 322 LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n"); 323 // Calling the auto-generated decoder function. 324 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 325 Size = 2; 326 } 327 328 return Result; 329 } 330