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