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
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
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.
tryAddingSymbolicOperand(int64_t Value,bool isBranch,uint64_t Address,uint64_t Offset,uint64_t Width,MCInst & MI,const void * Decoder)68 static 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
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const unsigned * Regs,unsigned Size)77 static 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
DecodeGR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)87 static 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
DecodeGRH32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)93 static 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
DecodeGR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)99 static 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
DecodeGR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)105 static 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
DecodeADDR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)111 static 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
DecodeFP32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)117 static 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
DecodeFP64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)123 static 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
DecodeFP128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)129 static 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
DecodeVR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)135 static 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
DecodeVR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)141 static 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
DecodeVR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)147 static 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
153 template<unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm)154 static 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
161 template<unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm)162 static 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
decodeAccessRegOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)169 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
170 uint64_t Address,
171 const void *Decoder) {
172 return decodeUImmOperand<4>(Inst, Imm);
173 }
174
decodeU1ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)175 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
176 uint64_t Address, const void *Decoder) {
177 return decodeUImmOperand<1>(Inst, Imm);
178 }
179
decodeU2ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)180 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
181 uint64_t Address, const void *Decoder) {
182 return decodeUImmOperand<2>(Inst, Imm);
183 }
184
decodeU3ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)185 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
186 uint64_t Address, const void *Decoder) {
187 return decodeUImmOperand<3>(Inst, Imm);
188 }
189
decodeU4ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)190 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
191 uint64_t Address, const void *Decoder) {
192 return decodeUImmOperand<4>(Inst, Imm);
193 }
194
decodeU6ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)195 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
196 uint64_t Address, const void *Decoder) {
197 return decodeUImmOperand<6>(Inst, Imm);
198 }
199
decodeU8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)200 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
201 uint64_t Address, const void *Decoder) {
202 return decodeUImmOperand<8>(Inst, Imm);
203 }
204
decodeU12ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)205 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
206 uint64_t Address, const void *Decoder) {
207 return decodeUImmOperand<12>(Inst, Imm);
208 }
209
decodeU16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)210 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
211 uint64_t Address, const void *Decoder) {
212 return decodeUImmOperand<16>(Inst, Imm);
213 }
214
decodeU32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)215 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
216 uint64_t Address, const void *Decoder) {
217 return decodeUImmOperand<32>(Inst, Imm);
218 }
219
decodeS8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)220 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
221 uint64_t Address, const void *Decoder) {
222 return decodeSImmOperand<8>(Inst, Imm);
223 }
224
decodeS16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)225 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
226 uint64_t Address, const void *Decoder) {
227 return decodeSImmOperand<16>(Inst, Imm);
228 }
229
decodeS32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)230 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
231 uint64_t Address, const void *Decoder) {
232 return decodeSImmOperand<32>(Inst, Imm);
233 }
234
235 template<unsigned N>
decodePCDBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,bool isBranch,const void * Decoder)236 static 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
decodePC16DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)250 static 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
decodePC32DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)256 static 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
decodePC32DBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)262 static 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
decodeBDAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)268 static 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
decodeBDAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)278 static 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
decodeBDXAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)288 static 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
decodeBDXAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)300 static 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
decodeBDLAddr12Len8Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)312 static 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
decodeBDVAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)324 static 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
decodeBDAddr32Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)336 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
337 uint64_t Address,
338 const void *Decoder) {
339 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
340 }
341
decodeBDAddr32Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)342 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
343 uint64_t Address,
344 const void *Decoder) {
345 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
346 }
347
decodeBDAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)348 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
349 uint64_t Address,
350 const void *Decoder) {
351 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
352 }
353
decodeBDAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)354 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
355 uint64_t Address,
356 const void *Decoder) {
357 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
358 }
359
decodeBDXAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)360 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
361 uint64_t Address,
362 const void *Decoder) {
363 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
364 }
365
decodeBDXAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)366 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
367 uint64_t Address,
368 const void *Decoder) {
369 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
370 }
371
decodeBDLAddr64Disp12Len8Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)372 static 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
decodeBDVAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)379 static 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
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const387 DecodeStatus 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