brintos

brintos / llvm-project-archived public Read only

0
0
Text · 32.2 KiB · 4bea4c4 Raw
870 lines · cpp
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-exception6//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/MCDecoder.h"18#include "llvm/MC/MCDecoderOps.h"19#include "llvm/MC/MCDisassembler/MCDisassembler.h"20#include "llvm/MC/MCInst.h"21#include "llvm/MC/MCInstrInfo.h"22#include "llvm/MC/MCRegisterInfo.h"23#include "llvm/MC/MCSubtargetInfo.h"24#include "llvm/MC/TargetRegistry.h"25#include "llvm/Support/Compiler.h"26#include "llvm/Support/Endian.h"27 28using namespace llvm;29using namespace llvm::MCD;30 31#define DEBUG_TYPE "riscv-disassembler"32 33typedef MCDisassembler::DecodeStatus DecodeStatus;34 35namespace {36class RISCVDisassembler : public MCDisassembler {37  std::unique_ptr<MCInstrInfo const> const MCII;38 39public:40  RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,41                    MCInstrInfo const *MCII)42      : MCDisassembler(STI, Ctx), MCII(MCII) {}43 44  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,45                              ArrayRef<uint8_t> Bytes, uint64_t Address,46                              raw_ostream &CStream) const override;47 48private:49  DecodeStatus getInstruction48(MCInst &Instr, uint64_t &Size,50                                ArrayRef<uint8_t> Bytes, uint64_t Address,51                                raw_ostream &CStream) const;52 53  DecodeStatus getInstruction32(MCInst &Instr, uint64_t &Size,54                                ArrayRef<uint8_t> Bytes, uint64_t Address,55                                raw_ostream &CStream) const;56  DecodeStatus getInstruction16(MCInst &Instr, uint64_t &Size,57                                ArrayRef<uint8_t> Bytes, uint64_t Address,58                                raw_ostream &CStream) const;59};60} // end anonymous namespace61 62static MCDisassembler *createRISCVDisassembler(const Target &T,63                                               const MCSubtargetInfo &STI,64                                               MCContext &Ctx) {65  return new RISCVDisassembler(STI, Ctx, T.createMCInstrInfo());66}67 68extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void69LLVMInitializeRISCVDisassembler() {70  // Register the disassembler for each target.71  TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),72                                         createRISCVDisassembler);73  TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),74                                         createRISCVDisassembler);75  TargetRegistry::RegisterMCDisassembler(getTheRISCV32beTarget(),76                                         createRISCVDisassembler);77  TargetRegistry::RegisterMCDisassembler(getTheRISCV64beTarget(),78                                         createRISCVDisassembler);79}80 81static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint32_t RegNo,82                                           uint64_t Address,83                                           const MCDisassembler *Decoder) {84  bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);85 86  if (RegNo >= 32 || (IsRVE && RegNo >= 16))87    return MCDisassembler::Fail;88 89  MCRegister Reg = RISCV::X0 + RegNo;90  Inst.addOperand(MCOperand::createReg(Reg));91  return MCDisassembler::Success;92}93 94static DecodeStatus DecodeGPRF16RegisterClass(MCInst &Inst, uint32_t RegNo,95                                              uint64_t Address,96                                              const MCDisassembler *Decoder) {97  bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);98 99  if (RegNo >= 32 || (IsRVE && RegNo >= 16))100    return MCDisassembler::Fail;101 102  MCRegister Reg = RISCV::X0_H + RegNo;103  Inst.addOperand(MCOperand::createReg(Reg));104  return MCDisassembler::Success;105}106 107static DecodeStatus DecodeGPRF32RegisterClass(MCInst &Inst, uint32_t RegNo,108                                              uint64_t Address,109                                              const MCDisassembler *Decoder) {110  bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);111 112  if (RegNo >= 32 || (IsRVE && RegNo >= 16))113    return MCDisassembler::Fail;114 115  MCRegister Reg = RISCV::X0_W + RegNo;116  Inst.addOperand(MCOperand::createReg(Reg));117  return MCDisassembler::Success;118}119 120static DecodeStatus DecodeGPRX1X5RegisterClass(MCInst &Inst, uint32_t RegNo,121                                               uint64_t Address,122                                               const MCDisassembler *Decoder) {123  MCRegister Reg = RISCV::X0 + RegNo;124  if (Reg != RISCV::X1 && Reg != RISCV::X5)125    return MCDisassembler::Fail;126 127  Inst.addOperand(MCOperand::createReg(Reg));128  return MCDisassembler::Success;129}130 131static DecodeStatus DecodeFPR16RegisterClass(MCInst &Inst, uint32_t RegNo,132                                             uint64_t Address,133                                             const MCDisassembler *Decoder) {134  if (RegNo >= 32)135    return MCDisassembler::Fail;136 137  MCRegister Reg = RISCV::F0_H + RegNo;138  Inst.addOperand(MCOperand::createReg(Reg));139  return MCDisassembler::Success;140}141 142static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint32_t RegNo,143                                             uint64_t Address,144                                             const MCDisassembler *Decoder) {145  if (RegNo >= 32)146    return MCDisassembler::Fail;147 148  MCRegister Reg = RISCV::F0_F + RegNo;149  Inst.addOperand(MCOperand::createReg(Reg));150  return MCDisassembler::Success;151}152 153static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint32_t RegNo,154                                              uint64_t Address,155                                              const MCDisassembler *Decoder) {156  if (RegNo >= 8) {157    return MCDisassembler::Fail;158  }159  MCRegister Reg = RISCV::F8_F + RegNo;160  Inst.addOperand(MCOperand::createReg(Reg));161  return MCDisassembler::Success;162}163 164static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint32_t RegNo,165                                             uint64_t Address,166                                             const MCDisassembler *Decoder) {167  if (RegNo >= 32)168    return MCDisassembler::Fail;169 170  MCRegister Reg = RISCV::F0_D + RegNo;171  Inst.addOperand(MCOperand::createReg(Reg));172  return MCDisassembler::Success;173}174 175static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint32_t RegNo,176                                              uint64_t Address,177                                              const MCDisassembler *Decoder) {178  if (RegNo >= 8) {179    return MCDisassembler::Fail;180  }181  MCRegister Reg = RISCV::F8_D + RegNo;182  Inst.addOperand(MCOperand::createReg(Reg));183  return MCDisassembler::Success;184}185 186static DecodeStatus DecodeFPR128RegisterClass(MCInst &Inst, uint32_t RegNo,187                                              uint64_t Address,188                                              const MCDisassembler *Decoder) {189  if (RegNo >= 32)190    return MCDisassembler::Fail;191 192  MCRegister Reg = RISCV::F0_Q + RegNo;193  Inst.addOperand(MCOperand::createReg(Reg));194  return MCDisassembler::Success;195}196 197static DecodeStatus DecodeGPRX1RegisterClass(MCInst &Inst,198                                             const MCDisassembler *Decoder) {199  Inst.addOperand(MCOperand::createReg(RISCV::X1));200  return MCDisassembler::Success;201}202 203static DecodeStatus DecodeSPRegisterClass(MCInst &Inst,204                                          const MCDisassembler *Decoder) {205  Inst.addOperand(MCOperand::createReg(RISCV::X2));206  return MCDisassembler::Success;207}208 209static DecodeStatus DecodeSPRegisterClass(MCInst &Inst, uint64_t RegNo,210                                          uint32_t Address,211                                          const MCDisassembler *Decoder) {212  assert(RegNo == 2);213  Inst.addOperand(MCOperand::createReg(RISCV::X2));214  return MCDisassembler::Success;215}216 217static DecodeStatus DecodeGPRX5RegisterClass(MCInst &Inst,218                                             const MCDisassembler *Decoder) {219  Inst.addOperand(MCOperand::createReg(RISCV::X5));220  return MCDisassembler::Success;221}222 223static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint32_t RegNo,224                                               uint64_t Address,225                                               const MCDisassembler *Decoder) {226  if (RegNo == 0)227    return MCDisassembler::Fail;228 229  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);230}231 232static DecodeStatus DecodeGPRNoX2RegisterClass(MCInst &Inst, uint64_t RegNo,233                                               uint32_t Address,234                                               const MCDisassembler *Decoder) {235  if (RegNo == 2)236    return MCDisassembler::Fail;237 238  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);239}240 241static DecodeStatus DecodeGPRNoX31RegisterClass(MCInst &Inst, uint32_t RegNo,242                                                uint64_t Address,243                                                const MCDisassembler *Decoder) {244  if (RegNo == 31) {245    return MCDisassembler::Fail;246  }247 248  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);249}250 251static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint32_t RegNo,252                                            uint64_t Address,253                                            const MCDisassembler *Decoder) {254  if (RegNo >= 8)255    return MCDisassembler::Fail;256 257  MCRegister Reg = RISCV::X8 + RegNo;258  Inst.addOperand(MCOperand::createReg(Reg));259  return MCDisassembler::Success;260}261 262static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint32_t RegNo,263                                               uint64_t Address,264                                               const MCDisassembler *Decoder) {265  if (RegNo >= 32 || RegNo % 2)266    return MCDisassembler::Fail;267 268  const RISCVDisassembler *Dis =269      static_cast<const RISCVDisassembler *>(Decoder);270  const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();271  MCRegister Reg = RI->getMatchingSuperReg(272      RISCV::X0 + RegNo, RISCV::sub_gpr_even,273      &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);274  Inst.addOperand(MCOperand::createReg(Reg));275  return MCDisassembler::Success;276}277 278static DecodeStatus279DecodeGPRPairNoX0RegisterClass(MCInst &Inst, uint32_t RegNo, uint64_t Address,280                               const MCDisassembler *Decoder) {281  if (RegNo == 0)282    return MCDisassembler::Fail;283 284  return DecodeGPRPairRegisterClass(Inst, RegNo, Address, Decoder);285}286 287static DecodeStatus DecodeGPRPairCRegisterClass(MCInst &Inst, uint32_t RegNo,288                                                uint64_t Address,289                                                const MCDisassembler *Decoder) {290  if (RegNo >= 8 || RegNo % 2)291    return MCDisassembler::Fail;292 293  const RISCVDisassembler *Dis =294      static_cast<const RISCVDisassembler *>(Decoder);295  const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();296  MCRegister Reg = RI->getMatchingSuperReg(297      RISCV::X8 + RegNo, RISCV::sub_gpr_even,298      &RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID]);299  Inst.addOperand(MCOperand::createReg(Reg));300  return MCDisassembler::Success;301}302 303static DecodeStatus DecodeSR07RegisterClass(MCInst &Inst, uint32_t RegNo,304                                            uint64_t Address,305                                            const void *Decoder) {306  if (RegNo >= 8)307    return MCDisassembler::Fail;308 309  MCRegister Reg = (RegNo < 2) ? (RegNo + RISCV::X8) : (RegNo - 2 + RISCV::X18);310  Inst.addOperand(MCOperand::createReg(Reg));311  return MCDisassembler::Success;312}313 314static DecodeStatus DecodeVRRegisterClass(MCInst &Inst, uint32_t RegNo,315                                          uint64_t Address,316                                          const MCDisassembler *Decoder) {317  if (RegNo >= 32)318    return MCDisassembler::Fail;319 320  MCRegister Reg = RISCV::V0 + RegNo;321  Inst.addOperand(MCOperand::createReg(Reg));322  return MCDisassembler::Success;323}324 325static DecodeStatus DecodeVRM2RegisterClass(MCInst &Inst, uint32_t RegNo,326                                            uint64_t Address,327                                            const MCDisassembler *Decoder) {328  if (RegNo >= 32 || RegNo % 2)329    return MCDisassembler::Fail;330 331  const RISCVDisassembler *Dis =332      static_cast<const RISCVDisassembler *>(Decoder);333  const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();334  MCRegister Reg =335      RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,336                              &RISCVMCRegisterClasses[RISCV::VRM2RegClassID]);337 338  Inst.addOperand(MCOperand::createReg(Reg));339  return MCDisassembler::Success;340}341 342static DecodeStatus DecodeVRM4RegisterClass(MCInst &Inst, uint32_t RegNo,343                                            uint64_t Address,344                                            const MCDisassembler *Decoder) {345  if (RegNo >= 32 || RegNo % 4)346    return MCDisassembler::Fail;347 348  const RISCVDisassembler *Dis =349      static_cast<const RISCVDisassembler *>(Decoder);350  const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();351  MCRegister Reg =352      RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,353                              &RISCVMCRegisterClasses[RISCV::VRM4RegClassID]);354 355  Inst.addOperand(MCOperand::createReg(Reg));356  return MCDisassembler::Success;357}358 359static DecodeStatus DecodeVRM8RegisterClass(MCInst &Inst, uint32_t RegNo,360                                            uint64_t Address,361                                            const MCDisassembler *Decoder) {362  if (RegNo >= 32 || RegNo % 8)363    return MCDisassembler::Fail;364 365  const RISCVDisassembler *Dis =366      static_cast<const RISCVDisassembler *>(Decoder);367  const MCRegisterInfo *RI = Dis->getContext().getRegisterInfo();368  MCRegister Reg =369      RI->getMatchingSuperReg(RISCV::V0 + RegNo, RISCV::sub_vrm1_0,370                              &RISCVMCRegisterClasses[RISCV::VRM8RegClassID]);371 372  Inst.addOperand(MCOperand::createReg(Reg));373  return MCDisassembler::Success;374}375 376static DecodeStatus DecodeVMV0RegisterClass(MCInst &Inst, uint32_t RegNo,377                                            uint64_t Address,378                                            const MCDisassembler *Decoder) {379  if (RegNo)380    return MCDisassembler::Fail;381 382  Inst.addOperand(MCOperand::createReg(RISCV::V0));383  return MCDisassembler::Success;384}385 386static DecodeStatus DecodeTRRegisterClass(MCInst &Inst, uint32_t RegNo,387                                          uint64_t Address,388                                          const MCDisassembler *Decoder) {389  if (RegNo > 15)390    return MCDisassembler::Fail;391 392  MCRegister Reg = RISCV::T0 + RegNo;393  Inst.addOperand(MCOperand::createReg(Reg));394  return MCDisassembler::Success;395}396 397static DecodeStatus DecodeTRM2RegisterClass(MCInst &Inst, uint32_t RegNo,398                                            uint64_t Address,399                                            const MCDisassembler *Decoder) {400  if (RegNo > 15 || RegNo % 2)401    return MCDisassembler::Fail;402 403  MCRegister Reg = RISCV::T0 + RegNo;404  Inst.addOperand(MCOperand::createReg(Reg));405  return MCDisassembler::Success;406}407 408static DecodeStatus DecodeTRM4RegisterClass(MCInst &Inst, uint32_t RegNo,409                                            uint64_t Address,410                                            const MCDisassembler *Decoder) {411  if (RegNo > 15 || RegNo % 4)412    return MCDisassembler::Fail;413 414  MCRegister Reg = RISCV::T0 + RegNo;415  Inst.addOperand(MCOperand::createReg(Reg));416  return MCDisassembler::Success;417}418 419static DecodeStatus decodeVMaskReg(MCInst &Inst, uint32_t RegNo,420                                   uint64_t Address,421                                   const MCDisassembler *Decoder) {422  if (RegNo >= 2)423    return MCDisassembler::Fail;424 425  MCRegister Reg = (RegNo == 0) ? RISCV::V0 : RISCV::NoRegister;426 427  Inst.addOperand(MCOperand::createReg(Reg));428  return MCDisassembler::Success;429}430 431static DecodeStatus decodeImmThreeOperand(MCInst &Inst,432                                          const MCDisassembler *Decoder) {433  Inst.addOperand(MCOperand::createImm(3));434  return MCDisassembler::Success;435}436 437static DecodeStatus decodeImmFourOperand(MCInst &Inst,438                                         const MCDisassembler *Decoder) {439  Inst.addOperand(MCOperand::createImm(4));440  return MCDisassembler::Success;441}442 443template <unsigned N>444static DecodeStatus decodeUImmOperand(MCInst &Inst, uint32_t Imm,445                                      int64_t Address,446                                      const MCDisassembler *Decoder) {447  assert(isUInt<N>(Imm) && "Invalid immediate");448  Inst.addOperand(MCOperand::createImm(Imm));449  return MCDisassembler::Success;450}451 452template <unsigned Width, unsigned LowerBound>453static DecodeStatus decodeUImmOperandGE(MCInst &Inst, uint32_t Imm,454                                        int64_t Address,455                                        const MCDisassembler *Decoder) {456  assert(isUInt<Width>(Imm) && "Invalid immediate");457 458  if (Imm < LowerBound)459    return MCDisassembler::Fail;460 461  Inst.addOperand(MCOperand::createImm(Imm));462  return MCDisassembler::Success;463}464 465template <unsigned Width, unsigned LowerBound>466static DecodeStatus decodeUImmPlus1OperandGE(MCInst &Inst, uint32_t Imm,467                                             int64_t Address,468                                             const MCDisassembler *Decoder) {469  assert(isUInt<Width>(Imm) && "Invalid immediate");470 471  if ((Imm + 1) < LowerBound)472    return MCDisassembler::Fail;473 474  Inst.addOperand(MCOperand::createImm(Imm + 1));475  return MCDisassembler::Success;476}477 478static DecodeStatus decodeUImmSlistOperand(MCInst &Inst, uint32_t Imm,479                                           int64_t Address,480                                           const MCDisassembler *Decoder) {481  assert(isUInt<3>(Imm) && "Invalid Slist immediate");482  const uint8_t Slist[] = {0, 1, 2, 4, 8, 16, 15, 31};483  Inst.addOperand(MCOperand::createImm(Slist[Imm]));484  return MCDisassembler::Success;485}486 487static DecodeStatus decodeUImmLog2XLenOperand(MCInst &Inst, uint32_t Imm,488                                              int64_t Address,489                                              const MCDisassembler *Decoder) {490  assert(isUInt<6>(Imm) && "Invalid immediate");491 492  if (!Decoder->getSubtargetInfo().hasFeature(RISCV::Feature64Bit) &&493      !isUInt<5>(Imm))494    return MCDisassembler::Fail;495 496  Inst.addOperand(MCOperand::createImm(Imm));497  return MCDisassembler::Success;498}499 500template <unsigned N>501static DecodeStatus decodeUImmNonZeroOperand(MCInst &Inst, uint32_t Imm,502                                             int64_t Address,503                                             const MCDisassembler *Decoder) {504  if (Imm == 0)505    return MCDisassembler::Fail;506  return decodeUImmOperand<N>(Inst, Imm, Address, Decoder);507}508 509static DecodeStatus510decodeUImmLog2XLenNonZeroOperand(MCInst &Inst, uint32_t Imm, int64_t Address,511                                 const MCDisassembler *Decoder) {512  if (Imm == 0)513    return MCDisassembler::Fail;514  return decodeUImmLog2XLenOperand(Inst, Imm, Address, Decoder);515}516 517template <unsigned N>518static DecodeStatus decodeUImmPlus1Operand(MCInst &Inst, uint32_t Imm,519                                           int64_t Address,520                                           const MCDisassembler *Decoder) {521  assert(isUInt<N>(Imm) && "Invalid immediate");522  Inst.addOperand(MCOperand::createImm(Imm + 1));523  return MCDisassembler::Success;524}525 526static DecodeStatus decodeImmZibiOperand(MCInst &Inst, uint32_t Imm,527                                         int64_t Address,528                                         const MCDisassembler *Decoder) {529  assert(isUInt<5>(Imm) && "Invalid immediate");530  Inst.addOperand(MCOperand::createImm(Imm ? Imm : -1LL));531  return MCDisassembler::Success;532}533 534template <unsigned N>535static DecodeStatus decodeSImmOperand(MCInst &Inst, uint32_t Imm,536                                      int64_t Address,537                                      const MCDisassembler *Decoder) {538  assert(isUInt<N>(Imm) && "Invalid immediate");539  // Sign-extend the number in the bottom N bits of Imm540  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));541  return MCDisassembler::Success;542}543 544template <unsigned N>545static DecodeStatus decodeSImmNonZeroOperand(MCInst &Inst, uint32_t Imm,546                                             int64_t Address,547                                             const MCDisassembler *Decoder) {548  if (Imm == 0)549    return MCDisassembler::Fail;550  return decodeSImmOperand<N>(Inst, Imm, Address, Decoder);551}552 553template <unsigned T, unsigned N>554static DecodeStatus decodeSImmOperandAndLslN(MCInst &Inst, uint32_t Imm,555                                             int64_t Address,556                                             const MCDisassembler *Decoder) {557  assert(isUInt<T - N + 1>(Imm) && "Invalid immediate");558  // Sign-extend the number in the bottom T bits of Imm after accounting for559  // the fact that the T bit immediate is stored in T-N bits (the LSB is560  // always zero)561  Inst.addOperand(MCOperand::createImm(SignExtend64<T>(Imm << N)));562  return MCDisassembler::Success;563}564 565static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint32_t Imm,566                                         int64_t Address,567                                         const MCDisassembler *Decoder) {568  assert(isUInt<6>(Imm) && "Invalid immediate");569  if (Imm == 0)570    return MCDisassembler::Fail;571  Imm = SignExtend64<6>(Imm) & 0xfffff;572  Inst.addOperand(MCOperand::createImm(Imm));573  return MCDisassembler::Success;574}575 576static DecodeStatus decodeFRMArg(MCInst &Inst, uint32_t Imm, int64_t Address,577                                 const MCDisassembler *Decoder) {578  assert(isUInt<3>(Imm) && "Invalid immediate");579  if (!llvm::RISCVFPRndMode::isValidRoundingMode(Imm))580    return MCDisassembler::Fail;581 582  Inst.addOperand(MCOperand::createImm(Imm));583  return MCDisassembler::Success;584}585 586static DecodeStatus decodeRTZArg(MCInst &Inst, uint32_t Imm, int64_t Address,587                                 const MCDisassembler *Decoder) {588  assert(isUInt<3>(Imm) && "Invalid immediate");589  if (Imm != RISCVFPRndMode::RTZ)590    return MCDisassembler::Fail;591 592  Inst.addOperand(MCOperand::createImm(Imm));593  return MCDisassembler::Success;594}595 596static DecodeStatus decodeZcmpRlist(MCInst &Inst, uint32_t Imm,597                                    uint64_t Address,598                                    const MCDisassembler *Decoder) {599  bool IsRVE = Decoder->getSubtargetInfo().hasFeature(RISCV::FeatureStdExtE);600  if (Imm < RISCVZC::RA || (IsRVE && Imm >= RISCVZC::RA_S0_S2))601    return MCDisassembler::Fail;602  Inst.addOperand(MCOperand::createImm(Imm));603  return MCDisassembler::Success;604}605 606static DecodeStatus decodeXqccmpRlistS0(MCInst &Inst, uint32_t Imm,607                                        uint64_t Address,608                                        const MCDisassembler *Decoder) {609  if (Imm < RISCVZC::RA_S0)610    return MCDisassembler::Fail;611  return decodeZcmpRlist(Inst, Imm, Address, Decoder);612}613 614#include "RISCVGenDisassemblerTables.inc"615 616namespace {617 618struct DecoderListEntry {619  const uint8_t *Table;620  FeatureBitset ContainedFeatures;621  const char *Desc;622 623  bool haveContainedFeatures(const FeatureBitset &ActiveFeatures) const {624    return ContainedFeatures.none() ||625           (ContainedFeatures & ActiveFeatures).any();626  }627};628 629} // end anonymous namespace630 631static constexpr FeatureBitset XCVFeatureGroup = {632    RISCV::FeatureVendorXCVbitmanip, RISCV::FeatureVendorXCVelw,633    RISCV::FeatureVendorXCVmac,      RISCV::FeatureVendorXCVmem,634    RISCV::FeatureVendorXCValu,      RISCV::FeatureVendorXCVsimd,635    RISCV::FeatureVendorXCVbi};636 637static constexpr FeatureBitset XRivosFeatureGroup = {638    RISCV::FeatureVendorXRivosVisni,639    RISCV::FeatureVendorXRivosVizip,640};641 642static constexpr FeatureBitset XqciFeatureGroup = {643    RISCV::FeatureVendorXqcia,   RISCV::FeatureVendorXqciac,644    RISCV::FeatureVendorXqcibi,  RISCV::FeatureVendorXqcibm,645    RISCV::FeatureVendorXqcicli, RISCV::FeatureVendorXqcicm,646    RISCV::FeatureVendorXqcics,  RISCV::FeatureVendorXqcicsr,647    RISCV::FeatureVendorXqciint, RISCV::FeatureVendorXqciio,648    RISCV::FeatureVendorXqcilb,  RISCV::FeatureVendorXqcili,649    RISCV::FeatureVendorXqcilia, RISCV::FeatureVendorXqcilo,650    RISCV::FeatureVendorXqcilsm, RISCV::FeatureVendorXqcisim,651    RISCV::FeatureVendorXqcisls, RISCV::FeatureVendorXqcisync,652};653 654static constexpr FeatureBitset XSfVectorGroup = {655    RISCV::FeatureVendorXSfvcp,          RISCV::FeatureVendorXSfvqmaccdod,656    RISCV::FeatureVendorXSfvqmaccqoq,    RISCV::FeatureVendorXSfvfwmaccqqq,657    RISCV::FeatureVendorXSfvfnrclipxfqf, RISCV::FeatureVendorXSfmmbase,658    RISCV::FeatureVendorXSfvfexpa,       RISCV::FeatureVendorXSfvfexpa64e,659    RISCV::FeatureVendorXSfvfbfexp16e,   RISCV::FeatureVendorXSfvfexp16e,660    RISCV::FeatureVendorXSfvfexp32e};661static constexpr FeatureBitset XSfSystemGroup = {662    RISCV::FeatureVendorXSiFivecdiscarddlone,663    RISCV::FeatureVendorXSiFivecflushdlone,664};665 666static constexpr FeatureBitset XMIPSGroup = {667    RISCV::FeatureVendorXMIPSLSP,668    RISCV::FeatureVendorXMIPSCMov,669    RISCV::FeatureVendorXMIPSCBOP,670    RISCV::FeatureVendorXMIPSEXECTL,671};672 673static constexpr FeatureBitset XTHeadGroup = {674    RISCV::FeatureVendorXTHeadBa,      RISCV::FeatureVendorXTHeadBb,675    RISCV::FeatureVendorXTHeadBs,      RISCV::FeatureVendorXTHeadCondMov,676    RISCV::FeatureVendorXTHeadCmo,     RISCV::FeatureVendorXTHeadFMemIdx,677    RISCV::FeatureVendorXTHeadMac,     RISCV::FeatureVendorXTHeadMemIdx,678    RISCV::FeatureVendorXTHeadMemPair, RISCV::FeatureVendorXTHeadSync,679    RISCV::FeatureVendorXTHeadVdot};680 681static constexpr FeatureBitset XAndesGroup = {682    RISCV::FeatureVendorXAndesPerf,      RISCV::FeatureVendorXAndesBFHCvt,683    RISCV::FeatureVendorXAndesVBFHCvt,   RISCV::FeatureVendorXAndesVSIntH,684    RISCV::FeatureVendorXAndesVSIntLoad, RISCV::FeatureVendorXAndesVPackFPH,685    RISCV::FeatureVendorXAndesVDot};686 687static constexpr FeatureBitset XSMTGroup = {RISCV::FeatureVendorXSMTVDot};688 689static constexpr DecoderListEntry DecoderList32[]{690    // Vendor Extensions691    {DecoderTableXCV32, XCVFeatureGroup, "CORE-V extensions"},692    {DecoderTableXRivos32, XRivosFeatureGroup, "Rivos"},693    {DecoderTableXqci32, XqciFeatureGroup, "Qualcomm uC Extensions"},694    {DecoderTableXVentana32,695     {RISCV::FeatureVendorXVentanaCondOps},696     "XVentanaCondOps"},697    {DecoderTableXTHead32, XTHeadGroup, "T-Head extensions"},698    {DecoderTableXSfvector32, XSfVectorGroup, "SiFive vector extensions"},699    {DecoderTableXSfsystem32, XSfSystemGroup, "SiFive system extensions"},700    {DecoderTableXSfcease32, {RISCV::FeatureVendorXSfcease}, "SiFive sf.cease"},701    {DecoderTableXMIPS32, XMIPSGroup, "Mips extensions"},702    {DecoderTableXAndes32, XAndesGroup, "Andes extensions"},703    {DecoderTableXSMT32, XSMTGroup, "SpacemiT extensions"},704    // Standard Extensions705    {DecoderTable32, {}, "standard 32-bit instructions"},706    {DecoderTableRV32Only32, {}, "RV32-only standard 32-bit instructions"},707    {DecoderTableZfinx32, {}, "Zfinx (Float in Integer)"},708    {DecoderTableZdinxRV32Only32, {}, "RV32-only Zdinx (Double in Integer)"},709};710 711namespace {712// Define bitwidths for various types used to instantiate the decoder.713template <> constexpr uint32_t InsnBitWidth<uint16_t> = 16;714template <> constexpr uint32_t InsnBitWidth<uint32_t> = 32;715// Use uint64_t to represent 48 bit instructions.716template <> constexpr uint32_t InsnBitWidth<uint64_t> = 48;717} // namespace718 719DecodeStatus RISCVDisassembler::getInstruction32(MCInst &MI, uint64_t &Size,720                                                 ArrayRef<uint8_t> Bytes,721                                                 uint64_t Address,722                                                 raw_ostream &CS) const {723  if (Bytes.size() < 4) {724    Size = 0;725    return MCDisassembler::Fail;726  }727  Size = 4;728 729  uint32_t Insn = support::endian::read32le(Bytes.data());730 731  for (const DecoderListEntry &Entry : DecoderList32) {732    if (!Entry.haveContainedFeatures(STI.getFeatureBits()))733      continue;734 735    LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");736    DecodeStatus Result =737        decodeInstruction(Entry.Table, MI, Insn, Address, this, STI);738    if (Result == MCDisassembler::Fail)739      continue;740 741    return Result;742  }743 744  return MCDisassembler::Fail;745}746 747static constexpr DecoderListEntry DecoderList16[]{748    // Vendor Extensions749    {DecoderTableXqci16, XqciFeatureGroup, "Qualcomm uC 16-bit"},750    {DecoderTableXqccmp16,751     {RISCV::FeatureVendorXqccmp},752     "Xqccmp (Qualcomm 16-bit Push/Pop & Double Move Instructions)"},753    {DecoderTableXwchc16, {RISCV::FeatureVendorXwchc}, "WCH QingKe XW"},754    // Standard Extensions755    // DecoderTableZicfiss16 must be checked before DecoderTable16.756    {DecoderTableZicfiss16, {}, "Zicfiss (Shadow Stack 16-bit)"},757    {DecoderTable16, {}, "standard 16-bit instructions"},758    {DecoderTableRV32Only16, {}, "RV32-only 16-bit instructions"},759    // Zc* instructions incompatible with Zcf or Zcd760    {DecoderTableZcOverlap16,761     {},762     "ZcOverlap (16-bit Instructions overlapping with Zcf/Zcd)"},763};764 765DecodeStatus RISCVDisassembler::getInstruction16(MCInst &MI, uint64_t &Size,766                                                 ArrayRef<uint8_t> Bytes,767                                                 uint64_t Address,768                                                 raw_ostream &CS) const {769  if (Bytes.size() < 2) {770    Size = 0;771    return MCDisassembler::Fail;772  }773  Size = 2;774 775  uint16_t Insn = support::endian::read16le(Bytes.data());776 777  for (const DecoderListEntry &Entry : DecoderList16) {778    if (!Entry.haveContainedFeatures(STI.getFeatureBits()))779      continue;780 781    LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");782    DecodeStatus Result =783        decodeInstruction(Entry.Table, MI, Insn, Address, this, STI);784    if (Result != MCDisassembler::Fail)785      return Result;786  }787 788  return MCDisassembler::Fail;789}790 791static constexpr DecoderListEntry DecoderList48[]{792    {DecoderTableXqci48, XqciFeatureGroup, "Qualcomm uC 48bit"},793};794 795DecodeStatus RISCVDisassembler::getInstruction48(MCInst &MI, uint64_t &Size,796                                                 ArrayRef<uint8_t> Bytes,797                                                 uint64_t Address,798                                                 raw_ostream &CS) const {799  if (Bytes.size() < 6) {800    Size = 0;801    return MCDisassembler::Fail;802  }803  Size = 6;804 805  uint64_t Insn = 0;806  for (size_t i = Size; i-- != 0;)807    Insn += (static_cast<uint64_t>(Bytes[i]) << 8 * i);808 809  for (const DecoderListEntry &Entry : DecoderList48) {810    if (!Entry.haveContainedFeatures(STI.getFeatureBits()))811      continue;812 813    LLVM_DEBUG(dbgs() << "Trying " << Entry.Desc << " table:\n");814    DecodeStatus Result =815        decodeInstruction(Entry.Table, MI, Insn, Address, this, STI);816    if (Result == MCDisassembler::Fail)817      continue;818 819    return Result;820  }821 822  return MCDisassembler::Fail;823}824 825DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,826                                               ArrayRef<uint8_t> Bytes,827                                               uint64_t Address,828                                               raw_ostream &CS) const {829  CommentStream = &CS;830  // It's a 16 bit instruction if bit 0 and 1 are not 0b11.831  if ((Bytes[0] & 0b11) != 0b11)832    return getInstruction16(MI, Size, Bytes, Address, CS);833 834  // It's a 32 bit instruction if bit 1:0 are 0b11(checked above) and bits 4:2835  // are not 0b111.836  if ((Bytes[0] & 0b1'1100) != 0b1'1100)837    return getInstruction32(MI, Size, Bytes, Address, CS);838 839  // 48-bit instructions are encoded as 0bxx011111.840  if ((Bytes[0] & 0b11'1111) == 0b01'1111) {841    return getInstruction48(MI, Size, Bytes, Address, CS);842  }843 844  // 64-bit instructions are encoded as 0x0111111.845  if ((Bytes[0] & 0b111'1111) == 0b011'1111) {846    Size = Bytes.size() >= 8 ? 8 : 0;847    return MCDisassembler::Fail;848  }849 850  // Remaining cases need to check a second byte.851  if (Bytes.size() < 2) {852    Size = 0;853    return MCDisassembler::Fail;854  }855 856  // 80-bit through 176-bit instructions are encoded as 0bxnnnxxxx_x1111111.857  // Where the number of bits is (80 + (nnn * 16)) for nnn != 0b111.858  unsigned nnn = (Bytes[1] >> 4) & 0b111;859  if (nnn != 0b111) {860    Size = 10 + (nnn * 2);861    if (Bytes.size() < Size)862      Size = 0;863    return MCDisassembler::Fail;864  }865 866  // Remaining encodings are reserved for > 176-bit instructions.867  Size = 0;868  return MCDisassembler::Fail;869}870