LLVM  3.7.0
SparcDisassembler.cpp
Go to the documentation of this file.
1 //===- SparcDisassembler.cpp - Disassembler for Sparc -----------*- 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 // This file is part of the Sparc Disassembler.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "Sparc.h"
15 #include "SparcRegisterInfo.h"
16 #include "SparcSubtarget.h"
17 #include "llvm/MC/MCDisassembler.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCAsmInfo.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "sparc-disassembler"
27 
29 
30 namespace {
31 
32 /// A disassembler class for Sparc.
33 class SparcDisassembler : public MCDisassembler {
34 public:
35  SparcDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
36  : MCDisassembler(STI, Ctx) {}
37  virtual ~SparcDisassembler() {}
38 
39  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
40  ArrayRef<uint8_t> Bytes, uint64_t Address,
41  raw_ostream &VStream,
42  raw_ostream &CStream) const override;
43 };
44 }
45 
46 namespace llvm {
48 }
49 
51  const MCSubtargetInfo &STI,
52  MCContext &Ctx) {
53  return new SparcDisassembler(STI, Ctx);
54 }
55 
56 
58  // Register the disassembler.
65 }
66 
67 static const unsigned IntRegDecoderTable[] = {
68  SP::G0, SP::G1, SP::G2, SP::G3,
69  SP::G4, SP::G5, SP::G6, SP::G7,
70  SP::O0, SP::O1, SP::O2, SP::O3,
71  SP::O4, SP::O5, SP::O6, SP::O7,
72  SP::L0, SP::L1, SP::L2, SP::L3,
73  SP::L4, SP::L5, SP::L6, SP::L7,
74  SP::I0, SP::I1, SP::I2, SP::I3,
75  SP::I4, SP::I5, SP::I6, SP::I7 };
76 
77 static const unsigned FPRegDecoderTable[] = {
78  SP::F0, SP::F1, SP::F2, SP::F3,
79  SP::F4, SP::F5, SP::F6, SP::F7,
80  SP::F8, SP::F9, SP::F10, SP::F11,
81  SP::F12, SP::F13, SP::F14, SP::F15,
82  SP::F16, SP::F17, SP::F18, SP::F19,
83  SP::F20, SP::F21, SP::F22, SP::F23,
84  SP::F24, SP::F25, SP::F26, SP::F27,
85  SP::F28, SP::F29, SP::F30, SP::F31 };
86 
87 static const unsigned DFPRegDecoderTable[] = {
88  SP::D0, SP::D16, SP::D1, SP::D17,
89  SP::D2, SP::D18, SP::D3, SP::D19,
90  SP::D4, SP::D20, SP::D5, SP::D21,
91  SP::D6, SP::D22, SP::D7, SP::D23,
92  SP::D8, SP::D24, SP::D9, SP::D25,
93  SP::D10, SP::D26, SP::D11, SP::D27,
94  SP::D12, SP::D28, SP::D13, SP::D29,
95  SP::D14, SP::D30, SP::D15, SP::D31 };
96 
97 static const unsigned QFPRegDecoderTable[] = {
98  SP::Q0, SP::Q8, ~0U, ~0U,
99  SP::Q1, SP::Q9, ~0U, ~0U,
100  SP::Q2, SP::Q10, ~0U, ~0U,
101  SP::Q3, SP::Q11, ~0U, ~0U,
102  SP::Q4, SP::Q12, ~0U, ~0U,
103  SP::Q5, SP::Q13, ~0U, ~0U,
104  SP::Q6, SP::Q14, ~0U, ~0U,
105  SP::Q7, SP::Q15, ~0U, ~0U } ;
106 
107 static const unsigned FCCRegDecoderTable[] = {
108  SP::FCC0, SP::FCC1, SP::FCC2, SP::FCC3 };
109 
110 static const unsigned ASRRegDecoderTable[] = {
111  SP::Y, SP::ASR1, SP::ASR2, SP::ASR3,
112  SP::ASR4, SP::ASR5, SP::ASR6, SP::ASR7,
113  SP::ASR8, SP::ASR9, SP::ASR10, SP::ASR11,
114  SP::ASR12, SP::ASR13, SP::ASR14, SP::ASR15,
115  SP::ASR16, SP::ASR17, SP::ASR18, SP::ASR19,
116  SP::ASR20, SP::ASR21, SP::ASR22, SP::ASR23,
117  SP::ASR24, SP::ASR25, SP::ASR26, SP::ASR27,
118  SP::ASR28, SP::ASR29, SP::ASR30, SP::ASR31};
119 
121  unsigned RegNo,
122  uint64_t Address,
123  const void *Decoder) {
124  if (RegNo > 31)
125  return MCDisassembler::Fail;
126  unsigned Reg = IntRegDecoderTable[RegNo];
127  Inst.addOperand(MCOperand::createReg(Reg));
129 }
130 
132  unsigned RegNo,
133  uint64_t Address,
134  const void *Decoder) {
135  if (RegNo > 31)
136  return MCDisassembler::Fail;
137  unsigned Reg = IntRegDecoderTable[RegNo];
138  Inst.addOperand(MCOperand::createReg(Reg));
140 }
141 
142 
144  unsigned RegNo,
145  uint64_t Address,
146  const void *Decoder) {
147  if (RegNo > 31)
148  return MCDisassembler::Fail;
149  unsigned Reg = FPRegDecoderTable[RegNo];
150  Inst.addOperand(MCOperand::createReg(Reg));
152 }
153 
154 
156  unsigned RegNo,
157  uint64_t Address,
158  const void *Decoder) {
159  if (RegNo > 31)
160  return MCDisassembler::Fail;
161  unsigned Reg = DFPRegDecoderTable[RegNo];
162  Inst.addOperand(MCOperand::createReg(Reg));
164 }
165 
166 
168  unsigned RegNo,
169  uint64_t Address,
170  const void *Decoder) {
171  if (RegNo > 31)
172  return MCDisassembler::Fail;
173 
174  unsigned Reg = QFPRegDecoderTable[RegNo];
175  if (Reg == ~0U)
176  return MCDisassembler::Fail;
177  Inst.addOperand(MCOperand::createReg(Reg));
179 }
180 
181 static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo,
182  uint64_t Address,
183  const void *Decoder) {
184  if (RegNo > 3)
185  return MCDisassembler::Fail;
188 }
189 
190 static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo,
191  uint64_t Address,
192  const void *Decoder) {
193  if (RegNo > 31)
194  return MCDisassembler::Fail;
197 }
198 
199 
200 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
201  const void *Decoder);
202 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
203  const void *Decoder);
204 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
205  const void *Decoder);
206 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
207  const void *Decoder);
208 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
209  uint64_t Address, const void *Decoder);
210 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn,
211  uint64_t Address, const void *Decoder);
212 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
213  uint64_t Address, const void *Decoder);
214 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
215  uint64_t Address, const void *Decoder);
216 static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn,
217  uint64_t Address, const void *Decoder);
218 static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn,
219  uint64_t Address, const void *Decoder);
220 static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address,
221  const void *Decoder);
222 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
223  const void *Decoder);
224 static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address,
225  const void *Decoder);
226 
227 #include "SparcGenDisassemblerTables.inc"
228 
229 /// Read four bytes from the ArrayRef and return 32 bit word.
231  uint64_t &Size, uint32_t &Insn,
232  bool IsLittleEndian) {
233  // We want to read exactly 4 Bytes of data.
234  if (Bytes.size() < 4) {
235  Size = 0;
236  return MCDisassembler::Fail;
237  }
238 
239  Insn = IsLittleEndian
240  ? (Bytes[0] << 0) | (Bytes[1] << 8) | (Bytes[2] << 16) |
241  (Bytes[3] << 24)
242  : (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) |
243  (Bytes[0] << 24);
244 
246 }
247 
248 DecodeStatus SparcDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,
249  ArrayRef<uint8_t> Bytes,
250  uint64_t Address,
251  raw_ostream &VStream,
252  raw_ostream &CStream) const {
253  uint32_t Insn;
254  bool isLittleEndian = getContext().getAsmInfo()->isLittleEndian();
255  DecodeStatus Result =
256  readInstruction32(Bytes, Address, Size, Insn, isLittleEndian);
257  if (Result == MCDisassembler::Fail)
258  return MCDisassembler::Fail;
259 
260  // Calling the auto-generated decoder function.
261  Result =
262  decodeInstruction(DecoderTableSparc32, Instr, Insn, Address, this, STI);
263 
264  if (Result != MCDisassembler::Fail) {
265  Size = 4;
266  return Result;
267  }
268 
269  return MCDisassembler::Fail;
270 }
271 
272 
273 typedef DecodeStatus (*DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address,
274  const void *Decoder);
275 
276 static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address,
277  const void *Decoder,
278  bool isLoad, DecodeFunc DecodeRD) {
279  unsigned rd = fieldFromInstruction(insn, 25, 5);
280  unsigned rs1 = fieldFromInstruction(insn, 14, 5);
281  bool isImm = fieldFromInstruction(insn, 13, 1);
282  bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
283  unsigned asi = fieldFromInstruction(insn, 5, 8);
284  unsigned rs2 = 0;
285  unsigned simm13 = 0;
286  if (isImm)
287  simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
288  else
289  rs2 = fieldFromInstruction(insn, 0, 5);
290 
292  if (isLoad) {
293  status = DecodeRD(MI, rd, Address, Decoder);
294  if (status != MCDisassembler::Success)
295  return status;
296  }
297 
298  // Decode rs1.
299  status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
300  if (status != MCDisassembler::Success)
301  return status;
302 
303  // Decode imm|rs2.
304  if (isImm)
305  MI.addOperand(MCOperand::createImm(simm13));
306  else {
307  status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
308  if (status != MCDisassembler::Success)
309  return status;
310  }
311 
312  if (hasAsi)
314 
315  if (!isLoad) {
316  status = DecodeRD(MI, rd, Address, Decoder);
317  if (status != MCDisassembler::Success)
318  return status;
319  }
321 }
322 
323 static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address,
324  const void *Decoder) {
325  return DecodeMem(Inst, insn, Address, Decoder, true,
327 }
328 
329 static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address,
330  const void *Decoder) {
331  return DecodeMem(Inst, insn, Address, Decoder, true,
333 }
334 
335 static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address,
336  const void *Decoder) {
337  return DecodeMem(Inst, insn, Address, Decoder, true,
339 }
340 
341 static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address,
342  const void *Decoder) {
343  return DecodeMem(Inst, insn, Address, Decoder, true,
345 }
346 
347 static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn,
348  uint64_t Address, const void *Decoder) {
349  return DecodeMem(Inst, insn, Address, Decoder, false,
351 }
352 
353 static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address,
354  const void *Decoder) {
355  return DecodeMem(Inst, insn, Address, Decoder, false,
357 }
358 
359 static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn,
360  uint64_t Address, const void *Decoder) {
361  return DecodeMem(Inst, insn, Address, Decoder, false,
363 }
364 
365 static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn,
366  uint64_t Address, const void *Decoder) {
367  return DecodeMem(Inst, insn, Address, Decoder, false,
369 }
370 
371 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
372  uint64_t Address, uint64_t Offset,
373  uint64_t Width, MCInst &MI,
374  const void *Decoder) {
375  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
376  return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
377  Offset, Width);
378 }
379 
380 static DecodeStatus DecodeCall(MCInst &MI, unsigned insn,
381  uint64_t Address, const void *Decoder) {
382  unsigned tgt = fieldFromInstruction(insn, 0, 30);
383  tgt <<= 2;
384  if (!tryAddingSymbolicOperand(tgt+Address, false, Address,
385  0, 30, MI, Decoder))
388 }
389 
390 static DecodeStatus DecodeSIMM13(MCInst &MI, unsigned insn,
391  uint64_t Address, const void *Decoder) {
392  unsigned tgt = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
395 }
396 
397 static DecodeStatus DecodeJMPL(MCInst &MI, unsigned insn, uint64_t Address,
398  const void *Decoder) {
399 
400  unsigned rd = fieldFromInstruction(insn, 25, 5);
401  unsigned rs1 = fieldFromInstruction(insn, 14, 5);
402  unsigned isImm = fieldFromInstruction(insn, 13, 1);
403  unsigned rs2 = 0;
404  unsigned simm13 = 0;
405  if (isImm)
406  simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
407  else
408  rs2 = fieldFromInstruction(insn, 0, 5);
409 
410  // Decode RD.
411  DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
412  if (status != MCDisassembler::Success)
413  return status;
414 
415  // Decode RS1.
416  status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
417  if (status != MCDisassembler::Success)
418  return status;
419 
420  // Decode RS1 | SIMM13.
421  if (isImm)
422  MI.addOperand(MCOperand::createImm(simm13));
423  else {
424  status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
425  if (status != MCDisassembler::Success)
426  return status;
427  }
429 }
430 
431 static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address,
432  const void *Decoder) {
433 
434  unsigned rs1 = fieldFromInstruction(insn, 14, 5);
435  unsigned isImm = fieldFromInstruction(insn, 13, 1);
436  unsigned rs2 = 0;
437  unsigned simm13 = 0;
438  if (isImm)
439  simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
440  else
441  rs2 = fieldFromInstruction(insn, 0, 5);
442 
443  // Decode RS1.
444  DecodeStatus status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
445  if (status != MCDisassembler::Success)
446  return status;
447 
448  // Decode RS2 | SIMM13.
449  if (isImm)
450  MI.addOperand(MCOperand::createImm(simm13));
451  else {
452  status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
453  if (status != MCDisassembler::Success)
454  return status;
455  }
457 }
458 
459 static DecodeStatus DecodeSWAP(MCInst &MI, unsigned insn, uint64_t Address,
460  const void *Decoder) {
461 
462  unsigned rd = fieldFromInstruction(insn, 25, 5);
463  unsigned rs1 = fieldFromInstruction(insn, 14, 5);
464  unsigned isImm = fieldFromInstruction(insn, 13, 1);
465  bool hasAsi = fieldFromInstruction(insn, 23, 1); // (in op3 field)
466  unsigned asi = fieldFromInstruction(insn, 5, 8);
467  unsigned rs2 = 0;
468  unsigned simm13 = 0;
469  if (isImm)
470  simm13 = SignExtend32<13>(fieldFromInstruction(insn, 0, 13));
471  else
472  rs2 = fieldFromInstruction(insn, 0, 5);
473 
474  // Decode RD.
475  DecodeStatus status = DecodeIntRegsRegisterClass(MI, rd, Address, Decoder);
476  if (status != MCDisassembler::Success)
477  return status;
478 
479  // Decode RS1.
480  status = DecodeIntRegsRegisterClass(MI, rs1, Address, Decoder);
481  if (status != MCDisassembler::Success)
482  return status;
483 
484  // Decode RS1 | SIMM13.
485  if (isImm)
486  MI.addOperand(MCOperand::createImm(simm13));
487  else {
488  status = DecodeIntRegsRegisterClass(MI, rs2, Address, Decoder);
489  if (status != MCDisassembler::Success)
490  return status;
491  }
492 
493  if (hasAsi)
495 
497 }
static DecodeStatus DecodeLoadInt(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeMem(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder, bool isLoad, DecodeFunc DecodeRD)
DecodeStatus
Ternary decode status.
static DecodeStatus DecodeLoadDFP(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
Superclass for all disassemblers.
static DecodeStatus DecodeStoreFP(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
DecodeStatus(* DecodeFunc)(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeDFPRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeStoreInt(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeStoreDFP(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
Target TheSparcTarget
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
static DecodeStatus DecodeFPRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
MCDisassembler::DecodeStatus DecodeStatus
Reg
All possible values of the reg field in the ModR/M byte.
static DecodeStatus DecodeLoadFP(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
Context object for machine code objects.
Definition: MCContext.h:48
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...
void LLVMInitializeSparcDisassembler()
static DecodeStatus readInstruction32(ArrayRef< uint8_t > Bytes, uint64_t Address, uint64_t &Size, uint32_t &Insn, bool IsLittleEndian)
Read four bytes from the ArrayRef and return 32 bit word.
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:134
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
static DecodeStatus DecodeASRRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeQFPRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeSIMM13(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
static const unsigned FCCRegDecoderTable[]
static DecodeStatus DecodeCall(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
bool tryAddingSymbolicOperand(MCInst &Inst, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t InstSize) const
static DecodeStatus DecodeReturn(MCInst &MI, unsigned insn, uint64_t Address, const void *Decoder)
static const unsigned IntRegDecoderTable[]
static const unsigned FPRegDecoderTable[]
static DecodeStatus DecodeSWAP(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeI64RegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static const unsigned ASRRegDecoderTable[]
static DecodeStatus DecodeLoadQFP(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
static const unsigned DFPRegDecoderTable[]
Target - Wrapper for Target specific information.
Target TheSparcV9Target
static DecodeStatus DecodeIntRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeStoreQFP(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeJMPL(MCInst &Inst, unsigned insn, uint64_t Address, const void *Decoder)
static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, uint64_t Address, uint64_t Offset, uint64_t Width, MCInst &MI, const void *Decoder)
static const unsigned QFPRegDecoderTable[]
MCSubtargetInfo - Generic base class for all target subtargets.
static DecodeStatus DecodeFCCRegsRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder)
static bool isBranch(unsigned Opcode)
Target TheSparcelTarget
LLVM Value Representation.
Definition: Value.h:69
static MCDisassembler * createSparcDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
void addOperand(const MCOperand &Op)
Definition: MCInst.h:168
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml","ocaml 3.10-compatible collector")
std::error_code status(const Twine &path, file_status &result)
Get file status as if by POSIX stat().
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117