brintos

brintos / llvm-project-archived public Read only

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