SystemZDisassembler.cpp revision 541c5de2fb57b2f459f0ec49f33a0ecce3532acd
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"
12#include "llvm/MC/MCFixedLenDisassembler.h"
13#include "llvm/MC/MCInst.h"
14#include "llvm/MC/MCSubtargetInfo.h"
15#include "llvm/Support/MemoryObject.h"
16#include "llvm/Support/TargetRegistry.h"
17
18using namespace llvm;
19
20typedef MCDisassembler::DecodeStatus DecodeStatus;
21
22namespace {
23class SystemZDisassembler : public MCDisassembler {
24public:
25  SystemZDisassembler(const MCSubtargetInfo &STI)
26    : MCDisassembler(STI) {}
27  virtual ~SystemZDisassembler() {}
28
29  // Override MCDisassembler.
30  virtual DecodeStatus getInstruction(MCInst &instr,
31                                      uint64_t &size,
32                                      const MemoryObject &region,
33                                      uint64_t address,
34                                      raw_ostream &vStream,
35                                      raw_ostream &cStream) const LLVM_OVERRIDE;
36};
37} // end anonymous namespace
38
39static MCDisassembler *createSystemZDisassembler(const Target &T,
40                                                 const MCSubtargetInfo &STI) {
41  return new SystemZDisassembler(STI);
42}
43
44extern "C" void LLVMInitializeSystemZDisassembler() {
45  // Register the disassembler.
46  TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
47                                         createSystemZDisassembler);
48}
49
50static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
51                                        const unsigned *Regs) {
52  assert(RegNo < 16 && "Invalid register");
53  RegNo = Regs[RegNo];
54  if (RegNo == 0)
55    return MCDisassembler::Fail;
56  Inst.addOperand(MCOperand::CreateReg(RegNo));
57  return MCDisassembler::Success;
58}
59
60static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
61                                               uint64_t Address,
62                                               const void *Decoder) {
63  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs);
64}
65
66static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
67                                                uint64_t Address,
68                                                const void *Decoder) {
69  return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs);
70}
71
72static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
73                                               uint64_t Address,
74                                               const void *Decoder) {
75  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
76}
77
78static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
79                                                uint64_t Address,
80                                                const void *Decoder) {
81  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs);
82}
83
84static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
85                                                 uint64_t Address,
86                                                 const void *Decoder) {
87  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
88}
89
90static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
91                                               uint64_t Address,
92                                               const void *Decoder) {
93  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs);
94}
95
96static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
97                                               uint64_t Address,
98                                               const void *Decoder) {
99  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs);
100}
101
102static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
103                                                uint64_t Address,
104                                                const void *Decoder) {
105  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs);
106}
107
108template<unsigned N>
109static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
110  assert(isUInt<N>(Imm) && "Invalid immediate");
111  Inst.addOperand(MCOperand::CreateImm(Imm));
112  return MCDisassembler::Success;
113}
114
115template<unsigned N>
116static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
117  assert(isUInt<N>(Imm) && "Invalid immediate");
118  Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm)));
119  return MCDisassembler::Success;
120}
121
122static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
123                                           uint64_t Address,
124                                           const void *Decoder) {
125  return decodeUImmOperand<4>(Inst, Imm);
126}
127
128static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
129                                       uint64_t Address, const void *Decoder) {
130  return decodeUImmOperand<4>(Inst, Imm);
131}
132
133static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
134                                       uint64_t Address, const void *Decoder) {
135  return decodeUImmOperand<6>(Inst, Imm);
136}
137
138static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
139                                       uint64_t Address, const void *Decoder) {
140  return decodeUImmOperand<8>(Inst, Imm);
141}
142
143static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
144                                        uint64_t Address, const void *Decoder) {
145  return decodeUImmOperand<16>(Inst, Imm);
146}
147
148static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
149                                        uint64_t Address, const void *Decoder) {
150  return decodeUImmOperand<32>(Inst, Imm);
151}
152
153static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
154                                       uint64_t Address, const void *Decoder) {
155  return decodeSImmOperand<8>(Inst, Imm);
156}
157
158static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
159                                        uint64_t Address, const void *Decoder) {
160  return decodeSImmOperand<16>(Inst, Imm);
161}
162
163static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
164                                        uint64_t Address, const void *Decoder) {
165  return decodeSImmOperand<32>(Inst, Imm);
166}
167
168template<unsigned N>
169static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
170                                       uint64_t Address) {
171  assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
172  Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address));
173  return MCDisassembler::Success;
174}
175
176static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
177                                         uint64_t Address,
178                                         const void *Decoder) {
179  return decodePCDBLOperand<16>(Inst, Imm, Address);
180}
181
182static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
183                                         uint64_t Address,
184                                         const void *Decoder) {
185  return decodePCDBLOperand<32>(Inst, Imm, Address);
186}
187
188static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
189                                          const unsigned *Regs) {
190  uint64_t Base = Field >> 12;
191  uint64_t Disp = Field & 0xfff;
192  assert(Base < 16 && "Invalid BDAddr12");
193  Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
194  Inst.addOperand(MCOperand::CreateImm(Disp));
195  return MCDisassembler::Success;
196}
197
198static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
199                                          const unsigned *Regs) {
200  uint64_t Base = Field >> 20;
201  uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
202  assert(Base < 16 && "Invalid BDAddr20");
203  Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
204  Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
205  return MCDisassembler::Success;
206}
207
208static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
209                                           const unsigned *Regs) {
210  uint64_t Index = Field >> 16;
211  uint64_t Base = (Field >> 12) & 0xf;
212  uint64_t Disp = Field & 0xfff;
213  assert(Index < 16 && "Invalid BDXAddr12");
214  Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
215  Inst.addOperand(MCOperand::CreateImm(Disp));
216  Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
217  return MCDisassembler::Success;
218}
219
220static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
221                                           const unsigned *Regs) {
222  uint64_t Index = Field >> 24;
223  uint64_t Base = (Field >> 20) & 0xf;
224  uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
225  assert(Index < 16 && "Invalid BDXAddr20");
226  Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
227  Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
228  Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
229  return MCDisassembler::Success;
230}
231
232static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
233                                               const unsigned *Regs) {
234  uint64_t Length = Field >> 16;
235  uint64_t Base = (Field >> 12) & 0xf;
236  uint64_t Disp = Field & 0xfff;
237  assert(Length < 256 && "Invalid BDLAddr12Len8");
238  Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
239  Inst.addOperand(MCOperand::CreateImm(Disp));
240  Inst.addOperand(MCOperand::CreateImm(Length + 1));
241  return MCDisassembler::Success;
242}
243
244static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
245                                                uint64_t Address,
246                                                const void *Decoder) {
247  return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
248}
249
250static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
251                                                uint64_t Address,
252                                                const void *Decoder) {
253  return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
254}
255
256static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
257                                                uint64_t Address,
258                                                const void *Decoder) {
259  return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
260}
261
262static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
263                                                uint64_t Address,
264                                                const void *Decoder) {
265  return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
266}
267
268static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
269                                                 uint64_t Address,
270                                                 const void *Decoder) {
271  return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
272}
273
274static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
275                                                 uint64_t Address,
276                                                 const void *Decoder) {
277  return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
278}
279
280static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
281                                                     uint64_t Field,
282                                                     uint64_t Address,
283                                                     const void *Decoder) {
284  return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
285}
286
287#include "SystemZGenDisassemblerTables.inc"
288
289DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
290                                                 const MemoryObject &Region,
291                                                 uint64_t Address,
292                                                 raw_ostream &os,
293                                                 raw_ostream &cs) const {
294  // Get the first two bytes of the instruction.
295  uint8_t Bytes[6];
296  Size = 0;
297  if (Region.readBytes(Address, 2, Bytes) == -1)
298    return MCDisassembler::Fail;
299
300  // The top 2 bits of the first byte specify the size.
301  const uint8_t *Table;
302  if (Bytes[0] < 0x40) {
303    Size = 2;
304    Table = DecoderTable16;
305  } else if (Bytes[0] < 0xc0) {
306    Size = 4;
307    Table = DecoderTable32;
308  } else {
309    Size = 6;
310    Table = DecoderTable48;
311  }
312
313  // Read any remaining bytes.
314  if (Size > 2 && Region.readBytes(Address + 2, Size - 2, Bytes + 2) == -1)
315    return MCDisassembler::Fail;
316
317  // Construct the instruction.
318  uint64_t Inst = 0;
319  for (uint64_t I = 0; I < Size; ++I)
320    Inst = (Inst << 8) | Bytes[I];
321
322  return decodeInstruction(Table, MI, Inst, Address, this, STI);
323}
324