LLVM 19.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
10#include "SystemZ.h"
14#include "llvm/MC/MCInst.h"
18#include <cassert>
19#include <cstdint>
20
21using namespace llvm;
22
23#define DEBUG_TYPE "systemz-disassembler"
24
26
27namespace {
28
29class SystemZDisassembler : public MCDisassembler {
30public:
31 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
32 : MCDisassembler(STI, Ctx) {}
33 ~SystemZDisassembler() override = default;
34
36 ArrayRef<uint8_t> Bytes, uint64_t Address,
37 raw_ostream &CStream) const override;
38};
39
40} // end anonymous namespace
41
43 const MCSubtargetInfo &STI,
44 MCContext &Ctx) {
45 return new SystemZDisassembler(STI, Ctx);
46}
47
48// NOLINTNEXTLINE(readability-identifier-naming)
50 // Register the disassembler.
53}
54
55/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
56/// immediate Value in the MCInst.
57///
58/// @param Value - The immediate Value, has had any PC adjustment made by
59/// the caller.
60/// @param isBranch - If the instruction is a branch instruction
61/// @param Address - The starting address of the instruction
62/// @param Offset - The byte offset to this immediate in the instruction
63/// @param Width - The byte width of this immediate in the instruction
64///
65/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
66/// called then that function is called to get any symbolic information for the
67/// immediate in the instruction using the Address, Offset and Width. If that
68/// returns non-zero then the symbolic information it returns is used to create
69/// an MCExpr and that is added as an operand to the MCInst. If getOpInfo()
70/// returns zero and isBranch is true then a symbol look up for immediate Value
71/// is done and if a symbol is found an MCExpr is created with that, else
72/// an MCExpr with the immediate Value is created. This function returns true
73/// if it adds an operand to the MCInst and false otherwise.
74static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
75 uint64_t Address, uint64_t Offset,
76 uint64_t Width, MCInst &MI,
77 const MCDisassembler *Decoder) {
78 return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
79 Width, /*InstSize=*/0);
80}
81
83 const unsigned *Regs, unsigned Size,
84 bool IsAddr = false) {
85 assert(RegNo < Size && "Invalid register");
86 if (IsAddr && RegNo == 0) {
87 RegNo = SystemZ::NoRegister;
88 } else {
89 RegNo = Regs[RegNo];
90 if (RegNo == 0)
92 }
95}
96
98 uint64_t Address,
99 const MCDisassembler *Decoder) {
100 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
101}
102
104 uint64_t Address,
105 const MCDisassembler *Decoder) {
106 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
107}
108
110 uint64_t Address,
111 const MCDisassembler *Decoder) {
112 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
113}
114
116 uint64_t Address,
117 const MCDisassembler *Decoder) {
118 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
119}
120
121static DecodeStatus
123 const MCDisassembler *Decoder) {
124 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16, true);
125}
126
127static DecodeStatus
129 const MCDisassembler *Decoder) {
130 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16, true);
131}
132
134 uint64_t Address,
135 const MCDisassembler *Decoder) {
136 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
137}
138
140 uint64_t Address,
141 const MCDisassembler *Decoder) {
142 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
143}
144
146 uint64_t Address,
147 const MCDisassembler *Decoder) {
148 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
149}
150
152 uint64_t Address,
153 const MCDisassembler *Decoder) {
154 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
155}
156
158 uint64_t Address,
159 const MCDisassembler *Decoder) {
160 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
161}
162
164 uint64_t Address,
165 const MCDisassembler *Decoder) {
166 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
167}
168
170 uint64_t Address,
171 const MCDisassembler *Decoder) {
172 return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
173}
174
176 uint64_t Address,
177 const MCDisassembler *Decoder) {
178 return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);
179}
180
181template<unsigned N>
183 if (!isUInt<N>(Imm))
187}
188
189template<unsigned N>
191 if (!isUInt<N>(Imm))
193 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
195}
196
198 uint64_t Address,
199 const MCDisassembler *Decoder) {
200 return decodeUImmOperand<1>(Inst, Imm);
201}
202
204 uint64_t Address,
205 const MCDisassembler *Decoder) {
206 return decodeUImmOperand<2>(Inst, Imm);
207}
208
210 uint64_t Address,
211 const MCDisassembler *Decoder) {
212 return decodeUImmOperand<3>(Inst, Imm);
213}
214
216 uint64_t Address,
217 const MCDisassembler *Decoder) {
218 return decodeUImmOperand<4>(Inst, Imm);
219}
220
222 uint64_t Address,
223 const MCDisassembler *Decoder) {
224 return decodeUImmOperand<8>(Inst, Imm);
225}
226
228 uint64_t Address,
229 const MCDisassembler *Decoder) {
230 return decodeUImmOperand<12>(Inst, Imm);
231}
232
234 uint64_t Address,
235 const MCDisassembler *Decoder) {
236 return decodeUImmOperand<16>(Inst, Imm);
237}
238
240 uint64_t Address,
241 const MCDisassembler *Decoder) {
242 return decodeUImmOperand<32>(Inst, Imm);
243}
244
246 uint64_t Address,
247 const MCDisassembler *Decoder) {
248 return decodeSImmOperand<8>(Inst, Imm);
249}
250
252 uint64_t Address,
253 const MCDisassembler *Decoder) {
254 return decodeSImmOperand<16>(Inst, Imm);
255}
256
258 uint64_t Address,
259 const MCDisassembler *Decoder) {
260 return decodeSImmOperand<20>(Inst, Imm);
261}
262
264 uint64_t Address,
265 const MCDisassembler *Decoder) {
266 return decodeSImmOperand<32>(Inst, Imm);
267}
268
269template <unsigned N>
271 uint64_t Address,
272 const MCDisassembler *Decoder) {
273 if (!isUInt<N>(Imm))
275 Inst.addOperand(MCOperand::createImm(Imm + 1));
277}
278
279template <unsigned N>
281 uint64_t Address, bool isBranch,
282 const MCDisassembler *Decoder) {
283 assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
284 uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
285
286 if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
287 Inst, Decoder))
289
291}
292
294 uint64_t Address,
295 const MCDisassembler *Decoder) {
296 return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
297}
298
300 uint64_t Address,
301 const MCDisassembler *Decoder) {
302 return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
303}
304
306 uint64_t Address,
307 const MCDisassembler *Decoder) {
308 return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
309}
310
312 uint64_t Address,
313 const MCDisassembler *Decoder) {
314 return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
315}
316
318 uint64_t Address,
319 const MCDisassembler *Decoder) {
320 return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
321}
322
323#include "SystemZGenDisassemblerTables.inc"
324
325DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
326 ArrayRef<uint8_t> Bytes,
327 uint64_t Address,
328 raw_ostream &CS) const {
329 // Get the first two bytes of the instruction.
330 Size = 0;
331 if (Bytes.size() < 2)
333
334 // The top 2 bits of the first byte specify the size.
335 const uint8_t *Table;
336 if (Bytes[0] < 0x40) {
337 Size = 2;
338 Table = DecoderTable16;
339 } else if (Bytes[0] < 0xc0) {
340 Size = 4;
341 Table = DecoderTable32;
342 } else {
343 Size = 6;
344 Table = DecoderTable48;
345 }
346
347 // Read any remaining bytes.
348 if (Bytes.size() < Size) {
349 Size = Bytes.size();
351 }
352
353 // Construct the instruction.
354 uint64_t Inst = 0;
355 for (uint64_t I = 0; I < Size; ++I)
356 Inst = (Inst << 8) | Bytes[I];
357
358 return decodeInstruction(Table, MI, Inst, Address, this, STI);
359}
#define LLVM_EXTERNAL_VISIBILITY
Definition: Compiler.h:135
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:165
Context object for machine code objects.
Definition: MCContext.h:76
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:184
void addOperand(const MCOperand Op)
Definition: MCInst.h:210
static MCOperand createReg(unsigned Reg)
Definition: MCInst.h:134
static MCOperand createImm(int64_t Val)
Definition: MCInst.h:141
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:456
#define N
static void RegisterMCDisassembler(Target &T, Target::MCDisassemblerCtorTy Fn)
RegisterMCDisassembler - Register a MCDisassembler implementation for the given target.