1 //===-- RISCVDisassembler.cpp - Disassembler for RISC-V -------------------===// 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/RISCVBaseInfo.h" 14 #include "MCTargetDesc/RISCVMCTargetDesc.h" 15 #include "TargetInfo/RISCVTargetInfo.h" 16 #include "llvm/MC/MCContext.h" 17 #include "llvm/MC/MCDecoderOps.h" 18 #include "llvm/MC/MCDisassembler/MCDisassembler.h" 19 #include "llvm/MC/MCInst.h" 20 #include "llvm/MC/MCInstrInfo.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/MC/MCSubtargetInfo.h" 23 #include "llvm/MC/TargetRegistry.h" 24 #include "llvm/Support/Endian.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 std::unique_ptr<MCInstrInfo const> const MCII; 35 36 public: 37 RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 38 MCInstrInfo const *MCII) 39 : MCDisassembler(STI, Ctx), MCII(MCII) {} 40 41 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 42 ArrayRef<uint8_t> Bytes, uint64_t Address, 43 raw_ostream &CStream) const override; 44 45 private: 46 void addSPOperands(MCInst &MI) const; 47 48 DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size, 49 ArrayRef<uint8_t> Bytes, uint64_t Address, 50 raw_ostream &CStream) const; 51 DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size, 52 ArrayRef<uint8_t> Bytes, uint64_t Address, 53 raw_ostream &CStream) const; 54 }; 55 } // end anonymous namespace 56 57 static MCDisassembler *createRISCVDisassembler(const Target &T, 58 const MCSubtargetInfo &STI, 59 MCContext &Ctx) { 60 return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo()); 61 } 62 63 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVDisassembler() { 64 // Register the disassembler for each target. 65 TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(), 66 createRISCVDisassembler); 67 TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(), 68 createRISCVDisassembler); 69 } 70 71 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo, 72 uint64_t Address, 73 const MCDisassembler *Decoder) { 74 bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE); 75 76 if (RegNo >= 32 || (IsRVE && RegNo >= 16)) 77 return MCDisassembler::Fail; 78 79 MCRegister Reg = RISCV::X0 + RegNo; 80 Inst.addOperand(MCOperand::createReg(Reg)); 81 return MCDisassembler::Success; 82 } 83 84 static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo, 85 uint64_t Address, 86 const MCDisassembler *Decoder) { 87 MCRegister Reg = RISCV::X0 + RegNo; 88 if (Reg != RISCV::X1 && Reg != RISCV::X5) 89 return MCDisassembler::Fail; 90 91 Inst.addOperand(MCOperand::createReg(Reg)); 92 return MCDisassembler::Success; 93 } 94 95 static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo, 96 uint64_t Address, 97 const MCDisassembler *Decoder) { 98 if (RegNo >= 32) 99 return MCDisassembler::Fail; 100 101 MCRegister Reg = RISCV::F0_H + RegNo; 102 Inst.addOperand(MCOperand::createReg(Reg)); 103 return MCDisassembler::Success; 104 } 105 106 static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo, 107 uint64_t Address, 108 const MCDisassembler *Decoder) { 109 if (RegNo >= 32) 110 return MCDisassembler::Fail; 111 112 MCRegister Reg = RISCV::F0_F + RegNo; 113 Inst.addOperand(MCOperand::createReg(Reg)); 114 return MCDisassembler::Success; 115 } 116 117 static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo, 118 uint64_t Address, 119 const MCDisassembler *Decoder) { 120 if (RegNo >= 8) { 121 return MCDisassembler::Fail; 122 } 123 MCRegister Reg = RISCV::F8_F + RegNo; 124 Inst.addOperand(MCOperand::createReg(Reg)); 125 return MCDisassembler::Success; 126 } 127 128 static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo, 129 uint64_t Address, 130 const MCDisassembler *Decoder) { 131 if (RegNo >= 32) 132 return MCDisassembler::Fail; 133 134 MCRegister Reg = RISCV::F0_D + RegNo; 135 Inst.addOperand(MCOperand::createReg(Reg)); 136 return MCDisassembler::Success; 137 } 138 139 static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo, 140 uint64_t Address, 141 const MCDisassembler *Decoder) { 142 if (RegNo >= 8) { 143 return MCDisassembler::Fail; 144 } 145 MCRegister Reg = RISCV::F8_D + RegNo; 146 Inst.addOperand(MCOperand::createReg(Reg)); 147 return MCDisassembler::Success; 148 } 149 150 static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo, 151 uint64_t Address, 152 const MCDisassembler *Decoder) { 153 if (RegNo == 0) { 154 return MCDisassembler::Fail; 155 } 156 157 return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); 158 } 159 160 static DecodeStatus 161 DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo, uint32_t Address, 162 const MCDisassembler *Decoder) { 163 if (RegNo == 2) { 164 return MCDisassembler::Fail; 165 } 166 167 return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder); 168 } 169 170 static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo, 171 uint64_t Address, 172 const MCDisassembler *Decoder) { 173 if (RegNo >= 8) 174 return MCDisassembler::Fail; 175 176 MCRegister Reg = RISCV::X8 + RegNo; 177 Inst.addOperand(MCOperand::createReg(Reg)); 178 return MCDisassembler::Success; 179 } 180 181 static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo, 182 uint64_t Address, 183 const MCDisassembler *Decoder) { 184 if (RegNo >= 32 || RegNo & 1) 185 return MCDisassembler::Fail; 186 187 MCRegister Reg = RISCV::X0 + RegNo; 188 Inst.addOperand(MCOperand::createReg(Reg)); 189 return MCDisassembler::Success; 190 } 191 192 static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo, 193 uint64_t Address, 194 const void *Decoder) { 195 if (RegNo >= 8) 196 return MCDisassembler::Fail; 197 198 MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18); 199 Inst.addOperand(MCOperand::createReg(Reg)); 200 return MCDisassembler::Success; 201 } 202 203 static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo, 204 uint64_t Address, 205 const MCDisassembler *Decoder) { 206 if (RegNo >= 32) 207 return MCDisassembler::Fail; 208 209 MCRegister Reg = RISCV::V0 + RegNo; 210 Inst.addOperand(MCOperand::createReg(Reg)); 211 return MCDisassembler::Success; 212 } 213 214 static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo, 215 uint64_t Address, 216 const MCDisassembler *Decoder) { 217 if (RegNo >= 32 || RegNo % 2) 218 return MCDisassembler::Fail; 219 220 const RISCVDisassembler *Dis = 221 static_cast<const RISCVDisassembler *>(Decoder); 222 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); 223 MCRegister Reg = 224 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0, 225 &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]); 226 227 Inst.addOperand(MCOperand::createReg(Reg)); 228 return MCDisassembler::Success; 229 } 230 231 static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo, 232 uint64_t Address, 233 const MCDisassembler *Decoder) { 234 if (RegNo >= 32 || RegNo % 4) 235 return MCDisassembler::Fail; 236 237 const RISCVDisassembler *Dis = 238 static_cast<const RISCVDisassembler *>(Decoder); 239 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); 240 MCRegister Reg = 241 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0, 242 &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]); 243 244 Inst.addOperand(MCOperand::createReg(Reg)); 245 return MCDisassembler::Success; 246 } 247 248 static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo, 249 uint64_t Address, 250 const MCDisassembler *Decoder) { 251 if (RegNo >= 32 || RegNo % 8) 252 return MCDisassembler::Fail; 253 254 const RISCVDisassembler *Dis = 255 static_cast<const RISCVDisassembler *>(Decoder); 256 const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo(); 257 MCRegister Reg = 258 RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0, 259 &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]); 260 261 Inst.addOperand(MCOperand::createReg(Reg)); 262 return MCDisassembler::Success; 263 } 264 265 static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo, 266 uint64_t Address, 267 const MCDisassembler *Decoder) { 268 if (RegNo >= 2) 269 return MCDisassembler::Fail; 270 271 MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister; 272 273 Inst.addOperand(MCOperand::createReg(Reg)); 274 return MCDisassembler::Success; 275 } 276 277 template <unsigned N> 278 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm, 279 int64_t Address, 280 const MCDisassembler *Decoder) { 281 assert(isUInt<N>(Imm) && "Invalid immediate"); 282 Inst.addOperand(MCOperand::createImm(Imm)); 283 return MCDisassembler::Success; 284 } 285 286 template <unsigned N> 287 static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm, 288 int64_t Address, 289 const MCDisassembler *Decoder) { 290 if (Imm == 0) 291 return MCDisassembler::Fail; 292 return decodeUImmOperand<N>(Inst, Imm, Address, Decoder); 293 } 294 295 template <unsigned N> 296 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm, 297 int64_t Address, 298 const MCDisassembler *Decoder) { 299 assert(isUInt<N>(Imm) && "Invalid immediate"); 300 // Sign-extend the number in the bottom N bits of Imm 301 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 302 return MCDisassembler::Success; 303 } 304 305 template <unsigned N> 306 static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm, 307 int64_t Address, 308 const MCDisassembler *Decoder) { 309 if (Imm == 0) 310 return MCDisassembler::Fail; 311 return decodeSImmOperand<N>(Inst, Imm, Address, Decoder); 312 } 313 314 template <unsigned N> 315 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint32_t Imm, 316 int64_t Address, 317 const MCDisassembler *Decoder) { 318 assert(isUInt<N>(Imm) && "Invalid immediate"); 319 // Sign-extend the number in the bottom N bits of Imm after accounting for 320 // the fact that the N bit immediate is stored in N-1 bits (the LSB is 321 // always zero) 322 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1))); 323 return MCDisassembler::Success; 324 } 325 326 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm, 327 int64_t Address, 328 const MCDisassembler *Decoder) { 329 assert(isUInt<6>(Imm) && "Invalid immediate"); 330 if (Imm > 31) { 331 Imm = (SignExtend64<6>(Imm) & 0xfffff); 332 } 333 Inst.addOperand(MCOperand::createImm(Imm)); 334 return MCDisassembler::Success; 335 } 336 337 static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address, 338 const MCDisassembler *Decoder) { 339 assert(isUInt<3>(Imm) && "Invalid immediate"); 340 if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm)) 341 return MCDisassembler::Fail; 342 343 Inst.addOperand(MCOperand::createImm(Imm)); 344 return MCDisassembler::Success; 345 } 346 347 static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn, 348 uint64_t Address, 349 const MCDisassembler *Decoder); 350 351 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn, 352 uint64_t Address, 353 const MCDisassembler *Decoder); 354 355 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn, 356 uint64_t Address, 357 const MCDisassembler *Decoder); 358 359 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn, 360 uint64_t Address, 361 const MCDisassembler *Decoder); 362 363 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn, 364 uint64_t Address, 365 const MCDisassembler *Decoder); 366 367 static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn, 368 uint64_t Address, 369 const MCDisassembler *Decoder); 370 371 static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm, 372 uint64_t Address, const void *Decoder); 373 374 static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address, 375 const MCDisassembler *Decoder); 376 377 static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm, 378 uint64_t Address, const void *Decoder); 379 380 static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn, 381 uint64_t Address, 382 const MCDisassembler *Decoder); 383 384 #include "RISCVGenDisassemblerTables.inc" 385 386 static DecodeStatus decodeRVCInstrRdRs1ImmZero(MCInst &Inst, uint32_t Insn, 387 uint64_t Address, 388 const MCDisassembler *Decoder) { 389 uint32_t Rd = fieldFromInstruction(Insn, 7, 5); 390 [[maybe_unused]] DecodeStatus Result = 391 DecodeGPRNoX0RegisterClass(Inst, Rd, Address, Decoder); 392 assert(Result == MCDisassembler::Success && "Invalid register"); 393 Inst.addOperand(Inst.getOperand(0)); 394 Inst.addOperand(MCOperand::createImm(0)); 395 return MCDisassembler::Success; 396 } 397 398 static DecodeStatus decodeCSSPushPopchk(MCInst &Inst, uint32_t Insn, 399 uint64_t Address, 400 const MCDisassembler *Decoder) { 401 uint32_t Rs1 = fieldFromInstruction(Insn, 7, 5); 402 [[maybe_unused]] DecodeStatus Result = 403 DecodeGPRX1X5RegisterClass(Inst, Rs1, Address, Decoder); 404 assert(Result == MCDisassembler::Success && "Invalid register"); 405 return MCDisassembler::Success; 406 } 407 408 static DecodeStatus decodeRVCInstrRdSImm(MCInst &Inst, uint32_t Insn, 409 uint64_t Address, 410 const MCDisassembler *Decoder) { 411 Inst.addOperand(MCOperand::createReg(RISCV::X0)); 412 uint32_t SImm6 = 413 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 414 [[maybe_unused]] DecodeStatus Result = 415 decodeSImmOperand<6>(Inst, SImm6, Address, Decoder); 416 assert(Result == MCDisassembler::Success && "Invalid immediate"); 417 return MCDisassembler::Success; 418 } 419 420 static DecodeStatus decodeRVCInstrRdRs1UImm(MCInst &Inst, uint32_t Insn, 421 uint64_t Address, 422 const MCDisassembler *Decoder) { 423 Inst.addOperand(MCOperand::createReg(RISCV::X0)); 424 Inst.addOperand(Inst.getOperand(0)); 425 uint32_t UImm6 = 426 fieldFromInstruction(Insn, 12, 1) << 5 | fieldFromInstruction(Insn, 2, 5); 427 [[maybe_unused]] DecodeStatus Result = 428 decodeUImmOperand<6>(Inst, UImm6, Address, Decoder); 429 assert(Result == MCDisassembler::Success && "Invalid immediate"); 430 return MCDisassembler::Success; 431 } 432 433 static DecodeStatus decodeRVCInstrRdRs2(MCInst &Inst, uint32_t Insn, 434 uint64_t Address, 435 const MCDisassembler *Decoder) { 436 uint32_t Rd = fieldFromInstruction(Insn, 7, 5); 437 uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5); 438 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder); 439 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 440 return MCDisassembler::Success; 441 } 442 443 static DecodeStatus decodeRVCInstrRdRs1Rs2(MCInst &Inst, uint32_t Insn, 444 uint64_t Address, 445 const MCDisassembler *Decoder) { 446 uint32_t Rd = fieldFromInstruction(Insn, 7, 5); 447 uint32_t Rs2 = fieldFromInstruction(Insn, 2, 5); 448 DecodeGPRRegisterClass(Inst, Rd, Address, Decoder); 449 Inst.addOperand(Inst.getOperand(0)); 450 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 451 return MCDisassembler::Success; 452 } 453 454 static DecodeStatus decodeXTHeadMemPair(MCInst &Inst, uint32_t Insn, 455 uint64_t Address, 456 const MCDisassembler *Decoder) { 457 uint32_t Rd1 = fieldFromInstruction(Insn, 7, 5); 458 uint32_t Rs1 = fieldFromInstruction(Insn, 15, 5); 459 uint32_t Rd2 = fieldFromInstruction(Insn, 20, 5); 460 uint32_t UImm2 = fieldFromInstruction(Insn, 25, 2); 461 DecodeGPRRegisterClass(Inst, Rd1, Address, Decoder); 462 DecodeGPRRegisterClass(Inst, Rd2, Address, Decoder); 463 DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder); 464 [[maybe_unused]] DecodeStatus Result = 465 decodeUImmOperand<2>(Inst, UImm2, Address, Decoder); 466 assert(Result == MCDisassembler::Success && "Invalid immediate"); 467 468 // Disassemble the final operand which is implicit. 469 unsigned Opcode = Inst.getOpcode(); 470 bool IsWordOp = (Opcode == RISCV::TH_LWD || Opcode == RISCV::TH_LWUD || 471 Opcode == RISCV::TH_SWD); 472 if (IsWordOp) 473 Inst.addOperand(MCOperand::createImm(3)); 474 else 475 Inst.addOperand(MCOperand::createImm(4)); 476 477 return MCDisassembler::Success; 478 } 479 480 static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm, 481 uint64_t Address, const void *Decoder) { 482 if (Imm <= 3) 483 return MCDisassembler::Fail; 484 Inst.addOperand(MCOperand::createImm(Imm)); 485 return MCDisassembler::Success; 486 } 487 488 static DecodeStatus decodeRegReg(MCInst &Inst, uint32_t Insn, uint64_t Address, 489 const MCDisassembler *Decoder) { 490 uint32_t Rs1 = fieldFromInstruction(Insn, 0, 5); 491 uint32_t Rs2 = fieldFromInstruction(Insn, 5, 5); 492 DecodeGPRRegisterClass(Inst, Rs1, Address, Decoder); 493 DecodeGPRRegisterClass(Inst, Rs2, Address, Decoder); 494 return MCDisassembler::Success; 495 } 496 497 static DecodeStatus decodeZcmpSpimm(MCInst &Inst, uint32_t Imm, 498 uint64_t Address, const void *Decoder) { 499 Inst.addOperand(MCOperand::createImm(Imm)); 500 return MCDisassembler::Success; 501 } 502 503 // Add implied SP operand for C.*SP compressed instructions. The SP operand 504 // isn't explicitly encoded in the instruction. 505 void RISCVDisassembler::addSPOperands(MCInst &MI) const { 506 const MCInstrDesc &MCID = MCII->get(MI.getOpcode()); 507 for (unsigned i = 0; i < MCID.getNumOperands(); i++) 508 if (MCID.operands()[i].RegClass == RISCV::SPRegClassID) 509 MI.insert(MI.begin() + i, MCOperand::createReg(RISCV::X2)); 510 } 511 512 #define TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, \ 513 DESC, ADDITIONAL_OPERATION) \ 514 do { \ 515 if (FEATURE_CHECKS) { \ 516 LLVM_DEBUG(dbgs() << "Trying " DESC ":\n"); \ 517 DecodeStatus Result = \ 518 decodeInstruction(DECODER_TABLE, MI, Insn, Address, this, STI); \ 519 if (Result != MCDisassembler::Fail) { \ 520 ADDITIONAL_OPERATION; \ 521 return Result; \ 522 } \ 523 } \ 524 } while (false) 525 #define TRY_TO_DECODE_AND_ADD_SP(FEATURE_CHECKS, DECODER_TABLE, DESC) \ 526 TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \ 527 addSPOperands(MI)) 528 #define TRY_TO_DECODE(FEATURE_CHECKS, DECODER_TABLE, DESC) \ 529 TRY_TO_DECODE_WITH_ADDITIONAL_OPERATION(FEATURE_CHECKS, DECODER_TABLE, DESC, \ 530 (void)nullptr) 531 #define TRY_TO_DECODE_FEATURE(FEATURE, DECODER_TABLE, DESC) \ 532 TRY_TO_DECODE(STI.hasFeature(FEATURE), DECODER_TABLE, DESC) 533 534 DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size, 535 ArrayRef<uint8_t> Bytes, 536 uint64_t Address, 537 raw_ostream &CS) const { 538 if (Bytes.size() < 4) { 539 Size = 0; 540 return MCDisassembler::Fail; 541 } 542 Size = 4; 543 544 uint32_t Insn = support::endian::read32le(Bytes.data()); 545 546 TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZdinx) && 547 !STI.hasFeature(RISCV::Feature64Bit), 548 DecoderTableRV32Zdinx32, 549 "RV32Zdinx table (Double in Integer and rv32)"); 550 TRY_TO_DECODE(STI.hasFeature(RISCV::FeatureStdExtZacas) && 551 !STI.hasFeature(RISCV::Feature64Bit), 552 DecoderTableRV32Zacas32, 553 "RV32Zacas table (Compare-And-Swap and rv32)"); 554 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZfinx, DecoderTableRVZfinx32, 555 "RVZfinx table (Float in Integer)"); 556 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXVentanaCondOps, 557 DecoderTableXVentana32, "Ventana custom opcode table"); 558 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBa, DecoderTableXTHeadBa32, 559 "XTHeadBa custom opcode table"); 560 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBb, DecoderTableXTHeadBb32, 561 "XTHeadBb custom opcode table"); 562 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadBs, DecoderTableXTHeadBs32, 563 "XTHeadBs custom opcode table"); 564 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCondMov, 565 DecoderTableXTHeadCondMov32, 566 "XTHeadCondMov custom opcode table"); 567 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadCmo, DecoderTableXTHeadCmo32, 568 "XTHeadCmo custom opcode table"); 569 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadFMemIdx, 570 DecoderTableXTHeadFMemIdx32, 571 "XTHeadFMemIdx custom opcode table"); 572 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMac, DecoderTableXTHeadMac32, 573 "XTHeadMac custom opcode table"); 574 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemIdx, 575 DecoderTableXTHeadMemIdx32, 576 "XTHeadMemIdx custom opcode table"); 577 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadMemPair, 578 DecoderTableXTHeadMemPair32, 579 "XTHeadMemPair custom opcode table"); 580 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadSync, 581 DecoderTableXTHeadSync32, 582 "XTHeadSync custom opcode table"); 583 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXTHeadVdot, 584 DecoderTableXTHeadVdot32, 585 "XTHeadVdot custom opcode table"); 586 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfvcp, DecoderTableXSfvcp32, 587 "SiFive VCIX custom opcode table"); 588 TRY_TO_DECODE_FEATURE( 589 RISCV::FeatureVendorXSfvqmaccdod, DecoderTableXSfvqmaccdod32, 590 "SiFive Matrix Multiplication (2x8 and 8x2) Instruction opcode table"); 591 TRY_TO_DECODE_FEATURE( 592 RISCV::FeatureVendorXSfvqmaccqoq, DecoderTableXSfvqmaccqoq32, 593 "SiFive Matrix Multiplication (4x8 and 8x4) Instruction opcode table"); 594 TRY_TO_DECODE_FEATURE( 595 RISCV::FeatureVendorXSfvfwmaccqqq, DecoderTableXSfvfwmaccqqq32, 596 "SiFive Matrix Multiplication Instruction opcode table"); 597 TRY_TO_DECODE_FEATURE( 598 RISCV::FeatureVendorXSfvfnrclipxfqf, DecoderTableXSfvfnrclipxfqf32, 599 "SiFive FP32-to-int8 Ranged Clip Instructions opcode table"); 600 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecdiscarddlone, 601 DecoderTableXSiFivecdiscarddlone32, 602 "SiFive sf.cdiscard.d.l1 custom opcode table"); 603 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSiFivecflushdlone, 604 DecoderTableXSiFivecflushdlone32, 605 "SiFive sf.cflush.d.l1 custom opcode table"); 606 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXSfcease, DecoderTableXSfcease32, 607 "SiFive sf.cease custom opcode table"); 608 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbitmanip, 609 DecoderTableXCVbitmanip32, 610 "CORE-V Bit Manipulation custom opcode table"); 611 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVelw, DecoderTableXCVelw32, 612 "CORE-V Event load custom opcode table"); 613 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmac, DecoderTableXCVmac32, 614 "CORE-V MAC custom opcode table"); 615 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVmem, DecoderTableXCVmem32, 616 "CORE-V MEM custom opcode table"); 617 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCValu, DecoderTableXCValu32, 618 "CORE-V ALU custom opcode table"); 619 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVsimd, DecoderTableXCVsimd32, 620 "CORE-V SIMD extensions custom opcode table"); 621 TRY_TO_DECODE_FEATURE(RISCV::FeatureVendorXCVbi, DecoderTableXCVbi32, 622 "CORE-V Immediate Branching custom opcode table"); 623 TRY_TO_DECODE(true, DecoderTable32, "RISCV32 table"); 624 625 return MCDisassembler::Fail; 626 } 627 628 DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size, 629 ArrayRef<uint8_t> Bytes, 630 uint64_t Address, 631 raw_ostream &CS) const { 632 if (Bytes.size() < 2) { 633 Size = 0; 634 return MCDisassembler::Fail; 635 } 636 Size = 2; 637 638 uint32_t Insn = support::endian::read16le(Bytes.data()); 639 TRY_TO_DECODE_AND_ADD_SP(!STI.hasFeature(RISCV::Feature64Bit), 640 DecoderTableRISCV32Only_16, 641 "RISCV32Only_16 table (16-bit Instruction)"); 642 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZicfiss, DecoderTableZicfiss16, 643 "RVZicfiss table (Shadow Stack)"); 644 TRY_TO_DECODE_FEATURE(RISCV::FeatureStdExtZcmt, DecoderTableRVZcmt16, 645 "Zcmt table (16-bit Table Jump Instructions)"); 646 TRY_TO_DECODE_FEATURE( 647 RISCV::FeatureStdExtZcmp, DecoderTableRVZcmp16, 648 "Zcmp table (16-bit Push/Pop & Double Move Instructions)"); 649 TRY_TO_DECODE_AND_ADD_SP(STI.hasFeature(RISCV::FeatureVendorXwchc), 650 DecoderTableXwchc16, 651 "WCH QingKe XW custom opcode table"); 652 TRY_TO_DECODE_AND_ADD_SP(true, DecoderTable16, 653 "RISCV_C table (16-bit Instruction)"); 654 655 return MCDisassembler::Fail; 656 } 657 658 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 659 ArrayRef<uint8_t> Bytes, 660 uint64_t Address, 661 raw_ostream &CS) const { 662 // It's a 16 bit instruction if bit 0 and 1 are not 0b11. 663 if ((Bytes[0] & 0b11) != 0b11) 664 return getInstruction16(MI, Size, Bytes, Address, CS); 665 666 // It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2 667 // are not 0b111. 668 if ((Bytes[0] & 0b1'1100) != 0b1'1100) 669 return getInstruction32(MI, Size, Bytes, Address, CS); 670 671 // 48-bit instructions are encoded as 0bxx011111. 672 if ((Bytes[0] & 0b11'1111) == 0b01'1111) { 673 Size = Bytes.size() >= 6 ? 6 : 0; 674 return MCDisassembler::Fail; 675 } 676 677 // 64-bit instructions are encoded as 0x0111111. 678 if ((Bytes[0] & 0b111'1111) == 0b011'1111) { 679 Size = Bytes.size() >= 8 ? 8 : 0; 680 return MCDisassembler::Fail; 681 } 682 683 // Remaining cases need to check a second byte. 684 if (Bytes.size() < 2) { 685 Size = 0; 686 return MCDisassembler::Fail; 687 } 688 689 // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111. 690 // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111. 691 unsigned nnn = (Bytes[1] >> 4) & 0b111; 692 if (nnn != 0b111) { 693 Size = 10 + (nnn * 2); 694 if (Bytes.size() < Size) 695 Size = 0; 696 return MCDisassembler::Fail; 697 } 698 699 // Remaining encodings are reserved for > 176-bit instructions. 700 Size = 0; 701 return MCDisassembler::Fail; 702 } 703