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/MemoryObject.h"
     23 #include "llvm/Support/TargetRegistry.h"
     24 
     25 using namespace llvm;
     26 
     27 typedef MCDisassembler::DecodeStatus DecodeStatus;
     28 
     29 namespace llvm {
     30 extern Target TheLanaiTarget;
     31 }
     32 
     33 static MCDisassembler *createLanaiDisassembler(const Target &T,
     34                                                const MCSubtargetInfo &STI,
     35                                                MCContext &Ctx) {
     36   return new LanaiDisassembler(STI, Ctx);
     37 }
     38 
     39 extern "C" void LLVMInitializeLanaiDisassembler() {
     40   // Register the disassembler
     41   TargetRegistry::RegisterMCDisassembler(TheLanaiTarget,
     42                                          createLanaiDisassembler);
     43 }
     44 
     45 LanaiDisassembler::LanaiDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
     46     : MCDisassembler(STI, Ctx) {}
     47 
     48 // Forward declare because the autogenerated code will reference this.
     49 // Definition is further down.
     50 DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
     51                                     uint64_t Address, 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 Address,
     75                                       uint64_t &Size, 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(MCInst &Instr, uint64_t &Size,
    131                                                ArrayRef<uint8_t> Bytes,
    132                                                uint64_t Address,
    133                                                raw_ostream &VStream,
    134                                                raw_ostream &CStream) const {
    135   uint32_t Insn;
    136 
    137   DecodeStatus Result = readInstruction32(Bytes, Address, Size, Insn);
    138 
    139   if (Result == MCDisassembler::Fail)
    140     return MCDisassembler::Fail;
    141 
    142   // Call auto-generated decoder function
    143   Result =
    144       decodeInstruction(DecoderTableLanai32, Instr, Insn, Address, this, STI);
    145 
    146   if (Result != MCDisassembler::Fail) {
    147     PostOperandDecodeAdjust(Instr, Insn);
    148     Size = 4;
    149     return Result;
    150   }
    151 
    152   return MCDisassembler::Fail;
    153 }
    154 
    155 static const unsigned GPRDecoderTable[] = {
    156     Lanai::R0,  Lanai::R1,  Lanai::PC,  Lanai::R3,  Lanai::SP,  Lanai::FP,
    157     Lanai::R6,  Lanai::R7,  Lanai::RV,  Lanai::R9,  Lanai::RR1, Lanai::RR2,
    158     Lanai::R12, Lanai::R13, Lanai::R14, Lanai::RCA, Lanai::R16, Lanai::R17,
    159     Lanai::R18, Lanai::R19, Lanai::R20, Lanai::R21, Lanai::R22, Lanai::R23,
    160     Lanai::R24, Lanai::R25, Lanai::R26, Lanai::R27, Lanai::R28, Lanai::R29,
    161     Lanai::R30, Lanai::R31};
    162 
    163 DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
    164                                     uint64_t Address, const void *Decoder) {
    165   if (RegNo > 31)
    166     return MCDisassembler::Fail;
    167 
    168   unsigned Reg = GPRDecoderTable[RegNo];
    169   Inst.addOperand(MCOperand::createReg(Reg));
    170   return MCDisassembler::Success;
    171 }
    172 
    173 static DecodeStatus decodeRiMemoryValue(MCInst &Inst, unsigned Insn,
    174                                         uint64_t Address, const void *Decoder) {
    175   // RI memory values encoded using 23 bits:
    176   //   5 bit register, 16 bit constant
    177   unsigned Register = (Insn >> 18) & 0x1f;
    178   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
    179   unsigned Offset = (Insn & 0xffff);
    180   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
    181 
    182   return MCDisassembler::Success;
    183 }
    184 
    185 static DecodeStatus decodeRrMemoryValue(MCInst &Inst, unsigned Insn,
    186                                         uint64_t Address, const void *Decoder) {
    187   // RR memory values encoded using 20 bits:
    188   //   5 bit register, 5 bit register, 2 bit PQ, 3 bit ALU operator, 5 bit JJJJJ
    189   unsigned Register = (Insn >> 15) & 0x1f;
    190   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
    191   Register = (Insn >> 10) & 0x1f;
    192   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
    193 
    194   return MCDisassembler::Success;
    195 }
    196 
    197 static DecodeStatus decodeSplsValue(MCInst &Inst, unsigned Insn,
    198                                     uint64_t Address, const void *Decoder) {
    199   // RI memory values encoded using 17 bits:
    200   //   5 bit register, 10 bit constant
    201   unsigned Register = (Insn >> 12) & 0x1f;
    202   Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Register]));
    203   unsigned Offset = (Insn & 0x3ff);
    204   Inst.addOperand(MCOperand::createImm(SignExtend32<10>(Offset)));
    205 
    206   return MCDisassembler::Success;
    207 }
    208 
    209 static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
    210                                      uint64_t Address, uint64_t Offset,
    211                                      uint64_t Width, MCInst &MI,
    212                                      const void *Decoder) {
    213   const MCDisassembler *Dis = static_cast<const MCDisassembler *>(Decoder);
    214   return Dis->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
    215                                        Width);
    216 }
    217 
    218 static DecodeStatus decodeBranch(MCInst &MI, unsigned Insn, uint64_t Address,
    219                                  const void *Decoder) {
    220   if (!tryAddingSymbolicOperand(Insn + Address, false, Address, 2, 23, MI,
    221                                 Decoder))
    222     MI.addOperand(MCOperand::createImm(Insn));
    223   return MCDisassembler::Success;
    224 }
    225 
    226 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
    227                                    uint64_t Address, const void *Decoder) {
    228   unsigned Offset = (Insn & 0xffff);
    229   Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Offset)));
    230 
    231   return MCDisassembler::Success;
    232 }
    233 
    234 static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
    235                                            uint64_t Address,
    236                                            const void *Decoder) {
    237   if (Val >= LPCC::UNKNOWN)
    238     return MCDisassembler::Fail;
    239   Inst.addOperand(MCOperand::createImm(Val));
    240   return MCDisassembler::Success;
    241 }
    242