1 //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/SystemZMCTargetDesc.h"
11 #include "TargetInfo/SystemZTargetInfo.h"
12 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
13 #include "llvm/MC/MCFixedLenDisassembler.h"
14 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCSubtargetInfo.h"
16 #include "llvm/Support/MathExtras.h"
17 #include "llvm/Support/TargetRegistry.h"
23 #define DEBUG_TYPE "systemz-disassembler"
25 typedef MCDisassembler::DecodeStatus DecodeStatus
;
29 class SystemZDisassembler
: public MCDisassembler
{
31 SystemZDisassembler(const MCSubtargetInfo
&STI
, MCContext
&Ctx
)
32 : MCDisassembler(STI
, Ctx
) {}
33 ~SystemZDisassembler() override
= default;
35 DecodeStatus
getInstruction(MCInst
&instr
, uint64_t &Size
,
36 ArrayRef
<uint8_t> Bytes
, uint64_t Address
,
37 raw_ostream
&CStream
) const override
;
40 } // end anonymous namespace
42 static MCDisassembler
*createSystemZDisassembler(const Target
&T
,
43 const MCSubtargetInfo
&STI
,
45 return new SystemZDisassembler(STI
, Ctx
);
48 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializeSystemZDisassembler() {
49 // Register the disassembler.
50 TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(),
51 createSystemZDisassembler
);
54 /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
55 /// immediate Value in the MCInst.
57 /// @param Value - The immediate Value, has had any PC adjustment made by
59 /// @param isBranch - If the instruction is a branch instruction
60 /// @param Address - The starting address of the instruction
61 /// @param Offset - The byte offset to this immediate in the instruction
62 /// @param Width - The byte width of this immediate in the instruction
64 /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
65 /// called then that function is called to get any symbolic information for the
66 /// immediate in the instruction using the Address, Offset and Width. If that
67 /// returns non-zero then the symbolic information it returns is used to create
68 /// an MCExpr and that is added as an operand to the MCInst. If getOpInfo()
69 /// returns zero and isBranch is true then a symbol look up for immediate Value
70 /// is done and if a symbol is found an MCExpr is created with that, else
71 /// an MCExpr with the immediate Value is created. This function returns true
72 /// if it adds an operand to the MCInst and false otherwise.
73 static bool tryAddingSymbolicOperand(int64_t Value
, bool isBranch
,
74 uint64_t Address
, uint64_t Offset
,
75 uint64_t Width
, MCInst
&MI
,
76 const void *Decoder
) {
77 const MCDisassembler
*Dis
= static_cast<const MCDisassembler
*>(Decoder
);
78 return Dis
->tryAddingSymbolicOperand(MI
, Value
, Address
, isBranch
,
82 static DecodeStatus
decodeRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
83 const unsigned *Regs
, unsigned Size
) {
84 assert(RegNo
< Size
&& "Invalid register");
87 return MCDisassembler::Fail
;
88 Inst
.addOperand(MCOperand::createReg(RegNo
));
89 return MCDisassembler::Success
;
92 static DecodeStatus
DecodeGR32BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
94 const void *Decoder
) {
95 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::GR32Regs
, 16);
98 static DecodeStatus
DecodeGRH32BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
100 const void *Decoder
) {
101 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::GRH32Regs
, 16);
104 static DecodeStatus
DecodeGR64BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
106 const void *Decoder
) {
107 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::GR64Regs
, 16);
110 static DecodeStatus
DecodeGR128BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
112 const void *Decoder
) {
113 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::GR128Regs
, 16);
116 static DecodeStatus
DecodeADDR64BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
118 const void *Decoder
) {
119 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::GR64Regs
, 16);
122 static DecodeStatus
DecodeFP32BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
124 const void *Decoder
) {
125 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::FP32Regs
, 16);
128 static DecodeStatus
DecodeFP64BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
130 const void *Decoder
) {
131 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::FP64Regs
, 16);
134 static DecodeStatus
DecodeFP128BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
136 const void *Decoder
) {
137 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::FP128Regs
, 16);
140 static DecodeStatus
DecodeVR32BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
142 const void *Decoder
) {
143 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::VR32Regs
, 32);
146 static DecodeStatus
DecodeVR64BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
148 const void *Decoder
) {
149 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::VR64Regs
, 32);
152 static DecodeStatus
DecodeVR128BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
154 const void *Decoder
) {
155 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::VR128Regs
, 32);
158 static DecodeStatus
DecodeAR32BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
160 const void *Decoder
) {
161 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::AR32Regs
, 16);
164 static DecodeStatus
DecodeCR64BitRegisterClass(MCInst
&Inst
, uint64_t RegNo
,
166 const void *Decoder
) {
167 return decodeRegisterClass(Inst
, RegNo
, SystemZMC::CR64Regs
, 16);
171 static DecodeStatus
decodeUImmOperand(MCInst
&Inst
, uint64_t Imm
) {
173 return MCDisassembler::Fail
;
174 Inst
.addOperand(MCOperand::createImm(Imm
));
175 return MCDisassembler::Success
;
179 static DecodeStatus
decodeSImmOperand(MCInst
&Inst
, uint64_t Imm
) {
181 return MCDisassembler::Fail
;
182 Inst
.addOperand(MCOperand::createImm(SignExtend64
<N
>(Imm
)));
183 return MCDisassembler::Success
;
186 static DecodeStatus
decodeU1ImmOperand(MCInst
&Inst
, uint64_t Imm
,
187 uint64_t Address
, const void *Decoder
) {
188 return decodeUImmOperand
<1>(Inst
, Imm
);
191 static DecodeStatus
decodeU2ImmOperand(MCInst
&Inst
, uint64_t Imm
,
192 uint64_t Address
, const void *Decoder
) {
193 return decodeUImmOperand
<2>(Inst
, Imm
);
196 static DecodeStatus
decodeU3ImmOperand(MCInst
&Inst
, uint64_t Imm
,
197 uint64_t Address
, const void *Decoder
) {
198 return decodeUImmOperand
<3>(Inst
, Imm
);
201 static DecodeStatus
decodeU4ImmOperand(MCInst
&Inst
, uint64_t Imm
,
202 uint64_t Address
, const void *Decoder
) {
203 return decodeUImmOperand
<4>(Inst
, Imm
);
206 static DecodeStatus
decodeU6ImmOperand(MCInst
&Inst
, uint64_t Imm
,
207 uint64_t Address
, const void *Decoder
) {
208 return decodeUImmOperand
<6>(Inst
, Imm
);
211 static DecodeStatus
decodeU8ImmOperand(MCInst
&Inst
, uint64_t Imm
,
212 uint64_t Address
, const void *Decoder
) {
213 return decodeUImmOperand
<8>(Inst
, Imm
);
216 static DecodeStatus
decodeU12ImmOperand(MCInst
&Inst
, uint64_t Imm
,
217 uint64_t Address
, const void *Decoder
) {
218 return decodeUImmOperand
<12>(Inst
, Imm
);
221 static DecodeStatus
decodeU16ImmOperand(MCInst
&Inst
, uint64_t Imm
,
222 uint64_t Address
, const void *Decoder
) {
223 return decodeUImmOperand
<16>(Inst
, Imm
);
226 static DecodeStatus
decodeU32ImmOperand(MCInst
&Inst
, uint64_t Imm
,
227 uint64_t Address
, const void *Decoder
) {
228 return decodeUImmOperand
<32>(Inst
, Imm
);
231 static DecodeStatus
decodeS8ImmOperand(MCInst
&Inst
, uint64_t Imm
,
232 uint64_t Address
, const void *Decoder
) {
233 return decodeSImmOperand
<8>(Inst
, Imm
);
236 static DecodeStatus
decodeS16ImmOperand(MCInst
&Inst
, uint64_t Imm
,
237 uint64_t Address
, const void *Decoder
) {
238 return decodeSImmOperand
<16>(Inst
, Imm
);
241 static DecodeStatus
decodeS32ImmOperand(MCInst
&Inst
, uint64_t Imm
,
242 uint64_t Address
, const void *Decoder
) {
243 return decodeSImmOperand
<32>(Inst
, Imm
);
247 static DecodeStatus
decodePCDBLOperand(MCInst
&Inst
, uint64_t Imm
,
250 const void *Decoder
) {
251 assert(isUInt
<N
>(Imm
) && "Invalid PC-relative offset");
252 uint64_t Value
= SignExtend64
<N
>(Imm
) * 2 + Address
;
254 if (!tryAddingSymbolicOperand(Value
, isBranch
, Address
, 2, N
/ 8,
256 Inst
.addOperand(MCOperand::createImm(Value
));
258 return MCDisassembler::Success
;
261 static DecodeStatus
decodePC12DBLBranchOperand(MCInst
&Inst
, uint64_t Imm
,
263 const void *Decoder
) {
264 return decodePCDBLOperand
<12>(Inst
, Imm
, Address
, true, Decoder
);
267 static DecodeStatus
decodePC16DBLBranchOperand(MCInst
&Inst
, uint64_t Imm
,
269 const void *Decoder
) {
270 return decodePCDBLOperand
<16>(Inst
, Imm
, Address
, true, Decoder
);
273 static DecodeStatus
decodePC24DBLBranchOperand(MCInst
&Inst
, uint64_t Imm
,
275 const void *Decoder
) {
276 return decodePCDBLOperand
<24>(Inst
, Imm
, Address
, true, Decoder
);
279 static DecodeStatus
decodePC32DBLBranchOperand(MCInst
&Inst
, uint64_t Imm
,
281 const void *Decoder
) {
282 return decodePCDBLOperand
<32>(Inst
, Imm
, Address
, true, Decoder
);
285 static DecodeStatus
decodePC32DBLOperand(MCInst
&Inst
, uint64_t Imm
,
287 const void *Decoder
) {
288 return decodePCDBLOperand
<32>(Inst
, Imm
, Address
, false, Decoder
);
291 static DecodeStatus
decodeBDAddr12Operand(MCInst
&Inst
, uint64_t Field
,
292 const unsigned *Regs
) {
293 uint64_t Base
= Field
>> 12;
294 uint64_t Disp
= Field
& 0xfff;
295 assert(Base
< 16 && "Invalid BDAddr12");
296 Inst
.addOperand(MCOperand::createReg(Base
== 0 ? 0 : Regs
[Base
]));
297 Inst
.addOperand(MCOperand::createImm(Disp
));
298 return MCDisassembler::Success
;
301 static DecodeStatus
decodeBDAddr20Operand(MCInst
&Inst
, uint64_t Field
,
302 const unsigned *Regs
) {
303 uint64_t Base
= Field
>> 20;
304 uint64_t Disp
= ((Field
<< 12) & 0xff000) | ((Field
>> 8) & 0xfff);
305 assert(Base
< 16 && "Invalid BDAddr20");
306 Inst
.addOperand(MCOperand::createReg(Base
== 0 ? 0 : Regs
[Base
]));
307 Inst
.addOperand(MCOperand::createImm(SignExtend64
<20>(Disp
)));
308 return MCDisassembler::Success
;
311 static DecodeStatus
decodeBDXAddr12Operand(MCInst
&Inst
, uint64_t Field
,
312 const unsigned *Regs
) {
313 uint64_t Index
= Field
>> 16;
314 uint64_t Base
= (Field
>> 12) & 0xf;
315 uint64_t Disp
= Field
& 0xfff;
316 assert(Index
< 16 && "Invalid BDXAddr12");
317 Inst
.addOperand(MCOperand::createReg(Base
== 0 ? 0 : Regs
[Base
]));
318 Inst
.addOperand(MCOperand::createImm(Disp
));
319 Inst
.addOperand(MCOperand::createReg(Index
== 0 ? 0 : Regs
[Index
]));
320 return MCDisassembler::Success
;
323 static DecodeStatus
decodeBDXAddr20Operand(MCInst
&Inst
, uint64_t Field
,
324 const unsigned *Regs
) {
325 uint64_t Index
= Field
>> 24;
326 uint64_t Base
= (Field
>> 20) & 0xf;
327 uint64_t Disp
= ((Field
& 0xfff00) >> 8) | ((Field
& 0xff) << 12);
328 assert(Index
< 16 && "Invalid BDXAddr20");
329 Inst
.addOperand(MCOperand::createReg(Base
== 0 ? 0 : Regs
[Base
]));
330 Inst
.addOperand(MCOperand::createImm(SignExtend64
<20>(Disp
)));
331 Inst
.addOperand(MCOperand::createReg(Index
== 0 ? 0 : Regs
[Index
]));
332 return MCDisassembler::Success
;
335 static DecodeStatus
decodeBDLAddr12Len4Operand(MCInst
&Inst
, uint64_t Field
,
336 const unsigned *Regs
) {
337 uint64_t Length
= Field
>> 16;
338 uint64_t Base
= (Field
>> 12) & 0xf;
339 uint64_t Disp
= Field
& 0xfff;
340 assert(Length
< 16 && "Invalid BDLAddr12Len4");
341 Inst
.addOperand(MCOperand::createReg(Base
== 0 ? 0 : Regs
[Base
]));
342 Inst
.addOperand(MCOperand::createImm(Disp
));
343 Inst
.addOperand(MCOperand::createImm(Length
+ 1));
344 return MCDisassembler::Success
;
347 static DecodeStatus
decodeBDLAddr12Len8Operand(MCInst
&Inst
, uint64_t Field
,
348 const unsigned *Regs
) {
349 uint64_t Length
= Field
>> 16;
350 uint64_t Base
= (Field
>> 12) & 0xf;
351 uint64_t Disp
= Field
& 0xfff;
352 assert(Length
< 256 && "Invalid BDLAddr12Len8");
353 Inst
.addOperand(MCOperand::createReg(Base
== 0 ? 0 : Regs
[Base
]));
354 Inst
.addOperand(MCOperand::createImm(Disp
));
355 Inst
.addOperand(MCOperand::createImm(Length
+ 1));
356 return MCDisassembler::Success
;
359 static DecodeStatus
decodeBDRAddr12Operand(MCInst
&Inst
, uint64_t Field
,
360 const unsigned *Regs
) {
361 uint64_t Length
= Field
>> 16;
362 uint64_t Base
= (Field
>> 12) & 0xf;
363 uint64_t Disp
= Field
& 0xfff;
364 assert(Length
< 16 && "Invalid BDRAddr12");
365 Inst
.addOperand(MCOperand::createReg(Base
== 0 ? 0 : Regs
[Base
]));
366 Inst
.addOperand(MCOperand::createImm(Disp
));
367 Inst
.addOperand(MCOperand::createReg(Regs
[Length
]));
368 return MCDisassembler::Success
;
371 static DecodeStatus
decodeBDVAddr12Operand(MCInst
&Inst
, uint64_t Field
,
372 const unsigned *Regs
) {
373 uint64_t Index
= Field
>> 16;
374 uint64_t Base
= (Field
>> 12) & 0xf;
375 uint64_t Disp
= Field
& 0xfff;
376 assert(Index
< 32 && "Invalid BDVAddr12");
377 Inst
.addOperand(MCOperand::createReg(Base
== 0 ? 0 : Regs
[Base
]));
378 Inst
.addOperand(MCOperand::createImm(Disp
));
379 Inst
.addOperand(MCOperand::createReg(SystemZMC::VR128Regs
[Index
]));
380 return MCDisassembler::Success
;
383 static DecodeStatus
decodeBDAddr32Disp12Operand(MCInst
&Inst
, uint64_t Field
,
385 const void *Decoder
) {
386 return decodeBDAddr12Operand(Inst
, Field
, SystemZMC::GR32Regs
);
389 static DecodeStatus
decodeBDAddr32Disp20Operand(MCInst
&Inst
, uint64_t Field
,
391 const void *Decoder
) {
392 return decodeBDAddr20Operand(Inst
, Field
, SystemZMC::GR32Regs
);
395 static DecodeStatus
decodeBDAddr64Disp12Operand(MCInst
&Inst
, uint64_t Field
,
397 const void *Decoder
) {
398 return decodeBDAddr12Operand(Inst
, Field
, SystemZMC::GR64Regs
);
401 static DecodeStatus
decodeBDAddr64Disp20Operand(MCInst
&Inst
, uint64_t Field
,
403 const void *Decoder
) {
404 return decodeBDAddr20Operand(Inst
, Field
, SystemZMC::GR64Regs
);
407 static DecodeStatus
decodeBDXAddr64Disp12Operand(MCInst
&Inst
, uint64_t Field
,
409 const void *Decoder
) {
410 return decodeBDXAddr12Operand(Inst
, Field
, SystemZMC::GR64Regs
);
413 static DecodeStatus
decodeBDXAddr64Disp20Operand(MCInst
&Inst
, uint64_t Field
,
415 const void *Decoder
) {
416 return decodeBDXAddr20Operand(Inst
, Field
, SystemZMC::GR64Regs
);
419 static DecodeStatus
decodeBDLAddr64Disp12Len4Operand(MCInst
&Inst
,
422 const void *Decoder
) {
423 return decodeBDLAddr12Len4Operand(Inst
, Field
, SystemZMC::GR64Regs
);
426 static DecodeStatus
decodeBDLAddr64Disp12Len8Operand(MCInst
&Inst
,
429 const void *Decoder
) {
430 return decodeBDLAddr12Len8Operand(Inst
, Field
, SystemZMC::GR64Regs
);
433 static DecodeStatus
decodeBDRAddr64Disp12Operand(MCInst
&Inst
,
436 const void *Decoder
) {
437 return decodeBDRAddr12Operand(Inst
, Field
, SystemZMC::GR64Regs
);
440 static DecodeStatus
decodeBDVAddr64Disp12Operand(MCInst
&Inst
, uint64_t Field
,
442 const void *Decoder
) {
443 return decodeBDVAddr12Operand(Inst
, Field
, SystemZMC::GR64Regs
);
446 #include "SystemZGenDisassemblerTables.inc"
448 DecodeStatus
SystemZDisassembler::getInstruction(MCInst
&MI
, uint64_t &Size
,
449 ArrayRef
<uint8_t> Bytes
,
451 raw_ostream
&CS
) const {
452 // Get the first two bytes of the instruction.
454 if (Bytes
.size() < 2)
455 return MCDisassembler::Fail
;
457 // The top 2 bits of the first byte specify the size.
458 const uint8_t *Table
;
459 if (Bytes
[0] < 0x40) {
461 Table
= DecoderTable16
;
462 } else if (Bytes
[0] < 0xc0) {
464 Table
= DecoderTable32
;
467 Table
= DecoderTable48
;
470 // Read any remaining bytes.
471 if (Bytes
.size() < Size
) {
473 return MCDisassembler::Fail
;
476 // Construct the instruction.
478 for (uint64_t I
= 0; I
< Size
; ++I
)
479 Inst
= (Inst
<< 8) | Bytes
[I
];
481 return decodeInstruction(Table
, MI
, Inst
, Address
, this, STI
);