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/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
49/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
50/// immediate Value in the MCInst.
51///
52/// @param Value      - The immediate Value, has had any PC adjustment made by
53///                     the caller.
54/// @param isBranch   - If the instruction is a branch instruction
55/// @param Address    - The starting address of the instruction
56/// @param Offset     - The byte offset to this immediate in the instruction
57/// @param Width      - The byte width of this immediate in the instruction
58///
59/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
60/// called then that function is called to get any symbolic information for the
61/// immediate in the instruction using the Address, Offset and Width.  If that
62/// returns non-zero then the symbolic information it returns is used to create
63/// an MCExpr and that is added as an operand to the MCInst.  If getOpInfo()
64/// returns zero and isBranch is true then a symbol look up for immediate Value
65/// is done and if a symbol is found an MCExpr is created with that, else
66/// an MCExpr with the immediate Value is created.  This function returns true
67/// if it adds an operand to the MCInst and false otherwise.
68static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
69                                     uint64_t Address, uint64_t Offset,
70                                     uint64_t Width, MCInst &MI,
71                                     const void *Decoder) {
72  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
73  return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
74                                       Offset, Width);
75}
76
77static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
78                                        const unsigned *Regs, unsigned Size) {
79  assert(RegNo < Size && "Invalid register");
80  RegNo = Regs[RegNo];
81  if (RegNo == 0)
82    return MCDisassembler::Fail;
83  Inst.addOperand(MCOperand::createReg(RegNo));
84  return MCDisassembler::Success;
85}
86
87static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
88                                               uint64_t Address,
89                                               const void *Decoder) {
90  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
91}
92
93static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
94                                                uint64_t Address,
95                                                const void *Decoder) {
96  return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
97}
98
99static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
100                                               uint64_t Address,
101                                               const void *Decoder) {
102  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
103}
104
105static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
106                                                uint64_t Address,
107                                                const void *Decoder) {
108  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
109}
110
111static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
112                                                 uint64_t Address,
113                                                 const void *Decoder) {
114  return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
115}
116
117static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
118                                               uint64_t Address,
119                                               const void *Decoder) {
120  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
121}
122
123static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
124                                               uint64_t Address,
125                                               const void *Decoder) {
126  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
127}
128
129static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
130                                                uint64_t Address,
131                                                const void *Decoder) {
132  return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
133}
134
135static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
136                                               uint64_t Address,
137                                               const void *Decoder) {
138  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
139}
140
141static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
142                                               uint64_t Address,
143                                               const void *Decoder) {
144  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
145}
146
147static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
148                                                uint64_t Address,
149                                                const void *Decoder) {
150  return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
151}
152
153template<unsigned N>
154static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
155  if (!isUInt<N>(Imm))
156    return MCDisassembler::Fail;
157  Inst.addOperand(MCOperand::createImm(Imm));
158  return MCDisassembler::Success;
159}
160
161template<unsigned N>
162static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
163  if (!isUInt<N>(Imm))
164    return MCDisassembler::Fail;
165  Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
166  return MCDisassembler::Success;
167}
168
169static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
170                                           uint64_t Address,
171                                           const void *Decoder) {
172  return decodeUImmOperand<4>(Inst, Imm);
173}
174
175static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
176                                       uint64_t Address, const void *Decoder) {
177  return decodeUImmOperand<1>(Inst, Imm);
178}
179
180static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
181                                       uint64_t Address, const void *Decoder) {
182  return decodeUImmOperand<2>(Inst, Imm);
183}
184
185static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
186                                       uint64_t Address, const void *Decoder) {
187  return decodeUImmOperand<3>(Inst, Imm);
188}
189
190static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
191                                       uint64_t Address, const void *Decoder) {
192  return decodeUImmOperand<4>(Inst, Imm);
193}
194
195static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
196                                       uint64_t Address, const void *Decoder) {
197  return decodeUImmOperand<6>(Inst, Imm);
198}
199
200static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
201                                       uint64_t Address, const void *Decoder) {
202  return decodeUImmOperand<8>(Inst, Imm);
203}
204
205static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
206                                        uint64_t Address, const void *Decoder) {
207  return decodeUImmOperand<12>(Inst, Imm);
208}
209
210static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
211                                        uint64_t Address, const void *Decoder) {
212  return decodeUImmOperand<16>(Inst, Imm);
213}
214
215static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
216                                        uint64_t Address, const void *Decoder) {
217  return decodeUImmOperand<32>(Inst, Imm);
218}
219
220static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
221                                       uint64_t Address, const void *Decoder) {
222  return decodeSImmOperand<8>(Inst, Imm);
223}
224
225static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
226                                        uint64_t Address, const void *Decoder) {
227  return decodeSImmOperand<16>(Inst, Imm);
228}
229
230static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
231                                        uint64_t Address, const void *Decoder) {
232  return decodeSImmOperand<32>(Inst, Imm);
233}
234
235template<unsigned N>
236static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
237                                       uint64_t Address,
238                                       bool isBranch,
239                                       const void *Decoder) {
240  assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
241  uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
242
243  if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
244                                Inst, Decoder))
245    Inst.addOperand(MCOperand::createImm(Value));
246
247  return MCDisassembler::Success;
248}
249
250static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
251                                               uint64_t Address,
252                                               const void *Decoder) {
253  return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
254}
255
256static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
257                                               uint64_t Address,
258                                               const void *Decoder) {
259  return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
260}
261
262static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
263                                         uint64_t Address,
264                                         const void *Decoder) {
265  return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
266}
267
268static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
269                                          const unsigned *Regs) {
270  uint64_t Base = Field >> 12;
271  uint64_t Disp = Field & 0xfff;
272  assert(Base < 16 && "Invalid BDAddr12");
273  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
274  Inst.addOperand(MCOperand::createImm(Disp));
275  return MCDisassembler::Success;
276}
277
278static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
279                                          const unsigned *Regs) {
280  uint64_t Base = Field >> 20;
281  uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
282  assert(Base < 16 && "Invalid BDAddr20");
283  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
284  Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
285  return MCDisassembler::Success;
286}
287
288static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
289                                           const unsigned *Regs) {
290  uint64_t Index = Field >> 16;
291  uint64_t Base = (Field >> 12) & 0xf;
292  uint64_t Disp = Field & 0xfff;
293  assert(Index < 16 && "Invalid BDXAddr12");
294  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
295  Inst.addOperand(MCOperand::createImm(Disp));
296  Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
297  return MCDisassembler::Success;
298}
299
300static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
301                                           const unsigned *Regs) {
302  uint64_t Index = Field >> 24;
303  uint64_t Base = (Field >> 20) & 0xf;
304  uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
305  assert(Index < 16 && "Invalid BDXAddr20");
306  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
307  Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
308  Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
309  return MCDisassembler::Success;
310}
311
312static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
313                                               const unsigned *Regs) {
314  uint64_t Length = Field >> 16;
315  uint64_t Base = (Field >> 12) & 0xf;
316  uint64_t Disp = Field & 0xfff;
317  assert(Length < 256 && "Invalid BDLAddr12Len8");
318  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
319  Inst.addOperand(MCOperand::createImm(Disp));
320  Inst.addOperand(MCOperand::createImm(Length + 1));
321  return MCDisassembler::Success;
322}
323
324static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
325                                           const unsigned *Regs) {
326  uint64_t Index = Field >> 16;
327  uint64_t Base = (Field >> 12) & 0xf;
328  uint64_t Disp = Field & 0xfff;
329  assert(Index < 32 && "Invalid BDVAddr12");
330  Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
331  Inst.addOperand(MCOperand::createImm(Disp));
332  Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
333  return MCDisassembler::Success;
334}
335
336static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
337                                                uint64_t Address,
338                                                const void *Decoder) {
339  return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
340}
341
342static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
343                                                uint64_t Address,
344                                                const void *Decoder) {
345  return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
346}
347
348static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
349                                                uint64_t Address,
350                                                const void *Decoder) {
351  return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
352}
353
354static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
355                                                uint64_t Address,
356                                                const void *Decoder) {
357  return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
358}
359
360static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
361                                                 uint64_t Address,
362                                                 const void *Decoder) {
363  return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
364}
365
366static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
367                                                 uint64_t Address,
368                                                 const void *Decoder) {
369  return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
370}
371
372static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
373                                                     uint64_t Field,
374                                                     uint64_t Address,
375                                                     const void *Decoder) {
376  return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
377}
378
379static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
380                                                 uint64_t Address,
381                                                 const void *Decoder) {
382  return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
383}
384
385#include "SystemZGenDisassemblerTables.inc"
386
387DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
388                                                 ArrayRef<uint8_t> Bytes,
389                                                 uint64_t Address,
390                                                 raw_ostream &OS,
391                                                 raw_ostream &CS) const {
392  // Get the first two bytes of the instruction.
393  Size = 0;
394  if (Bytes.size() < 2)
395    return MCDisassembler::Fail;
396
397  // The top 2 bits of the first byte specify the size.
398  const uint8_t *Table;
399  if (Bytes[0] < 0x40) {
400    Size = 2;
401    Table = DecoderTable16;
402  } else if (Bytes[0] < 0xc0) {
403    Size = 4;
404    Table = DecoderTable32;
405  } else {
406    Size = 6;
407    Table = DecoderTable48;
408  }
409
410  // Read any remaining bytes.
411  if (Bytes.size() < Size)
412    return MCDisassembler::Fail;
413
414  // Construct the instruction.
415  uint64_t Inst = 0;
416  for (uint64_t I = 0; I < Size; ++I)
417    Inst = (Inst << 8) | Bytes[I];
418
419  return decodeInstruction(Table, MI, Inst, Address, this, STI);
420}
421