Path: blob/main/contrib/llvm-project/llvm/lib/Target/Sparc/Disassembler/SparcDisassembler.cpp
35293 views
//===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file is part of the Sparc Disassembler.9//10//===----------------------------------------------------------------------===//1112#include "MCTargetDesc/SparcMCTargetDesc.h"13#include "TargetInfo/SparcTargetInfo.h"14#include "llvm/MC/MCAsmInfo.h"15#include "llvm/MC/MCContext.h"16#include "llvm/MC/MCDecoderOps.h"17#include "llvm/MC/MCDisassembler/MCDisassembler.h"18#include "llvm/MC/MCInst.h"19#include "llvm/MC/TargetRegistry.h"2021using namespace llvm;2223#define DEBUG_TYPE "sparc-disassembler"2425typedef MCDisassembler::DecodeStatus DecodeStatus;2627namespace {2829/// A disassembler class for Sparc.30class SparcDisassembler : public MCDisassembler {31public:32SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)33: MCDisassembler(STI, Ctx) {}34virtual ~SparcDisassembler() = default;3536DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,37ArrayRef<uint8_t> Bytes, uint64_t Address,38raw_ostream &CStream) const override;39};40}4142static MCDisassembler *createSparcDisassembler(const Target &T,43const MCSubtargetInfo &STI,44MCContext &Ctx) {45return new SparcDisassembler(STI, Ctx);46}474849extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSparcDisassembler() {50// Register the disassembler.51TargetRegistry::RegisterMCDisassembler(getTheSparcTarget(),52createSparcDisassembler);53TargetRegistry::RegisterMCDisassembler(getTheSparcV9Target(),54createSparcDisassembler);55TargetRegistry::RegisterMCDisassembler(getTheSparcelTarget(),56createSparcDisassembler);57}5859static const unsigned IntRegDecoderTable[] = {60SP::G0, SP::G1, SP::G2, SP::G3,61SP::G4, SP::G5, SP::G6, SP::G7,62SP::O0, SP::O1, SP::O2, SP::O3,63SP::O4, SP::O5, SP::O6, SP::O7,64SP::L0, SP::L1, SP::L2, SP::L3,65SP::L4, SP::L5, SP::L6, SP::L7,66SP::I0, SP::I1, SP::I2, SP::I3,67SP::I4, SP::I5, SP::I6, SP::I7 };6869static const unsigned FPRegDecoderTable[] = {70SP::F0, SP::F1, SP::F2, SP::F3,71SP::F4, SP::F5, SP::F6, SP::F7,72SP::F8, SP::F9, SP::F10, SP::F11,73SP::F12, SP::F13, SP::F14, SP::F15,74SP::F16, SP::F17, SP::F18, SP::F19,75SP::F20, SP::F21, SP::F22, SP::F23,76SP::F24, SP::F25, SP::F26, SP::F27,77SP::F28, SP::F29, SP::F30, SP::F31 };7879static const unsigned DFPRegDecoderTable[] = {80SP::D0, SP::D16, SP::D1, SP::D17,81SP::D2, SP::D18, SP::D3, SP::D19,82SP::D4, SP::D20, SP::D5, SP::D21,83SP::D6, SP::D22, SP::D7, SP::D23,84SP::D8, SP::D24, SP::D9, SP::D25,85SP::D10, SP::D26, SP::D11, SP::D27,86SP::D12, SP::D28, SP::D13, SP::D29,87SP::D14, SP::D30, SP::D15, SP::D31 };8889static const unsigned QFPRegDecoderTable[] = {90SP::Q0, SP::Q8, ~0U, ~0U,91SP::Q1, SP::Q9, ~0U, ~0U,92SP::Q2, SP::Q10, ~0U, ~0U,93SP::Q3, SP::Q11, ~0U, ~0U,94SP::Q4, SP::Q12, ~0U, ~0U,95SP::Q5, SP::Q13, ~0U, ~0U,96SP::Q6, SP::Q14, ~0U, ~0U,97SP::Q7, SP::Q15, ~0U, ~0U } ;9899static const unsigned FCCRegDecoderTable[] = {100SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };101102static const unsigned ASRRegDecoderTable[] = {103SP::Y, SP::ASR1, SP::ASR2, SP::ASR3, SP::ASR4, SP::ASR5, SP::ASR6,104SP::ASR7, SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11, SP::ASR12, SP::ASR13,105SP::ASR14, SP::ASR15, SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19, SP::ASR20,106SP::ASR21, SP::ASR22, SP::ASR23, SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,107SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};108109static const unsigned PRRegDecoderTable[] = {110SP::TPC, SP::TNPC, SP::TSTATE, SP::TT, SP::TICK,111SP::TBA, SP::PSTATE, SP::TL, SP::PIL, SP::CWP,112SP::CANSAVE, SP::CANRESTORE, SP::CLEANWIN, SP::OTHERWIN, SP::WSTATE};113114static const uint16_t IntPairDecoderTable[] = {115SP::G0_G1, SP::G2_G3, SP::G4_G5, SP::G6_G7,116SP::O0_O1, SP::O2_O3, SP::O4_O5, SP::O6_O7,117SP::L0_L1, SP::L2_L3, SP::L4_L5, SP::L6_L7,118SP::I0_I1, SP::I2_I3, SP::I4_I5, SP::I6_I7,119};120121static const unsigned CPRegDecoderTable[] = {122SP::C0, SP::C1, SP::C2, SP::C3,123SP::C4, SP::C5, SP::C6, SP::C7,124SP::C8, SP::C9, SP::C10, SP::C11,125SP::C12, SP::C13, SP::C14, SP::C15,126SP::C16, SP::C17, SP::C18, SP::C19,127SP::C20, SP::C21, SP::C22, SP::C23,128SP::C24, SP::C25, SP::C26, SP::C27,129SP::C28, SP::C29, SP::C30, SP::C31130};131132133static const uint16_t CPPairDecoderTable[] = {134SP::C0_C1, SP::C2_C3, SP::C4_C5, SP::C6_C7,135SP::C8_C9, SP::C10_C11, SP::C12_C13, SP::C14_C15,136SP::C16_C17, SP::C18_C19, SP::C20_C21, SP::C22_C23,137SP::C24_C25, SP::C26_C27, SP::C28_C29, SP::C30_C31138};139140static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo,141uint64_t Address,142const MCDisassembler *Decoder) {143if (RegNo > 31)144return MCDisassembler::Fail;145unsigned Reg = IntRegDecoderTable[RegNo];146Inst.addOperand(MCOperand::createReg(Reg));147return MCDisassembler::Success;148}149150static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, unsigned RegNo,151uint64_t Address,152const MCDisassembler *Decoder) {153return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);154}155156// This is used for the type "ptr_rc", which is either IntRegs or I64Regs157// depending on SparcRegisterInfo::getPointerRegClass.158static DecodeStatus DecodePointerLikeRegClass0(MCInst &Inst, unsigned RegNo,159uint64_t Address,160const MCDisassembler *Decoder) {161return DecodeIntRegsRegisterClass(Inst, RegNo, Address, Decoder);162}163164static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,165uint64_t Address,166const MCDisassembler *Decoder) {167if (RegNo > 31)168return MCDisassembler::Fail;169unsigned Reg = FPRegDecoderTable[RegNo];170Inst.addOperand(MCOperand::createReg(Reg));171return MCDisassembler::Success;172}173174static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,175uint64_t Address,176const MCDisassembler *Decoder) {177if (RegNo > 31)178return MCDisassembler::Fail;179unsigned Reg = DFPRegDecoderTable[RegNo];180Inst.addOperand(MCOperand::createReg(Reg));181return MCDisassembler::Success;182}183184static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, unsigned RegNo,185uint64_t Address,186const MCDisassembler *Decoder) {187if (RegNo > 31)188return MCDisassembler::Fail;189190unsigned Reg = QFPRegDecoderTable[RegNo];191if (Reg == ~0U)192return MCDisassembler::Fail;193Inst.addOperand(MCOperand::createReg(Reg));194return MCDisassembler::Success;195}196197static DecodeStatus198DecodeCoprocRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,199const MCDisassembler *Decoder) {200if (RegNo > 31)201return MCDisassembler::Fail;202unsigned Reg = CPRegDecoderTable[RegNo];203Inst.addOperand(MCOperand::createReg(Reg));204return MCDisassembler::Success;205}206207static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,208uint64_t Address,209const MCDisassembler *Decoder) {210if (RegNo > 3)211return MCDisassembler::Fail;212Inst.addOperand(MCOperand::createReg(FCCRegDecoderTable[RegNo]));213return MCDisassembler::Success;214}215216static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,217uint64_t Address,218const MCDisassembler *Decoder) {219if (RegNo > 31)220return MCDisassembler::Fail;221Inst.addOperand(MCOperand::createReg(ASRRegDecoderTable[RegNo]));222return MCDisassembler::Success;223}224225static DecodeStatus DecodePRRegsRegisterClass(MCInst &Inst, unsigned RegNo,226uint64_t Address,227const MCDisassembler *Decoder) {228if (RegNo >= std::size(PRRegDecoderTable))229return MCDisassembler::Fail;230Inst.addOperand(MCOperand::createReg(PRRegDecoderTable[RegNo]));231return MCDisassembler::Success;232}233234static DecodeStatus DecodeIntPairRegisterClass(MCInst &Inst, unsigned RegNo,235uint64_t Address,236const MCDisassembler *Decoder) {237DecodeStatus S = MCDisassembler::Success;238239if (RegNo > 31)240return MCDisassembler::Fail;241242if ((RegNo & 1))243S = MCDisassembler::SoftFail;244245unsigned RegisterPair = IntPairDecoderTable[RegNo/2];246Inst.addOperand(MCOperand::createReg(RegisterPair));247return S;248}249250static DecodeStatus251DecodeCoprocPairRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address,252const MCDisassembler *Decoder) {253if (RegNo > 31)254return MCDisassembler::Fail;255256unsigned RegisterPair = CPPairDecoderTable[RegNo/2];257Inst.addOperand(MCOperand::createReg(RegisterPair));258return MCDisassembler::Success;259}260261static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address,262const MCDisassembler *Decoder);263static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address,264const MCDisassembler *Decoder);265266#include "SparcGenDisassemblerTables.inc"267268/// Read four bytes from the ArrayRef and return 32 bit word.269static DecodeStatus readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,270uint64_t &Size, uint32_t &Insn,271bool IsLittleEndian) {272// We want to read exactly 4 Bytes of data.273if (Bytes.size() < 4) {274Size = 0;275return MCDisassembler::Fail;276}277278Insn = IsLittleEndian279? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |280(Bytes[3] << 24)281: (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |282(Bytes[0] << 24);283284return MCDisassembler::Success;285}286287DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,288ArrayRef<uint8_t> Bytes,289uint64_t Address,290raw_ostream &CStream) const {291uint32_t Insn;292bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();293DecodeStatus Result =294readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);295if (Result == MCDisassembler::Fail)296return MCDisassembler::Fail;297298// Calling the auto-generated decoder function.299300if (STI.hasFeature(Sparc::FeatureV9))301{302Result = decodeInstruction(DecoderTableSparcV932, Instr, Insn, Address, this, STI);303}304else305{306Result = decodeInstruction(DecoderTableSparcV832, Instr, Insn, Address, this, STI);307}308if (Result != MCDisassembler::Fail) {309Size = 4;310return Result;311}312313Result =314decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);315316if (Result != MCDisassembler::Fail) {317Size = 4;318return Result;319}320321return MCDisassembler::Fail;322}323324static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,325uint64_t Address, uint64_t Offset,326uint64_t Width, MCInst &MI,327const MCDisassembler *Decoder) {328return Decoder->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset,329Width, /*InstSize=*/4);330}331332static DecodeStatus DecodeCall(MCInst &MI, unsigned insn, uint64_t Address,333const MCDisassembler *Decoder) {334unsigned tgt = fieldFromInstruction(insn, 0, 30);335tgt <<= 2;336if (!tryAddingSymbolicOperand(tgt+Address, false, Address,3370, 30, MI, Decoder))338MI.addOperand(MCOperand::createImm(tgt));339return MCDisassembler::Success;340}341342static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn, uint64_t Address,343const MCDisassembler *Decoder) {344assert(isUInt<13>(insn));345MI.addOperand(MCOperand::createImm(SignExtend64<13>(insn)));346return MCDisassembler::Success;347}348349350