181ad6265SDimitry Andric //===-- CSKYDisassembler.cpp - Disassembler for CSKY ----------------------===// 281ad6265SDimitry Andric // 381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 681ad6265SDimitry Andric // 781ad6265SDimitry Andric //===----------------------------------------------------------------------===// 881ad6265SDimitry Andric // 981ad6265SDimitry Andric // This file implements the CSKYDisassembler class. 1081ad6265SDimitry Andric // 1181ad6265SDimitry Andric //===----------------------------------------------------------------------===// 1281ad6265SDimitry Andric 1381ad6265SDimitry Andric #include "MCTargetDesc/CSKYBaseInfo.h" 1481ad6265SDimitry Andric #include "MCTargetDesc/CSKYMCTargetDesc.h" 1581ad6265SDimitry Andric #include "TargetInfo/CSKYTargetInfo.h" 1681ad6265SDimitry Andric #include "llvm/ADT/DenseMap.h" 1781ad6265SDimitry Andric #include "llvm/MC/MCContext.h" 1881ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h" 1981ad6265SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h" 2081ad6265SDimitry Andric #include "llvm/MC/MCInst.h" 2181ad6265SDimitry Andric #include "llvm/MC/MCInstrInfo.h" 2281ad6265SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 2381ad6265SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h" 2481ad6265SDimitry Andric #include "llvm/MC/TargetRegistry.h" 2581ad6265SDimitry Andric #include "llvm/Support/Endian.h" 2681ad6265SDimitry Andric 2781ad6265SDimitry Andric using namespace llvm; 2881ad6265SDimitry Andric 2981ad6265SDimitry Andric #define DEBUG_TYPE "csky-disassembler" 3081ad6265SDimitry Andric 3181ad6265SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus; 3281ad6265SDimitry Andric 3381ad6265SDimitry Andric namespace { 3481ad6265SDimitry Andric class CSKYDisassembler : public MCDisassembler { 3581ad6265SDimitry Andric std::unique_ptr<MCInstrInfo const> const MCII; 3681ad6265SDimitry Andric mutable StringRef symbolName; 3781ad6265SDimitry Andric 3881ad6265SDimitry Andric DecodeStatus handleCROperand(MCInst &Instr) const; 3981ad6265SDimitry Andric 4081ad6265SDimitry Andric public: 4181ad6265SDimitry Andric CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 4281ad6265SDimitry Andric MCInstrInfo const *MCII); 4381ad6265SDimitry Andric 4481ad6265SDimitry Andric DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 4581ad6265SDimitry Andric ArrayRef<uint8_t> Bytes, uint64_t Address, 4681ad6265SDimitry Andric raw_ostream &CStream) const override; 4781ad6265SDimitry Andric }; 4881ad6265SDimitry Andric } // end anonymous namespace 4981ad6265SDimitry Andric 5081ad6265SDimitry Andric CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 5181ad6265SDimitry Andric MCInstrInfo const *MCII) 5281ad6265SDimitry Andric : MCDisassembler(STI, Ctx), MCII(MCII) {} 5381ad6265SDimitry Andric 5481ad6265SDimitry Andric static MCDisassembler *createCSKYDisassembler(const Target &T, 5581ad6265SDimitry Andric const MCSubtargetInfo &STI, 5681ad6265SDimitry Andric MCContext &Ctx) { 5781ad6265SDimitry Andric return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo()); 5881ad6265SDimitry Andric } 5981ad6265SDimitry Andric 6081ad6265SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYDisassembler() { 6181ad6265SDimitry Andric TargetRegistry::RegisterMCDisassembler(getTheCSKYTarget(), 6281ad6265SDimitry Andric createCSKYDisassembler); 6381ad6265SDimitry Andric } 6481ad6265SDimitry Andric 6581ad6265SDimitry Andric static const uint16_t GPRDecoderTable[] = { 6681ad6265SDimitry Andric CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3, CSKY::R4, CSKY::R5, CSKY::R6, 6781ad6265SDimitry Andric CSKY::R7, CSKY::R8, CSKY::R9, CSKY::R10, CSKY::R11, CSKY::R12, CSKY::R13, 6881ad6265SDimitry Andric CSKY::R14, CSKY::R15, CSKY::R16, CSKY::R17, CSKY::R18, CSKY::R19, CSKY::R20, 6981ad6265SDimitry Andric CSKY::R21, CSKY::R22, CSKY::R23, CSKY::R24, CSKY::R25, CSKY::R26, CSKY::R27, 7081ad6265SDimitry Andric CSKY::R28, CSKY::R29, CSKY::R30, CSKY::R31}; 7181ad6265SDimitry Andric 7281ad6265SDimitry Andric static const uint16_t GPRPairDecoderTable[] = { 7381ad6265SDimitry Andric CSKY::R0_R1, CSKY::R1_R2, CSKY::R2_R3, CSKY::R3_R4, CSKY::R4_R5, 7481ad6265SDimitry Andric CSKY::R5_R6, CSKY::R6_R7, CSKY::R7_R8, CSKY::R8_R9, CSKY::R9_R10, 7581ad6265SDimitry Andric CSKY::R10_R11, CSKY::R11_R12, CSKY::R12_R13, CSKY::R13_R14, CSKY::R14_R15, 7681ad6265SDimitry Andric CSKY::R15_R16, CSKY::R16_R17, CSKY::R17_R18, CSKY::R18_R19, CSKY::R19_R20, 7781ad6265SDimitry Andric CSKY::R20_R21, CSKY::R21_R22, CSKY::R22_R23, CSKY::R23_R24, CSKY::R24_R25, 7881ad6265SDimitry Andric CSKY::R25_R26, CSKY::R26_R27, CSKY::R27_R28, CSKY::R28_R29, CSKY::R29_R30, 7981ad6265SDimitry Andric CSKY::R30_R31, CSKY::R31_R32}; 8081ad6265SDimitry Andric 8181ad6265SDimitry Andric static const uint16_t FPR32DecoderTable[] = { 8281ad6265SDimitry Andric CSKY::F0_32, CSKY::F1_32, CSKY::F2_32, CSKY::F3_32, CSKY::F4_32, 8381ad6265SDimitry Andric CSKY::F5_32, CSKY::F6_32, CSKY::F7_32, CSKY::F8_32, CSKY::F9_32, 8481ad6265SDimitry Andric CSKY::F10_32, CSKY::F11_32, CSKY::F12_32, CSKY::F13_32, CSKY::F14_32, 8581ad6265SDimitry Andric CSKY::F15_32, CSKY::F16_32, CSKY::F17_32, CSKY::F18_32, CSKY::F19_32, 8681ad6265SDimitry Andric CSKY::F20_32, CSKY::F21_32, CSKY::F22_32, CSKY::F23_32, CSKY::F24_32, 8781ad6265SDimitry Andric CSKY::F25_32, CSKY::F26_32, CSKY::F27_32, CSKY::F28_32, CSKY::F29_32, 8881ad6265SDimitry Andric CSKY::F30_32, CSKY::F31_32}; 8981ad6265SDimitry Andric 9081ad6265SDimitry Andric static const uint16_t FPR64DecoderTable[] = { 9181ad6265SDimitry Andric CSKY::F0_64, CSKY::F1_64, CSKY::F2_64, CSKY::F3_64, CSKY::F4_64, 9281ad6265SDimitry Andric CSKY::F5_64, CSKY::F6_64, CSKY::F7_64, CSKY::F8_64, CSKY::F9_64, 9381ad6265SDimitry Andric CSKY::F10_64, CSKY::F11_64, CSKY::F12_64, CSKY::F13_64, CSKY::F14_64, 9481ad6265SDimitry Andric CSKY::F15_64, CSKY::F16_64, CSKY::F17_64, CSKY::F18_64, CSKY::F19_64, 9581ad6265SDimitry Andric CSKY::F20_64, CSKY::F21_64, CSKY::F22_64, CSKY::F23_64, CSKY::F24_64, 9681ad6265SDimitry Andric CSKY::F25_64, CSKY::F26_64, CSKY::F27_64, CSKY::F28_64, CSKY::F29_64, 9781ad6265SDimitry Andric CSKY::F30_64, CSKY::F31_64}; 9881ad6265SDimitry Andric 9981ad6265SDimitry Andric static const uint16_t FPR128DecoderTable[] = { 10081ad6265SDimitry Andric CSKY::F0_128, CSKY::F1_128, CSKY::F2_128, CSKY::F3_128, CSKY::F4_128, 10181ad6265SDimitry Andric CSKY::F5_128, CSKY::F6_128, CSKY::F7_128, CSKY::F8_128, CSKY::F9_128, 10281ad6265SDimitry Andric CSKY::F10_128, CSKY::F11_128, CSKY::F12_128, CSKY::F13_128, CSKY::F14_128, 10381ad6265SDimitry Andric CSKY::F15_128, CSKY::F16_128, CSKY::F17_128, CSKY::F18_128, CSKY::F19_128, 10481ad6265SDimitry Andric CSKY::F20_128, CSKY::F21_128, CSKY::F22_128, CSKY::F23_128, CSKY::F24_128, 10581ad6265SDimitry Andric CSKY::F25_128, CSKY::F26_128, CSKY::F27_128, CSKY::F28_128, CSKY::F29_128, 10681ad6265SDimitry Andric CSKY::F30_128, CSKY::F31_128}; 10781ad6265SDimitry Andric 10881ad6265SDimitry Andric static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 10981ad6265SDimitry Andric uint64_t Address, 11081ad6265SDimitry Andric const MCDisassembler *Decoder) { 11181ad6265SDimitry Andric if (RegNo >= 32) 11281ad6265SDimitry Andric return MCDisassembler::Fail; 11381ad6265SDimitry Andric 11481ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo])); 11581ad6265SDimitry Andric return MCDisassembler::Success; 11681ad6265SDimitry Andric } 11781ad6265SDimitry Andric 11881ad6265SDimitry Andric static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 11981ad6265SDimitry Andric uint64_t Address, 12081ad6265SDimitry Andric const MCDisassembler *Decoder) { 12181ad6265SDimitry Andric if (RegNo >= 32) 12281ad6265SDimitry Andric return MCDisassembler::Fail; 12381ad6265SDimitry Andric 12481ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo])); 12581ad6265SDimitry Andric return MCDisassembler::Success; 12681ad6265SDimitry Andric } 12781ad6265SDimitry Andric 12881ad6265SDimitry Andric static DecodeStatus DecodesFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 12981ad6265SDimitry Andric uint64_t Address, 13081ad6265SDimitry Andric const MCDisassembler *Decoder) { 13181ad6265SDimitry Andric if (RegNo >= 16) 13281ad6265SDimitry Andric return MCDisassembler::Fail; 13381ad6265SDimitry Andric 13481ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo])); 13581ad6265SDimitry Andric return MCDisassembler::Success; 13681ad6265SDimitry Andric } 13781ad6265SDimitry Andric 13881ad6265SDimitry Andric static DecodeStatus DecodesFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 13981ad6265SDimitry Andric uint64_t Address, 14081ad6265SDimitry Andric const MCDisassembler *Decoder) { 14181ad6265SDimitry Andric if (RegNo >= 16) 14281ad6265SDimitry Andric return MCDisassembler::Fail; 14381ad6265SDimitry Andric 14481ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo])); 14581ad6265SDimitry Andric return MCDisassembler::Success; 14681ad6265SDimitry Andric } 14781ad6265SDimitry Andric 14881ad6265SDimitry Andric static DecodeStatus DecodesFPR64_VRegisterClass(MCInst &Inst, uint64_t RegNo, 14981ad6265SDimitry Andric uint64_t Address, 15081ad6265SDimitry Andric const MCDisassembler *Decoder) { 15181ad6265SDimitry Andric if (RegNo >= 16) 15281ad6265SDimitry Andric return MCDisassembler::Fail; 15381ad6265SDimitry Andric 15481ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo])); 15581ad6265SDimitry Andric return MCDisassembler::Success; 15681ad6265SDimitry Andric } 15781ad6265SDimitry Andric 15881ad6265SDimitry Andric static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 15981ad6265SDimitry Andric uint64_t Address, 16081ad6265SDimitry Andric const MCDisassembler *Decoder) { 16181ad6265SDimitry Andric if (RegNo >= 32) 16281ad6265SDimitry Andric return MCDisassembler::Fail; 16381ad6265SDimitry Andric 16481ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo])); 16581ad6265SDimitry Andric return MCDisassembler::Success; 16681ad6265SDimitry Andric } 16781ad6265SDimitry Andric 16881ad6265SDimitry Andric // TODO 16981ad6265SDimitry Andric LLVM_ATTRIBUTE_UNUSED 17081ad6265SDimitry Andric static DecodeStatus DecodesFPR128RegisterClass(MCInst &Inst, uint64_t RegNo, 17181ad6265SDimitry Andric uint64_t Address, 17281ad6265SDimitry Andric const MCDisassembler *Decoder) { 17381ad6265SDimitry Andric if (RegNo >= 16) 17481ad6265SDimitry Andric return MCDisassembler::Fail; 17581ad6265SDimitry Andric 17681ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR128DecoderTable[RegNo])); 17781ad6265SDimitry Andric return MCDisassembler::Success; 17881ad6265SDimitry Andric } 17981ad6265SDimitry Andric 18081ad6265SDimitry Andric static DecodeStatus DecodesGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 18181ad6265SDimitry Andric uint64_t Address, 18281ad6265SDimitry Andric const MCDisassembler *Decoder) { 18381ad6265SDimitry Andric if (RegNo >= 16) 18481ad6265SDimitry Andric return MCDisassembler::Fail; 18581ad6265SDimitry Andric 18681ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo])); 18781ad6265SDimitry Andric return MCDisassembler::Success; 18881ad6265SDimitry Andric } 18981ad6265SDimitry Andric 19081ad6265SDimitry Andric static DecodeStatus DecodemGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 19181ad6265SDimitry Andric uint64_t Address, 19281ad6265SDimitry Andric const MCDisassembler *Decoder) { 19381ad6265SDimitry Andric if (RegNo >= 8) 19481ad6265SDimitry Andric return MCDisassembler::Fail; 19581ad6265SDimitry Andric 19681ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo])); 19781ad6265SDimitry Andric return MCDisassembler::Success; 19881ad6265SDimitry Andric } 19981ad6265SDimitry Andric 20081ad6265SDimitry Andric // TODO 20181ad6265SDimitry Andric LLVM_ATTRIBUTE_UNUSED 20281ad6265SDimitry Andric static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst, uint64_t RegNo, 20381ad6265SDimitry Andric uint64_t Address, 20481ad6265SDimitry Andric const MCDisassembler *Decoder) { 20581ad6265SDimitry Andric if (RegNo != 14) 20681ad6265SDimitry Andric return MCDisassembler::Fail; 20781ad6265SDimitry Andric 20881ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo])); 20981ad6265SDimitry Andric return MCDisassembler::Success; 21081ad6265SDimitry Andric } 21181ad6265SDimitry Andric 21281ad6265SDimitry Andric static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint64_t RegNo, 21381ad6265SDimitry Andric uint64_t Address, 21481ad6265SDimitry Andric const MCDisassembler *Decoder) { 21581ad6265SDimitry Andric const FeatureBitset &FeatureBits = 21681ad6265SDimitry Andric Decoder->getSubtargetInfo().getFeatureBits(); 21781ad6265SDimitry Andric bool hasHighReg = FeatureBits[CSKY::FeatureHighreg]; 21881ad6265SDimitry Andric 21981ad6265SDimitry Andric if (RegNo >= 32 || (!hasHighReg && RegNo >= 16)) 22081ad6265SDimitry Andric return MCDisassembler::Fail; 22181ad6265SDimitry Andric 22281ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[RegNo])); 22381ad6265SDimitry Andric return MCDisassembler::Success; 22481ad6265SDimitry Andric } 22581ad6265SDimitry Andric 22681ad6265SDimitry Andric template <unsigned N, unsigned S> 22781ad6265SDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 22881ad6265SDimitry Andric int64_t Address, 22981ad6265SDimitry Andric const MCDisassembler *Decoder) { 23081ad6265SDimitry Andric assert(isUInt<N>(Imm) && "Invalid immediate"); 23181ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm << S)); 23281ad6265SDimitry Andric return MCDisassembler::Success; 23381ad6265SDimitry Andric } 23481ad6265SDimitry Andric 23581ad6265SDimitry Andric template <unsigned N> 23681ad6265SDimitry Andric static DecodeStatus decodeOImmOperand(MCInst &Inst, uint64_t Imm, 23781ad6265SDimitry Andric int64_t Address, 23881ad6265SDimitry Andric const MCDisassembler *Decoder) { 23981ad6265SDimitry Andric assert(isUInt<N>(Imm) && "Invalid immediate"); 24081ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm + 1)); 24181ad6265SDimitry Andric return MCDisassembler::Success; 24281ad6265SDimitry Andric } 24381ad6265SDimitry Andric 24481ad6265SDimitry Andric static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address, 24581ad6265SDimitry Andric const MCDisassembler *Decoder) { 24681ad6265SDimitry Andric assert(isUInt<8>(Imm) && "Invalid immediate"); 24781ad6265SDimitry Andric if ((Imm >> 7) & 0x1) { 24881ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm((Imm & 0x7F) << 2)); 24981ad6265SDimitry Andric } else { 25081ad6265SDimitry Andric uint64_t V = ((Imm ^ 0xFFFFFFFF) & 0xFF); 25181ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm(V << 2)); 25281ad6265SDimitry Andric } 25381ad6265SDimitry Andric 25481ad6265SDimitry Andric return MCDisassembler::Success; 25581ad6265SDimitry Andric } 25681ad6265SDimitry Andric 25781ad6265SDimitry Andric static DecodeStatus decodeJMPIXImmOperand(MCInst &Inst, uint64_t Imm, 25881ad6265SDimitry Andric int64_t Address, 25981ad6265SDimitry Andric const MCDisassembler *Decoder) { 26081ad6265SDimitry Andric assert(isUInt<2>(Imm) && "Invalid immediate"); 26181ad6265SDimitry Andric 26281ad6265SDimitry Andric if (Imm == 0) 26381ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm(16)); 26481ad6265SDimitry Andric else if (Imm == 1) 26581ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm(24)); 26681ad6265SDimitry Andric else if (Imm == 2) 26781ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm(32)); 26881ad6265SDimitry Andric else if (Imm == 3) 26981ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm(40)); 27081ad6265SDimitry Andric else 27181ad6265SDimitry Andric return MCDisassembler::Fail; 27281ad6265SDimitry Andric 27381ad6265SDimitry Andric return MCDisassembler::Success; 27481ad6265SDimitry Andric } 27581ad6265SDimitry Andric 27681ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperand(MCInst &Inst, uint64_t Imm, 27781ad6265SDimitry Andric int64_t Address, 27881ad6265SDimitry Andric const MCDisassembler *Decoder) { 27981ad6265SDimitry Andric assert(isUInt<10>(Imm) && "Invalid immediate"); 28081ad6265SDimitry Andric 28181ad6265SDimitry Andric auto Imm5 = Imm & 0x1f; 28281ad6265SDimitry Andric auto Ry = (Imm >> 5) & 0x1f; 28381ad6265SDimitry Andric 28481ad6265SDimitry Andric if (DecodeGPRRegisterClass(Inst, Ry, Address, Decoder) == 28581ad6265SDimitry Andric MCDisassembler::Fail) 28681ad6265SDimitry Andric return MCDisassembler::Fail; 28781ad6265SDimitry Andric 28881ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Ry + Imm5])); 28981ad6265SDimitry Andric 29081ad6265SDimitry Andric return MCDisassembler::Success; 29181ad6265SDimitry Andric } 29281ad6265SDimitry Andric 29381ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperandF1(MCInst &Inst, uint64_t Imm, 29481ad6265SDimitry Andric int64_t Address, 29581ad6265SDimitry Andric const MCDisassembler *Decoder) { 29681ad6265SDimitry Andric assert(isUInt<10>(Imm) && "Invalid immediate"); 29781ad6265SDimitry Andric 29881ad6265SDimitry Andric auto Imm5 = Imm & 0x1f; 29981ad6265SDimitry Andric auto Ry = (Imm >> 5) & 0x1f; 30081ad6265SDimitry Andric 30181ad6265SDimitry Andric if (DecodesFPR32RegisterClass(Inst, Ry, Address, Decoder) == 30281ad6265SDimitry Andric MCDisassembler::Fail) 30381ad6265SDimitry Andric return MCDisassembler::Fail; 30481ad6265SDimitry Andric 30581ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5])); 30681ad6265SDimitry Andric 30781ad6265SDimitry Andric return MCDisassembler::Success; 30881ad6265SDimitry Andric } 30981ad6265SDimitry Andric 31081ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperandD1(MCInst &Inst, uint64_t Imm, 31181ad6265SDimitry Andric int64_t Address, 31281ad6265SDimitry Andric const MCDisassembler *Decoder) { 31381ad6265SDimitry Andric assert(isUInt<10>(Imm) && "Invalid immediate"); 31481ad6265SDimitry Andric 31581ad6265SDimitry Andric auto Imm5 = Imm & 0x1f; 31681ad6265SDimitry Andric auto Ry = (Imm >> 5) & 0x1f; 31781ad6265SDimitry Andric 31881ad6265SDimitry Andric if (DecodesFPR64RegisterClass(Inst, Ry, Address, Decoder) == 31981ad6265SDimitry Andric MCDisassembler::Fail) 32081ad6265SDimitry Andric return MCDisassembler::Fail; 32181ad6265SDimitry Andric 32281ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5])); 32381ad6265SDimitry Andric 32481ad6265SDimitry Andric return MCDisassembler::Success; 32581ad6265SDimitry Andric } 32681ad6265SDimitry Andric 32781ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperandF2(MCInst &Inst, uint64_t Imm, 32881ad6265SDimitry Andric int64_t Address, 32981ad6265SDimitry Andric const MCDisassembler *Decoder) { 33081ad6265SDimitry Andric assert(isUInt<10>(Imm) && "Invalid immediate"); 33181ad6265SDimitry Andric 33281ad6265SDimitry Andric auto Imm5 = Imm & 0x1f; 33381ad6265SDimitry Andric auto Ry = (Imm >> 5) & 0x1f; 33481ad6265SDimitry Andric 33581ad6265SDimitry Andric if (DecodeFPR32RegisterClass(Inst, Ry, Address, Decoder) == 33681ad6265SDimitry Andric MCDisassembler::Fail) 33781ad6265SDimitry Andric return MCDisassembler::Fail; 33881ad6265SDimitry Andric 33981ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5])); 34081ad6265SDimitry Andric 34181ad6265SDimitry Andric return MCDisassembler::Success; 34281ad6265SDimitry Andric } 34381ad6265SDimitry Andric 34481ad6265SDimitry Andric static DecodeStatus DecodeRegSeqOperandD2(MCInst &Inst, uint64_t Imm, 34581ad6265SDimitry Andric int64_t Address, 34681ad6265SDimitry Andric const MCDisassembler *Decoder) { 34781ad6265SDimitry Andric assert(isUInt<10>(Imm) && "Invalid immediate"); 34881ad6265SDimitry Andric 34981ad6265SDimitry Andric auto Imm5 = Imm & 0x1f; 35081ad6265SDimitry Andric auto Ry = (Imm >> 5) & 0x1f; 35181ad6265SDimitry Andric 35281ad6265SDimitry Andric if (DecodeFPR64RegisterClass(Inst, Ry, Address, Decoder) == 35381ad6265SDimitry Andric MCDisassembler::Fail) 35481ad6265SDimitry Andric return MCDisassembler::Fail; 35581ad6265SDimitry Andric 35681ad6265SDimitry Andric Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5])); 35781ad6265SDimitry Andric 35881ad6265SDimitry Andric return MCDisassembler::Success; 35981ad6265SDimitry Andric } 36081ad6265SDimitry Andric 36181ad6265SDimitry Andric static DecodeStatus decodeImmShiftOpValue(MCInst &Inst, uint64_t Imm, 36281ad6265SDimitry Andric int64_t Address, 36381ad6265SDimitry Andric const MCDisassembler *Decoder) { 364*bdd1243dSDimitry Andric Inst.addOperand(MCOperand::createImm(Log2_64(Imm))); 36581ad6265SDimitry Andric return MCDisassembler::Success; 36681ad6265SDimitry Andric } 36781ad6265SDimitry Andric 36881ad6265SDimitry Andric template <unsigned N, unsigned S> 36981ad6265SDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 37081ad6265SDimitry Andric int64_t Address, 37181ad6265SDimitry Andric const MCDisassembler *Decoder) { 37281ad6265SDimitry Andric assert(isUInt<N>(Imm) && "Invalid immediate"); 37381ad6265SDimitry Andric // Sign-extend the number in the bottom N bits of Imm 37481ad6265SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) << S)); 37581ad6265SDimitry Andric return MCDisassembler::Success; 37681ad6265SDimitry Andric } 37781ad6265SDimitry Andric 37881ad6265SDimitry Andric #include "CSKYGenDisassemblerTables.inc" 37981ad6265SDimitry Andric 38081ad6265SDimitry Andric DecodeStatus CSKYDisassembler::handleCROperand(MCInst &MI) const { 38181ad6265SDimitry Andric 38281ad6265SDimitry Andric // FIXME: To query instruction info from td file or a table inc file 38381ad6265SDimitry Andric switch (MI.getOpcode()) { 38481ad6265SDimitry Andric default: 38581ad6265SDimitry Andric return MCDisassembler::Success; 38681ad6265SDimitry Andric case CSKY::LD16WSP: 38781ad6265SDimitry Andric case CSKY::ST16WSP: 38881ad6265SDimitry Andric case CSKY::ADDI16ZSP: 38981ad6265SDimitry Andric MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::R14)); 39081ad6265SDimitry Andric return MCDisassembler::Success; 39181ad6265SDimitry Andric case CSKY::ADDI16SPSP: 39281ad6265SDimitry Andric case CSKY::SUBI16SPSP: 39381ad6265SDimitry Andric MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14)); 39481ad6265SDimitry Andric MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14)); 39581ad6265SDimitry Andric return MCDisassembler::Success; 39681ad6265SDimitry Andric case CSKY::FCMPHS_S: 39781ad6265SDimitry Andric case CSKY::FCMPHS_D: 39881ad6265SDimitry Andric case CSKY::FCMPLT_S: 39981ad6265SDimitry Andric case CSKY::FCMPLT_D: 40081ad6265SDimitry Andric case CSKY::FCMPNE_S: 40181ad6265SDimitry Andric case CSKY::FCMPNE_D: 40281ad6265SDimitry Andric case CSKY::FCMPUO_S: 40381ad6265SDimitry Andric case CSKY::FCMPUO_D: 40481ad6265SDimitry Andric case CSKY::FCMPZHS_S: 40581ad6265SDimitry Andric case CSKY::FCMPZHS_D: 40681ad6265SDimitry Andric case CSKY::FCMPZLS_S: 40781ad6265SDimitry Andric case CSKY::FCMPZLS_D: 40881ad6265SDimitry Andric case CSKY::FCMPZNE_S: 40981ad6265SDimitry Andric case CSKY::FCMPZNE_D: 41081ad6265SDimitry Andric case CSKY::FCMPZUO_S: 41181ad6265SDimitry Andric case CSKY::FCMPZUO_D: 41281ad6265SDimitry Andric case CSKY::f2FCMPHS_S: 41381ad6265SDimitry Andric case CSKY::f2FCMPHS_D: 41481ad6265SDimitry Andric case CSKY::f2FCMPLT_S: 41581ad6265SDimitry Andric case CSKY::f2FCMPLT_D: 41681ad6265SDimitry Andric case CSKY::f2FCMPNE_S: 41781ad6265SDimitry Andric case CSKY::f2FCMPNE_D: 41881ad6265SDimitry Andric case CSKY::f2FCMPUO_S: 41981ad6265SDimitry Andric case CSKY::f2FCMPUO_D: 42081ad6265SDimitry Andric case CSKY::f2FCMPHSZ_S: 42181ad6265SDimitry Andric case CSKY::f2FCMPHSZ_D: 42281ad6265SDimitry Andric case CSKY::f2FCMPHZ_S: 42381ad6265SDimitry Andric case CSKY::f2FCMPHZ_D: 42481ad6265SDimitry Andric case CSKY::f2FCMPLSZ_S: 42581ad6265SDimitry Andric case CSKY::f2FCMPLSZ_D: 42681ad6265SDimitry Andric case CSKY::f2FCMPLTZ_S: 42781ad6265SDimitry Andric case CSKY::f2FCMPLTZ_D: 42881ad6265SDimitry Andric case CSKY::f2FCMPNEZ_S: 42981ad6265SDimitry Andric case CSKY::f2FCMPNEZ_D: 43081ad6265SDimitry Andric case CSKY::f2FCMPUOZ_S: 43181ad6265SDimitry Andric case CSKY::f2FCMPUOZ_D: 43281ad6265SDimitry Andric 43381ad6265SDimitry Andric case CSKY::BT32: 43481ad6265SDimitry Andric case CSKY::BF32: 43581ad6265SDimitry Andric case CSKY::BT16: 43681ad6265SDimitry Andric case CSKY::BF16: 43781ad6265SDimitry Andric case CSKY::CMPNEI32: 43881ad6265SDimitry Andric case CSKY::CMPNEI16: 43981ad6265SDimitry Andric case CSKY::CMPNE32: 44081ad6265SDimitry Andric case CSKY::CMPNE16: 44181ad6265SDimitry Andric case CSKY::CMPHSI32: 44281ad6265SDimitry Andric case CSKY::CMPHSI16: 44381ad6265SDimitry Andric case CSKY::CMPHS32: 44481ad6265SDimitry Andric case CSKY::CMPHS16: 44581ad6265SDimitry Andric case CSKY::CMPLTI32: 44681ad6265SDimitry Andric case CSKY::CMPLTI16: 44781ad6265SDimitry Andric case CSKY::CMPLT32: 44881ad6265SDimitry Andric case CSKY::CMPLT16: 44981ad6265SDimitry Andric case CSKY::BTSTI32: 45081ad6265SDimitry Andric case CSKY::BTSTI16: 45181ad6265SDimitry Andric case CSKY::TSTNBZ32: 45281ad6265SDimitry Andric case CSKY::TSTNBZ16: 45381ad6265SDimitry Andric case CSKY::TST32: 45481ad6265SDimitry Andric case CSKY::TST16: 45581ad6265SDimitry Andric MI.insert(MI.begin(), MCOperand::createReg(CSKY::C)); 45681ad6265SDimitry Andric return MCDisassembler::Success; 45781ad6265SDimitry Andric case CSKY::LSLC32: 45881ad6265SDimitry Andric case CSKY::LSRC32: 45981ad6265SDimitry Andric case CSKY::ASRC32: 46081ad6265SDimitry Andric MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C)); 46181ad6265SDimitry Andric return MCDisassembler::Success; 46281ad6265SDimitry Andric case CSKY::MOVF32: 46381ad6265SDimitry Andric case CSKY::MOVT32: 46481ad6265SDimitry Andric case CSKY::MVC32: 46581ad6265SDimitry Andric case CSKY::MVCV32: 46681ad6265SDimitry Andric case CSKY::MVCV16: 46781ad6265SDimitry Andric case CSKY::INCT32: 46881ad6265SDimitry Andric case CSKY::INCF32: 46981ad6265SDimitry Andric case CSKY::DECT32: 47081ad6265SDimitry Andric case CSKY::DECF32: 47181ad6265SDimitry Andric case CSKY::DECGT32: 47281ad6265SDimitry Andric case CSKY::DECLT32: 47381ad6265SDimitry Andric case CSKY::DECNE32: 47481ad6265SDimitry Andric case CSKY::CLRF32: 47581ad6265SDimitry Andric case CSKY::CLRT32: 47681ad6265SDimitry Andric case CSKY::f2FSEL_S: 47781ad6265SDimitry Andric case CSKY::f2FSEL_D: 47881ad6265SDimitry Andric MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C)); 47981ad6265SDimitry Andric return MCDisassembler::Success; 48081ad6265SDimitry Andric case CSKY::ADDC32: 48181ad6265SDimitry Andric case CSKY::ADDC16: 48281ad6265SDimitry Andric case CSKY::SUBC32: 48381ad6265SDimitry Andric case CSKY::SUBC16: 48481ad6265SDimitry Andric case CSKY::XSR32: 48581ad6265SDimitry Andric MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C)); 48681ad6265SDimitry Andric MI.insert(MI.end(), MCOperand::createReg(CSKY::C)); 48781ad6265SDimitry Andric return MCDisassembler::Success; 48881ad6265SDimitry Andric case CSKY::INS32: 48981ad6265SDimitry Andric MI.getOperand(3).setImm(MI.getOperand(3).getImm() + 49081ad6265SDimitry Andric MI.getOperand(4).getImm()); 49181ad6265SDimitry Andric return MCDisassembler::Success; 49281ad6265SDimitry Andric } 49381ad6265SDimitry Andric } 49481ad6265SDimitry Andric 49581ad6265SDimitry Andric static bool decodeFPUV3Instruction(MCInst &MI, uint32_t insn, uint64_t Address, 49681ad6265SDimitry Andric const MCDisassembler *DisAsm, 49781ad6265SDimitry Andric const MCSubtargetInfo &STI) { 49881ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit fpuv3 table :\n"); 49981ad6265SDimitry Andric if (!STI.getFeatureBits()[CSKY::FeatureFPUV3_HF] && 50081ad6265SDimitry Andric !STI.getFeatureBits()[CSKY::FeatureFPUV3_SF] && 50181ad6265SDimitry Andric !STI.getFeatureBits()[CSKY::FeatureFPUV3_DF]) 50281ad6265SDimitry Andric return false; 50381ad6265SDimitry Andric 50481ad6265SDimitry Andric DecodeStatus Result = 50581ad6265SDimitry Andric decodeInstruction(DecoderTableFPUV332, MI, insn, Address, DisAsm, STI); 50681ad6265SDimitry Andric 50781ad6265SDimitry Andric if (Result == MCDisassembler::Fail) { 50881ad6265SDimitry Andric MI.clear(); 50981ad6265SDimitry Andric return false; 51081ad6265SDimitry Andric } 51181ad6265SDimitry Andric 51281ad6265SDimitry Andric return true; 51381ad6265SDimitry Andric } 51481ad6265SDimitry Andric 51581ad6265SDimitry Andric DecodeStatus CSKYDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 51681ad6265SDimitry Andric ArrayRef<uint8_t> Bytes, 51781ad6265SDimitry Andric uint64_t Address, 51881ad6265SDimitry Andric raw_ostream &CS) const { 51981ad6265SDimitry Andric 52081ad6265SDimitry Andric uint32_t Insn; 52181ad6265SDimitry Andric DecodeStatus Result = MCDisassembler::Fail; 52281ad6265SDimitry Andric 52381ad6265SDimitry Andric Insn = support::endian::read16le(Bytes.data()); 52481ad6265SDimitry Andric 52581ad6265SDimitry Andric if ((Insn >> 14) == 0x3) { 52681ad6265SDimitry Andric if (Bytes.size() < 4) { 52781ad6265SDimitry Andric Size = 0; 52881ad6265SDimitry Andric return MCDisassembler::Fail; 52981ad6265SDimitry Andric } 53081ad6265SDimitry Andric Insn = (Insn << 16) | support::endian::read16le(&Bytes[2]); 53181ad6265SDimitry Andric 53281ad6265SDimitry Andric if (decodeFPUV3Instruction(MI, Insn, Address, this, STI)) 53381ad6265SDimitry Andric Result = MCDisassembler::Success; 53481ad6265SDimitry Andric else { 53581ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit table :\n"); 53681ad6265SDimitry Andric Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 53781ad6265SDimitry Andric } 53881ad6265SDimitry Andric 53981ad6265SDimitry Andric Size = 4; 54081ad6265SDimitry Andric } else { 54181ad6265SDimitry Andric if (Bytes.size() < 2) { 54281ad6265SDimitry Andric Size = 0; 54381ad6265SDimitry Andric return MCDisassembler::Fail; 54481ad6265SDimitry Andric } 54581ad6265SDimitry Andric LLVM_DEBUG(dbgs() << "Trying CSKY 16-bit table :\n"); 54681ad6265SDimitry Andric Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 54781ad6265SDimitry Andric Size = 2; 54881ad6265SDimitry Andric } 54981ad6265SDimitry Andric 55081ad6265SDimitry Andric handleCROperand(MI); 55181ad6265SDimitry Andric 55281ad6265SDimitry Andric return Result; 55381ad6265SDimitry Andric } 554