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