12cab237bSDimitry Andric //===-- RISCVDisassembler.cpp - Disassembler for RISCV --------------------===//
22cab237bSDimitry Andric //
32cab237bSDimitry Andric //                     The LLVM Compiler Infrastructure
42cab237bSDimitry Andric //
52cab237bSDimitry Andric // This file is distributed under the University of Illinois Open Source
62cab237bSDimitry Andric // License. See LICENSE.TXT for details.
72cab237bSDimitry Andric //
82cab237bSDimitry Andric //===----------------------------------------------------------------------===//
92cab237bSDimitry Andric //
102cab237bSDimitry Andric // This file implements the RISCVDisassembler class.
112cab237bSDimitry Andric //
122cab237bSDimitry Andric //===----------------------------------------------------------------------===//
132cab237bSDimitry Andric 
142cab237bSDimitry Andric #include "MCTargetDesc/RISCVMCTargetDesc.h"
152cab237bSDimitry Andric #include "llvm/MC/MCContext.h"
162cab237bSDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
172cab237bSDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
182cab237bSDimitry Andric #include "llvm/MC/MCInst.h"
192cab237bSDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
202cab237bSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
212cab237bSDimitry Andric #include "llvm/Support/Endian.h"
222cab237bSDimitry Andric #include "llvm/Support/TargetRegistry.h"
232cab237bSDimitry Andric 
242cab237bSDimitry Andric using namespace llvm;
252cab237bSDimitry Andric 
262cab237bSDimitry Andric #define DEBUG_TYPE "riscv-disassembler"
272cab237bSDimitry Andric 
282cab237bSDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
292cab237bSDimitry Andric 
302cab237bSDimitry Andric namespace {
312cab237bSDimitry Andric class RISCVDisassembler : public MCDisassembler {
322cab237bSDimitry Andric 
332cab237bSDimitry Andric public:
342cab237bSDimitry Andric   RISCVDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
352cab237bSDimitry Andric       : MCDisassembler(STI, Ctx) {}
362cab237bSDimitry Andric 
372cab237bSDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
382cab237bSDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
392cab237bSDimitry Andric                               raw_ostream &VStream,
402cab237bSDimitry Andric                               raw_ostream &CStream) const override;
412cab237bSDimitry Andric };
422cab237bSDimitry Andric } // end anonymous namespace
432cab237bSDimitry Andric 
442cab237bSDimitry Andric static MCDisassembler *createRISCVDisassembler(const Target &T,
452cab237bSDimitry Andric                                                const MCSubtargetInfo &STI,
462cab237bSDimitry Andric                                                MCContext &Ctx) {
472cab237bSDimitry Andric   return new RISCVDisassembler(STI, Ctx);
482cab237bSDimitry Andric }
492cab237bSDimitry Andric 
502cab237bSDimitry Andric extern "C" void LLVMInitializeRISCVDisassembler() {
512cab237bSDimitry Andric   // Register the disassembler for each target.
522cab237bSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheRISCV32Target(),
532cab237bSDimitry Andric                                          createRISCVDisassembler);
542cab237bSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheRISCV64Target(),
552cab237bSDimitry Andric                                          createRISCVDisassembler);
562cab237bSDimitry Andric }
572cab237bSDimitry Andric 
582cab237bSDimitry Andric static const unsigned GPRDecoderTable[] = {
592cab237bSDimitry Andric   RISCV::X0,  RISCV::X1,  RISCV::X2,  RISCV::X3,
602cab237bSDimitry Andric   RISCV::X4,  RISCV::X5,  RISCV::X6,  RISCV::X7,
612cab237bSDimitry Andric   RISCV::X8,  RISCV::X9,  RISCV::X10, RISCV::X11,
622cab237bSDimitry Andric   RISCV::X12, RISCV::X13, RISCV::X14, RISCV::X15,
632cab237bSDimitry Andric   RISCV::X16, RISCV::X17, RISCV::X18, RISCV::X19,
642cab237bSDimitry Andric   RISCV::X20, RISCV::X21, RISCV::X22, RISCV::X23,
652cab237bSDimitry Andric   RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27,
662cab237bSDimitry Andric   RISCV::X28, RISCV::X29, RISCV::X30, RISCV::X31
672cab237bSDimitry Andric };
682cab237bSDimitry Andric 
692cab237bSDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,
702cab237bSDimitry Andric                                            uint64_t Address,
712cab237bSDimitry Andric                                            const void *Decoder) {
722cab237bSDimitry Andric   if (RegNo > sizeof(GPRDecoderTable))
732cab237bSDimitry Andric     return MCDisassembler::Fail;
742cab237bSDimitry Andric 
752cab237bSDimitry Andric   // We must define our own mapping from RegNo to register identifier.
762cab237bSDimitry Andric   // Accessing index RegNo in the register class will work in the case that
772cab237bSDimitry Andric   // registers were added in ascending order, but not in general.
782cab237bSDimitry Andric   unsigned Reg = GPRDecoderTable[RegNo];
792cab237bSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
802cab237bSDimitry Andric   return MCDisassembler::Success;
812cab237bSDimitry Andric }
822cab237bSDimitry Andric 
832cab237bSDimitry Andric static const unsigned FPR32DecoderTable[] = {
842cab237bSDimitry Andric   RISCV::F0_32,  RISCV::F1_32,  RISCV::F2_32,  RISCV::F3_32,
852cab237bSDimitry Andric   RISCV::F4_32,  RISCV::F5_32,  RISCV::F6_32,  RISCV::F7_32,
862cab237bSDimitry Andric   RISCV::F8_32,  RISCV::F9_32,  RISCV::F10_32, RISCV::F11_32,
872cab237bSDimitry Andric   RISCV::F12_32, RISCV::F13_32, RISCV::F14_32, RISCV::F15_32,
882cab237bSDimitry Andric   RISCV::F16_32, RISCV::F17_32, RISCV::F18_32, RISCV::F19_32,
892cab237bSDimitry Andric   RISCV::F20_32, RISCV::F21_32, RISCV::F22_32, RISCV::F23_32,
902cab237bSDimitry Andric   RISCV::F24_32, RISCV::F25_32, RISCV::F26_32, RISCV::F27_32,
912cab237bSDimitry Andric   RISCV::F28_32, RISCV::F29_32, RISCV::F30_32, RISCV::F31_32
922cab237bSDimitry Andric };
932cab237bSDimitry Andric 
942cab237bSDimitry Andric static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,
952cab237bSDimitry Andric                                              uint64_t Address,
962cab237bSDimitry Andric                                              const void *Decoder) {
972cab237bSDimitry Andric   if (RegNo > sizeof(FPR32DecoderTable))
982cab237bSDimitry Andric     return MCDisassembler::Fail;
992cab237bSDimitry Andric 
1002cab237bSDimitry Andric   // We must define our own mapping from RegNo to register identifier.
1012cab237bSDimitry Andric   // Accessing index RegNo in the register class will work in the case that
1022cab237bSDimitry Andric   // registers were added in ascending order, but not in general.
1032cab237bSDimitry Andric   unsigned Reg = FPR32DecoderTable[RegNo];
1042cab237bSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1052cab237bSDimitry Andric   return MCDisassembler::Success;
1062cab237bSDimitry Andric }
1072cab237bSDimitry Andric 
1082cab237bSDimitry Andric static DecodeStatus DecodeFPR32CRegisterClass(MCInst &Inst, uint64_t RegNo,
1092cab237bSDimitry Andric                                               uint64_t Address,
1102cab237bSDimitry Andric                                               const void *Decoder) {
1112cab237bSDimitry Andric   if (RegNo > 8) {
1122cab237bSDimitry Andric     return MCDisassembler::Fail;
1132cab237bSDimitry Andric   }
1142cab237bSDimitry Andric   unsigned Reg = FPR32DecoderTable[RegNo + 8];
1152cab237bSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1162cab237bSDimitry Andric   return MCDisassembler::Success;
1172cab237bSDimitry Andric }
1182cab237bSDimitry Andric 
1192cab237bSDimitry Andric static const unsigned FPR64DecoderTable[] = {
1202cab237bSDimitry Andric   RISCV::F0_64,  RISCV::F1_64,  RISCV::F2_64,  RISCV::F3_64,
1212cab237bSDimitry Andric   RISCV::F4_64,  RISCV::F5_64,  RISCV::F6_64,  RISCV::F7_64,
1222cab237bSDimitry Andric   RISCV::F8_64,  RISCV::F9_64,  RISCV::F10_64, RISCV::F11_64,
1232cab237bSDimitry Andric   RISCV::F12_64, RISCV::F13_64, RISCV::F14_64, RISCV::F15_64,
1242cab237bSDimitry Andric   RISCV::F16_64, RISCV::F17_64, RISCV::F18_64, RISCV::F19_64,
1252cab237bSDimitry Andric   RISCV::F20_64, RISCV::F21_64, RISCV::F22_64, RISCV::F23_64,
1262cab237bSDimitry Andric   RISCV::F24_64, RISCV::F25_64, RISCV::F26_64, RISCV::F27_64,
1272cab237bSDimitry Andric   RISCV::F28_64, RISCV::F29_64, RISCV::F30_64, RISCV::F31_64
1282cab237bSDimitry Andric };
1292cab237bSDimitry Andric 
1302cab237bSDimitry Andric static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,
1312cab237bSDimitry Andric                                              uint64_t Address,
1322cab237bSDimitry Andric                                              const void *Decoder) {
1332cab237bSDimitry Andric   if (RegNo > sizeof(FPR64DecoderTable))
1342cab237bSDimitry Andric     return MCDisassembler::Fail;
1352cab237bSDimitry Andric 
1362cab237bSDimitry Andric   // We must define our own mapping from RegNo to register identifier.
1372cab237bSDimitry Andric   // Accessing index RegNo in the register class will work in the case that
1382cab237bSDimitry Andric   // registers were added in ascending order, but not in general.
1392cab237bSDimitry Andric   unsigned Reg = FPR64DecoderTable[RegNo];
1402cab237bSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1412cab237bSDimitry Andric   return MCDisassembler::Success;
1422cab237bSDimitry Andric }
1432cab237bSDimitry Andric 
1442cab237bSDimitry Andric static DecodeStatus DecodeFPR64CRegisterClass(MCInst &Inst, uint64_t RegNo,
1452cab237bSDimitry Andric                                               uint64_t Address,
1462cab237bSDimitry Andric                                               const void *Decoder) {
1472cab237bSDimitry Andric   if (RegNo > 8) {
1482cab237bSDimitry Andric     return MCDisassembler::Fail;
1492cab237bSDimitry Andric   }
1502cab237bSDimitry Andric   unsigned Reg = FPR64DecoderTable[RegNo + 8];
1512cab237bSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1522cab237bSDimitry Andric   return MCDisassembler::Success;
1532cab237bSDimitry Andric }
1542cab237bSDimitry Andric 
1552cab237bSDimitry Andric static DecodeStatus DecodeGPRNoX0RegisterClass(MCInst &Inst, uint64_t RegNo,
1562cab237bSDimitry Andric                                                uint64_t Address,
1572cab237bSDimitry Andric                                                const void *Decoder) {
1582cab237bSDimitry Andric   if (RegNo == 0) {
1592cab237bSDimitry Andric     return MCDisassembler::Fail;
1602cab237bSDimitry Andric   }
1612cab237bSDimitry Andric 
1622cab237bSDimitry Andric   return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
1632cab237bSDimitry Andric }
1642cab237bSDimitry Andric 
1652cab237bSDimitry Andric static DecodeStatus DecodeGPRNoX0X2RegisterClass(MCInst &Inst, uint64_t RegNo,
1662cab237bSDimitry Andric                                                  uint64_t Address,
1672cab237bSDimitry Andric                                                  const void *Decoder) {
1682cab237bSDimitry Andric   if (RegNo == 2) {
1692cab237bSDimitry Andric     return MCDisassembler::Fail;
1702cab237bSDimitry Andric   }
1712cab237bSDimitry Andric 
1722cab237bSDimitry Andric   return DecodeGPRNoX0RegisterClass(Inst, RegNo, Address, Decoder);
1732cab237bSDimitry Andric }
1742cab237bSDimitry Andric 
1752cab237bSDimitry Andric static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1762cab237bSDimitry Andric                                             uint64_t Address,
1772cab237bSDimitry Andric                                             const void *Decoder) {
1782cab237bSDimitry Andric   if (RegNo > 8)
1792cab237bSDimitry Andric     return MCDisassembler::Fail;
1802cab237bSDimitry Andric 
1812cab237bSDimitry Andric   unsigned Reg = GPRDecoderTable[RegNo + 8];
1822cab237bSDimitry Andric   Inst.addOperand(MCOperand::createReg(Reg));
1832cab237bSDimitry Andric   return MCDisassembler::Success;
1842cab237bSDimitry Andric }
1852cab237bSDimitry Andric 
1862cab237bSDimitry Andric // Add implied SP operand for instructions *SP compressed instructions. The SP
1872cab237bSDimitry Andric // operand isn't explicitly encoded in the instruction.
1882cab237bSDimitry Andric static void addImplySP(MCInst &Inst, int64_t Address, const void *Decoder) {
1892cab237bSDimitry Andric   if (Inst.getOpcode() == RISCV::C_LWSP || Inst.getOpcode() == RISCV::C_SWSP ||
1902cab237bSDimitry Andric       Inst.getOpcode() == RISCV::C_LDSP || Inst.getOpcode() == RISCV::C_SDSP ||
1912cab237bSDimitry Andric       Inst.getOpcode() == RISCV::C_FLWSP ||
1922cab237bSDimitry Andric       Inst.getOpcode() == RISCV::C_FSWSP ||
1932cab237bSDimitry Andric       Inst.getOpcode() == RISCV::C_FLDSP ||
1942cab237bSDimitry Andric       Inst.getOpcode() == RISCV::C_FSDSP ||
1952cab237bSDimitry Andric       Inst.getOpcode() == RISCV::C_ADDI4SPN) {
1962cab237bSDimitry Andric     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
1972cab237bSDimitry Andric   }
1982cab237bSDimitry Andric   if (Inst.getOpcode() == RISCV::C_ADDI16SP) {
1992cab237bSDimitry Andric     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
2002cab237bSDimitry Andric     DecodeGPRRegisterClass(Inst, 2, Address, Decoder);
2012cab237bSDimitry Andric   }
2022cab237bSDimitry Andric }
2032cab237bSDimitry Andric 
2042cab237bSDimitry Andric template <unsigned N>
2052cab237bSDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
2062cab237bSDimitry Andric                                       int64_t Address, const void *Decoder) {
2072cab237bSDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
2082cab237bSDimitry Andric   addImplySP(Inst, Address, Decoder);
2092cab237bSDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
2102cab237bSDimitry Andric   return MCDisassembler::Success;
2112cab237bSDimitry Andric }
2122cab237bSDimitry Andric 
2132cab237bSDimitry Andric template <unsigned N>
2142cab237bSDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
2152cab237bSDimitry Andric                                       int64_t Address, const void *Decoder) {
2162cab237bSDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
2172cab237bSDimitry Andric   addImplySP(Inst, Address, Decoder);
2182cab237bSDimitry Andric   // Sign-extend the number in the bottom N bits of Imm
2192cab237bSDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
2202cab237bSDimitry Andric   return MCDisassembler::Success;
2212cab237bSDimitry Andric }
2222cab237bSDimitry Andric 
2232cab237bSDimitry Andric template <unsigned N>
2242cab237bSDimitry Andric static DecodeStatus decodeSImmOperandAndLsl1(MCInst &Inst, uint64_t Imm,
2252cab237bSDimitry Andric                                              int64_t Address,
2262cab237bSDimitry Andric                                              const void *Decoder) {
2272cab237bSDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
2282cab237bSDimitry Andric   // Sign-extend the number in the bottom N bits of Imm after accounting for
2292cab237bSDimitry Andric   // the fact that the N bit immediate is stored in N-1 bits (the LSB is
2302cab237bSDimitry Andric   // always zero)
2312cab237bSDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm << 1)));
2322cab237bSDimitry Andric   return MCDisassembler::Success;
2332cab237bSDimitry Andric }
2342cab237bSDimitry Andric 
2352cab237bSDimitry Andric #include "RISCVGenDisassemblerTables.inc"
2362cab237bSDimitry Andric 
2372cab237bSDimitry Andric DecodeStatus RISCVDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
2382cab237bSDimitry Andric                                                ArrayRef<uint8_t> Bytes,
2392cab237bSDimitry Andric                                                uint64_t Address,
2402cab237bSDimitry Andric                                                raw_ostream &OS,
2412cab237bSDimitry Andric                                                raw_ostream &CS) const {
2422cab237bSDimitry Andric   // TODO: This will need modification when supporting instruction set
2432cab237bSDimitry Andric   // extensions with instructions > 32-bits (up to 176 bits wide).
2442cab237bSDimitry Andric   uint32_t Insn;
2452cab237bSDimitry Andric   DecodeStatus Result;
2462cab237bSDimitry Andric 
2472cab237bSDimitry Andric   // It's a 32 bit instruction if bit 0 and 1 are 1.
2482cab237bSDimitry Andric   if ((Bytes[0] & 0x3) == 0x3) {
2492cab237bSDimitry Andric     Insn = support::endian::read32le(Bytes.data());
2502cab237bSDimitry Andric     DEBUG(dbgs() << "Trying RISCV32 table :\n");
2512cab237bSDimitry Andric     Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
2522cab237bSDimitry Andric     Size = 4;
2532cab237bSDimitry Andric   } else {
2542cab237bSDimitry Andric     Insn = support::endian::read16le(Bytes.data());
2552cab237bSDimitry Andric 
2562cab237bSDimitry Andric     if (!STI.getFeatureBits()[RISCV::Feature64Bit]) {
2572cab237bSDimitry Andric       DEBUG(dbgs() << "Trying RISCV32Only_16 table (16-bit Instruction):\n");
2582cab237bSDimitry Andric       // Calling the auto-generated decoder function.
2592cab237bSDimitry Andric       Result = decodeInstruction(DecoderTableRISCV32Only_16, MI, Insn, Address,
2602cab237bSDimitry Andric                                  this, STI);
2612cab237bSDimitry Andric       if (Result != MCDisassembler::Fail) {
2622cab237bSDimitry Andric         Size = 2;
2632cab237bSDimitry Andric         return Result;
2642cab237bSDimitry Andric       }
2652cab237bSDimitry Andric     }
2662cab237bSDimitry Andric 
2672cab237bSDimitry Andric     DEBUG(dbgs() << "Trying RISCV_C table (16-bit Instruction):\n");
2682cab237bSDimitry Andric     // Calling the auto-generated decoder function.
2692cab237bSDimitry Andric     Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
2702cab237bSDimitry Andric     Size = 2;
2712cab237bSDimitry Andric   }
2722cab237bSDimitry Andric 
2732cab237bSDimitry Andric   return Result;
2742cab237bSDimitry Andric }
275