LLVM 20.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
13#include "llvm/MC/MCInst.h"
17#include <cassert>
18#include <cstdint>
19
20using namespace llvm;
21
22#define DEBUG_TYPE "systemz-disassembler"
23
25
26namespace {
27
28class SystemZDisassembler : public MCDisassembler {
29public:
30 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
31 : MCDisassembler(STI, Ctx) {}
32 ~SystemZDisassembler() override = default;
33
36 raw_ostream &CStream) const override;
37};
38
39} // end anonymous namespace
40
42 const MCSubtargetInfo &STI,
43 MCContext &Ctx) {
44 return new SystemZDisassembler(STI, Ctx);
45}
46
47// NOLINTNEXTLINE(readability-identifier-naming)
49 // Register the disassembler.
52}
53
54/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
55/// immediate Value in the MCInst.
56///
57/// @param Value - The immediate Value, has had any PC adjustment made by
58/// the caller.
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
63///
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.
73static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
74 uint64_t Address, uint64_t Offset,
75 uint64_t Width, MCInst &MI,
76 const MCDisassembler *Decoder) {
77 return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
78 Width, /*InstSize=*/0);
79}
80
82 const unsigned *Regs, unsigned Size,
83 bool IsAddr = false) {
84 assert(RegNo < Size && "Invalid register");
85 if (IsAddr && RegNo == 0) {
86 RegNo = SystemZ::NoRegister;
87 } else {
88 RegNo = Regs[RegNo];
89 if (RegNo == 0)
91 }
94}
95
97 uint64_t Address,
98 const MCDisassembler *Decoder) {
99 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
100}
101
103 uint64_t Address,
104 const MCDisassembler *Decoder) {
105 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
106}
107
109 uint64_t Address,
110 const MCDisassembler *Decoder) {
111 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
112}
113
115 uint64_t Address,
116 const MCDisassembler *Decoder) {
117 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
118}
119
120static DecodeStatus
122 const MCDisassembler *Decoder) {
123 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16, true);
124}
125
126static DecodeStatus
128 const MCDisassembler *Decoder) {
129 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16, true);
130}
131
133 uint64_t Address,
134 const MCDisassembler *Decoder) {
135 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
136}
137
139 uint64_t Address,
140 const MCDisassembler *Decoder) {
141 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
142}
143
145 uint64_t Address,
146 const MCDisassembler *Decoder) {
147 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
148}
149
151 uint64_t Address,
152 const MCDisassembler *Decoder) {
153 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
154}
155
157 uint64_t Address,
158 const MCDisassembler *Decoder) {
159 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
160}
161
163 uint64_t Address,
164 const MCDisassembler *Decoder) {
165 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
166}
167
169 uint64_t Address,
170 const MCDisassembler *Decoder) {
171 return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
172}
173
175 uint64_t Address,
176 const MCDisassembler *Decoder) {
177 return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);
178}
179
180template<unsigned N>
182 if (!isUInt<N>(Imm))
186}
187
188template<unsigned N>
190 if (!isUInt<N>(Imm))
192 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
194}
195
197 uint64_t Address,
198 const MCDisassembler *Decoder) {
199 return decodeUImmOperand<1>(Inst, Imm);
200}
201
203 uint64_t Address,
204 const MCDisassembler *Decoder) {
205 return decodeUImmOperand<2>(Inst, Imm);
206}
207
209 uint64_t Address,
210 const MCDisassembler *Decoder) {
211 return decodeUImmOperand<3>(Inst, Imm);
212}
213
215 uint64_t Address,
216 const MCDisassembler *Decoder) {
217 return decodeUImmOperand<4>(Inst, Imm);
218}
219
221 uint64_t Address,
222 const MCDisassembler *Decoder) {
223 return decodeUImmOperand<8>(Inst, Imm);
224}
225
227 uint64_t Address,
228 const MCDisassembler *Decoder) {
229 return decodeUImmOperand<12>(Inst, Imm);
230}
231
233 uint64_t Address,
234 const MCDisassembler *Decoder) {
235 return decodeUImmOperand<16>(Inst, Imm);
236}
237
239 uint64_t Address,
240 const MCDisassembler *Decoder) {
241 return decodeUImmOperand<32>(Inst, Imm);
242}
243
245 uint64_t Address,
246 const MCDisassembler *Decoder) {
247 return decodeSImmOperand<8>(Inst, Imm);
248}
249
251 uint64_t Address,
252 const MCDisassembler *Decoder) {
253 return decodeSImmOperand<16>(Inst, Imm);
254}
255
257 uint64_t Address,
258 const MCDisassembler *Decoder) {
259 return decodeSImmOperand<20>(Inst, Imm);
260}
261
263 uint64_t Address,
264 const MCDisassembler *Decoder) {
265 return decodeSImmOperand<32>(Inst, Imm);
266}
267
268template <unsigned N>
270 uint64_t Address,
271 const MCDisassembler *Decoder) {
272 if (!isUInt<N>(Imm))
274 Inst.addOperand(MCOperand::createImm(Imm + 1));
276}
277
278template <unsigned N>
280 uint64_t Address, bool isBranch,
281 const MCDisassembler *Decoder) {
282 assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
283 uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
284
286 Inst, Decoder))
288
290}
291
293 uint64_t Address,
294 const MCDisassembler *Decoder) {
295 return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
296}
297
299 uint64_t Address,
300 const MCDisassembler *Decoder) {
301 return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
302}
303
305 uint64_t Address,
306 const MCDisassembler *Decoder) {
307 return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
308}
309
311 uint64_t Address,
312 const MCDisassembler *Decoder) {
313 return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
314}
315
317 uint64_t Address,
318 const MCDisassembler *Decoder) {
319 return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
320}
321
322#include "SystemZGenDisassemblerTables.inc"
323
324DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
325 ArrayRef<uint8_t> Bytes,
326 uint64_t Address,
327 raw_ostream &CS) const {
328 // Get the first two bytes of the instruction.
329 Size = 0;
330 if (Bytes.size() < 2)
332
333 // The top 2 bits of the first byte specify the size.
334 const uint8_t *Table;
335 if (Bytes[0] < 0x40) {
336 Size = 2;
337 Table = DecoderTable16;
338 } else if (Bytes[0] < 0xc0) {
339 Size = 4;
340 Table = DecoderTable32;
341 } else {
342 Size = 6;
343 Table = DecoderTable48;
344 }
345
346 // Read any remaining bytes.
347 if (Bytes.size() < Size) {
348 Size = Bytes.size();
350 }
351
352 // Construct the instruction.
353 uint64_t Inst = 0;
354 for (uint64_t I = 0; I < Size; ++I)
355 Inst = (Inst << 8) | Bytes[I];
356
357 return decodeInstruction(Table, MI, Inst, Address, this, STI);
358}
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:128
uint64_t Size
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
static bool isBranch(unsigned Opcode)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
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)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZDisassembler()
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:168
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:185
void addOperand(const MCOperand Op)
Definition: MCInst.h:211
static MCOperand createReg(MCRegister Reg)
Definition: MCInst.h:135
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:142
Generic base class for all target subtargets.
Target - Wrapper for Target specific information.
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
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:480
#define N
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.