Home | History | Annotate | Download | only in Disassembler
      1 //===- LanaiDisassembler.cpp - Disassembler for Lanai -----------*- C++ -*-===//
      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 is part of the Lanai Disassembler.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "LanaiDisassembler.h"
     15 
     16 #include "Lanai.h"
     17 #include "LanaiSubtarget.h"
     18 #include "llvm/MC/MCFixedLenDisassembler.h"
     19 #include "llvm/MC/MCInst.h"
     20 #include "llvm/MC/MCSubtargetInfo.h"
     21 #include "llvm/Support/MathExtras.h"
     22 #include "llvm/Support/TargetRegistry.h"
     23 
     24 using namespace llvm;
     25 
     26 typedef MCDisassembler::DecodeStatus DecodeStatus;
     27 
     28 namespace llvm {
     29 Target &getTheLanaiTarget();
     30 }
     31 
     32 static MCDisassembler *createLanaiDisassembler(const Target & /*T*/,
     33                                                const MCSubtargetInfo &STI,
     34                                                MCContext &Ctx) {
     35   return new LanaiDisassembler(STI, Ctx);
     36 }
     37 
     38 extern "C" void LLVMInitializeLanaiDisassembler() {
     39   // Register the disassembler
     40   TargetRegistry::RegisterMCDisassembler(getTheLanaiTarget(),
     41                                          createLanaiDisassembler);
     42 }
     43 
     44 LanaiDisassembler::LanaiDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
     45     : MCDisassembler(STI, Ctx) {}
     46 
     47 // Forward declare because the autogenerated code will reference this.
     48 // Definition is further down.
     49 static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
     50                                            uint64_t Address,
     51                                            const void *Decoder);
     52 
     53 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
     54                                         uint64_t Address, const void *Decoder);
     55 
     56 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
     57                                         uint64_t Address, const void *Decoder);
     58 
     59 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
     60                                     uint64_t Address, const void *Decoder);
     61 
     62 static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address,
     63                                  const void *Decoder);
     64 
     65 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
     66                                            uint64_t Address,
     67                                            const void *Decoder);
     68 
     69 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
     70                                    uint64_t Address, const void *Decoder);
     71 
     72 #include "LanaiGenDisassemblerTables.inc"
     73 
     74 static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t &Size,
     75                                       uint32_t &Insn) {
     76   // We want to read exactly 4 bytes of data.
     77   if (Bytes.size() < 4) {
     78     Size = 0;
     79     return MCDisassembler::Fail;
     80   }
     81 
     82   // Encoded as big-endian 32-bit word in the stream.
     83   Insn =
     84       (Bytes[0] << 24) | (Bytes[1] << 16) | (Bytes[2] << 8) | (Bytes[3] << 0);
     85 
     86   return MCDisassembler::Success;
     87 }
     88 
     89 static void PostOperandDecodeAdjust(MCInst &Instr, uint32_t Insn) {
     90   unsigned AluOp = LPAC::ADD;
     91   // Fix up for pre and post operations.
     92   int PqShift = -1;
     93   if (isRMOpcode(Instr.getOpcode()))
     94     PqShift = 16;
     95   else if (isSPLSOpcode(Instr.getOpcode()))
     96     PqShift = 10;
     97   else if (isRRMOpcode(Instr.getOpcode())) {
     98     PqShift = 16;
     99     // Determine RRM ALU op.
    100     AluOp = (Insn >> 8) & 0x7;
    101     if (AluOp == 7)
    102       // Handle JJJJJ
    103       // 0b10000 or 0b11000
    104       AluOp |= 0x20 | (((Insn >> 3) & 0xf) << 1);
    105   }
    106 
    107   if (PqShift != -1) {
    108     unsigned PQ = (Insn >> PqShift) & 0x3;
    109     switch (PQ) {
    110     case 0x0:
    111       if (Instr.getOperand(2).isReg()) {
    112         Instr.getOperand(2).setReg(Lanai::R0);
    113       }
    114       if (Instr.getOperand(2).isImm())
    115         Instr.getOperand(2).setImm(0);
    116       break;
    117     case 0x1:
    118       AluOp = LPAC::makePostOp(AluOp);
    119       break;
    120     case 0x2:
    121       break;
    122     case 0x3:
    123       AluOp = LPAC::makePreOp(AluOp);
    124       break;
    125     }
    126     Instr.addOperand(MCOperand::createImm(AluOp));
    127   }
    128 }
    129 
    130 DecodeStatus LanaiDisassembler::getInstruction(
    131     MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address,
    132     raw_ostream & /*VStream*/, raw_ostream & /*CStream*/) const {
    133   uint32_t Insn;
    134 
    135   DecodeStatus Result = readInstruction32(Bytes, Size, Insn);
    136 
    137   if (Result == MCDisassembler::Fail)
    138     return MCDisassembler::Fail;
    139 
    140   // Call auto-generated decoder function
    141   Result =
    142       decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI);
    143 
    144   if (Result != MCDisassembler::Fail) {
    145     PostOperandDecodeAdjust(Instr, Insn);
    146     Size = 4;
    147     return Result;
    148   }
    149 
    150   return MCDisassembler::Fail;
    151 }
    152 
    153 static const unsigned GPRDecoderTable[] = {
    154     Lanai::R0,  Lanai::R1,  Lanai::PC,  Lanai::R3,  Lanai::SP,  Lanai::FP,
    155     Lanai::R6,  Lanai::R7,  Lanai::RV,  Lanai::R9,  Lanai::RR1, Lanai::RR2,
    156     Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17,
    157     Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23,
    158     Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29,
    159     Lanai::R30, Lanai::R31};
    160 
    161 DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
    162                                     uint64_t /*Address*/,
    163                                     const void * /*Decoder*/) {
    164   if (RegNo > 31)
    165     return MCDisassembler::Fail;
    166 
    167   unsigned Reg = GPRDecoderTable[RegNo];
    168   Inst.addOperand(MCOperand::createReg(Reg));
    169   return MCDisassembler::Success;
    170 }
    171 
    172 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
    173                                         uint64_t Address, const void *Decoder) {
    174   // RI memory values encoded using 23 bits:
    175   //   5 bit register, 16 bit constant
    176   unsigned Register = (Insn >> 18) & 0x1f;
    177   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
    178   unsigned Offset = (Insn & 0xffff);
    179   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
    180 
    181   return MCDisassembler::Success;
    182 }
    183 
    184 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
    185                                         uint64_t Address, const void *Decoder) {
    186   // RR memory values encoded using 20 bits:
    187   //   5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ
    188   unsigned Register = (Insn >> 15) & 0x1f;
    189   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
    190   Register = (Insn >> 10) & 0x1f;
    191   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
    192 
    193   return MCDisassembler::Success;
    194 }
    195 
    196 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
    197                                     uint64_t Address, const void *Decoder) {
    198   // RI memory values encoded using 17 bits:
    199   //   5 bit register, 10 bit constant
    200   unsigned Register = (Insn >> 12) & 0x1f;
    201   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
    202   unsigned Offset = (Insn & 0x3ff);
    203   Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset)));
    204 
    205   return MCDisassembler::Success;
    206 }
    207 
    208 static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
    209                                      uint64_t Address, uint64_t Offset,
    210                                      uint64_t Width, MCInst &MI,
    211                                      const void *Decoder) {
    212   const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder);
    213   return Dis->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
    214                                        Width);
    215 }
    216 
    217 static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address,
    218                                  const void *Decoder) {
    219   if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI,
    220                                 Decoder))
    221     MI.addOperand(MCOperand::createImm(Insn));
    222   return MCDisassembler::Success;
    223 }
    224 
    225 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
    226                                    uint64_t Address, const void *Decoder) {
    227   unsigned Offset = (Insn & 0xffff);
    228   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
    229 
    230   return MCDisassembler::Success;
    231 }
    232 
    233 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
    234                                            uint64_t Address,
    235                                            const void *Decoder) {
    236   if (Val >= LPCC::UNKNOWN)
    237     return MCDisassembler::Fail;
    238   Inst.addOperand(MCOperand::createImm(Val));
    239   return MCDisassembler::Success;
    240 }
    241