[Darwin][Driver][clang] apple-none-macho orders the resource directory after internal...
[llvm-project.git] / llvm / lib / Target / SystemZ / Disassembler / SystemZDisassembler.cpp
blob8f7367b4f2dd8e119d03fe54d5ba68a884117597
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 //===----------------------------------------------------------------------===//
9 #include "MCTargetDesc/SystemZMCTargetDesc.h"
10 #include "TargetInfo/SystemZTargetInfo.h"
11 #include "llvm/MC/MCDecoderOps.h"
12 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
13 #include "llvm/MC/MCInst.h"
14 #include "llvm/MC/MCSubtargetInfo.h"
15 #include "llvm/MC/TargetRegistry.h"
16 #include "llvm/Support/MathExtras.h"
17 #include <cassert>
18 #include <cstdint>
20 using namespace llvm;
22 #define DEBUG_TYPE "systemz-disassembler"
24 typedef MCDisassembler::DecodeStatus DecodeStatus;
26 namespace {
28 class SystemZDisassembler : public MCDisassembler {
29 public:
30 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
31 : MCDisassembler(STI, Ctx) {}
32 ~SystemZDisassembler() override = default;
34 DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
35 ArrayRef<uint8_t> Bytes, uint64_t Address,
36 raw_ostream &CStream) const override;
39 } // end anonymous namespace
41 static MCDisassembler *createSystemZDisassembler(const Target &T,
42 const MCSubtargetInfo &STI,
43 MCContext &Ctx) {
44 return new SystemZDisassembler(STI, Ctx);
47 // NOLINTNEXTLINE(readability-identifier-naming)
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.
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.
73 static 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);
81 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
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)
90 return MCDisassembler::Fail;
92 Inst.addOperand(MCOperand::createReg(RegNo));
93 return MCDisassembler::Success;
96 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
97 uint64_t Address,
98 const MCDisassembler *Decoder) {
99 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
102 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
103 uint64_t Address,
104 const MCDisassembler *Decoder) {
105 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
108 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
109 uint64_t Address,
110 const MCDisassembler *Decoder) {
111 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
114 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
115 uint64_t Address,
116 const MCDisassembler *Decoder) {
117 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
120 static DecodeStatus
121 DecodeADDR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
122 const MCDisassembler *Decoder) {
123 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16, true);
126 static DecodeStatus
127 DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
128 const MCDisassembler *Decoder) {
129 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16, true);
132 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
133 uint64_t Address,
134 const MCDisassembler *Decoder) {
135 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
138 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
139 uint64_t Address,
140 const MCDisassembler *Decoder) {
141 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
144 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
145 uint64_t Address,
146 const MCDisassembler *Decoder) {
147 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
150 static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
151 uint64_t Address,
152 const MCDisassembler *Decoder) {
153 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
156 static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
157 uint64_t Address,
158 const MCDisassembler *Decoder) {
159 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
162 static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
163 uint64_t Address,
164 const MCDisassembler *Decoder) {
165 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
168 static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
169 uint64_t Address,
170 const MCDisassembler *Decoder) {
171 return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
174 static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
175 uint64_t Address,
176 const MCDisassembler *Decoder) {
177 return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);
180 template<unsigned N>
181 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
182 if (!isUInt<N>(Imm))
183 return MCDisassembler::Fail;
184 Inst.addOperand(MCOperand::createImm(Imm));
185 return MCDisassembler::Success;
188 template<unsigned N>
189 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
190 if (!isUInt<N>(Imm))
191 return MCDisassembler::Fail;
192 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
193 return MCDisassembler::Success;
196 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
197 uint64_t Address,
198 const MCDisassembler *Decoder) {
199 return decodeUImmOperand<1>(Inst, Imm);
202 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
203 uint64_t Address,
204 const MCDisassembler *Decoder) {
205 return decodeUImmOperand<2>(Inst, Imm);
208 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
209 uint64_t Address,
210 const MCDisassembler *Decoder) {
211 return decodeUImmOperand<3>(Inst, Imm);
214 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
215 uint64_t Address,
216 const MCDisassembler *Decoder) {
217 return decodeUImmOperand<4>(Inst, Imm);
220 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
221 uint64_t Address,
222 const MCDisassembler *Decoder) {
223 return decodeUImmOperand<8>(Inst, Imm);
226 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
227 uint64_t Address,
228 const MCDisassembler *Decoder) {
229 return decodeUImmOperand<12>(Inst, Imm);
232 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
233 uint64_t Address,
234 const MCDisassembler *Decoder) {
235 return decodeUImmOperand<16>(Inst, Imm);
238 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
239 uint64_t Address,
240 const MCDisassembler *Decoder) {
241 return decodeUImmOperand<32>(Inst, Imm);
244 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
245 uint64_t Address,
246 const MCDisassembler *Decoder) {
247 return decodeSImmOperand<8>(Inst, Imm);
250 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
251 uint64_t Address,
252 const MCDisassembler *Decoder) {
253 return decodeSImmOperand<16>(Inst, Imm);
256 static DecodeStatus decodeS20ImmOperand(MCInst &Inst, uint64_t Imm,
257 uint64_t Address,
258 const MCDisassembler *Decoder) {
259 return decodeSImmOperand<20>(Inst, Imm);
262 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
263 uint64_t Address,
264 const MCDisassembler *Decoder) {
265 return decodeSImmOperand<32>(Inst, Imm);
268 template <unsigned N>
269 static DecodeStatus decodeLenOperand(MCInst &Inst, uint64_t Imm,
270 uint64_t Address,
271 const MCDisassembler *Decoder) {
272 if (!isUInt<N>(Imm))
273 return MCDisassembler::Fail;
274 Inst.addOperand(MCOperand::createImm(Imm + 1));
275 return MCDisassembler::Success;
278 template <unsigned N>
279 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
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;
285 if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
286 Inst, Decoder))
287 Inst.addOperand(MCOperand::createImm(Value));
289 return MCDisassembler::Success;
292 static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm,
293 uint64_t Address,
294 const MCDisassembler *Decoder) {
295 return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
298 static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
299 uint64_t Address,
300 const MCDisassembler *Decoder) {
301 return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
304 static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm,
305 uint64_t Address,
306 const MCDisassembler *Decoder) {
307 return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
310 static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
311 uint64_t Address,
312 const MCDisassembler *Decoder) {
313 return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
316 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
317 uint64_t Address,
318 const MCDisassembler *Decoder) {
319 return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
322 #include "SystemZGenDisassemblerTables.inc"
324 DecodeStatus 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)
331 return MCDisassembler::Fail;
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;
346 // Read any remaining bytes.
347 if (Bytes.size() < Size) {
348 Size = Bytes.size();
349 return MCDisassembler::Fail;
352 // Construct the instruction.
353 uint64_t Inst = 0;
354 for (uint64_t I = 0; I < Size; ++I)
355 Inst = (Inst << 8) | Bytes[I];
357 return decodeInstruction(Table, MI, Inst, Address, this, STI);