LLVM  3.7.0
SystemZDisassembler.cpp
Go to the documentation of this file.
1 //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- 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 #include "SystemZ.h"
11 #include "llvm/MC/MCDisassembler.h"
13 #include "llvm/MC/MCInst.h"
16 
17 using namespace llvm;
18 
19 #define DEBUG_TYPE "systemz-disassembler"
20 
22 
23 namespace {
24 class SystemZDisassembler : public MCDisassembler {
25 public:
26  SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
27  : MCDisassembler(STI, Ctx) {}
28  ~SystemZDisassembler() override {}
29 
30  DecodeStatus getInstruction(MCInst &instr, uint64_t &Size,
31  ArrayRef<uint8_t> Bytes, uint64_t Address,
32  raw_ostream &VStream,
33  raw_ostream &CStream) const override;
34 };
35 } // end anonymous namespace
36 
38  const MCSubtargetInfo &STI,
39  MCContext &Ctx) {
40  return new SystemZDisassembler(STI, Ctx);
41 }
42 
44  // Register the disassembler.
47 }
48 
49 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
50  const unsigned *Regs, unsigned Size) {
51  assert(RegNo < Size && "Invalid register");
52  RegNo = Regs[RegNo];
53  if (RegNo == 0)
54  return MCDisassembler::Fail;
55  Inst.addOperand(MCOperand::createReg(RegNo));
57 }
58 
59 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
60  uint64_t Address,
61  const void *Decoder) {
62  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
63 }
64 
65 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
66  uint64_t Address,
67  const void *Decoder) {
68  return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
69 }
70 
71 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
72  uint64_t Address,
73  const void *Decoder) {
74  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
75 }
76 
77 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
78  uint64_t Address,
79  const void *Decoder) {
80  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
81 }
82 
83 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
84  uint64_t Address,
85  const void *Decoder) {
86  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
87 }
88 
89 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
90  uint64_t Address,
91  const void *Decoder) {
92  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
93 }
94 
95 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
96  uint64_t Address,
97  const void *Decoder) {
98  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
99 }
100 
101 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
102  uint64_t Address,
103  const void *Decoder) {
104  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
105 }
106 
107 static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
108  uint64_t Address,
109  const void *Decoder) {
110  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
111 }
112 
113 static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
114  uint64_t Address,
115  const void *Decoder) {
116  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
117 }
118 
119 static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
120  uint64_t Address,
121  const void *Decoder) {
122  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
123 }
124 
125 template<unsigned N>
126 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
127  if (!isUInt<N>(Imm))
128  return MCDisassembler::Fail;
129  Inst.addOperand(MCOperand::createImm(Imm));
131 }
132 
133 template<unsigned N>
134 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
135  if (!isUInt<N>(Imm))
136  return MCDisassembler::Fail;
137  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
139 }
140 
141 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
142  uint64_t Address,
143  const void *Decoder) {
144  return decodeUImmOperand<4>(Inst, Imm);
145 }
146 
147 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
148  uint64_t Address, const void *Decoder) {
149  return decodeUImmOperand<1>(Inst, Imm);
150 }
151 
152 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
153  uint64_t Address, const void *Decoder) {
154  return decodeUImmOperand<2>(Inst, Imm);
155 }
156 
157 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
158  uint64_t Address, const void *Decoder) {
159  return decodeUImmOperand<3>(Inst, Imm);
160 }
161 
162 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
163  uint64_t Address, const void *Decoder) {
164  return decodeUImmOperand<4>(Inst, Imm);
165 }
166 
167 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
168  uint64_t Address, const void *Decoder) {
169  return decodeUImmOperand<6>(Inst, Imm);
170 }
171 
172 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
173  uint64_t Address, const void *Decoder) {
174  return decodeUImmOperand<8>(Inst, Imm);
175 }
176 
177 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
178  uint64_t Address, const void *Decoder) {
179  return decodeUImmOperand<12>(Inst, Imm);
180 }
181 
182 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
183  uint64_t Address, const void *Decoder) {
184  return decodeUImmOperand<16>(Inst, Imm);
185 }
186 
187 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
188  uint64_t Address, const void *Decoder) {
189  return decodeUImmOperand<32>(Inst, Imm);
190 }
191 
192 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
193  uint64_t Address, const void *Decoder) {
194  return decodeSImmOperand<8>(Inst, Imm);
195 }
196 
197 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
198  uint64_t Address, const void *Decoder) {
199  return decodeSImmOperand<16>(Inst, Imm);
200 }
201 
202 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
203  uint64_t Address, const void *Decoder) {
204  return decodeSImmOperand<32>(Inst, Imm);
205 }
206 
207 template<unsigned N>
208 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
209  uint64_t Address) {
210  assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
211  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) * 2 + Address));
213 }
214 
215 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
216  uint64_t Address,
217  const void *Decoder) {
218  return decodePCDBLOperand<16>(Inst, Imm, Address);
219 }
220 
221 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
222  uint64_t Address,
223  const void *Decoder) {
224  return decodePCDBLOperand<32>(Inst, Imm, Address);
225 }
226 
228  const unsigned *Regs) {
229  uint64_t Base = Field >> 12;
230  uint64_t Disp = Field & 0xfff;
231  assert(Base < 16 && "Invalid BDAddr12");
232  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
233  Inst.addOperand(MCOperand::createImm(Disp));
235 }
236 
238  const unsigned *Regs) {
239  uint64_t Base = Field >> 20;
240  uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
241  assert(Base < 16 && "Invalid BDAddr20");
242  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
243  Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
245 }
246 
248  const unsigned *Regs) {
249  uint64_t Index = Field >> 16;
250  uint64_t Base = (Field >> 12) & 0xf;
251  uint64_t Disp = Field & 0xfff;
252  assert(Index < 16 && "Invalid BDXAddr12");
253  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
254  Inst.addOperand(MCOperand::createImm(Disp));
255  Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
257 }
258 
260  const unsigned *Regs) {
261  uint64_t Index = Field >> 24;
262  uint64_t Base = (Field >> 20) & 0xf;
263  uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
264  assert(Index < 16 && "Invalid BDXAddr20");
265  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
266  Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
267  Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
269 }
270 
272  const unsigned *Regs) {
273  uint64_t Length = Field >> 16;
274  uint64_t Base = (Field >> 12) & 0xf;
275  uint64_t Disp = Field & 0xfff;
276  assert(Length < 256 && "Invalid BDLAddr12Len8");
277  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
278  Inst.addOperand(MCOperand::createImm(Disp));
279  Inst.addOperand(MCOperand::createImm(Length + 1));
281 }
282 
284  const unsigned *Regs) {
285  uint64_t Index = Field >> 16;
286  uint64_t Base = (Field >> 12) & 0xf;
287  uint64_t Disp = Field & 0xfff;
288  assert(Index < 32 && "Invalid BDVAddr12");
289  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
290  Inst.addOperand(MCOperand::createImm(Disp));
293 }
294 
296  uint64_t Address,
297  const void *Decoder) {
298  return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
299 }
300 
302  uint64_t Address,
303  const void *Decoder) {
304  return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
305 }
306 
308  uint64_t Address,
309  const void *Decoder) {
310  return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
311 }
312 
314  uint64_t Address,
315  const void *Decoder) {
316  return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
317 }
318 
320  uint64_t Address,
321  const void *Decoder) {
322  return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
323 }
324 
326  uint64_t Address,
327  const void *Decoder) {
328  return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
329 }
330 
332  uint64_t Field,
333  uint64_t Address,
334  const void *Decoder) {
335  return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
336 }
337 
339  uint64_t Address,
340  const void *Decoder) {
341  return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
342 }
343 
344 #include "SystemZGenDisassemblerTables.inc"
345 
346 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
347  ArrayRef<uint8_t> Bytes,
348  uint64_t Address,
349  raw_ostream &OS,
350  raw_ostream &CS) const {
351  // Get the first two bytes of the instruction.
352  Size = 0;
353  if (Bytes.size() < 2)
354  return MCDisassembler::Fail;
355 
356  // The top 2 bits of the first byte specify the size.
357  const uint8_t *Table;
358  if (Bytes[0] < 0x40) {
359  Size = 2;
360  Table = DecoderTable16;
361  } else if (Bytes[0] < 0xc0) {
362  Size = 4;
363  Table = DecoderTable32;
364  } else {
365  Size = 6;
366  Table = DecoderTable48;
367  }
368 
369  // Read any remaining bytes.
370  if (Bytes.size() < Size)
371  return MCDisassembler::Fail;
372 
373  // Construct the instruction.
374  uint64_t Inst = 0;
375  for (uint64_t I = 0; I < Size; ++I)
376  Inst = (Inst << 8) | Bytes[I];
377 
378  return decodeInstruction(Table, MI, Inst, Address, this, STI);
379 }
static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, const unsigned *Regs)
const unsigned GR32Regs[16]
const unsigned FP128Regs[16]
static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address, const void *Decoder)
DecodeStatus
Ternary decode status.
static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, const unsigned *Regs)
Superclass for all disassemblers.
static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, const unsigned *Regs)
static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
MCDisassembler::DecodeStatus DecodeStatus
static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.
const unsigned FP32Regs[16]
static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field, const unsigned *Regs)
Target TheSystemZTarget
static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address, const void *Decoder)
static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
const unsigned VR64Regs[32]
static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:111
static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, uint64_t Address, const void *Decoder)
static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, const unsigned *Regs)
const unsigned GRH32Regs[16]
static MCDisassembler * createSystemZDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
Context object for machine code objects.
Definition: MCContext.h:48
static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
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...
static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address, const void *Decoder)
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 decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address, const void *Decoder)
static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, const unsigned *Regs)
static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm)
static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, uint64_t Address, const void *Decoder)
static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, uint64_t Address)
static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, uint64_t Field, uint64_t Address, const void *Decoder)
const unsigned FP64Regs[16]
const unsigned GR128Regs[16]
const unsigned GR64Regs[16]
static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
Target - Wrapper for Target specific information.
static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
#define I(x, y, z)
Definition: MD5.cpp:54
static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
MCSubtargetInfo - Generic base class for all target subtargets.
static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm)
const unsigned VR32Regs[32]
static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const void *Decoder)
void LLVMInitializeSystemZDisassembler()
static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)
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 DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, const unsigned *Regs, unsigned Size)
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:117
const unsigned VR128Regs[32]
static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder)