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/TargetRegistry.h"
16
17using namespace llvm;
18
19#define DEBUG_TYPE "systemz-disassembler"
20
21typedef MCDisassembler::DecodeStatus DecodeStatus;
22
23namespace {
24class SystemZDisassembler : public MCDisassembler {
25public:
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
37static MCDisassembler *createSystemZDisassembler(const Target &T,
38                                                 const MCSubtargetInfo &STI,
39                                                 MCContext &Ctx) {
40  return new SystemZDisassembler(STI, Ctx);
41}
42
43extern "C" void LLVMInitializeSystemZDisassembler() {
44  // Register the disassembler.
45  TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
46                                         createSystemZDisassembler);
47}
48
49static 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));
56  return MCDisassembler::Success;
57}
58
59static 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
65static 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
71static 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
77static 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
83static 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
89static 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
95static 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
101static 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
107static 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
113static 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
119static 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
125template<unsigned N>
126static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
127  if (!isUInt<N>(Imm))
128    return MCDisassembler::Fail;
129  Inst.addOperand(MCOperand::createImm(Imm));
130  return MCDisassembler::Success;
131}
132
133template<unsigned N>
134static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
135  if (!isUInt<N>(Imm))
136    return MCDisassembler::Fail;
137  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
138  return MCDisassembler::Success;
139}
140
141static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
142                                           uint64_t Address,
143                                           const void *Decoder) {
144  return decodeUImmOperand<4>(Inst, Imm);
145}
146
147static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
148                                       uint64_t Address, const void *Decoder) {
149  return decodeUImmOperand<1>(Inst, Imm);
150}
151
152static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
153                                       uint64_t Address, const void *Decoder) {
154  return decodeUImmOperand<2>(Inst, Imm);
155}
156
157static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
158                                       uint64_t Address, const void *Decoder) {
159  return decodeUImmOperand<3>(Inst, Imm);
160}
161
162static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
163                                       uint64_t Address, const void *Decoder) {
164  return decodeUImmOperand<4>(Inst, Imm);
165}
166
167static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
168                                       uint64_t Address, const void *Decoder) {
169  return decodeUImmOperand<6>(Inst, Imm);
170}
171
172static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
173                                       uint64_t Address, const void *Decoder) {
174  return decodeUImmOperand<8>(Inst, Imm);
175}
176
177static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
178                                        uint64_t Address, const void *Decoder) {
179  return decodeUImmOperand<12>(Inst, Imm);
180}
181
182static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
183                                        uint64_t Address, const void *Decoder) {
184  return decodeUImmOperand<16>(Inst, Imm);
185}
186
187static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
188                                        uint64_t Address, const void *Decoder) {
189  return decodeUImmOperand<32>(Inst, Imm);
190}
191
192static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
193                                       uint64_t Address, const void *Decoder) {
194  return decodeSImmOperand<8>(Inst, Imm);
195}
196
197static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
198                                        uint64_t Address, const void *Decoder) {
199  return decodeSImmOperand<16>(Inst, Imm);
200}
201
202static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
203                                        uint64_t Address, const void *Decoder) {
204  return decodeSImmOperand<32>(Inst, Imm);
205}
206
207template<unsigned N>
208static 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));
212  return MCDisassembler::Success;
213}
214
215static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
216                                         uint64_t Address,
217                                         const void *Decoder) {
218  return decodePCDBLOperand<16>(Inst, Imm, Address);
219}
220
221static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
222                                         uint64_t Address,
223                                         const void *Decoder) {
224  return decodePCDBLOperand<32>(Inst, Imm, Address);
225}
226
227static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
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));
234  return MCDisassembler::Success;
235}
236
237static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
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)));
244  return MCDisassembler::Success;
245}
246
247static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
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]));
256  return MCDisassembler::Success;
257}
258
259static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
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]));
268  return MCDisassembler::Success;
269}
270
271static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
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));
280  return MCDisassembler::Success;
281}
282
283static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
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));
291  Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
292  return MCDisassembler::Success;
293}
294
295static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
296                                                uint64_t Address,
297                                                const void *Decoder) {
298  return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
299}
300
301static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
302                                                uint64_t Address,
303                                                const void *Decoder) {
304  return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
305}
306
307static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
308                                                uint64_t Address,
309                                                const void *Decoder) {
310  return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
311}
312
313static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
314                                                uint64_t Address,
315                                                const void *Decoder) {
316  return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
317}
318
319static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
320                                                 uint64_t Address,
321                                                 const void *Decoder) {
322  return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
323}
324
325static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
326                                                 uint64_t Address,
327                                                 const void *Decoder) {
328  return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
329}
330
331static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
332                                                     uint64_t Field,
333                                                     uint64_t Address,
334                                                     const void *Decoder) {
335  return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
336}
337
338static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
339                                                 uint64_t Address,
340                                                 const void *Decoder) {
341  return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
342}
343
344#include "SystemZGenDisassemblerTables.inc"
345
346DecodeStatus 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}
380