LLVM  14.0.0git
ARCDisassembler.cpp
Go to the documentation of this file.
1 //===- ARCDisassembler.cpp - Disassembler for ARC ---------------*- C++ -*-===//
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 /// \file
10 /// This file is part of the ARC Disassembler.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "ARC.h"
15 #include "ARCRegisterInfo.h"
18 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/TargetRegistry.h"
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "arc-disassembler"
29 
31 
32 namespace {
33 
34 /// A disassembler class for ARC.
35 class ARCDisassembler : public MCDisassembler {
36 public:
37  std::unique_ptr<MCInstrInfo const> const MCII;
38 
39  ARCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
40  MCInstrInfo const *MCII)
41  : MCDisassembler(STI, Ctx), MCII(MCII) {}
42 
43  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
45  raw_ostream &CStream) const override;
46 };
47 
48 } // end anonymous namespace
49 
50 static bool readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
52  Size = 4;
53  // Read 2 16-bit values, but swap hi/lo parts.
54  Insn =
55  (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
56  return true;
57 }
58 
59 static bool readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address,
61  Size = 8;
62  Insn = ((uint64_t)Bytes[0] << 16) | ((uint64_t)Bytes[1] << 24) |
63  ((uint64_t)Bytes[2] << 0) | ((uint64_t)Bytes[3] << 8) |
64  ((uint64_t)Bytes[4] << 48) | ((uint64_t)Bytes[5] << 56) |
65  ((uint64_t)Bytes[6] << 32) | ((uint64_t)Bytes[7] << 40);
66  return true;
67 }
68 
69 static bool readInstruction48(ArrayRef<uint8_t> Bytes, uint64_t Address,
71  Size = 6;
72  Insn = ((uint64_t)Bytes[0] << 0) | ((uint64_t)Bytes[1] << 8) |
73  ((uint64_t)Bytes[2] << 32) | ((uint64_t)Bytes[3] << 40) |
74  ((uint64_t)Bytes[4] << 16) | ((uint64_t)Bytes[5] << 24);
75  return true;
76 }
77 
78 static bool readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
80  Size = 2;
81  Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
82  return true;
83 }
84 
85 template <unsigned B>
86 static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS,
87  uint64_t Address = 0,
88  const void *Decoder = nullptr);
89 
90 template <unsigned B>
91 static DecodeStatus DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS,
92  uint64_t Address = 0,
93  const void *Decoder = nullptr);
94 
95 template <unsigned B>
96 static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS,
97  uint64_t Address, const void *Decoder);
98 
99 static DecodeStatus DecodeMEMrs9(MCInst &, unsigned, uint64_t, const void *);
100 
102  const void *);
103 
105  const void *);
106 
108  const void *);
109 
111  const void *);
112 
114  const void *);
115 
117  const void *);
118 
120  const void *);
121 
122 static const uint16_t GPR32DecoderTable[] = {
123  ARC::R0, ARC::R1, ARC::R2, ARC::R3, ARC::R4, ARC::R5, ARC::R6,
124  ARC::R7, ARC::R8, ARC::R9, ARC::R10, ARC::R11, ARC::R12, ARC::R13,
125  ARC::R14, ARC::R15, ARC::R16, ARC::R17, ARC::R18, ARC::R19, ARC::R20,
126  ARC::R21, ARC::R22, ARC::R23, ARC::R24, ARC::R25, ARC::GP, ARC::FP,
127  ARC::SP, ARC::ILINK, ARC::R30, ARC::BLINK};
128 
129 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
130  uint64_t Address,
131  const void *Decoder) {
132  if (RegNo >= 32) {
133  LLVM_DEBUG(dbgs() << "Not a GPR32 register.");
134  return MCDisassembler::Fail;
135  }
136 
137  unsigned Reg = GPR32DecoderTable[RegNo];
140 }
141 
142 static DecodeStatus DecodeGBR32ShortRegister(MCInst &Inst, unsigned RegNo,
143  uint64_t Address,
144  const void *Decoder) {
145  // Enumerates registers from ranges [r0-r3],[r12-r15].
146  if (RegNo > 3)
147  RegNo += 8; // 4 for r12, etc...
148 
149  return DecodeGPR32RegisterClass(Inst, RegNo, Address, Decoder);
150 }
151 
152 #include "ARCGenDisassemblerTables.inc"
153 
154 static unsigned decodeCField(unsigned Insn) {
155  return fieldFromInstruction(Insn, 6, 6);
156 }
157 
158 static unsigned decodeBField(unsigned Insn) {
159  return (fieldFromInstruction(Insn, 12, 3) << 3) |
160  fieldFromInstruction(Insn, 24, 3);
161 }
162 
163 static unsigned decodeAField(unsigned Insn) {
164  return fieldFromInstruction(Insn, 0, 6);
165 }
166 
167 static DecodeStatus DecodeMEMrs9(MCInst &Inst, unsigned Insn, uint64_t Address,
168  const void *Dec) {
169  // We have the 9-bit immediate in the low bits, 6-bit register in high bits.
170  unsigned S9 = Insn & 0x1ff;
171  unsigned R = (Insn & (0x7fff & ~0x1ff)) >> 9;
172  DecodeGPR32RegisterClass(Inst, R, Address, Dec);
173  Inst.addOperand(MCOperand::createImm(SignExtend32<9>(S9)));
175 }
176 
177 static bool DecodeSymbolicOperand(MCInst &Inst, uint64_t Address,
178  uint64_t Value, const void *Decoder) {
179  static const uint64_t AtLeast = 2;
180  // TODO: Try to force emitter to use MCDisassembler* instead of void*.
181  auto Disassembler = static_cast<const MCDisassembler *>(Decoder);
182  return (nullptr != Disassembler &&
183  Disassembler->tryAddingSymbolicOperand(Inst, Value, Address, true, 0,
184  AtLeast));
185 }
186 
187 static void DecodeSymbolicOperandOff(MCInst &Inst, uint64_t Address,
188  uint64_t Offset, const void *Decoder) {
189  uint64_t NextAddress = Address + Offset;
190 
191  if (!DecodeSymbolicOperand(Inst, Address, NextAddress, Decoder))
193 }
194 
195 template <unsigned B>
196 static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS,
197  uint64_t Address, const void *Decoder) {
198 
199  static_assert(B > 0, "field is empty");
200  DecodeSymbolicOperandOff(Inst, Address, SignExtend32<B>(InsnS), Decoder);
202 }
203 
204 template <unsigned B>
205 static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS,
206  uint64_t /*Address*/,
207  const void * /*Decoder*/) {
208 
209  static_assert(B > 0, "field is empty");
211  SignExtend32<B>(maskTrailingOnes<decltype(InsnS)>(B) & InsnS)));
213 }
214 
215 template <unsigned B>
216 static DecodeStatus DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS,
217  uint64_t /*Address*/,
218  const void * /*Decoder*/) {
219 
220  static_assert(B > 0, "field is empty");
221  const unsigned max = (1u << B) - 1;
222  Inst.addOperand(
223  MCOperand::createImm(InsnS < max ? static_cast<int>(InsnS) : -1));
225 }
226 
228  uint64_t Address,
229  const void *Decoder) {
230  unsigned SrcC, DstB, LImm;
231  DstB = decodeBField(Insn);
232  if (DstB != 62) {
233  LLVM_DEBUG(dbgs() << "Decoding StLImm found non-limm register.");
234  return MCDisassembler::Fail;
235  }
236  SrcC = decodeCField(Insn);
237  DecodeGPR32RegisterClass(Inst, SrcC, Address, Decoder);
238  LImm = (Insn >> 32);
239  Inst.addOperand(MCOperand::createImm(LImm));
242 }
243 
245  uint64_t Address,
246  const void *Decoder) {
247  unsigned DstA, SrcB, LImm;
248  LLVM_DEBUG(dbgs() << "Decoding LdLImm:\n");
249  SrcB = decodeBField(Insn);
250  if (SrcB != 62) {
251  LLVM_DEBUG(dbgs() << "Decoding LdLImm found non-limm register.");
252  return MCDisassembler::Fail;
253  }
254  DstA = decodeAField(Insn);
255  DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder);
256  LImm = (Insn >> 32);
257  Inst.addOperand(MCOperand::createImm(LImm));
260 }
261 
263  uint64_t Address,
264  const void *Decoder) {
265  unsigned DstA, SrcB;
266  LLVM_DEBUG(dbgs() << "Decoding LdRLimm\n");
267  DstA = decodeAField(Insn);
268  DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder);
269  SrcB = decodeBField(Insn);
270  DecodeGPR32RegisterClass(Inst, SrcB, Address, Decoder);
271  if (decodeCField(Insn) != 62) {
272  LLVM_DEBUG(dbgs() << "Decoding LdRLimm found non-limm register.");
273  return MCDisassembler::Fail;
274  }
277 }
278 
280  uint64_t Address,
281  const void *Decoder) {
282  LLVM_DEBUG(dbgs() << "Decoding MOV_S h-register\n");
283  using Field = decltype(Insn);
284  Field H = fieldFromInstruction(Insn, 5, 3) |
285  (fieldFromInstruction(Insn, 0, 2) << 3);
286  Field G = fieldFromInstruction(Insn, 8, 3) |
287  (fieldFromInstruction(Insn, 3, 2) << 3);
288 
289  auto DecodeRegisterOrImm = [&Inst, Address, Decoder](Field RegNum,
290  Field Value) {
291  if (30 == RegNum) {
294  }
295 
296  return DecodeGPR32RegisterClass(Inst, RegNum, Address, Decoder);
297  };
298 
299  if (MCDisassembler::Success != DecodeRegisterOrImm(G, 0))
300  return MCDisassembler::Fail;
301 
302  return DecodeRegisterOrImm(H, Insn >> 16u);
303 }
304 
306  uint64_t Address,
307  const void *Decoder) {
308  unsigned DstB;
309  LLVM_DEBUG(dbgs() << "Decoding CCRU6 instruction:\n");
310  DstB = decodeBField(Insn);
311  DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder);
312  using Field = decltype(Insn);
313  Field U6Field = fieldFromInstruction(Insn, 6, 6);
314  Inst.addOperand(MCOperand::createImm(U6Field));
315  Field CCField = fieldFromInstruction(Insn, 0, 4);
316  Inst.addOperand(MCOperand::createImm(CCField));
318 }
319 
321  uint64_t Address, const void *Decoder) {
322  unsigned DstB = decodeBField(Insn);
323  DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder);
324  using Field = decltype(Insn);
325  Field U6 = fieldFromInstruction(Insn, 6, 6);
328 }
329 
331  uint64_t Address, const void *Decoder) {
332  unsigned DstB = decodeBField(Insn);
333  DecodeGPR32RegisterClass(Inst, DstB, Address, Decoder);
334  using Field = decltype(Insn);
335  Field Lower = fieldFromInstruction(Insn, 6, 6);
336  Field Upper = fieldFromInstruction(Insn, 0, 5);
337  Field Sign = fieldFromInstruction(Insn, 5, 1) ? -1 : 1;
338  Field Result = Sign * ((Upper << 6) + Lower);
339  Inst.addOperand(MCOperand::createImm(Result));
341 }
342 
343 DecodeStatus ARCDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
344  ArrayRef<uint8_t> Bytes,
345  uint64_t Address,
346  raw_ostream &cStream) const {
348  if (Bytes.size() < 2) {
349  Size = 0;
350  return Fail;
351  }
352  uint8_t DecodeByte = (Bytes[1] & 0xF7) >> 3;
353  // 0x00 -> 0x07 are 32-bit instructions.
354  // 0x08 -> 0x1F are 16-bit instructions.
355  if (DecodeByte < 0x08) {
356  // 32-bit instruction.
357  if (Bytes.size() < 4) {
358  // Did we decode garbage?
359  Size = 0;
360  return Fail;
361  }
362  if (Bytes.size() >= 8) {
363  // Attempt to decode 64-bit instruction.
364  uint64_t Insn64;
365  if (!readInstruction64(Bytes, Address, Size, Insn64))
366  return Fail;
367  Result =
368  decodeInstruction(DecoderTable64, Instr, Insn64, Address, this, STI);
369  if (Success == Result) {
370  LLVM_DEBUG(dbgs() << "Successfully decoded 64-bit instruction.");
371  return Result;
372  }
373  LLVM_DEBUG(dbgs() << "Not a 64-bit instruction, falling back to 32-bit.");
374  }
375  uint32_t Insn32;
376  if (!readInstruction32(Bytes, Address, Size, Insn32)) {
377  return Fail;
378  }
379  // Calling the auto-generated decoder function.
380  return decodeInstruction(DecoderTable32, Instr, Insn32, Address, this, STI);
381  } else {
382  if (Bytes.size() >= 6) {
383  // Attempt to treat as instr. with limm data.
384  uint64_t Insn48;
385  if (!readInstruction48(Bytes, Address, Size, Insn48))
386  return Fail;
387  Result =
388  decodeInstruction(DecoderTable48, Instr, Insn48, Address, this, STI);
389  if (Success == Result) {
390  LLVM_DEBUG(
391  dbgs() << "Successfully decoded 16-bit instruction with limm.");
392  return Result;
393  }
394  LLVM_DEBUG(
395  dbgs() << "Not a 16-bit instruction with limm, try without it.");
396  }
397 
398  uint32_t Insn16;
399  if (!readInstruction16(Bytes, Address, Size, Insn16))
400  return Fail;
401 
402  // Calling the auto-generated decoder function.
403  return decodeInstruction(DecoderTable16, Instr, Insn16, Address, this, STI);
404  }
405 }
406 
408  const MCSubtargetInfo &STI,
409  MCContext &Ctx) {
410  return new ARCDisassembler(STI, Ctx, T.createMCInstrInfo());
411 }
412 
414  // Register the disassembler.
417 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
decodeAField
static unsigned decodeAField(unsigned Insn)
Definition: ARCDisassembler.cpp:163
MCFixedLenDisassembler.h
DecodeFromCyclicRange
static DecodeStatus DecodeFromCyclicRange(MCInst &Inst, unsigned InsnS, uint64_t Address=0, const void *Decoder=nullptr)
Definition: ARCDisassembler.cpp:216
DecodeSignedOperand
static DecodeStatus DecodeSignedOperand(MCInst &Inst, unsigned InsnS, uint64_t Address=0, const void *Decoder=nullptr)
Definition: ARCDisassembler.cpp:205
readInstruction16
static bool readInstruction16(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
Definition: ARCDisassembler.cpp:78
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
llvm::HexPrintStyle::Upper
@ Upper
llvm::maskTrailingOnes
T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
Definition: MathExtras.h:248
MCDisassembler.h
T
llvm::MCOperand::createImm
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:72
DecodeGPR32RegisterClass
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Definition: ARCDisassembler.cpp:129
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
DecodeLdRLImmInstruction
static DecodeStatus DecodeLdRLImmInstruction(MCInst &, uint64_t, uint64_t, const void *)
Definition: ARCDisassembler.cpp:262
DecodeMoveHRegInstruction
static DecodeStatus DecodeMoveHRegInstruction(MCInst &Inst, uint64_t, uint64_t, const void *)
Definition: ARCDisassembler.cpp:279
Fail
#define Fail
Definition: AArch64Disassembler.cpp:261
DecodeSymbolicOperandOff
static void DecodeSymbolicOperandOff(MCInst &Inst, uint64_t Address, uint64_t Offset, const void *Decoder)
Definition: ARCDisassembler.cpp:187
R4
#define R4(n)
DecodeStLImmInstruction
static DecodeStatus DecodeStLImmInstruction(MCInst &, uint64_t, uint64_t, const void *)
Definition: ARCDisassembler.cpp:227
decodeCField
static unsigned decodeCField(unsigned Insn)
Definition: ARCDisassembler.cpp:154
llvm::TargetRegistry::RegisterMCDisassembler
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
Definition: TargetRegistry.h:916
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
createARCDisassembler
static MCDisassembler * createARCDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
Definition: ARCDisassembler.cpp:407
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
DecodeCCRU6Instruction
static DecodeStatus DecodeCCRU6Instruction(MCInst &, uint64_t, uint64_t, const void *)
Definition: ARCDisassembler.cpp:305
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
R2
#define R2(n)
ARCRegisterInfo.h
DecodeLdLImmInstruction
static DecodeStatus DecodeLdLImmInstruction(MCInst &, uint64_t, uint64_t, const void *)
Definition: ARCDisassembler.cpp:244
MCContext.h
MCInstrInfo.h
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::MCDisassembler::Success
@ Success
Definition: MCDisassembler.h:103
MCInst.h
readInstruction64
static bool readInstruction64(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint64_t &Insn)
Definition: ARCDisassembler.cpp:59
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LLVMInitializeARCDisassembler
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARCDisassembler()
Definition: ARCDisassembler.cpp:413
MCSubtargetInfo.h
llvm::getTheARCTarget
Target & getTheARCTarget()
Definition: ARCTargetInfo.cpp:14
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
readInstruction32
static bool readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
Definition: ARCDisassembler.cpp:50
llvm::MCDisassembler::DecodeStatus
DecodeStatus
Ternary decode status.
Definition: MCDisassembler.h:100
llvm::MCInst::addOperand
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
G
const DataFlowGraph & G
Definition: RDFGraph.cpp:202
uint64_t
LLVM_EXTERNAL_VISIBILITY
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
ARCTargetInfo.h
llvm::MCDisassembler
Superclass for all disassemblers.
Definition: MCDisassembler.h:76
llvm::HighlightColor::Address
@ Address
R6
#define R6(n)
llvm::ArrayRef< uint8_t >
llvm::MCOperand::createReg
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
uint32_t
DecodeMEMrs9
static DecodeStatus DecodeMEMrs9(MCInst &, unsigned, uint64_t, const void *)
Definition: ARCDisassembler.cpp:167
DecodeBranchTargetS
static DecodeStatus DecodeBranchTargetS(MCInst &Inst, unsigned InsnS, uint64_t Address, const void *Decoder)
Definition: ARCDisassembler.cpp:196
llvm::MCDisassembler::Fail
@ Fail
Definition: MCDisassembler.h:101
ARCMCTargetDesc.h
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:25
GPR32DecoderTable
static const uint16_t GPR32DecoderTable[]
Definition: ARCDisassembler.cpp:122
Insn
SmallVector< AArch64_IMM::ImmInsnModel, 4 > Insn
Definition: AArch64MIPeepholeOpt.cpp:74
H
#define H(x, y, z)
Definition: MD5.cpp:58
uint16_t
DecodeGBR32ShortRegister
static DecodeStatus DecodeGBR32ShortRegister(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
Definition: ARCDisassembler.cpp:142
readInstruction48
static bool readInstruction48(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint64_t &Insn)
Definition: ARCDisassembler.cpp:69
Success
#define Success
Definition: AArch64Disassembler.cpp:260
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
DecodeSOPwithRU6
static DecodeStatus DecodeSOPwithRU6(MCInst &, uint64_t, uint64_t, const void *)
Definition: ARCDisassembler.cpp:320
decodeBField
static unsigned decodeBField(unsigned Insn)
Definition: ARCDisassembler.cpp:158
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
ARC.h
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::OptimizedStructLayoutField
A field in a structure.
Definition: OptimizedStructLayout.h:45
TargetRegistry.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
DecodeSOPwithRS12
static DecodeStatus DecodeSOPwithRS12(MCInst &, uint64_t, uint64_t, const void *)
Definition: ARCDisassembler.cpp:330
DecodeSymbolicOperand
static bool DecodeSymbolicOperand(MCInst &Inst, uint64_t Address, uint64_t Value, const void *Decoder)
Definition: ARCDisassembler.cpp:177