LLVM 22.0.0git
SystemZDisassembler.cpp
Go to the documentation of this file.
1//===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8
11#include "llvm/MC/MCDecoder.h"
14#include "llvm/MC/MCInst.h"
19#include <cassert>
20#include <cstdint>
21
22using namespace llvm;
23
24#define DEBUG_TYPE "systemz-disassembler"
25
27
28namespace {
29
30class SystemZDisassembler : public MCDisassembler {
31public:
32 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
33 : MCDisassembler(STI, Ctx) {}
34 ~SystemZDisassembler() override = default;
35
38 raw_ostream &CStream) const override;
39};
40
41} // end anonymous namespace
42
44 const MCSubtargetInfo &STI,
45 MCContext &Ctx) {
46 return new SystemZDisassembler(STI, Ctx);
47}
48
49// NOLINTNEXTLINE(readability-identifier-naming)
52 // Register the disassembler.
55}
56
57/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
58/// immediate Value in the MCInst.
59///
60/// @param Value - The immediate Value, has had any PC adjustment made by
61/// the caller.
62/// @param isBranch - If the instruction is a branch instruction
63/// @param Address - The starting address of the instruction
64/// @param Offset - The byte offset to this immediate in the instruction
65/// @param Width - The byte width of this immediate in the instruction
66///
67/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
68/// called then that function is called to get any symbolic information for the
69/// immediate in the instruction using the Address, Offset and Width. If that
70/// returns non-zero then the symbolic information it returns is used to create
71/// an MCExpr and that is added as an operand to the MCInst. If getOpInfo()
72/// returns zero and isBranch is true then a symbol look up for immediate Value
73/// is done and if a symbol is found an MCExpr is created with that, else
74/// an MCExpr with the immediate Value is created. This function returns true
75/// if it adds an operand to the MCInst and false otherwise.
76static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
77 uint64_t Address, uint64_t Offset,
78 uint64_t Width, MCInst &MI,
79 const MCDisassembler *Decoder) {
80 return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
81 Width, /*InstSize=*/0);
82}
83
85 const unsigned *Regs, unsigned Size,
86 bool IsAddr = false) {
87 assert(RegNo < Size && "Invalid register");
88 if (IsAddr && RegNo == 0) {
89 RegNo = SystemZ::NoRegister;
90 } else {
91 RegNo = Regs[RegNo];
92 if (RegNo == 0)
94 }
97}
98
100 uint64_t Address,
101 const MCDisassembler *Decoder) {
102 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
103}
104
106 uint64_t Address,
107 const MCDisassembler *Decoder) {
108 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
109}
110
112 uint64_t Address,
113 const MCDisassembler *Decoder) {
114 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
115}
116
118 uint64_t Address,
119 const MCDisassembler *Decoder) {
120 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
121}
122
123static DecodeStatus
125 const MCDisassembler *Decoder) {
126 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16, true);
127}
128
129static DecodeStatus
131 const MCDisassembler *Decoder) {
132 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16, true);
133}
134
136 uint64_t Address,
137 const MCDisassembler *Decoder) {
138 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
139}
140
142 uint64_t Address,
143 const MCDisassembler *Decoder) {
144 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
145}
146
148 uint64_t Address,
149 const MCDisassembler *Decoder) {
150 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
151}
152
154 uint64_t Address,
155 const MCDisassembler *Decoder) {
156 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
157}
158
160 uint64_t Address,
161 const MCDisassembler *Decoder) {
162 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
163}
164
166 uint64_t Address,
167 const MCDisassembler *Decoder) {
168 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
169}
170
172 uint64_t Address,
173 const MCDisassembler *Decoder) {
174 return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
175}
176
178 uint64_t Address,
179 const MCDisassembler *Decoder) {
180 return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);
181}
182
183template<unsigned N>
185 if (!isUInt<N>(Imm))
189}
190
191template<unsigned N>
193 if (!isUInt<N>(Imm))
195 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
197}
198
200 uint64_t Address,
201 const MCDisassembler *Decoder) {
202 return decodeUImmOperand<1>(Inst, Imm);
203}
204
206 uint64_t Address,
207 const MCDisassembler *Decoder) {
208 return decodeUImmOperand<2>(Inst, Imm);
209}
210
212 uint64_t Address,
213 const MCDisassembler *Decoder) {
214 return decodeUImmOperand<3>(Inst, Imm);
215}
216
218 uint64_t Address,
219 const MCDisassembler *Decoder) {
220 return decodeUImmOperand<4>(Inst, Imm);
221}
222
224 uint64_t Address,
225 const MCDisassembler *Decoder) {
226 return decodeUImmOperand<8>(Inst, Imm);
227}
228
230 uint64_t Address,
231 const MCDisassembler *Decoder) {
232 return decodeUImmOperand<12>(Inst, Imm);
233}
234
236 uint64_t Address,
237 const MCDisassembler *Decoder) {
238 return decodeUImmOperand<16>(Inst, Imm);
239}
240
242 uint64_t Address,
243 const MCDisassembler *Decoder) {
244 return decodeUImmOperand<32>(Inst, Imm);
245}
246
248 uint64_t Address,
249 const MCDisassembler *Decoder) {
250 return decodeSImmOperand<8>(Inst, Imm);
251}
252
254 uint64_t Address,
255 const MCDisassembler *Decoder) {
256 return decodeSImmOperand<16>(Inst, Imm);
257}
258
260 uint64_t Address,
261 const MCDisassembler *Decoder) {
262 return decodeSImmOperand<20>(Inst, Imm);
263}
264
266 uint64_t Address,
267 const MCDisassembler *Decoder) {
268 return decodeSImmOperand<32>(Inst, Imm);
269}
270
271template <unsigned N>
273 uint64_t Address,
274 const MCDisassembler *Decoder) {
275 if (!isUInt<N>(Imm))
277 Inst.addOperand(MCOperand::createImm(Imm + 1));
279}
280
281template <unsigned N>
283 uint64_t Address, bool isBranch,
284 const MCDisassembler *Decoder) {
285 assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
286 uint64_t Value = SignExtend64<N>(Imm) * 2;
287
289 Inst, Decoder))
291
293}
294
296 uint64_t Address,
297 const MCDisassembler *Decoder) {
298 return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
299}
300
302 uint64_t Address,
303 const MCDisassembler *Decoder) {
304 return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
305}
306
308 uint64_t Address,
309 const MCDisassembler *Decoder) {
310 return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
311}
312
314 uint64_t Address,
315 const MCDisassembler *Decoder) {
316 return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
317}
318
320 uint64_t Address,
321 const MCDisassembler *Decoder) {
322 return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
323}
324
325#include "SystemZGenDisassemblerTables.inc"
326
327DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
328 ArrayRef<uint8_t> Bytes,
329 uint64_t Address,
330 raw_ostream &CS) const {
331 CommentStream = &CS;
332
333 // Get the first two bytes of the instruction.
334 Size = 0;
335 if (Bytes.size() < 2)
337
338 // The top 2 bits of the first byte specify the size.
339 const uint8_t *Table;
340 if (Bytes[0] < 0x40) {
341 Size = 2;
342 Table = DecoderTable16;
343 } else if (Bytes[0] < 0xc0) {
344 Size = 4;
345 Table = DecoderTable32;
346 } else {
347 Size = 6;
348 Table = DecoderTable48;
349 }
350
351 // Read any remaining bytes.
352 if (Bytes.size() < Size) {
353 Size = Bytes.size();
355 }
356
357 // Construct the instruction.
358 uint64_t Inst = 0;
359 for (uint64_t I = 0; I < Size; ++I)
360 Inst = (Inst << 8) | Bytes[I];
361
362 return decodeInstruction(Table, MI, Inst, Address, this, STI);
363}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI
Definition: Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:132
uint64_t Size
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
static bool isBranch(unsigned Opcode)
static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
MCDisassembler::DecodeStatus DecodeStatus
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm)
static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZDisassembler()
static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, bool isBranch, const MCDisassembler *Decoder)
static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeLenOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeS20ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static MCDisassembler * createSystemZDisassembler(const Target &T, const MCSubtargetInfo &STI, MCContext &Ctx)
static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, const unsigned *Regs, unsigned Size, bool IsAddr=false)
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm)
static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static DecodeStatus DecodeADDR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const MCDisassembler *Decoder)
static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch, uint64_t Address, uint64_t Offset, uint64_t Width, MCInst &MI, const MCDisassembler *Decoder)
tryAddingSymbolicOperand - trys to add a symbolic operand in place of the immediate Value in the MCIn...
static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm, uint64_t Address, const MCDisassembler *Decoder)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
Context object for machine code objects.
Definition: MCContext.h:83
Superclass for all disassemblers.
bool tryAddingSymbolicOperand(MCInst &Inst, int64_t Value, uint64_t Address, bool IsBranch, uint64_t Offset, uint64_t OpSize, uint64_t InstSize) const
DecodeStatus
Ternary decode status.
virtual DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, ArrayRef< uint8_t > Bytes, uint64_t Address, raw_ostream &CStream) const =0
Returns the disassembly of a single instruction.
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:188
void addOperand(const MCOperand Op)
Definition: MCInst.h:215
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:138
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:145
Generic base class for all target subtargets.
Target - Wrapper for Target specific information.
LLVM Value Representation.
Definition: Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
const unsigned GR64Regs[16]
const unsigned VR128Regs[32]
const unsigned GR128Regs[16]
const unsigned GRH32Regs[16]
const unsigned FP32Regs[16]
const unsigned GR32Regs[16]
const unsigned FP64Regs[16]
const unsigned VR64Regs[32]
const unsigned FP128Regs[16]
const unsigned AR32Regs[16]
const unsigned VR32Regs[32]
const unsigned CR64Regs[16]
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Target & getTheSystemZTarget()
@ Offset
Definition: DWP.cpp:477
#define N
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.