1ec642ceeSZi Xuan Wu //===-- CSKYDisassembler.cpp - Disassembler for CSKY ----------------------===// 2ec642ceeSZi Xuan Wu // 3ec642ceeSZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4ec642ceeSZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information. 5ec642ceeSZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ec642ceeSZi Xuan Wu // 7ec642ceeSZi Xuan Wu //===----------------------------------------------------------------------===// 8ec642ceeSZi Xuan Wu // 9ec642ceeSZi Xuan Wu // This file implements the CSKYDisassembler class. 10ec642ceeSZi Xuan Wu // 11ec642ceeSZi Xuan Wu //===----------------------------------------------------------------------===// 12ec642ceeSZi Xuan Wu 13ec642ceeSZi Xuan Wu #include "MCTargetDesc/CSKYBaseInfo.h" 14ec642ceeSZi Xuan Wu #include "MCTargetDesc/CSKYMCTargetDesc.h" 15ec642ceeSZi Xuan Wu #include "TargetInfo/CSKYTargetInfo.h" 16ec642ceeSZi Xuan Wu #include "llvm/ADT/DenseMap.h" 17ec642ceeSZi Xuan Wu #include "llvm/MC/MCContext.h" 18ec642ceeSZi Xuan Wu #include "llvm/MC/MCDisassembler/MCDisassembler.h" 19ec642ceeSZi Xuan Wu #include "llvm/MC/MCFixedLenDisassembler.h" 20ec642ceeSZi Xuan Wu #include "llvm/MC/MCInst.h" 21ec642ceeSZi Xuan Wu #include "llvm/MC/MCInstrInfo.h" 22ec642ceeSZi Xuan Wu #include "llvm/MC/MCRegisterInfo.h" 23ec642ceeSZi Xuan Wu #include "llvm/MC/MCSubtargetInfo.h" 24ec642ceeSZi Xuan Wu #include "llvm/MC/TargetRegistry.h" 25ec642ceeSZi Xuan Wu #include "llvm/Support/Endian.h" 26ec642ceeSZi Xuan Wu 27ec642ceeSZi Xuan Wu using namespace llvm; 28ec642ceeSZi Xuan Wu 29ec642ceeSZi Xuan Wu #define DEBUG_TYPE "csky-disassembler" 30ec642ceeSZi Xuan Wu 31ec642ceeSZi Xuan Wu typedef MCDisassembler::DecodeStatus DecodeStatus; 32ec642ceeSZi Xuan Wu 33ec642ceeSZi Xuan Wu namespace { 34ec642ceeSZi Xuan Wu class CSKYDisassembler : public MCDisassembler { 35ec642ceeSZi Xuan Wu std::unique_ptr<MCInstrInfo const> const MCII; 36ec642ceeSZi Xuan Wu mutable StringRef symbolName; 37ec642ceeSZi Xuan Wu 38ec642ceeSZi Xuan Wu DecodeStatus handleCROperand(MCInst &Instr) const; 39ec642ceeSZi Xuan Wu 40ec642ceeSZi Xuan Wu public: 41ec642ceeSZi Xuan Wu CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 42ec642ceeSZi Xuan Wu MCInstrInfo const *MCII); 43ec642ceeSZi Xuan Wu 44ec642ceeSZi Xuan Wu DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 45ec642ceeSZi Xuan Wu ArrayRef<uint8_t> Bytes, uint64_t Address, 46ec642ceeSZi Xuan Wu raw_ostream &CStream) const override; 47ec642ceeSZi Xuan Wu }; 48ec642ceeSZi Xuan Wu } // end anonymous namespace 49ec642ceeSZi Xuan Wu 50ec642ceeSZi Xuan Wu CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 51ec642ceeSZi Xuan Wu MCInstrInfo const *MCII) 52ec642ceeSZi Xuan Wu : MCDisassembler(STI, Ctx), MCII(MCII) {} 53ec642ceeSZi Xuan Wu 54ec642ceeSZi Xuan Wu static MCDisassembler *createCSKYDisassembler(const Target &T, 55ec642ceeSZi Xuan Wu const MCSubtargetInfo &STI, 56ec642ceeSZi Xuan Wu MCContext &Ctx) { 57ec642ceeSZi Xuan Wu return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo()); 58ec642ceeSZi Xuan Wu } 59ec642ceeSZi Xuan Wu 60ec642ceeSZi Xuan Wu extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYDisassembler() { 61ec642ceeSZi Xuan Wu TargetRegistry::RegisterMCDisassembler(getTheCSKYTarget(), 62ec642ceeSZi Xuan Wu createCSKYDisassembler); 63ec642ceeSZi Xuan Wu } 64ec642ceeSZi Xuan Wu 65ec642ceeSZi Xuan Wu static const uint16_t GPRDecoderTable[] = { 66ec642ceeSZi Xuan Wu CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3, CSKY::R4, CSKY::R5, CSKY::R6, 67ec642ceeSZi Xuan Wu CSKY::R7, CSKY::R8, CSKY::R9, CSKY::R10, CSKY::R11, CSKY::R12, CSKY::R13, 68ec642ceeSZi Xuan Wu CSKY::R14, CSKY::R15, CSKY::R16, CSKY::R17, CSKY::R18, CSKY::R19, CSKY::R20, 69ec642ceeSZi Xuan Wu CSKY::R21, CSKY::R22, CSKY::R23, CSKY::R24, CSKY::R25, CSKY::R26, CSKY::R27, 70ec642ceeSZi Xuan Wu CSKY::R28, CSKY::R29, CSKY::R30, CSKY::R31}; 71ec642ceeSZi Xuan Wu 72ec642ceeSZi Xuan Wu static const uint16_t GPRPairDecoderTable[] = { 73ec642ceeSZi Xuan Wu CSKY::R0_R1, CSKY::R1_R2, CSKY::R2_R3, CSKY::R3_R4, CSKY::R4_R5, 74ec642ceeSZi Xuan Wu CSKY::R5_R6, CSKY::R6_R7, CSKY::R7_R8, CSKY::R8_R9, CSKY::R9_R10, 75ec642ceeSZi Xuan Wu CSKY::R10_R11, CSKY::R11_R12, CSKY::R12_R13, CSKY::R13_R14, CSKY::R14_R15, 76ec642ceeSZi Xuan Wu CSKY::R15_R16, CSKY::R16_R17, CSKY::R17_R18, CSKY::R18_R19, CSKY::R19_R20, 77ec642ceeSZi Xuan Wu CSKY::R20_R21, CSKY::R21_R22, CSKY::R22_R23, CSKY::R23_R24, CSKY::R24_R25, 78ec642ceeSZi Xuan Wu CSKY::R25_R26, CSKY::R26_R27, CSKY::R27_R28, CSKY::R28_R29, CSKY::R29_R30, 79ec642ceeSZi Xuan Wu CSKY::R30_R31, CSKY::R31_R32}; 80ec642ceeSZi Xuan Wu 81ec642ceeSZi Xuan Wu static const uint16_t FPR32DecoderTable[] = { 82ec642ceeSZi Xuan Wu CSKY::F0_32, CSKY::F1_32, CSKY::F2_32, CSKY::F3_32, CSKY::F4_32, 83ec642ceeSZi Xuan Wu CSKY::F5_32, CSKY::F6_32, CSKY::F7_32, CSKY::F8_32, CSKY::F9_32, 84ec642ceeSZi Xuan Wu CSKY::F10_32, CSKY::F11_32, CSKY::F12_32, CSKY::F13_32, CSKY::F14_32, 85ec642ceeSZi Xuan Wu CSKY::F15_32, CSKY::F16_32, CSKY::F17_32, CSKY::F18_32, CSKY::F19_32, 86ec642ceeSZi Xuan Wu CSKY::F20_32, CSKY::F21_32, CSKY::F22_32, CSKY::F23_32, CSKY::F24_32, 87ec642ceeSZi Xuan Wu CSKY::F25_32, CSKY::F26_32, CSKY::F27_32, CSKY::F28_32, CSKY::F29_32, 88ec642ceeSZi Xuan Wu CSKY::F30_32, CSKY::F31_32}; 89ec642ceeSZi Xuan Wu 90ec642ceeSZi Xuan Wu static const uint16_t FPR64DecoderTable[] = { 91ec642ceeSZi Xuan Wu CSKY::F0_64, CSKY::F1_64, CSKY::F2_64, CSKY::F3_64, CSKY::F4_64, 92ec642ceeSZi Xuan Wu CSKY::F5_64, CSKY::F6_64, CSKY::F7_64, CSKY::F8_64, CSKY::F9_64, 93ec642ceeSZi Xuan Wu CSKY::F10_64, CSKY::F11_64, CSKY::F12_64, CSKY::F13_64, CSKY::F14_64, 94ec642ceeSZi Xuan Wu CSKY::F15_64, CSKY::F16_64, CSKY::F17_64, CSKY::F18_64, CSKY::F19_64, 95ec642ceeSZi Xuan Wu CSKY::F20_64, CSKY::F21_64, CSKY::F22_64, CSKY::F23_64, CSKY::F24_64, 96ec642ceeSZi Xuan Wu CSKY::F25_64, CSKY::F26_64, CSKY::F27_64, CSKY::F28_64, CSKY::F29_64, 97ec642ceeSZi Xuan Wu CSKY::F30_64, CSKY::F31_64}; 98ec642ceeSZi Xuan Wu 99ec642ceeSZi Xuan Wu static const uint16_t FPR128DecoderTable[] = { 100ec642ceeSZi Xuan Wu CSKY::F0_128, CSKY::F1_128, CSKY::F2_128, CSKY::F3_128, CSKY::F4_128, 101ec642ceeSZi Xuan Wu CSKY::F5_128, CSKY::F6_128, CSKY::F7_128, CSKY::F8_128, CSKY::F9_128, 102ec642ceeSZi Xuan Wu CSKY::F10_128, CSKY::F11_128, CSKY::F12_128, CSKY::F13_128, CSKY::F14_128, 103ec642ceeSZi Xuan Wu CSKY::F15_128, CSKY::F16_128, CSKY::F17_128, CSKY::F18_128, CSKY::F19_128, 104ec642ceeSZi Xuan Wu CSKY::F20_128, CSKY::F21_128, CSKY::F22_128, CSKY::F23_128, CSKY::F24_128, 105ec642ceeSZi Xuan Wu CSKY::F25_128, CSKY::F26_128, CSKY::F27_128, CSKY::F28_128, CSKY::F29_128, 106ec642ceeSZi Xuan Wu CSKY::F30_128, CSKY::F31_128}; 107ec642ceeSZi Xuan Wu 108ec642ceeSZi Xuan Wu static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 109ec642ceeSZi Xuan Wu uint64_t Address, 1104ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 111ec642ceeSZi Xuan Wu if (RegNo >= 32) 112ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 113ec642ceeSZi Xuan Wu 114ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo])); 115ec642ceeSZi Xuan Wu return MCDisassembler::Success; 116ec642ceeSZi Xuan Wu } 117ec642ceeSZi Xuan Wu 118ec642ceeSZi Xuan Wu static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 119ec642ceeSZi Xuan Wu uint64_t Address, 1204ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 121ec642ceeSZi Xuan Wu if (RegNo >= 32) 122ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 123ec642ceeSZi Xuan Wu 124ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo])); 125ec642ceeSZi Xuan Wu return MCDisassembler::Success; 126ec642ceeSZi Xuan Wu } 127ec642ceeSZi Xuan Wu 128ec642ceeSZi Xuan Wu static DecodeStatus DecodesFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, 129ec642ceeSZi Xuan Wu uint64_t Address, 1304ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 131ec642ceeSZi Xuan Wu if (RegNo >= 16) 132ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 133ec642ceeSZi Xuan Wu 134ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[RegNo])); 135ec642ceeSZi Xuan Wu return MCDisassembler::Success; 136ec642ceeSZi Xuan Wu } 137ec642ceeSZi Xuan Wu 138ec642ceeSZi Xuan Wu static DecodeStatus DecodesFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 139ec642ceeSZi Xuan Wu uint64_t Address, 1404ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 141ec642ceeSZi Xuan Wu if (RegNo >= 16) 142ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 143ec642ceeSZi Xuan Wu 144ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo])); 145ec642ceeSZi Xuan Wu return MCDisassembler::Success; 146ec642ceeSZi Xuan Wu } 147ec642ceeSZi Xuan Wu 148ec642ceeSZi Xuan Wu static DecodeStatus DecodesFPR64_VRegisterClass(MCInst &Inst, uint64_t RegNo, 149ec642ceeSZi Xuan Wu uint64_t Address, 1504ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 151ec642ceeSZi Xuan Wu if (RegNo >= 16) 152ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 153ec642ceeSZi Xuan Wu 154ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo])); 155ec642ceeSZi Xuan Wu return MCDisassembler::Success; 156ec642ceeSZi Xuan Wu } 157ec642ceeSZi Xuan Wu 158ec642ceeSZi Xuan Wu static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, 159ec642ceeSZi Xuan Wu uint64_t Address, 1604ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 161ec642ceeSZi Xuan Wu if (RegNo >= 32) 162ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 163ec642ceeSZi Xuan Wu 164ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[RegNo])); 165ec642ceeSZi Xuan Wu return MCDisassembler::Success; 166ec642ceeSZi Xuan Wu } 167ec642ceeSZi Xuan Wu 168*ef437a7dSFangrui Song // TODO 169*ef437a7dSFangrui Song LLVM_ATTRIBUTE_UNUSED 170ec642ceeSZi Xuan Wu static DecodeStatus DecodesFPR128RegisterClass(MCInst &Inst, uint64_t RegNo, 171ec642ceeSZi Xuan Wu uint64_t Address, 1724ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 173ec642ceeSZi Xuan Wu if (RegNo >= 16) 174ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 175ec642ceeSZi Xuan Wu 176ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR128DecoderTable[RegNo])); 177ec642ceeSZi Xuan Wu return MCDisassembler::Success; 178ec642ceeSZi Xuan Wu } 179ec642ceeSZi Xuan Wu 180ec642ceeSZi Xuan Wu static DecodeStatus DecodesGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 181ec642ceeSZi Xuan Wu uint64_t Address, 1824ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 183ec642ceeSZi Xuan Wu if (RegNo >= 16) 184ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 185ec642ceeSZi Xuan Wu 186ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo])); 187ec642ceeSZi Xuan Wu return MCDisassembler::Success; 188ec642ceeSZi Xuan Wu } 189ec642ceeSZi Xuan Wu 190ec642ceeSZi Xuan Wu static DecodeStatus DecodemGPRRegisterClass(MCInst &Inst, uint64_t RegNo, 191ec642ceeSZi Xuan Wu uint64_t Address, 1924ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 193ec642ceeSZi Xuan Wu if (RegNo >= 8) 194ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 195ec642ceeSZi Xuan Wu 196ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo])); 197ec642ceeSZi Xuan Wu return MCDisassembler::Success; 198ec642ceeSZi Xuan Wu } 199ec642ceeSZi Xuan Wu 200*ef437a7dSFangrui Song // TODO 201*ef437a7dSFangrui Song LLVM_ATTRIBUTE_UNUSED 202ec642ceeSZi Xuan Wu static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst, uint64_t RegNo, 203ec642ceeSZi Xuan Wu uint64_t Address, 2044ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 205ec642ceeSZi Xuan Wu if (RegNo != 14) 206ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 207ec642ceeSZi Xuan Wu 208ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(GPRDecoderTable[RegNo])); 209ec642ceeSZi Xuan Wu return MCDisassembler::Success; 210ec642ceeSZi Xuan Wu } 211ec642ceeSZi Xuan Wu 212ec642ceeSZi Xuan Wu static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint64_t RegNo, 213ec642ceeSZi Xuan Wu uint64_t Address, 2144ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 215ec642ceeSZi Xuan Wu const FeatureBitset &FeatureBits = 2164ae9745aSMaksim Panchenko Decoder->getSubtargetInfo().getFeatureBits(); 217ec642ceeSZi Xuan Wu bool hasHighReg = FeatureBits[CSKY::FeatureHighreg]; 218ec642ceeSZi Xuan Wu 219ec642ceeSZi Xuan Wu if (RegNo >= 32 || (!hasHighReg && RegNo >= 16)) 220ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 221ec642ceeSZi Xuan Wu 222ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(GPRPairDecoderTable[RegNo])); 223ec642ceeSZi Xuan Wu return MCDisassembler::Success; 224ec642ceeSZi Xuan Wu } 225ec642ceeSZi Xuan Wu 226ec642ceeSZi Xuan Wu template <unsigned N, unsigned S> 227ec642ceeSZi Xuan Wu static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 2284ae9745aSMaksim Panchenko int64_t Address, 2294ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 230ec642ceeSZi Xuan Wu assert(isUInt<N>(Imm) && "Invalid immediate"); 231ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(Imm << S)); 232ec642ceeSZi Xuan Wu return MCDisassembler::Success; 233ec642ceeSZi Xuan Wu } 234ec642ceeSZi Xuan Wu 235ec642ceeSZi Xuan Wu template <unsigned N> 236ec642ceeSZi Xuan Wu static DecodeStatus decodeOImmOperand(MCInst &Inst, uint64_t Imm, 2374ae9745aSMaksim Panchenko int64_t Address, 2384ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 239ec642ceeSZi Xuan Wu assert(isUInt<N>(Imm) && "Invalid immediate"); 240ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(Imm + 1)); 241ec642ceeSZi Xuan Wu return MCDisassembler::Success; 242ec642ceeSZi Xuan Wu } 243ec642ceeSZi Xuan Wu 244ec642ceeSZi Xuan Wu static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address, 2454ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 246ec642ceeSZi Xuan Wu assert(isUInt<8>(Imm) && "Invalid immediate"); 247ec642ceeSZi Xuan Wu if ((Imm >> 7) & 0x1) { 248ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm((Imm & 0x7F) << 2)); 249ec642ceeSZi Xuan Wu } else { 250ec642ceeSZi Xuan Wu uint64_t V = ((Imm ^ 0xFFFFFFFF) & 0xFF); 251ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(V << 2)); 252ec642ceeSZi Xuan Wu } 253ec642ceeSZi Xuan Wu 254ec642ceeSZi Xuan Wu return MCDisassembler::Success; 255ec642ceeSZi Xuan Wu } 256ec642ceeSZi Xuan Wu 257ec642ceeSZi Xuan Wu static DecodeStatus decodeJMPIXImmOperand(MCInst &Inst, uint64_t Imm, 258ec642ceeSZi Xuan Wu int64_t Address, 2594ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 260ec642ceeSZi Xuan Wu assert(isUInt<2>(Imm) && "Invalid immediate"); 261ec642ceeSZi Xuan Wu 262ec642ceeSZi Xuan Wu if (Imm == 0) 263ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(16)); 264ec642ceeSZi Xuan Wu else if (Imm == 1) 265ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(24)); 266ec642ceeSZi Xuan Wu else if (Imm == 2) 267ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(32)); 268ec642ceeSZi Xuan Wu else if (Imm == 3) 269ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(40)); 270ec642ceeSZi Xuan Wu else 271ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 272ec642ceeSZi Xuan Wu 273ec642ceeSZi Xuan Wu return MCDisassembler::Success; 274ec642ceeSZi Xuan Wu } 275ec642ceeSZi Xuan Wu 276ec642ceeSZi Xuan Wu static DecodeStatus DecodeRegSeqOperand(MCInst &Inst, uint64_t Imm, 2774ae9745aSMaksim Panchenko int64_t Address, 2784ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 279ec642ceeSZi Xuan Wu assert(isUInt<10>(Imm) && "Invalid immediate"); 280ec642ceeSZi Xuan Wu 281ec642ceeSZi Xuan Wu auto Imm5 = Imm & 0x1f; 282ec642ceeSZi Xuan Wu auto Ry = (Imm >> 5) & 0x1f; 283ec642ceeSZi Xuan Wu 284ec642ceeSZi Xuan Wu if (DecodeGPRRegisterClass(Inst, Ry, Address, Decoder) == 285ec642ceeSZi Xuan Wu MCDisassembler::Fail) 286ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 287ec642ceeSZi Xuan Wu 288ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(GPRDecoderTable[Ry + Imm5])); 289ec642ceeSZi Xuan Wu 290ec642ceeSZi Xuan Wu return MCDisassembler::Success; 291ec642ceeSZi Xuan Wu } 292ec642ceeSZi Xuan Wu 293ec642ceeSZi Xuan Wu static DecodeStatus DecodeRegSeqOperandF1(MCInst &Inst, uint64_t Imm, 294ec642ceeSZi Xuan Wu int64_t Address, 2954ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 296ec642ceeSZi Xuan Wu assert(isUInt<10>(Imm) && "Invalid immediate"); 297ec642ceeSZi Xuan Wu 298ec642ceeSZi Xuan Wu auto Imm5 = Imm & 0x1f; 299ec642ceeSZi Xuan Wu auto Ry = (Imm >> 5) & 0x1f; 300ec642ceeSZi Xuan Wu 301ec642ceeSZi Xuan Wu if (DecodesFPR32RegisterClass(Inst, Ry, Address, Decoder) == 302ec642ceeSZi Xuan Wu MCDisassembler::Fail) 303ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 304ec642ceeSZi Xuan Wu 305ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5])); 306ec642ceeSZi Xuan Wu 307ec642ceeSZi Xuan Wu return MCDisassembler::Success; 308ec642ceeSZi Xuan Wu } 309ec642ceeSZi Xuan Wu 310ec642ceeSZi Xuan Wu static DecodeStatus DecodeRegSeqOperandD1(MCInst &Inst, uint64_t Imm, 311ec642ceeSZi Xuan Wu int64_t Address, 3124ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 313ec642ceeSZi Xuan Wu assert(isUInt<10>(Imm) && "Invalid immediate"); 314ec642ceeSZi Xuan Wu 315ec642ceeSZi Xuan Wu auto Imm5 = Imm & 0x1f; 316ec642ceeSZi Xuan Wu auto Ry = (Imm >> 5) & 0x1f; 317ec642ceeSZi Xuan Wu 318ec642ceeSZi Xuan Wu if (DecodesFPR64RegisterClass(Inst, Ry, Address, Decoder) == 319ec642ceeSZi Xuan Wu MCDisassembler::Fail) 320ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 321ec642ceeSZi Xuan Wu 322ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5])); 323ec642ceeSZi Xuan Wu 324ec642ceeSZi Xuan Wu return MCDisassembler::Success; 325ec642ceeSZi Xuan Wu } 326ec642ceeSZi Xuan Wu 327ec642ceeSZi Xuan Wu static DecodeStatus DecodeRegSeqOperandF2(MCInst &Inst, uint64_t Imm, 328ec642ceeSZi Xuan Wu int64_t Address, 3294ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 330ec642ceeSZi Xuan Wu assert(isUInt<10>(Imm) && "Invalid immediate"); 331ec642ceeSZi Xuan Wu 332ec642ceeSZi Xuan Wu auto Imm5 = Imm & 0x1f; 333ec642ceeSZi Xuan Wu auto Ry = (Imm >> 5) & 0x1f; 334ec642ceeSZi Xuan Wu 335ec642ceeSZi Xuan Wu if (DecodeFPR32RegisterClass(Inst, Ry, Address, Decoder) == 336ec642ceeSZi Xuan Wu MCDisassembler::Fail) 337ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 338ec642ceeSZi Xuan Wu 339ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR32DecoderTable[Ry + Imm5])); 340ec642ceeSZi Xuan Wu 341ec642ceeSZi Xuan Wu return MCDisassembler::Success; 342ec642ceeSZi Xuan Wu } 343ec642ceeSZi Xuan Wu 344ec642ceeSZi Xuan Wu static DecodeStatus DecodeRegSeqOperandD2(MCInst &Inst, uint64_t Imm, 345ec642ceeSZi Xuan Wu int64_t Address, 3464ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 347ec642ceeSZi Xuan Wu assert(isUInt<10>(Imm) && "Invalid immediate"); 348ec642ceeSZi Xuan Wu 349ec642ceeSZi Xuan Wu auto Imm5 = Imm & 0x1f; 350ec642ceeSZi Xuan Wu auto Ry = (Imm >> 5) & 0x1f; 351ec642ceeSZi Xuan Wu 352ec642ceeSZi Xuan Wu if (DecodeFPR64RegisterClass(Inst, Ry, Address, Decoder) == 353ec642ceeSZi Xuan Wu MCDisassembler::Fail) 354ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 355ec642ceeSZi Xuan Wu 356ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createReg(FPR64DecoderTable[Ry + Imm5])); 357ec642ceeSZi Xuan Wu 358ec642ceeSZi Xuan Wu return MCDisassembler::Success; 359ec642ceeSZi Xuan Wu } 360ec642ceeSZi Xuan Wu 361ec642ceeSZi Xuan Wu static DecodeStatus decodeImmShiftOpValue(MCInst &Inst, uint64_t Imm, 362ec642ceeSZi Xuan Wu int64_t Address, 3634ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 364ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(Log2(Imm))); 365ec642ceeSZi Xuan Wu return MCDisassembler::Success; 366ec642ceeSZi Xuan Wu } 367ec642ceeSZi Xuan Wu 368ec642ceeSZi Xuan Wu template <unsigned N, unsigned S> 369ec642ceeSZi Xuan Wu static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 3704ae9745aSMaksim Panchenko int64_t Address, 3714ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 372ec642ceeSZi Xuan Wu assert(isUInt<N>(Imm) && "Invalid immediate"); 373ec642ceeSZi Xuan Wu // Sign-extend the number in the bottom N bits of Imm 374ec642ceeSZi Xuan Wu Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) << S)); 375ec642ceeSZi Xuan Wu return MCDisassembler::Success; 376ec642ceeSZi Xuan Wu } 377ec642ceeSZi Xuan Wu 378ec642ceeSZi Xuan Wu #include "CSKYGenDisassemblerTables.inc" 379ec642ceeSZi Xuan Wu 380ec642ceeSZi Xuan Wu DecodeStatus CSKYDisassembler::handleCROperand(MCInst &MI) const { 381ec642ceeSZi Xuan Wu 382ec642ceeSZi Xuan Wu // FIXME: To query instruction info from td file or a table inc file 383ec642ceeSZi Xuan Wu switch (MI.getOpcode()) { 384ec642ceeSZi Xuan Wu default: 385ec642ceeSZi Xuan Wu return MCDisassembler::Success; 386ec642ceeSZi Xuan Wu case CSKY::LD16WSP: 387ec642ceeSZi Xuan Wu case CSKY::ST16WSP: 388ec642ceeSZi Xuan Wu case CSKY::ADDI16ZSP: 389ec642ceeSZi Xuan Wu MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::R14)); 390ec642ceeSZi Xuan Wu return MCDisassembler::Success; 391ec642ceeSZi Xuan Wu case CSKY::ADDI16SPSP: 392ec642ceeSZi Xuan Wu case CSKY::SUBI16SPSP: 393ec642ceeSZi Xuan Wu MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14)); 394ec642ceeSZi Xuan Wu MI.insert(MI.begin(), MCOperand::createReg(CSKY::R14)); 395ec642ceeSZi Xuan Wu return MCDisassembler::Success; 396ec642ceeSZi Xuan Wu case CSKY::FCMPHS_S: 397ec642ceeSZi Xuan Wu case CSKY::FCMPHS_D: 398ec642ceeSZi Xuan Wu case CSKY::FCMPLT_S: 399ec642ceeSZi Xuan Wu case CSKY::FCMPLT_D: 400ec642ceeSZi Xuan Wu case CSKY::FCMPNE_S: 401ec642ceeSZi Xuan Wu case CSKY::FCMPNE_D: 402ec642ceeSZi Xuan Wu case CSKY::FCMPUO_S: 403ec642ceeSZi Xuan Wu case CSKY::FCMPUO_D: 404ec642ceeSZi Xuan Wu case CSKY::FCMPZHS_S: 405ec642ceeSZi Xuan Wu case CSKY::FCMPZHS_D: 406ec642ceeSZi Xuan Wu case CSKY::FCMPZLS_S: 407ec642ceeSZi Xuan Wu case CSKY::FCMPZLS_D: 408ec642ceeSZi Xuan Wu case CSKY::FCMPZNE_S: 409ec642ceeSZi Xuan Wu case CSKY::FCMPZNE_D: 410ec642ceeSZi Xuan Wu case CSKY::FCMPZUO_S: 411ec642ceeSZi Xuan Wu case CSKY::FCMPZUO_D: 412ec642ceeSZi Xuan Wu case CSKY::f2FCMPHS_S: 413ec642ceeSZi Xuan Wu case CSKY::f2FCMPHS_D: 414ec642ceeSZi Xuan Wu case CSKY::f2FCMPLT_S: 415ec642ceeSZi Xuan Wu case CSKY::f2FCMPLT_D: 416ec642ceeSZi Xuan Wu case CSKY::f2FCMPNE_S: 417ec642ceeSZi Xuan Wu case CSKY::f2FCMPNE_D: 418ec642ceeSZi Xuan Wu case CSKY::f2FCMPUO_S: 419ec642ceeSZi Xuan Wu case CSKY::f2FCMPUO_D: 420ec642ceeSZi Xuan Wu case CSKY::f2FCMPHSZ_S: 421ec642ceeSZi Xuan Wu case CSKY::f2FCMPHSZ_D: 422ec642ceeSZi Xuan Wu case CSKY::f2FCMPHZ_S: 423ec642ceeSZi Xuan Wu case CSKY::f2FCMPHZ_D: 424ec642ceeSZi Xuan Wu case CSKY::f2FCMPLSZ_S: 425ec642ceeSZi Xuan Wu case CSKY::f2FCMPLSZ_D: 426ec642ceeSZi Xuan Wu case CSKY::f2FCMPLTZ_S: 427ec642ceeSZi Xuan Wu case CSKY::f2FCMPLTZ_D: 428ec642ceeSZi Xuan Wu case CSKY::f2FCMPNEZ_S: 429ec642ceeSZi Xuan Wu case CSKY::f2FCMPNEZ_D: 430ec642ceeSZi Xuan Wu case CSKY::f2FCMPUOZ_S: 431ec642ceeSZi Xuan Wu case CSKY::f2FCMPUOZ_D: 432ec642ceeSZi Xuan Wu 433ec642ceeSZi Xuan Wu case CSKY::BT32: 434ec642ceeSZi Xuan Wu case CSKY::BF32: 435ec642ceeSZi Xuan Wu case CSKY::BT16: 436ec642ceeSZi Xuan Wu case CSKY::BF16: 437ec642ceeSZi Xuan Wu case CSKY::CMPNEI32: 438ec642ceeSZi Xuan Wu case CSKY::CMPNEI16: 439ec642ceeSZi Xuan Wu case CSKY::CMPNE32: 440ec642ceeSZi Xuan Wu case CSKY::CMPNE16: 441ec642ceeSZi Xuan Wu case CSKY::CMPHSI32: 442ec642ceeSZi Xuan Wu case CSKY::CMPHSI16: 443ec642ceeSZi Xuan Wu case CSKY::CMPHS32: 444ec642ceeSZi Xuan Wu case CSKY::CMPHS16: 445ec642ceeSZi Xuan Wu case CSKY::CMPLTI32: 446ec642ceeSZi Xuan Wu case CSKY::CMPLTI16: 447ec642ceeSZi Xuan Wu case CSKY::CMPLT32: 448ec642ceeSZi Xuan Wu case CSKY::CMPLT16: 449ec642ceeSZi Xuan Wu case CSKY::BTSTI32: 450ec642ceeSZi Xuan Wu case CSKY::BTSTI16: 451ec642ceeSZi Xuan Wu case CSKY::TSTNBZ32: 452ec642ceeSZi Xuan Wu case CSKY::TSTNBZ16: 453ec642ceeSZi Xuan Wu case CSKY::TST32: 454ec642ceeSZi Xuan Wu case CSKY::TST16: 455ec642ceeSZi Xuan Wu MI.insert(MI.begin(), MCOperand::createReg(CSKY::C)); 456ec642ceeSZi Xuan Wu return MCDisassembler::Success; 457ec642ceeSZi Xuan Wu case CSKY::LSLC32: 458ec642ceeSZi Xuan Wu case CSKY::LSRC32: 459ec642ceeSZi Xuan Wu case CSKY::ASRC32: 460ec642ceeSZi Xuan Wu MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C)); 461ec642ceeSZi Xuan Wu return MCDisassembler::Success; 462ec642ceeSZi Xuan Wu case CSKY::MOVF32: 463ec642ceeSZi Xuan Wu case CSKY::MOVT32: 464ec642ceeSZi Xuan Wu case CSKY::MVC32: 465ec642ceeSZi Xuan Wu case CSKY::MVCV32: 466ec642ceeSZi Xuan Wu case CSKY::MVCV16: 467ec642ceeSZi Xuan Wu case CSKY::INCT32: 468ec642ceeSZi Xuan Wu case CSKY::INCF32: 469ec642ceeSZi Xuan Wu case CSKY::DECT32: 470ec642ceeSZi Xuan Wu case CSKY::DECF32: 471ec642ceeSZi Xuan Wu case CSKY::DECGT32: 472ec642ceeSZi Xuan Wu case CSKY::DECLT32: 473ec642ceeSZi Xuan Wu case CSKY::DECNE32: 474ec642ceeSZi Xuan Wu case CSKY::CLRF32: 475ec642ceeSZi Xuan Wu case CSKY::CLRT32: 476ec642ceeSZi Xuan Wu case CSKY::f2FSEL_S: 477ec642ceeSZi Xuan Wu case CSKY::f2FSEL_D: 478ec642ceeSZi Xuan Wu MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C)); 479ec642ceeSZi Xuan Wu return MCDisassembler::Success; 480ec642ceeSZi Xuan Wu case CSKY::ADDC32: 481ec642ceeSZi Xuan Wu case CSKY::ADDC16: 482ec642ceeSZi Xuan Wu case CSKY::SUBC32: 483ec642ceeSZi Xuan Wu case CSKY::SUBC16: 484ec642ceeSZi Xuan Wu case CSKY::XSR32: 485ec642ceeSZi Xuan Wu MI.insert(std::next(MI.begin()), MCOperand::createReg(CSKY::C)); 486ec642ceeSZi Xuan Wu MI.insert(MI.end(), MCOperand::createReg(CSKY::C)); 487ec642ceeSZi Xuan Wu return MCDisassembler::Success; 488ec642ceeSZi Xuan Wu case CSKY::INS32: 489ec642ceeSZi Xuan Wu MI.getOperand(3).setImm(MI.getOperand(3).getImm() + 490ec642ceeSZi Xuan Wu MI.getOperand(4).getImm()); 491ec642ceeSZi Xuan Wu return MCDisassembler::Success; 492ec642ceeSZi Xuan Wu } 493ec642ceeSZi Xuan Wu } 494ec642ceeSZi Xuan Wu 495ec642ceeSZi Xuan Wu static bool decodeFPUV3Instruction(MCInst &MI, uint32_t insn, uint64_t Address, 4964ae9745aSMaksim Panchenko const MCDisassembler *DisAsm, 497ec642ceeSZi Xuan Wu const MCSubtargetInfo &STI) { 498ec642ceeSZi Xuan Wu LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit fpuv3 table :\n"); 499ec642ceeSZi Xuan Wu if (!STI.getFeatureBits()[CSKY::FeatureFPUV3_HF] && 500ec642ceeSZi Xuan Wu !STI.getFeatureBits()[CSKY::FeatureFPUV3_SF] && 501ec642ceeSZi Xuan Wu !STI.getFeatureBits()[CSKY::FeatureFPUV3_DF]) 502ec642ceeSZi Xuan Wu return false; 503ec642ceeSZi Xuan Wu 504ec642ceeSZi Xuan Wu DecodeStatus Result = 505ec642ceeSZi Xuan Wu decodeInstruction(DecoderTableFPUV332, MI, insn, Address, DisAsm, STI); 506ec642ceeSZi Xuan Wu 507ec642ceeSZi Xuan Wu if (Result == MCDisassembler::Fail) { 508ec642ceeSZi Xuan Wu MI.clear(); 509ec642ceeSZi Xuan Wu return false; 510ec642ceeSZi Xuan Wu } 511ec642ceeSZi Xuan Wu 512ec642ceeSZi Xuan Wu return true; 513ec642ceeSZi Xuan Wu } 514ec642ceeSZi Xuan Wu 515ec642ceeSZi Xuan Wu DecodeStatus CSKYDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 516ec642ceeSZi Xuan Wu ArrayRef<uint8_t> Bytes, 517ec642ceeSZi Xuan Wu uint64_t Address, 518ec642ceeSZi Xuan Wu raw_ostream &CS) const { 519ec642ceeSZi Xuan Wu 520ec642ceeSZi Xuan Wu uint32_t Insn; 521ec642ceeSZi Xuan Wu DecodeStatus Result = MCDisassembler::Fail; 522ec642ceeSZi Xuan Wu 523ec642ceeSZi Xuan Wu Insn = support::endian::read16le(Bytes.data()); 524ec642ceeSZi Xuan Wu 525ec642ceeSZi Xuan Wu if ((Insn >> 14) == 0x3) { 526ec642ceeSZi Xuan Wu if (Bytes.size() < 4) { 527ec642ceeSZi Xuan Wu Size = 0; 528ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 529ec642ceeSZi Xuan Wu } 530ec642ceeSZi Xuan Wu Insn = (Insn << 16) | support::endian::read16le(&Bytes[2]); 531ec642ceeSZi Xuan Wu 532ec642ceeSZi Xuan Wu if (decodeFPUV3Instruction(MI, Insn, Address, this, STI)) 533ec642ceeSZi Xuan Wu Result = MCDisassembler::Success; 534ec642ceeSZi Xuan Wu else { 535ec642ceeSZi Xuan Wu LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit table :\n"); 536ec642ceeSZi Xuan Wu Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI); 537ec642ceeSZi Xuan Wu } 538ec642ceeSZi Xuan Wu 539ec642ceeSZi Xuan Wu Size = 4; 540ec642ceeSZi Xuan Wu } else { 541ec642ceeSZi Xuan Wu if (Bytes.size() < 2) { 542ec642ceeSZi Xuan Wu Size = 0; 543ec642ceeSZi Xuan Wu return MCDisassembler::Fail; 544ec642ceeSZi Xuan Wu } 545ec642ceeSZi Xuan Wu LLVM_DEBUG(dbgs() << "Trying CSKY 16-bit table :\n"); 546ec642ceeSZi Xuan Wu Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI); 547ec642ceeSZi Xuan Wu Size = 2; 548ec642ceeSZi Xuan Wu } 549ec642ceeSZi Xuan Wu 550ec642ceeSZi Xuan Wu handleCROperand(MI); 551ec642ceeSZi Xuan Wu 552ec642ceeSZi Xuan Wu return Result; 553ec642ceeSZi Xuan Wu } 554