Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/Disassembler/CSKYDisassembler.cpp
35293 views
//===-- CSKYDisassembler.cpp - Disassembler for CSKY ----------------------===//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 implements the CSKYDisassembler class.9//10//===----------------------------------------------------------------------===//1112#include "MCTargetDesc/CSKYBaseInfo.h"13#include "MCTargetDesc/CSKYMCTargetDesc.h"14#include "TargetInfo/CSKYTargetInfo.h"15#include "llvm/ADT/DenseMap.h"16#include "llvm/MC/MCContext.h"17#include "llvm/MC/MCDecoderOps.h"18#include "llvm/MC/MCDisassembler/MCDisassembler.h"19#include "llvm/MC/MCInst.h"20#include "llvm/MC/MCInstrInfo.h"21#include "llvm/MC/MCRegisterInfo.h"22#include "llvm/MC/MCSubtargetInfo.h"23#include "llvm/MC/TargetRegistry.h"24#include "llvm/Support/Endian.h"2526using namespace llvm;2728#define DEBUG_TYPE "csky-disassembler"2930typedef MCDisassembler::DecodeStatus DecodeStatus;3132namespace {33class CSKYDisassembler : public MCDisassembler {34std::unique_ptr<MCInstrInfo const> const MCII;35mutable StringRef symbolName;3637DecodeStatus handleCROperand(MCInst &Instr) const;3839public:40CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,41MCInstrInfo const *MCII);4243DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,44ArrayRef<uint8_t> Bytes, uint64_t Address,45raw_ostream &CStream) const override;46};47} // end anonymous namespace4849CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,50MCInstrInfo const *MCII)51: MCDisassembler(STI, Ctx), MCII(MCII) {}5253static MCDisassembler *createCSKYDisassembler(const Target &T,54const MCSubtargetInfo &STI,55MCContext &Ctx) {56return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo());57}5859extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYDisassembler() {60TargetRegistry::RegisterMCDisassembler(getTheCSKYTarget(),61createCSKYDisassembler);62}6364static const uint16_t GPRDecoderTable[] = {65CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3, CSKY::R4, CSKY::R5, CSKY::R6,66CSKY::R7, CSKY::R8, CSKY::R9, CSKY::R10, CSKY::R11, CSKY::R12, CSKY::R13,67CSKY::R14, CSKY::R15, CSKY::R16, CSKY::R17, CSKY::R18, CSKY::R19, CSKY::R20,68CSKY::R21, CSKY::R22, CSKY::R23, CSKY::R24, CSKY::R25, CSKY::R26, CSKY::R27,69CSKY::R28, CSKY::R29, CSKY::R30, CSKY::R31};7071static const uint16_t GPRPairDecoderTable[] = {72CSKY::R0_R1, CSKY::R1_R2, CSKY::R2_R3, CSKY::R3_R4, CSKY::R4_R5,73CSKY::R5_R6, CSKY::R6_R7, CSKY::R7_R8, CSKY::R8_R9, CSKY::R9_R10,74CSKY::R10_R11, CSKY::R11_R12, CSKY::R12_R13, CSKY::R13_R14, CSKY::R14_R15,75CSKY::R15_R16, CSKY::R16_R17, CSKY::R17_R18, CSKY::R18_R19, CSKY::R19_R20,76CSKY::R20_R21, CSKY::R21_R22, CSKY::R22_R23, CSKY::R23_R24, CSKY::R24_R25,77CSKY::R25_R26, CSKY::R26_R27, CSKY::R27_R28, CSKY::R28_R29, CSKY::R29_R30,78CSKY::R30_R31, CSKY::R31_R32};7980static const uint16_t FPR32DecoderTable[] = {81CSKY::F0_32, CSKY::F1_32, CSKY::F2_32, CSKY::F3_32, CSKY::F4_32,82CSKY::F5_32, CSKY::F6_32, CSKY::F7_32, CSKY::F8_32, CSKY::F9_32,83CSKY::F10_32, CSKY::F11_32, CSKY::F12_32, CSKY::F13_32, CSKY::F14_32,84CSKY::F15_32, CSKY::F16_32, CSKY::F17_32, CSKY::F18_32, CSKY::F19_32,85CSKY::F20_32, CSKY::F21_32, CSKY::F22_32, CSKY::F23_32, CSKY::F24_32,86CSKY::F25_32, CSKY::F26_32, CSKY::F27_32, CSKY::F28_32, CSKY::F29_32,87CSKY::F30_32, CSKY::F31_32};8889static const uint16_t FPR64DecoderTable[] = {90CSKY::F0_64, CSKY::F1_64, CSKY::F2_64, CSKY::F3_64, CSKY::F4_64,91CSKY::F5_64, CSKY::F6_64, CSKY::F7_64, CSKY::F8_64, CSKY::F9_64,92CSKY::F10_64, CSKY::F11_64, CSKY::F12_64, CSKY::F13_64, CSKY::F14_64,93CSKY::F15_64, CSKY::F16_64, CSKY::F17_64, CSKY::F18_64, CSKY::F19_64,94CSKY::F20_64, CSKY::F21_64, CSKY::F22_64, CSKY::F23_64, CSKY::F24_64,95CSKY::F25_64, CSKY::F26_64, CSKY::F27_64, CSKY::F28_64, CSKY::F29_64,96CSKY::F30_64, CSKY::F31_64};9798static const uint16_t FPR128DecoderTable[] = {99CSKY::F0_128, CSKY::F1_128, CSKY::F2_128, CSKY::F3_128, CSKY::F4_128,100CSKY::F5_128, CSKY::F6_128, CSKY::F7_128, CSKY::F8_128, CSKY::F9_128,101CSKY::F10_128, CSKY::F11_128, CSKY::F12_128, CSKY::F13_128, CSKY::F14_128,102CSKY::F15_128, CSKY::F16_128, CSKY::F17_128, CSKY::F18_128, CSKY::F19_128,103CSKY::F20_128, CSKY::F21_128, CSKY::F22_128, CSKY::F23_128, CSKY::F24_128,104CSKY::F25_128, CSKY::F26_128, CSKY::F27_128, CSKY::F28_128, CSKY::F29_128,105CSKY::F30_128, CSKY::F31_128};106107static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo,108uint64_t Address,109const MCDisassembler *Decoder) {110if (RegNo >= 32)111return MCDisassembler::Fail;112113Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));114return MCDisassembler::Success;115}116117static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,118uint64_t Address,119const MCDisassembler *Decoder) {120if (RegNo >= 32)121return MCDisassembler::Fail;122123Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));124return MCDisassembler::Success;125}126127static DecodeStatus DecodesFPR32RegisterClass(MCInst &Inst, uint64_t RegNo,128uint64_t Address,129const MCDisassembler *Decoder) {130if (RegNo >= 16)131return MCDisassembler::Fail;132133Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo]));134return MCDisassembler::Success;135}136137static DecodeStatus DecodesFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,138uint64_t Address,139const MCDisassembler *Decoder) {140if (RegNo >= 16)141return MCDisassembler::Fail;142143Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));144return MCDisassembler::Success;145}146147static DecodeStatus DecodesFPR64_VRegisterClass(MCInst &Inst, uint64_t RegNo,148uint64_t Address,149const MCDisassembler *Decoder) {150if (RegNo >= 16)151return MCDisassembler::Fail;152153Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));154return MCDisassembler::Success;155}156157static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo,158uint64_t Address,159const MCDisassembler *Decoder) {160if (RegNo >= 32)161return MCDisassembler::Fail;162163Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo]));164return MCDisassembler::Success;165}166167// TODO168LLVM_ATTRIBUTE_UNUSED169static DecodeStatus DecodesFPR128RegisterClass(MCInst &Inst, uint64_t RegNo,170uint64_t Address,171const MCDisassembler *Decoder) {172if (RegNo >= 16)173return MCDisassembler::Fail;174175Inst.addOperand(MCOperand::createReg(FPR128DecoderTable[RegNo]));176return MCDisassembler::Success;177}178179static DecodeStatus DecodesGPRRegisterClass(MCInst &Inst, uint64_t RegNo,180uint64_t Address,181const MCDisassembler *Decoder) {182if (RegNo >= 16)183return MCDisassembler::Fail;184185Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));186return MCDisassembler::Success;187}188189static DecodeStatus DecodemGPRRegisterClass(MCInst &Inst, uint64_t RegNo,190uint64_t Address,191const MCDisassembler *Decoder) {192if (RegNo >= 8)193return MCDisassembler::Fail;194195Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));196return MCDisassembler::Success;197}198199// TODO200LLVM_ATTRIBUTE_UNUSED201static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst, uint64_t RegNo,202uint64_t Address,203const MCDisassembler *Decoder) {204if (RegNo != 14)205return MCDisassembler::Fail;206207Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo]));208return MCDisassembler::Success;209}210211static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint64_t RegNo,212uint64_t Address,213const MCDisassembler *Decoder) {214const FeatureBitset &FeatureBits =215Decoder->getSubtargetInfo().getFeatureBits();216bool hasHighReg = FeatureBits[CSKY::FeatureHighreg];217218if (RegNo >= 32 || (!hasHighReg && RegNo >= 16))219return MCDisassembler::Fail;220221Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[RegNo]));222return MCDisassembler::Success;223}224225template <unsigned N, unsigned S>226static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,227int64_t Address,228const MCDisassembler *Decoder) {229assert(isUInt<N>(Imm) && "Invalid immediate");230Inst.addOperand(MCOperand::createImm(Imm << S));231return MCDisassembler::Success;232}233234template <unsigned N>235static DecodeStatus decodeOImmOperand(MCInst &Inst, uint64_t Imm,236int64_t Address,237const MCDisassembler *Decoder) {238assert(isUInt<N>(Imm) && "Invalid immediate");239Inst.addOperand(MCOperand::createImm(Imm + 1));240return MCDisassembler::Success;241}242243static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address,244const MCDisassembler *Decoder) {245assert(isUInt<8>(Imm) && "Invalid immediate");246if ((Imm >> 7) & 0x1) {247Inst.addOperand(MCOperand::createImm((Imm & 0x7F) << 2));248} else {249uint64_t V = ((Imm ^ 0xFFFFFFFF) & 0xFF);250Inst.addOperand(MCOperand::createImm(V << 2));251}252253return MCDisassembler::Success;254}255256static DecodeStatus decodeJMPIXImmOperand(MCInst &Inst, uint64_t Imm,257int64_t Address,258const MCDisassembler *Decoder) {259assert(isUInt<2>(Imm) && "Invalid immediate");260261if (Imm == 0)262Inst.addOperand(MCOperand::createImm(16));263else if (Imm == 1)264Inst.addOperand(MCOperand::createImm(24));265else if (Imm == 2)266Inst.addOperand(MCOperand::createImm(32));267else if (Imm == 3)268Inst.addOperand(MCOperand::createImm(40));269else270return MCDisassembler::Fail;271272return MCDisassembler::Success;273}274275static DecodeStatus DecodeRegSeqOperand(MCInst &Inst, uint64_t Imm,276int64_t Address,277const MCDisassembler *Decoder) {278assert(isUInt<10>(Imm) && "Invalid immediate");279280auto Imm5 = Imm & 0x1f;281auto Ry = (Imm >> 5) & 0x1f;282283if (DecodeGPRRegisterClass(Inst, Ry, Address, Decoder) ==284MCDisassembler::Fail)285return MCDisassembler::Fail;286287Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Ry + Imm5]));288289return MCDisassembler::Success;290}291292static DecodeStatus DecodeRegSeqOperandF1(MCInst &Inst, uint64_t Imm,293int64_t Address,294const MCDisassembler *Decoder) {295assert(isUInt<10>(Imm) && "Invalid immediate");296297auto Imm5 = Imm & 0x1f;298auto Ry = (Imm >> 5) & 0x1f;299300if (DecodesFPR32RegisterClass(Inst, Ry, Address, Decoder) ==301MCDisassembler::Fail)302return MCDisassembler::Fail;303304Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));305306return MCDisassembler::Success;307}308309static DecodeStatus DecodeRegSeqOperandD1(MCInst &Inst, uint64_t Imm,310int64_t Address,311const MCDisassembler *Decoder) {312assert(isUInt<10>(Imm) && "Invalid immediate");313314auto Imm5 = Imm & 0x1f;315auto Ry = (Imm >> 5) & 0x1f;316317if (DecodesFPR64RegisterClass(Inst, Ry, Address, Decoder) ==318MCDisassembler::Fail)319return MCDisassembler::Fail;320321Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));322323return MCDisassembler::Success;324}325326static DecodeStatus DecodeRegSeqOperandF2(MCInst &Inst, uint64_t Imm,327int64_t Address,328const MCDisassembler *Decoder) {329assert(isUInt<10>(Imm) && "Invalid immediate");330331auto Imm5 = Imm & 0x1f;332auto Ry = (Imm >> 5) & 0x1f;333334if (DecodeFPR32RegisterClass(Inst, Ry, Address, Decoder) ==335MCDisassembler::Fail)336return MCDisassembler::Fail;337338Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5]));339340return MCDisassembler::Success;341}342343static DecodeStatus DecodeRegSeqOperandD2(MCInst &Inst, uint64_t Imm,344int64_t Address,345const MCDisassembler *Decoder) {346assert(isUInt<10>(Imm) && "Invalid immediate");347348auto Imm5 = Imm & 0x1f;349auto Ry = (Imm >> 5) & 0x1f;350351if (DecodeFPR64RegisterClass(Inst, Ry, Address, Decoder) ==352MCDisassembler::Fail)353return MCDisassembler::Fail;354355Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5]));356357return MCDisassembler::Success;358}359360static DecodeStatus decodeImmShiftOpValue(MCInst &Inst, uint64_t Imm,361int64_t Address,362const MCDisassembler *Decoder) {363Inst.addOperand(MCOperand::createImm(Log2_64(Imm)));364return MCDisassembler::Success;365}366367template <unsigned N, unsigned S>368static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,369int64_t Address,370const MCDisassembler *Decoder) {371assert(isUInt<N>(Imm) && "Invalid immediate");372// Sign-extend the number in the bottom N bits of Imm373Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) << S));374return MCDisassembler::Success;375}376377#include "CSKYGenDisassemblerTables.inc"378379DecodeStatus CSKYDisassembler::handleCROperand(MCInst &MI) const {380381// FIXME: To query instruction info from td file or a table inc file382switch (MI.getOpcode()) {383default:384return MCDisassembler::Success;385case CSKY::LD16WSP:386case CSKY::ST16WSP:387case CSKY::ADDI16ZSP:388MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::R14));389return MCDisassembler::Success;390case CSKY::ADDI16SPSP:391case CSKY::SUBI16SPSP:392MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));393MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14));394return MCDisassembler::Success;395case CSKY::FCMPHS_S:396case CSKY::FCMPHS_D:397case CSKY::FCMPLT_S:398case CSKY::FCMPLT_D:399case CSKY::FCMPNE_S:400case CSKY::FCMPNE_D:401case CSKY::FCMPUO_S:402case CSKY::FCMPUO_D:403case CSKY::FCMPZHS_S:404case CSKY::FCMPZHS_D:405case CSKY::FCMPZLS_S:406case CSKY::FCMPZLS_D:407case CSKY::FCMPZNE_S:408case CSKY::FCMPZNE_D:409case CSKY::FCMPZUO_S:410case CSKY::FCMPZUO_D:411case CSKY::f2FCMPHS_S:412case CSKY::f2FCMPHS_D:413case CSKY::f2FCMPLT_S:414case CSKY::f2FCMPLT_D:415case CSKY::f2FCMPNE_S:416case CSKY::f2FCMPNE_D:417case CSKY::f2FCMPUO_S:418case CSKY::f2FCMPUO_D:419case CSKY::f2FCMPHSZ_S:420case CSKY::f2FCMPHSZ_D:421case CSKY::f2FCMPHZ_S:422case CSKY::f2FCMPHZ_D:423case CSKY::f2FCMPLSZ_S:424case CSKY::f2FCMPLSZ_D:425case CSKY::f2FCMPLTZ_S:426case CSKY::f2FCMPLTZ_D:427case CSKY::f2FCMPNEZ_S:428case CSKY::f2FCMPNEZ_D:429case CSKY::f2FCMPUOZ_S:430case CSKY::f2FCMPUOZ_D:431432case CSKY::BT32:433case CSKY::BF32:434case CSKY::BT16:435case CSKY::BF16:436case CSKY::CMPNEI32:437case CSKY::CMPNEI16:438case CSKY::CMPNE32:439case CSKY::CMPNE16:440case CSKY::CMPHSI32:441case CSKY::CMPHSI16:442case CSKY::CMPHS32:443case CSKY::CMPHS16:444case CSKY::CMPLTI32:445case CSKY::CMPLTI16:446case CSKY::CMPLT32:447case CSKY::CMPLT16:448case CSKY::BTSTI32:449case CSKY::BTSTI16:450case CSKY::TSTNBZ32:451case CSKY::TSTNBZ16:452case CSKY::TST32:453case CSKY::TST16:454MI.insert(MI.begin(), MCOperand::createReg(CSKY::C));455return MCDisassembler::Success;456case CSKY::LSLC32:457case CSKY::LSRC32:458case CSKY::ASRC32:459MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));460return MCDisassembler::Success;461case CSKY::MOVF32:462case CSKY::MOVT32:463case CSKY::MVC32:464case CSKY::MVCV32:465case CSKY::MVCV16:466case CSKY::INCT32:467case CSKY::INCF32:468case CSKY::DECT32:469case CSKY::DECF32:470case CSKY::DECGT32:471case CSKY::DECLT32:472case CSKY::DECNE32:473case CSKY::CLRF32:474case CSKY::CLRT32:475case CSKY::f2FSEL_S:476case CSKY::f2FSEL_D:477MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));478return MCDisassembler::Success;479case CSKY::ADDC32:480case CSKY::ADDC16:481case CSKY::SUBC32:482case CSKY::SUBC16:483case CSKY::XSR32:484MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C));485MI.insert(MI.end(), MCOperand::createReg(CSKY::C));486return MCDisassembler::Success;487case CSKY::INS32:488MI.getOperand(3).setImm(MI.getOperand(3).getImm() +489MI.getOperand(4).getImm());490return MCDisassembler::Success;491}492}493494static bool decodeFPUV3Instruction(MCInst &MI, uint32_t insn, uint64_t Address,495const MCDisassembler *DisAsm,496const MCSubtargetInfo &STI) {497LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit fpuv3 table :\n");498if (!STI.hasFeature(CSKY::FeatureFPUV3_HF) &&499!STI.hasFeature(CSKY::FeatureFPUV3_SF) &&500!STI.hasFeature(CSKY::FeatureFPUV3_DF))501return false;502503DecodeStatus Result =504decodeInstruction(DecoderTableFPUV332, MI, insn, Address, DisAsm, STI);505506if (Result == MCDisassembler::Fail) {507MI.clear();508return false;509}510511return true;512}513514DecodeStatus CSKYDisassembler::getInstruction(MCInst &MI, uint64_t &Size,515ArrayRef<uint8_t> Bytes,516uint64_t Address,517raw_ostream &CS) const {518519uint32_t Insn;520DecodeStatus Result = MCDisassembler::Fail;521522Insn = support::endian::read16le(Bytes.data());523524if ((Insn >> 14) == 0x3) {525if (Bytes.size() < 4) {526Size = 0;527return MCDisassembler::Fail;528}529Insn = (Insn << 16) | support::endian::read16le(&Bytes[2]);530531if (decodeFPUV3Instruction(MI, Insn, Address, this, STI))532Result = MCDisassembler::Success;533else {534LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit table :\n");535Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);536}537538Size = 4;539} else {540if (Bytes.size() < 2) {541Size = 0;542return MCDisassembler::Fail;543}544LLVM_DEBUG(dbgs() << "Trying CSKY 16-bit table :\n");545Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);546Size = 2;547}548549handleCROperand(MI);550551return Result;552}553554555