LLVM  6.0.0svn
ARCDisassembler.cpp
Go to the documentation of this file.
1 //===- ARCDisassembler.cpp - Disassembler for ARC ---------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file is part of the ARC Disassembler.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "ARC.h"
16 #include "ARCRegisterInfo.h"
18 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrInfo.h"
25 
26 using namespace llvm;
27 
28 #define DEBUG_TYPE "arc-disassembler"
29 
31 
32 namespace {
33 
34 /// \brief 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,
44  ArrayRef<uint8_t> Bytes, uint64_t Address,
45  raw_ostream &VStream,
46  raw_ostream &CStream) const override;
47 };
48 
49 } // end anonymous namespace
50 
51 static bool readInstruction32(ArrayRef<uint8_t> Bytes, uint64_t Address,
52  uint64_t &Size, uint32_t &Insn) {
53  Size = 4;
54  // Read 2 16-bit values, but swap hi/lo parts.
55  Insn =
56  (Bytes[0] << 16) | (Bytes[1] << 24) | (Bytes[2] << 0) | (Bytes[3] << 8);
57  return true;
58 }
59 
60 static bool readInstruction64(ArrayRef<uint8_t> Bytes, uint64_t Address,
61  uint64_t &Size, uint64_t &Insn) {
62  Size = 8;
63  Insn = ((uint64_t)Bytes[0] << 16) | ((uint64_t)Bytes[1] << 24) |
64  ((uint64_t)Bytes[2] << 0) | ((uint64_t)Bytes[3] << 8) |
65  ((uint64_t)Bytes[4] << 48) | ((uint64_t)Bytes[5] << 56) |
66  ((uint64_t)Bytes[6] << 32) | ((uint64_t)Bytes[7] << 40);
67  return true;
68 }
69 
70 static bool readInstruction16(ArrayRef<uint8_t> Bytes, uint64_t Address,
71  uint64_t &Size, uint32_t &Insn) {
72  Size = 2;
73  Insn = (Bytes[0] << 0) | (Bytes[1] << 8);
74  return true;
75 }
76 
78  uint64_t, const void *);
79 
81  uint64_t, const void *);
82 
84 DecodeBranchTargetS9(MCInst &, unsigned, uint64_t, const void *);
85 
87 DecodeBranchTargetS21(MCInst &, unsigned, uint64_t, const void *);
88 
90 DecodeBranchTargetS25(MCInst &, unsigned, uint64_t, const void *);
91 
92 static MCDisassembler::DecodeStatus DecodeMEMrs9(MCInst &, unsigned, uint64_t,
93  const void *);
94 
96 DecodeLdLImmInstruction(MCInst &, uint64_t, uint64_t, const void *);
97 
99 DecodeStLImmInstruction(MCInst &, uint64_t, uint64_t, const void *);
100 
102 DecodeLdRLImmInstruction(MCInst &, uint64_t, uint64_t, const void *);
103 
104 static const uint16_t GPR32DecoderTable[] = {
105  ARC::R0, ARC::R1, ARC::R2, ARC::R3, ARC::R4, ARC::R5, ARC::R6,
106  ARC::R7, ARC::R8, ARC::R9, ARC::R10, ARC::R11, ARC::R12, ARC::R13,
107  ARC::R14, ARC::R15, ARC::R16, ARC::R17, ARC::R18, ARC::R19, ARC::R20,
108  ARC::R21, ARC::R22, ARC::R23, ARC::R24, ARC::R25, ARC::GP, ARC::FP,
109  ARC::SP, ARC::ILINK, ARC::R30, ARC::BLINK};
110 
111 static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
112  uint64_t Address,
113  const void *Decoder) {
114  if (RegNo >= 32) {
115  DEBUG(dbgs() << "Not a GPR32 register.");
116  return MCDisassembler::Fail;
117  }
118  unsigned Reg = GPR32DecoderTable[RegNo];
119  Inst.addOperand(MCOperand::createReg(Reg));
121 }
122 
123 #include "ARCGenDisassemblerTables.inc"
124 
125 static unsigned decodeCField(unsigned Insn) {
126  return fieldFromInstruction(Insn, 6, 6);
127 }
128 
129 static unsigned decodeBField(unsigned Insn) {
130  return (fieldFromInstruction(Insn, 12, 3) << 3) |
131  fieldFromInstruction(Insn, 24, 3);
132 }
133 
134 static unsigned decodeAField(unsigned Insn) {
135  return fieldFromInstruction(Insn, 0, 6);
136 }
137 
139 DecodeMEMrs9(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Dec) {
140  // We have the 9-bit immediate in the low bits, 6-bit register in high bits.
141  unsigned S9 = Insn & 0x1ff;
142  unsigned R = (Insn & (0x7fff & ~0x1ff)) >> 9;
143  DecodeGPR32RegisterClass(Inst, R, Address, Dec);
144  Inst.addOperand(MCOperand::createImm(SignExtend32<9>(S9)));
146 }
147 
149  unsigned InsnS9,
150  uint64_t Address,
151  const void *Decoder) {
152  Inst.addOperand(MCOperand::createImm(SignExtend32<9>(0x1ff & InsnS9)));
154 }
155 
157  unsigned InsnS12,
158  uint64_t Address,
159  const void *Decoder) {
160  Inst.addOperand(MCOperand::createImm(SignExtend32<12>(0xfff & InsnS12)));
162 }
163 
165  unsigned S,
166  uint64_t Address,
167  const void *Decoder) {
168  Inst.addOperand(MCOperand::createImm(SignExtend32<9>(S)));
170 }
171 
173  unsigned S,
174  uint64_t Address,
175  const void *Decoder) {
176  Inst.addOperand(MCOperand::createImm(SignExtend32<21>(S)));
178 }
179 
181  unsigned S,
182  uint64_t Address,
183  const void *Decoder) {
184  Inst.addOperand(MCOperand::createImm(SignExtend32<25>(S)));
186 }
187 
189 DecodeStLImmInstruction(MCInst &Inst, uint64_t Insn, uint64_t Address,
190  const void *Decoder) {
191  unsigned SrcC, DstB, LImm;
192  DstB = decodeBField(Insn);
193  if (DstB != 62) {
194  DEBUG(dbgs() << "Decoding StLImm found non-limm register.");
195  return MCDisassembler::Fail;
196  }
197  SrcC = decodeCField(Insn);
198  DecodeGPR32RegisterClass(Inst, SrcC, Address, Decoder);
199  LImm = (Insn >> 32);
200  Inst.addOperand(MCOperand::createImm(LImm));
203 }
204 
206 DecodeLdLImmInstruction(MCInst &Inst, uint64_t Insn, uint64_t Address,
207  const void *Decoder) {
208  unsigned DstA, SrcB, LImm;
209  DEBUG(dbgs() << "Decoding LdLImm:\n");
210  SrcB = decodeBField(Insn);
211  if (SrcB != 62) {
212  DEBUG(dbgs() << "Decoding LdLImm found non-limm register.");
213  return MCDisassembler::Fail;
214  }
215  DstA = decodeAField(Insn);
216  DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder);
217  LImm = (Insn >> 32);
218  Inst.addOperand(MCOperand::createImm(LImm));
221 }
222 
224 DecodeLdRLImmInstruction(MCInst &Inst, uint64_t Insn, uint64_t Address,
225  const void *Decoder) {
226  unsigned DstA, SrcB;
227  DEBUG(dbgs() << "Decoding LdRLimm\n");
228  DstA = decodeAField(Insn);
229  DecodeGPR32RegisterClass(Inst, DstA, Address, Decoder);
230  SrcB = decodeBField(Insn);
231  DecodeGPR32RegisterClass(Inst, SrcB, Address, Decoder);
232  if (decodeCField(Insn) != 62) {
233  DEBUG(dbgs() << "Decoding LdRLimm found non-limm register.");
234  return MCDisassembler::Fail;
235  }
236  Inst.addOperand(MCOperand::createImm((uint32_t)(Insn >> 32)));
238 }
239 
240 MCDisassembler::DecodeStatus ARCDisassembler::getInstruction(
241  MCInst &Instr, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t Address,
242  raw_ostream &vStream, raw_ostream &cStream) const {
244  if (Bytes.size() < 2) {
245  Size = 0;
246  return Fail;
247  }
248  uint8_t DecodeByte = (Bytes[1] & 0xF7) >> 3;
249  // 0x00 -> 0x07 are 32-bit instructions.
250  // 0x08 -> 0x1F are 16-bit instructions.
251  if (DecodeByte < 0x08) {
252  // 32-bit instruction.
253  if (Bytes.size() < 4) {
254  // Did we decode garbage?
255  Size = 0;
256  return Fail;
257  }
258  if (Bytes.size() >= 8) {
259  // Attempt to decode 64-bit instruction.
260  uint64_t Insn64;
261  if (!readInstruction64(Bytes, Address, Size, Insn64))
262  return Fail;
263  Result =
264  decodeInstruction(DecoderTable64, Instr, Insn64, Address, this, STI);
265  if (Result == MCDisassembler::Success) {
266  DEBUG(dbgs() << "Successfully decoded 64-bit instruction.");
268  }
269  DEBUG(dbgs() << "Not a 64-bit instruction, falling back to 32-bit.");
270  }
271  uint32_t Insn32;
272  if (!readInstruction32(Bytes, Address, Size, Insn32)) {
273  return Fail;
274  }
275  // Calling the auto-generated decoder function.
276  return decodeInstruction(DecoderTable32, Instr, Insn32, Address, this, STI);
277  }
278 
279  // 16-bit instruction.
280  uint32_t Insn16;
281  if (!readInstruction16(Bytes, Address, Size, Insn16)) {
282  return Fail;
283  }
284  // Calling the auto-generated decoder function.
285  return decodeInstruction(DecoderTable16, Instr, Insn16, Address, this, STI);
286 }
287 
289  const MCSubtargetInfo &STI,
290  MCContext &Ctx) {
291  return new ARCDisassembler(STI, Ctx, T.createMCInstrInfo());
292 }
293 
294 extern "C" void LLVMInitializeARCDisassembler() {
295  // Register the disassembler.
298 }
static unsigned decodeCField(unsigned Insn)
static MCDisassembler::DecodeStatus DecodeStLImmInstruction(MCInst &, uint64_t, uint64_t, const void *)
#define R4(n)
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
DecodeStatus
Ternary decode status.
static const uint16_t GPR32DecoderTable[]
Superclass for all disassemblers.
MCInstrInfo * createMCInstrInfo() const
createMCInstrInfo - Create a MCInstrInfo implementation.
Target & getTheARCTarget()
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
static MCDisassembler::DecodeStatus DecodeS9Operand(MCInst &, unsigned, uint64_t, const void *)
#define R2(n)
static bool readInstruction64(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint64_t &Insn)
static MCDisassembler::DecodeStatus DecodeBranchTargetS9(MCInst &, unsigned, uint64_t, const void *)
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:116
static bool readInstruction16(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
#define Fail
Reg
All possible values of the reg field in the ModR/M byte.
void LLVMInitializeARCDisassembler()
Context object for machine code objects.
Definition: MCContext.h:59
static MCDisassembler::DecodeStatus DecodeMEMrs9(MCInst &, unsigned, uint64_t, const void *)
int decodeInstruction(InternalInstruction *insn, byteReader_t reader, const void *readerArg, dlog_t logger, void *loggerArg, const void *miiArg, uint64_t startLoc, DisassemblerMode mode)
Decode one instruction and store the decoding results in a buffer provided by the consumer...
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
static MCDisassembler::DecodeStatus DecodeBranchTargetS21(MCInst &, unsigned, uint64_t, const void *)
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
static MCDisassembler::DecodeStatus DecodeLdRLImmInstruction(MCInst &, uint64_t, uint64_t, const void *)
#define R6(n)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
Target - Wrapper for Target specific information.
static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static bool readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn)
static MCDisassembler * createARCDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
MCSubtargetInfo - Generic base class for all target subtargets.
static unsigned decodeBField(unsigned Insn)
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
#define DEBUG(X)
Definition: Debug.h:118
void addOperand(const MCOperand &Op)
Definition: MCInst.h:184
static MCDisassembler::DecodeStatus DecodeBranchTargetS25(MCInst &, unsigned, uint64_t, const void *)
static unsigned decodeAField(unsigned Insn)
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:123
static MCDisassembler::DecodeStatus DecodeLdLImmInstruction(MCInst &, uint64_t, uint64_t, const void *)
static MCDisassembler::DecodeStatus DecodeS12Operand(MCInst &, unsigned, uint64_t, const void *)