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
17 using namespace llvm;
18
19 #define DEBUG_TYPE "systemz-disassembler"
20
21 typedef MCDisassembler::DecodeStatus DecodeStatus;
22
23 namespace {
24 class SystemZDisassembler : public MCDisassembler {
25 public:
SystemZDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)26 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
27 : MCDisassembler(STI, Ctx) {}
~SystemZDisassembler()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
createSystemZDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)37 static MCDisassembler *createSystemZDisassembler(const Target &T,
38 const MCSubtargetInfo &STI,
39 MCContext &Ctx) {
40 return new SystemZDisassembler(STI, Ctx);
41 }
42
LLVMInitializeSystemZDisassembler()43 extern "C" void LLVMInitializeSystemZDisassembler() {
44 // Register the disassembler.
45 TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
46 createSystemZDisassembler);
47 }
48
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const unsigned * Regs,unsigned Size)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));
56 return MCDisassembler::Success;
57 }
58
DecodeGR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeGRH32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeGR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeGR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeADDR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFP32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFP64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeFP128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeVR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeVR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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
DecodeVR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)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>
decodeUImmOperand(MCInst & Inst,uint64_t Imm)126 static 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
133 template<unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm)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)));
138 return MCDisassembler::Success;
139 }
140
decodeAccessRegOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)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
decodeU1ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)147 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
148 uint64_t Address, const void *Decoder) {
149 return decodeUImmOperand<1>(Inst, Imm);
150 }
151
decodeU2ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)152 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
153 uint64_t Address, const void *Decoder) {
154 return decodeUImmOperand<2>(Inst, Imm);
155 }
156
decodeU3ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)157 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
158 uint64_t Address, const void *Decoder) {
159 return decodeUImmOperand<3>(Inst, Imm);
160 }
161
decodeU4ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)162 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
163 uint64_t Address, const void *Decoder) {
164 return decodeUImmOperand<4>(Inst, Imm);
165 }
166
decodeU6ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)167 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
168 uint64_t Address, const void *Decoder) {
169 return decodeUImmOperand<6>(Inst, Imm);
170 }
171
decodeU8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)172 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
173 uint64_t Address, const void *Decoder) {
174 return decodeUImmOperand<8>(Inst, Imm);
175 }
176
decodeU12ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)177 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
178 uint64_t Address, const void *Decoder) {
179 return decodeUImmOperand<12>(Inst, Imm);
180 }
181
decodeU16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)182 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
183 uint64_t Address, const void *Decoder) {
184 return decodeUImmOperand<16>(Inst, Imm);
185 }
186
decodeU32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)187 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
188 uint64_t Address, const void *Decoder) {
189 return decodeUImmOperand<32>(Inst, Imm);
190 }
191
decodeS8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)192 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
193 uint64_t Address, const void *Decoder) {
194 return decodeSImmOperand<8>(Inst, Imm);
195 }
196
decodeS16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)197 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
198 uint64_t Address, const void *Decoder) {
199 return decodeSImmOperand<16>(Inst, Imm);
200 }
201
decodeS32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)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>
decodePCDBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address)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));
212 return MCDisassembler::Success;
213 }
214
decodePC16DBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)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
decodePC32DBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)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
decodeBDAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)227 static 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
decodeBDAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)237 static 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
decodeBDXAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)247 static 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
decodeBDXAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)259 static 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
decodeBDLAddr12Len8Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)271 static 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
decodeBDVAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)283 static 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
decodeBDAddr32Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)295 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
296 uint64_t Address,
297 const void *Decoder) {
298 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
299 }
300
decodeBDAddr32Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)301 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
302 uint64_t Address,
303 const void *Decoder) {
304 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
305 }
306
decodeBDAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)307 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
308 uint64_t Address,
309 const void *Decoder) {
310 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
311 }
312
decodeBDAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)313 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
314 uint64_t Address,
315 const void *Decoder) {
316 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
317 }
318
decodeBDXAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)319 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
320 uint64_t Address,
321 const void *Decoder) {
322 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
323 }
324
decodeBDXAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)325 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
326 uint64_t Address,
327 const void *Decoder) {
328 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
329 }
330
decodeBDLAddr64Disp12Len8Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)331 static 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
decodeBDVAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)338 static 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
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const346 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 }
380