Home | History | Annotate | Download | only in Disassembler
      1 //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the RISCVDisassembler class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "MCTargetDesc/RISCVMCTargetDesc.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 decodeSImmOperand(MCInst &Inst, uint64_t Imm,
    215                                       int64_t Address, const void *Decoder) {
    216   assert(isUInt<N>(Imm) && "Invalid immediate");
    217   addImplySP(Inst, Address, Decoder);
    218   // Sign-extend the number in the bottom N bits of Imm
    219   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
    220   return MCDisassembler::Success;
    221 }
    222 
    223 template <unsigned N>
    224 static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
    225                                              int64_t Address,
    226                                              const void *Decoder) {
    227   assert(isUInt<N>(Imm) && "Invalid immediate");
    228   // Sign-extend the number in the bottom N bits of Imm after accounting for
    229   // the fact that the N bit immediate is stored in N-1 bits (the LSB is
    230   // always zero)
    231   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
    232   return MCDisassembler::Success;
    233 }
    234 
    235 static DecodeStatus decodeCLUIImmOperand(MCInst &Inst, uint64_t Imm,
    236                                          int64_t Address,
    237                                          const void *Decoder) {
    238   assert(isUInt<6>(Imm) && "Invalid immediate");
    239   if (Imm > 31) {
    240     Imm = (SignExtend64<6>(Imm) & 0xfffff);
    241   }
    242   Inst.addOperand(MCOperand::createImm(Imm));
    243   return MCDisassembler::Success;
    244 }
    245 
    246 #include "RISCVGenDisassemblerTables.inc"
    247 
    248 DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
    249                                                ArrayRef<uint8_t> Bytes,
    250                                                uint64_t Address,
    251                                                raw_ostream &OS,
    252                                                raw_ostream &CS) const {
    253   // TODO: This will need modification when supporting instruction set
    254   // extensions with instructions > 32-bits (up to 176 bits wide).
    255   uint32_t Insn;
    256   DecodeStatus Result;
    257 
    258   // It's a 32 bit instruction if bit 0 and 1 are 1.
    259   if ((Bytes[0] & 0x3) == 0x3) {
    260     Insn = support::endian::read32le(Bytes.data());
    261     LLVM_DEBUG(dbgs() << "Trying RISCV32 table :\n");
    262     Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
    263     Size = 4;
    264   } else {
    265     Insn = support::endian::read16le(Bytes.data());
    266 
    267     if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
    268       LLVM_DEBUG(
    269           dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
    270       // Calling the auto-generated decoder function.
    271       Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
    272                                  this, STI);
    273       if (Result != MCDisassembler::Fail) {
    274         Size = 2;
    275         return Result;
    276       }
    277     }
    278 
    279     LLVM_DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
    280     // Calling the auto-generated decoder function.
    281     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
    282     Size = 2;
    283   }
    284 
    285   return Result;
    286 }
    287