LLVM 22.0.0git
CSKYDisassembler.cpp
Go to the documentation of this file.
1//===-- CSKYDisassembler.cpp - Disassembler for CSKY ----------------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the CSKYDisassembler class.
10//
11//===----------------------------------------------------------------------===//
12
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/MC/MCContext.h"
18#include "llvm/MC/MCDecoder.h"
21#include "llvm/MC/MCInst.h"
22#include "llvm/MC/MCInstrInfo.h"
26#include "llvm/Support/Endian.h"
27
28using namespace llvm;
29
30#define DEBUG_TYPE "csky-disassembler"
31
33
34namespace {
35class CSKYDisassembler : public MCDisassembler {
36 std::unique_ptr<MCInstrInfo const> const MCII;
37 mutable StringRef symbolName;
38
39public:
40 CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
41 MCInstrInfo const *MCII);
42
43 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
44 ArrayRef<uint8_t> Bytes, uint64_t Address,
45 raw_ostream &CStream) const override;
46};
47} // end anonymous namespace
48
49CSKYDisassembler::CSKYDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
50 MCInstrInfo const *MCII)
51 : MCDisassembler(STI, Ctx), MCII(MCII) {}
52
54 const MCSubtargetInfo &STI,
55 MCContext &Ctx) {
56 return new CSKYDisassembler(STI, Ctx, T.createMCInstrInfo());
57}
58
63
64static const uint16_t GPRDecoderTable[] = {
65 CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3, CSKY::R4, CSKY::R5, CSKY::R6,
66 CSKY::R7, CSKY::R8, CSKY::R9, CSKY::R10, CSKY::R11, CSKY::R12, CSKY::R13,
67 CSKY::R14, CSKY::R15, CSKY::R16, CSKY::R17, CSKY::R18, CSKY::R19, CSKY::R20,
68 CSKY::R21, CSKY::R22, CSKY::R23, CSKY::R24, CSKY::R25, CSKY::R26, CSKY::R27,
69 CSKY::R28, CSKY::R29, CSKY::R30, CSKY::R31};
70
71static const uint16_t GPRPairDecoderTable[] = {
72 CSKY::R0_R1, CSKY::R1_R2, CSKY::R2_R3, CSKY::R3_R4, CSKY::R4_R5,
73 CSKY::R5_R6, CSKY::R6_R7, CSKY::R7_R8, CSKY::R8_R9, CSKY::R9_R10,
74 CSKY::R10_R11, CSKY::R11_R12, CSKY::R12_R13, CSKY::R13_R14, CSKY::R14_R15,
75 CSKY::R15_R16, CSKY::R16_R17, CSKY::R17_R18, CSKY::R18_R19, CSKY::R19_R20,
76 CSKY::R20_R21, CSKY::R21_R22, CSKY::R22_R23, CSKY::R23_R24, CSKY::R24_R25,
77 CSKY::R25_R26, CSKY::R26_R27, CSKY::R27_R28, CSKY::R28_R29, CSKY::R29_R30,
78 CSKY::R30_R31, CSKY::R31_R32};
79
80static const uint16_t FPR32DecoderTable[] = {
81 CSKY::F0_32, CSKY::F1_32, CSKY::F2_32, CSKY::F3_32, CSKY::F4_32,
82 CSKY::F5_32, CSKY::F6_32, CSKY::F7_32, CSKY::F8_32, CSKY::F9_32,
83 CSKY::F10_32, CSKY::F11_32, CSKY::F12_32, CSKY::F13_32, CSKY::F14_32,
84 CSKY::F15_32, CSKY::F16_32, CSKY::F17_32, CSKY::F18_32, CSKY::F19_32,
85 CSKY::F20_32, CSKY::F21_32, CSKY::F22_32, CSKY::F23_32, CSKY::F24_32,
86 CSKY::F25_32, CSKY::F26_32, CSKY::F27_32, CSKY::F28_32, CSKY::F29_32,
87 CSKY::F30_32, CSKY::F31_32};
88
89static const uint16_t FPR64DecoderTable[] = {
90 CSKY::F0_64, CSKY::F1_64, CSKY::F2_64, CSKY::F3_64, CSKY::F4_64,
91 CSKY::F5_64, CSKY::F6_64, CSKY::F7_64, CSKY::F8_64, CSKY::F9_64,
92 CSKY::F10_64, CSKY::F11_64, CSKY::F12_64, CSKY::F13_64, CSKY::F14_64,
93 CSKY::F15_64, CSKY::F16_64, CSKY::F17_64, CSKY::F18_64, CSKY::F19_64,
94 CSKY::F20_64, CSKY::F21_64, CSKY::F22_64, CSKY::F23_64, CSKY::F24_64,
95 CSKY::F25_64, CSKY::F26_64, CSKY::F27_64, CSKY::F28_64, CSKY::F29_64,
96 CSKY::F30_64, CSKY::F31_64};
97
98static const uint16_t FPR128DecoderTable[] = {
99 CSKY::F0_128, CSKY::F1_128, CSKY::F2_128, CSKY::F3_128, CSKY::F4_128,
100 CSKY::F5_128, CSKY::F6_128, CSKY::F7_128, CSKY::F8_128, CSKY::F9_128,
101 CSKY::F10_128, CSKY::F11_128, CSKY::F12_128, CSKY::F13_128, CSKY::F14_128,
102 CSKY::F15_128, CSKY::F16_128, CSKY::F17_128, CSKY::F18_128, CSKY::F19_128,
103 CSKY::F20_128, CSKY::F21_128, CSKY::F22_128, CSKY::F23_128, CSKY::F24_128,
104 CSKY::F25_128, CSKY::F26_128, CSKY::F27_128, CSKY::F28_128, CSKY::F29_128,
105 CSKY::F30_128, CSKY::F31_128};
106
108 uint64_t Address,
109 const MCDisassembler *Decoder) {
110 if (RegNo >= 32)
112
115}
116
118 uint64_t Address,
119 const MCDisassembler *Decoder) {
120 if (RegNo >= 32)
122
125}
126
128 uint64_t Address,
129 const MCDisassembler *Decoder) {
130 if (RegNo >= 16)
132
135}
136
138 uint64_t Address,
139 const MCDisassembler *Decoder) {
140 if (RegNo >= 16)
142
145}
146
148 uint64_t Address,
149 const MCDisassembler *Decoder) {
150 if (RegNo >= 16)
152
155}
156
158 uint64_t Address,
159 const MCDisassembler *Decoder) {
160 if (RegNo >= 32)
162
165}
166
167// TODO
170 uint64_t Address,
171 const MCDisassembler *Decoder) {
172 if (RegNo >= 16)
174
177}
178
180 uint64_t Address,
181 const MCDisassembler *Decoder) {
182 if (RegNo >= 16)
184
187}
188
190 uint64_t Address,
191 const MCDisassembler *Decoder) {
192 if (RegNo >= 8)
194
197}
198
200 const MCDisassembler *Decoder) {
201 Inst.addOperand(MCOperand::createReg(CSKY::R14));
203}
204
206 uint64_t Address,
207 const MCDisassembler *Decoder) {
208 const FeatureBitset &FeatureBits =
209 Decoder->getSubtargetInfo().getFeatureBits();
210 bool hasHighReg = FeatureBits[CSKY::FeatureHighreg];
211
212 if (RegNo >= 32 || (!hasHighReg && RegNo >= 16))
214
217}
218
220 const MCDisassembler *Decoder) {
221 Inst.addOperand(MCOperand::createReg(CSKY::C));
223}
224
225template <unsigned N, unsigned S>
227 int64_t Address,
228 const MCDisassembler *Decoder) {
229 assert(isUInt<N>(Imm) && "Invalid immediate");
230 Inst.addOperand(MCOperand::createImm(Imm << S));
232}
233
234template <unsigned N>
236 int64_t Address,
237 const MCDisassembler *Decoder) {
238 assert(isUInt<N>(Imm) && "Invalid immediate");
239 Inst.addOperand(MCOperand::createImm(Imm + 1));
241}
242
243static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address,
244 const MCDisassembler *Decoder) {
245 assert(isUInt<8>(Imm) && "Invalid immediate");
246 if ((Imm >> 7) & 0x1) {
247 Inst.addOperand(MCOperand::createImm((Imm & 0x7F) << 2));
248 } else {
249 uint64_t V = ((Imm ^ 0xFFFFFFFF) & 0xFF);
250 Inst.addOperand(MCOperand::createImm(V << 2));
251 }
252
254}
255
257 int64_t Address,
258 const MCDisassembler *Decoder) {
259 assert(isUInt<2>(Imm) && "Invalid immediate");
260
261 if (Imm == 0)
263 else if (Imm == 1)
265 else if (Imm == 2)
267 else if (Imm == 3)
269 else
271
273}
274
276 int64_t Address,
277 const MCDisassembler *Decoder) {
278 assert(isUInt<10>(Imm) && "Invalid immediate");
279
280 auto Imm5 = Imm & 0x1f;
281 auto Ry = (Imm >> 5) & 0x1f;
282
283 if (DecodeGPRRegisterClass(Inst, Ry, Address, Decoder) ==
286
288
290}
291
293 int64_t Address,
294 const MCDisassembler *Decoder) {
295 assert(isUInt<10>(Imm) && "Invalid immediate");
296
297 auto Imm5 = Imm & 0x1f;
298 auto Ry = (Imm >> 5) & 0x1f;
299
300 if (DecodesFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
303
305
307}
308
310 int64_t Address,
311 const MCDisassembler *Decoder) {
312 assert(isUInt<10>(Imm) && "Invalid immediate");
313
314 auto Imm5 = Imm & 0x1f;
315 auto Ry = (Imm >> 5) & 0x1f;
316
317 if (DecodesFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
320
322
324}
325
327 int64_t Address,
328 const MCDisassembler *Decoder) {
329 assert(isUInt<10>(Imm) && "Invalid immediate");
330
331 auto Imm5 = Imm & 0x1f;
332 auto Ry = (Imm >> 5) & 0x1f;
333
334 if (DecodeFPR32RegisterClass(Inst, Ry, Address, Decoder) ==
337
339
341}
342
344 int64_t Address,
345 const MCDisassembler *Decoder) {
346 assert(isUInt<10>(Imm) && "Invalid immediate");
347
348 auto Imm5 = Imm & 0x1f;
349 auto Ry = (Imm >> 5) & 0x1f;
350
351 if (DecodeFPR64RegisterClass(Inst, Ry, Address, Decoder) ==
354
356
358}
359
361 int64_t Address,
362 const MCDisassembler *Decoder) {
365}
366
367template <unsigned N, unsigned S>
369 int64_t Address,
370 const MCDisassembler *Decoder) {
371 assert(isUInt<N>(Imm) && "Invalid immediate");
372 // Sign-extend the number in the bottom N bits of Imm
375}
376
377#include "CSKYGenDisassemblerTables.inc"
378
380 const MCDisassembler *DisAsm,
381 const MCSubtargetInfo &STI) {
382 LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit fpuv3 table :\n");
383 if (!STI.hasFeature(CSKY::FeatureFPUV3_HF) &&
384 !STI.hasFeature(CSKY::FeatureFPUV3_SF) &&
385 !STI.hasFeature(CSKY::FeatureFPUV3_DF))
386 return false;
387
388 DecodeStatus Result =
389 decodeInstruction(DecoderTableFPUV332, MI, insn, Address, DisAsm, STI);
390
391 if (Result == MCDisassembler::Fail) {
392 MI.clear();
393 return false;
394 }
395
396 return true;
397}
398
399DecodeStatus CSKYDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
400 ArrayRef<uint8_t> Bytes,
401 uint64_t Address,
402 raw_ostream &CS) const {
403
404 uint32_t Insn;
406
407 Insn = support::endian::read16le(Bytes.data());
408
409 if ((Insn >> 14) == 0x3) {
410 if (Bytes.size() < 4) {
411 Size = 0;
413 }
414 Insn = (Insn << 16) | support::endian::read16le(&Bytes[2]);
415
416 if (decodeFPUV3Instruction(MI, Insn, Address, this, STI))
418 else {
419 LLVM_DEBUG(dbgs() << "Trying CSKY 32-bit table :\n");
420 Result = decodeInstruction(DecoderTable32, MI, Insn, Address, this, STI);
421 }
422
423 Size = 4;
424 } else {
425 if (Bytes.size() < 2) {
426 Size = 0;
428 }
429 LLVM_DEBUG(dbgs() << "Trying CSKY 16-bit table :\n");
430 Result = decodeInstruction(DecoderTable16, MI, Insn, Address, this, STI);
431 Size = 2;
432 }
433
434 if (MI.getOpcode() == CSKY::INS32) {
435 MI.getOperand(3).setImm(MI.getOperand(3).getImm() +
436 MI.getOperand(4).getImm());
437 }
438
439 return Result;
440}
MCDisassembler::DecodeStatus DecodeStatus
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const uint16_t GPRPairDecoderTable[]
static const uint16_t GPRDecoderTable[]
static LLVM_ATTRIBUTE_UNUSED DecodeStatus DecodesFPR128RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static const uint16_t FPR32DecoderTable[]
static DecodeStatus DecodeRegSeqOperandF2(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodesFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYDisassembler()
static DecodeStatus decodeJMPIXImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static const uint16_t FPR128DecoderTable[]
static MCDisassembler * createCSKYDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus DecodeFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeCARRYRegisterClass(MCInst &Inst, const MCDisassembler *Decoder)
static DecodeStatus DecodeRegSeqOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeLRW16Imm8(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeRegSeqOperandF1(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodesGPRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeRegSeqOperandD2(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeOImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFPR32RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeImmShiftOpValue(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodesFPR64_VRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeRegSeqOperandD1(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodemGPRRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static bool decodeFPUV3Instruction(MCInst &MI, uint32_t insn, uint64_t Address, const MCDisassembler *DisAsm, const MCSubtargetInfo &STI)
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, int64_t Address, const MCDisassembler *Decoder)
static const uint16_t FPR64DecoderTable[]
static DecodeStatus DecodeGPRSPRegisterClass(MCInst &Inst, const MCDisassembler *Decoder)
static DecodeStatus DecodesFPR64RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
#define LLVM_ATTRIBUTE_UNUSED
Definition Compiler.h:298
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
This file defines the DenseMap class.
IRTranslator LLVM IR MI
#define T
#define LLVM_DEBUG(...)
Definition Debug.h:119
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition ArrayRef.h:147
const T * data() const
Definition ArrayRef.h:144
Container class for subtarget features.
Context object for machine code objects.
Definition MCContext.h:83
Superclass for all disassemblers.
const MCSubtargetInfo & getSubtargetInfo() const
DecodeStatus
Ternary decode status.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
void addOperand(const MCOperand Op)
Definition MCInst.h:215
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
static MCOperand createReg(MCRegister Reg)
Definition MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition MCInst.h:145
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Target - Wrapper for Target specific information.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
uint16_t read16le(const void *P)
Definition Endian.h:426
This is an optimization pass for GlobalISel generic memory operations.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:342
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:198
Target & getTheCSKYTarget()
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:577
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.