brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.1 KiB · b4dadaa Raw
347 lines · cpp
1//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- 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 Sparc Disassembler.10//11//===----------------------------------------------------------------------===//12 13#include "MCTargetDesc/SparcMCTargetDesc.h"14#include "TargetInfo/SparcTargetInfo.h"15#include "llvm/MC/MCAsmInfo.h"16#include "llvm/MC/MCContext.h"17#include "llvm/MC/MCDecoder.h"18#include "llvm/MC/MCDecoderOps.h"19#include "llvm/MC/MCDisassembler/MCDisassembler.h"20#include "llvm/MC/MCInst.h"21#include "llvm/MC/TargetRegistry.h"22#include "llvm/Support/Compiler.h"23#include "llvm/Support/Endian.h"24 25using namespace llvm;26using namespace llvm::MCD;27 28#define DEBUG_TYPE "sparc-disassembler"29 30typedef MCDisassembler::DecodeStatus DecodeStatus;31 32namespace {33 34/// A disassembler class for Sparc.35class SparcDisassembler : public MCDisassembler {36public:37  SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)38      : MCDisassembler(STI, Ctx) {}39  ~SparcDisassembler() override = default;40 41  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,42                              ArrayRef<uint8_t> Bytes, uint64_t Address,43                              raw_ostream &CStream) const override;44};45}46 47static MCDisassembler *createSparcDisassembler(const Target &T,48                                               const MCSubtargetInfo &STI,49                                               MCContext &Ctx) {50  return new SparcDisassembler(STI, Ctx);51}52 53extern "C" LLVM_ABI LLVM_EXTERNAL_VISIBILITY void54LLVMInitializeSparcDisassembler() {55  // Register the disassembler.56  TargetRegistry::RegisterMCDisassembler(getTheSparcTarget(),57                                         createSparcDisassembler);58  TargetRegistry::RegisterMCDisassembler(getTheSparcV9Target(),59                                         createSparcDisassembler);60  TargetRegistry::RegisterMCDisassembler(getTheSparcelTarget(),61                                         createSparcDisassembler);62}63 64// clang-format off65static constexpr unsigned IntRegDecoderTable[] = {66  SP::G0,  SP::G1,  SP::G2,  SP::G3,67  SP::G4,  SP::G5,  SP::G6,  SP::G7,68  SP::O0,  SP::O1,  SP::O2,  SP::O3,69  SP::O4,  SP::O5,  SP::O6,  SP::O7,70  SP::L0,  SP::L1,  SP::L2,  SP::L3,71  SP::L4,  SP::L5,  SP::L6,  SP::L7,72  SP::I0,  SP::I1,  SP::I2,  SP::I3,73  SP::I4,  SP::I5,  SP::I6,  SP::I7 };74 75static constexpr unsigned FPRegDecoderTable[] = {76  SP::F0,   SP::F1,   SP::F2,   SP::F3,77  SP::F4,   SP::F5,   SP::F6,   SP::F7,78  SP::F8,   SP::F9,   SP::F10,  SP::F11,79  SP::F12,  SP::F13,  SP::F14,  SP::F15,80  SP::F16,  SP::F17,  SP::F18,  SP::F19,81  SP::F20,  SP::F21,  SP::F22,  SP::F23,82  SP::F24,  SP::F25,  SP::F26,  SP::F27,83  SP::F28,  SP::F29,  SP::F30,  SP::F31 };84 85static constexpr unsigned DFPRegDecoderTable[] = {86  SP::D0,   SP::D16,  SP::D1,   SP::D17,87  SP::D2,   SP::D18,  SP::D3,   SP::D19,88  SP::D4,   SP::D20,  SP::D5,   SP::D21,89  SP::D6,   SP::D22,  SP::D7,   SP::D23,90  SP::D8,   SP::D24,  SP::D9,   SP::D25,91  SP::D10,  SP::D26,  SP::D11,  SP::D27,92  SP::D12,  SP::D28,  SP::D13,  SP::D29,93  SP::D14,  SP::D30,  SP::D15,  SP::D31 };94 95static constexpr unsigned QFPRegDecoderTable[] = {96  SP::Q0,  SP::Q8,   ~0U,  ~0U,97  SP::Q1,  SP::Q9,   ~0U,  ~0U,98  SP::Q2,  SP::Q10,  ~0U,  ~0U,99  SP::Q3,  SP::Q11,  ~0U,  ~0U,100  SP::Q4,  SP::Q12,  ~0U,  ~0U,101  SP::Q5,  SP::Q13,  ~0U,  ~0U,102  SP::Q6,  SP::Q14,  ~0U,  ~0U,103  SP::Q7,  SP::Q15,  ~0U,  ~0U } ;104 105static constexpr unsigned FCCRegDecoderTable[] = {106  SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };107 108static constexpr unsigned ASRRegDecoderTable[] = {109    SP::Y,     SP::ASR1,  SP::ASR2,  SP::ASR3,  SP::ASR4,  SP::ASR5,  SP::ASR6,110    SP::ASR7,  SP::ASR8,  SP::ASR9,  SP::ASR10, SP::ASR11, SP::ASR12, SP::ASR13,111    SP::ASR14, SP::ASR15, SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, SP::ASR20,112    SP::ASR21, SP::ASR22, SP::ASR23, SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,113    SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};114 115static constexpr unsigned PRRegDecoderTable[] = {116    SP::TPC,     SP::TNPC,       SP::TSTATE,   SP::TT,       SP::TICK,117    SP::TBA,     SP::PSTATE,     SP::TL,       SP::PIL,      SP::CWP,118    SP::CANSAVE, SP::CANRESTORE, SP::CLEANWIN, SP::OTHERWIN, SP::WSTATE};119 120static constexpr uint16_t IntPairDecoderTable[] = {121  SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7,122  SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7,123  SP::L0_L1, SP::L2_L3, SP::L4_L5, SP::L6_L7,124  SP::I0_I1, SP::I2_I3, SP::I4_I5, SP::I6_I7,125};126 127static constexpr unsigned CPRegDecoderTable[] = {128  SP::C0,  SP::C1,  SP::C2,  SP::C3,129  SP::C4,  SP::C5,  SP::C6,  SP::C7,130  SP::C8,  SP::C9,  SP::C10, SP::C11,131  SP::C12, SP::C13, SP::C14, SP::C15,132  SP::C16, SP::C17, SP::C18, SP::C19,133  SP::C20, SP::C21, SP::C22, SP::C23,134  SP::C24, SP::C25, SP::C26, SP::C27,135  SP::C28, SP::C29, SP::C30, SP::C31136};137 138static constexpr uint16_t CPPairDecoderTable[] = {139  SP::C0_C1,   SP::C2_C3,   SP::C4_C5,   SP::C6_C7,140  SP::C8_C9,   SP::C10_C11, SP::C12_C13, SP::C14_C15,141  SP::C16_C17, SP::C18_C19, SP::C20_C21, SP::C22_C23,142  SP::C24_C25, SP::C26_C27, SP::C28_C29, SP::C30_C31143};144// clang-format on145 146static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,147                                               uint64_t Address,148                                               const MCDisassembler *Decoder) {149  if (RegNo >= std::size(IntRegDecoderTable))150    return MCDisassembler::Fail;151  unsigned Reg = IntRegDecoderTable[RegNo];152  Inst.addOperand(MCOperand::createReg(Reg));153  return MCDisassembler::Success;154}155 156static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, unsigned RegNo,157                                               uint64_t Address,158                                               const MCDisassembler *Decoder) {159  return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);160}161 162static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,163                                              uint64_t Address,164                                              const MCDisassembler *Decoder) {165  if (RegNo >= std::size(FPRegDecoderTable))166    return MCDisassembler::Fail;167  unsigned Reg = FPRegDecoderTable[RegNo];168  Inst.addOperand(MCOperand::createReg(Reg));169  return MCDisassembler::Success;170}171 172static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,173                                               uint64_t Address,174                                               const MCDisassembler *Decoder) {175  if (RegNo >= std::size(DFPRegDecoderTable))176    return MCDisassembler::Fail;177  unsigned Reg = DFPRegDecoderTable[RegNo];178  Inst.addOperand(MCOperand::createReg(Reg));179  return MCDisassembler::Success;180}181 182static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,183                                               uint64_t Address,184                                               const MCDisassembler *Decoder) {185  if (RegNo >= std::size(QFPRegDecoderTable))186    return MCDisassembler::Fail;187 188  unsigned Reg = QFPRegDecoderTable[RegNo];189  if (Reg == ~0U)190    return MCDisassembler::Fail;191  Inst.addOperand(MCOperand::createReg(Reg));192  return MCDisassembler::Success;193}194 195static DecodeStatus196DecodeCoprocRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,197                              const MCDisassembler *Decoder) {198  if (RegNo >= std::size(CPRegDecoderTable))199    return MCDisassembler::Fail;200  unsigned Reg = CPRegDecoderTable[RegNo];201  Inst.addOperand(MCOperand::createReg(Reg));202  return MCDisassembler::Success;203}204 205static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,206                                               uint64_t Address,207                                               const MCDisassembler *Decoder) {208  if (RegNo >= std::size(FCCRegDecoderTable))209    return MCDisassembler::Fail;210  Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));211  return MCDisassembler::Success;212}213 214static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,215                                               uint64_t Address,216                                               const MCDisassembler *Decoder) {217  if (RegNo >= std::size(ASRRegDecoderTable))218    return MCDisassembler::Fail;219  Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));220  return MCDisassembler::Success;221}222 223static DecodeStatus DecodePRRegsRegisterClass(MCInst &Inst, unsigned RegNo,224                                              uint64_t Address,225                                              const MCDisassembler *Decoder) {226  if (RegNo >= std::size(PRRegDecoderTable))227    return MCDisassembler::Fail;228  Inst.addOperand(MCOperand::createReg(PRRegDecoderTable[RegNo]));229  return MCDisassembler::Success;230}231 232static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo,233                                               uint64_t Address,234                                               const MCDisassembler *Decoder) {235  DecodeStatus S = MCDisassembler::Success;236 237  if ((RegNo & 1))238    S = MCDisassembler::SoftFail;239 240  RegNo = RegNo / 2;241  if (RegNo >= std::size(IntPairDecoderTable))242    return MCDisassembler::Fail;243 244  unsigned RegisterPair = IntPairDecoderTable[RegNo];245  Inst.addOperand(MCOperand::createReg(RegisterPair));246  return S;247}248 249static DecodeStatus250DecodeCoprocPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,251                              const MCDisassembler *Decoder) {252  RegNo = RegNo / 2;253  if (RegNo >= std::size(CPPairDecoderTable))254    return MCDisassembler::Fail;255 256  unsigned RegisterPair = CPPairDecoderTable[RegNo];257  Inst.addOperand(MCOperand::createReg(RegisterPair));258  return MCDisassembler::Success;259}260 261static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,262                                     uint64_t Address, uint64_t Offset,263                                     uint64_t Width, MCInst &MI,264                                     const MCDisassembler *Decoder) {265  return Decoder->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset,266                                           Width, /*InstSize=*/4);267}268 269static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address,270                               const MCDisassembler *Decoder) {271  int64_t CallOffset = SignExtend64(fieldFromInstruction(insn, 0, 30), 30) * 4;272  if (!tryAddingSymbolicOperand(Address + CallOffset, false, Address, 0, 30, MI,273                                Decoder))274    MI.addOperand(MCOperand::createImm(CallOffset));275  return MCDisassembler::Success;276}277 278static DecodeStatus DecodeSIMM5(MCInst &MI, unsigned insn, uint64_t Address,279                                const MCDisassembler *Decoder) {280  assert(isUInt<5>(insn));281  MI.addOperand(MCOperand::createImm(SignExtend64<5>(insn)));282  return MCDisassembler::Success;283}284 285static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address,286                                 const MCDisassembler *Decoder) {287  assert(isUInt<13>(insn));288  MI.addOperand(MCOperand::createImm(SignExtend64<13>(insn)));289  return MCDisassembler::Success;290}291 292template <unsigned N>293static DecodeStatus DecodeDisp(MCInst &MI, uint32_t ImmVal, uint64_t Address,294                               const MCDisassembler *Decoder) {295  int64_t BranchOffset = SignExtend64(ImmVal, N) * 4;296  if (!tryAddingSymbolicOperand(Address + BranchOffset, true, Address, 0, N, MI,297                                Decoder))298    MI.addOperand(MCOperand::createImm(BranchOffset));299  return MCDisassembler::Success;300}301 302#include "SparcGenDisassemblerTables.inc"303 304/// Read four bytes from the ArrayRef and return 32 bit word.305static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,306                                      uint64_t &Size, uint32_t &Insn,307                                      bool IsLittleEndian) {308  // We want to read exactly 4 Bytes of data.309  if (Bytes.size() < 4) {310    Size = 0;311    return MCDisassembler::Fail;312  }313 314  Size = 4;315  Insn = support::endian::read<uint32_t>(316      Bytes.data(), IsLittleEndian ? endianness::little : endianness::big);317  return MCDisassembler::Success;318}319 320DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,321                                               ArrayRef<uint8_t> Bytes,322                                               uint64_t Address,323                                               raw_ostream &CStream) const {324  uint32_t Insn;325  bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();326  DecodeStatus Result =327      readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);328  if (Result == MCDisassembler::Fail)329    return MCDisassembler::Fail;330 331  // Calling the auto-generated decoder function.332 333  if (STI.hasFeature(Sparc::FeatureV9))334    Result = decodeInstruction(DecoderTableSparcV932, Instr, Insn, Address,335                               this, STI);336  else337    Result = decodeInstruction(DecoderTableSparcV832, Instr, Insn, Address, this, STI);338 339  if (Result != MCDisassembler::Fail)340    return Result;341 342  Result =343      decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);344 345  return Result;346}347