1eb9af294SRichard Sandiford //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
2eb9af294SRichard Sandiford //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6eb9af294SRichard Sandiford //
7eb9af294SRichard Sandiford //===----------------------------------------------------------------------===//
8eb9af294SRichard Sandiford
93943d2b0SEugene Zelenko #include "MCTargetDesc/SystemZMCTargetDesc.h"
10eb9af294SRichard Sandiford #include "SystemZ.h"
111e6f98b8SRichard Trieu #include "TargetInfo/SystemZTargetInfo.h"
12c644488aSSheng #include "llvm/MC/MCDecoderOps.h"
13f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/MCDisassembler.h"
14eb9af294SRichard Sandiford #include "llvm/MC/MCInst.h"
15eb9af294SRichard Sandiford #include "llvm/MC/MCSubtargetInfo.h"
1689b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h"
173943d2b0SEugene Zelenko #include "llvm/Support/MathExtras.h"
183943d2b0SEugene Zelenko #include <cassert>
193943d2b0SEugene Zelenko #include <cstdint>
20eb9af294SRichard Sandiford
21eb9af294SRichard Sandiford using namespace llvm;
22eb9af294SRichard Sandiford
23e96dd897SChandler Carruth #define DEBUG_TYPE "systemz-disassembler"
24e96dd897SChandler Carruth
25eb9af294SRichard Sandiford typedef MCDisassembler::DecodeStatus DecodeStatus;
26eb9af294SRichard Sandiford
27eb9af294SRichard Sandiford namespace {
283943d2b0SEugene Zelenko
29eb9af294SRichard Sandiford class SystemZDisassembler : public MCDisassembler {
30eb9af294SRichard Sandiford public:
SystemZDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)31a1bc0f56SLang Hames SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
32a1bc0f56SLang Hames : MCDisassembler(STI, Ctx) {}
333943d2b0SEugene Zelenko ~SystemZDisassembler() override = default;
34eb9af294SRichard Sandiford
357fc5b874SRafael Espindola DecodeStatus getInstruction(MCInst &instr, uint64_t &Size,
367fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address,
374aa6bea7SRafael Espindola raw_ostream &CStream) const override;
38eb9af294SRichard Sandiford };
393943d2b0SEugene Zelenko
40eb9af294SRichard Sandiford } // end anonymous namespace
41eb9af294SRichard Sandiford
createSystemZDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)42eb9af294SRichard Sandiford static MCDisassembler *createSystemZDisassembler(const Target &T,
43a1bc0f56SLang Hames const MCSubtargetInfo &STI,
44a1bc0f56SLang Hames MCContext &Ctx) {
45a1bc0f56SLang Hames return new SystemZDisassembler(STI, Ctx);
46eb9af294SRichard Sandiford }
47eb9af294SRichard Sandiford
LLVMInitializeSystemZDisassembler()480dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZDisassembler() {
49eb9af294SRichard Sandiford // Register the disassembler.
50f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(),
51eb9af294SRichard Sandiford createSystemZDisassembler);
52eb9af294SRichard Sandiford }
53eb9af294SRichard Sandiford
546e648ea5SUlrich Weigand /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
556e648ea5SUlrich Weigand /// immediate Value in the MCInst.
566e648ea5SUlrich Weigand ///
576e648ea5SUlrich Weigand /// @param Value - The immediate Value, has had any PC adjustment made by
586e648ea5SUlrich Weigand /// the caller.
596e648ea5SUlrich Weigand /// @param isBranch - If the instruction is a branch instruction
606e648ea5SUlrich Weigand /// @param Address - The starting address of the instruction
616e648ea5SUlrich Weigand /// @param Offset - The byte offset to this immediate in the instruction
626e648ea5SUlrich Weigand /// @param Width - The byte width of this immediate in the instruction
636e648ea5SUlrich Weigand ///
646e648ea5SUlrich Weigand /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
656e648ea5SUlrich Weigand /// called then that function is called to get any symbolic information for the
666e648ea5SUlrich Weigand /// immediate in the instruction using the Address, Offset and Width. If that
676e648ea5SUlrich Weigand /// returns non-zero then the symbolic information it returns is used to create
686e648ea5SUlrich Weigand /// an MCExpr and that is added as an operand to the MCInst. If getOpInfo()
696e648ea5SUlrich Weigand /// returns zero and isBranch is true then a symbol look up for immediate Value
706e648ea5SUlrich Weigand /// is done and if a symbol is found an MCExpr is created with that, else
716e648ea5SUlrich Weigand /// an MCExpr with the immediate Value is created. This function returns true
726e648ea5SUlrich Weigand /// if it adds an operand to the MCInst and false otherwise.
tryAddingSymbolicOperand(int64_t Value,bool isBranch,uint64_t Address,uint64_t Offset,uint64_t Width,MCInst & MI,const MCDisassembler * Decoder)736e648ea5SUlrich Weigand static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
746e648ea5SUlrich Weigand uint64_t Address, uint64_t Offset,
756e648ea5SUlrich Weigand uint64_t Width, MCInst &MI,
764ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
774ae9745aSMaksim Panchenko return Decoder->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset,
78*bed9efedSMaksim Panchenko Width, /*InstSize=*/0);
796e648ea5SUlrich Weigand }
806e648ea5SUlrich Weigand
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const unsigned * Regs,unsigned Size)81eb9af294SRichard Sandiford static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
82a8b04e1cSUlrich Weigand const unsigned *Regs, unsigned Size) {
83a8b04e1cSUlrich Weigand assert(RegNo < Size && "Invalid register");
84eb9af294SRichard Sandiford RegNo = Regs[RegNo];
85eb9af294SRichard Sandiford if (RegNo == 0)
86eb9af294SRichard Sandiford return MCDisassembler::Fail;
87e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(RegNo));
88eb9af294SRichard Sandiford return MCDisassembler::Success;
89eb9af294SRichard Sandiford }
90eb9af294SRichard Sandiford
DecodeGR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)91eb9af294SRichard Sandiford static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
92eb9af294SRichard Sandiford uint64_t Address,
934ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
94a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
95eb9af294SRichard Sandiford }
96eb9af294SRichard Sandiford
DecodeGRH32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)97f9496060SRichard Sandiford static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
98f9496060SRichard Sandiford uint64_t Address,
994ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
100a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
101f9496060SRichard Sandiford }
102f9496060SRichard Sandiford
DecodeGR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)103eb9af294SRichard Sandiford static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
104eb9af294SRichard Sandiford uint64_t Address,
1054ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
106a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
107eb9af294SRichard Sandiford }
108eb9af294SRichard Sandiford
DecodeGR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)109eb9af294SRichard Sandiford static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
110eb9af294SRichard Sandiford uint64_t Address,
1114ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
112a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
113eb9af294SRichard Sandiford }
114eb9af294SRichard Sandiford
1154ae9745aSMaksim Panchenko static DecodeStatus
DecodeADDR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1164ae9745aSMaksim Panchenko DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
1174ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
118a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
119eb9af294SRichard Sandiford }
120eb9af294SRichard Sandiford
DecodeFP32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)121eb9af294SRichard Sandiford static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
122eb9af294SRichard Sandiford uint64_t Address,
1234ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
124a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
125eb9af294SRichard Sandiford }
126eb9af294SRichard Sandiford
DecodeFP64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)127eb9af294SRichard Sandiford static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
128eb9af294SRichard Sandiford uint64_t Address,
1294ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
130a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
131eb9af294SRichard Sandiford }
132eb9af294SRichard Sandiford
DecodeFP128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)133eb9af294SRichard Sandiford static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
134eb9af294SRichard Sandiford uint64_t Address,
1354ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
136a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
137a8b04e1cSUlrich Weigand }
138a8b04e1cSUlrich Weigand
DecodeVR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)139a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
140a8b04e1cSUlrich Weigand uint64_t Address,
1414ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
142a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
143a8b04e1cSUlrich Weigand }
144a8b04e1cSUlrich Weigand
DecodeVR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)145a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
146a8b04e1cSUlrich Weigand uint64_t Address,
1474ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
148a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
149a8b04e1cSUlrich Weigand }
150a8b04e1cSUlrich Weigand
DecodeVR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)151a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
152a8b04e1cSUlrich Weigand uint64_t Address,
1534ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
154a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
155eb9af294SRichard Sandiford }
156eb9af294SRichard Sandiford
DecodeAR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)157fffc7110SUlrich Weigand static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
158fffc7110SUlrich Weigand uint64_t Address,
1594ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
160fffc7110SUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
161fffc7110SUlrich Weigand }
162fffc7110SUlrich Weigand
DecodeCR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)16303ab2e2bSUlrich Weigand static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
16403ab2e2bSUlrich Weigand uint64_t Address,
1654ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
16603ab2e2bSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);
16703ab2e2bSUlrich Weigand }
16803ab2e2bSUlrich Weigand
169eb9af294SRichard Sandiford template<unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm)170eb9af294SRichard Sandiford static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
171a8b04e1cSUlrich Weigand if (!isUInt<N>(Imm))
172a8b04e1cSUlrich Weigand return MCDisassembler::Fail;
173e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Imm));
174eb9af294SRichard Sandiford return MCDisassembler::Success;
175eb9af294SRichard Sandiford }
176eb9af294SRichard Sandiford
177eb9af294SRichard Sandiford template<unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm)178eb9af294SRichard Sandiford static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
179a8b04e1cSUlrich Weigand if (!isUInt<N>(Imm))
180a8b04e1cSUlrich Weigand return MCDisassembler::Fail;
181e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
182eb9af294SRichard Sandiford return MCDisassembler::Success;
183eb9af294SRichard Sandiford }
184eb9af294SRichard Sandiford
decodeU1ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)185a8b04e1cSUlrich Weigand static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
1864ae9745aSMaksim Panchenko uint64_t Address,
1874ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
188a8b04e1cSUlrich Weigand return decodeUImmOperand<1>(Inst, Imm);
189a8b04e1cSUlrich Weigand }
190a8b04e1cSUlrich Weigand
decodeU2ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)191a8b04e1cSUlrich Weigand static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
1924ae9745aSMaksim Panchenko uint64_t Address,
1934ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
194a8b04e1cSUlrich Weigand return decodeUImmOperand<2>(Inst, Imm);
195a8b04e1cSUlrich Weigand }
196a8b04e1cSUlrich Weigand
decodeU3ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)197a8b04e1cSUlrich Weigand static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
1984ae9745aSMaksim Panchenko uint64_t Address,
1994ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
200a8b04e1cSUlrich Weigand return decodeUImmOperand<3>(Inst, Imm);
201a8b04e1cSUlrich Weigand }
202a8b04e1cSUlrich Weigand
decodeU4ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)203eb9af294SRichard Sandiford static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
2044ae9745aSMaksim Panchenko uint64_t Address,
2054ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
206eb9af294SRichard Sandiford return decodeUImmOperand<4>(Inst, Imm);
207eb9af294SRichard Sandiford }
208eb9af294SRichard Sandiford
decodeU6ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)209eb9af294SRichard Sandiford static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
2104ae9745aSMaksim Panchenko uint64_t Address,
2114ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
212eb9af294SRichard Sandiford return decodeUImmOperand<6>(Inst, Imm);
213eb9af294SRichard Sandiford }
214eb9af294SRichard Sandiford
decodeU8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)215eb9af294SRichard Sandiford static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
2164ae9745aSMaksim Panchenko uint64_t Address,
2174ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
218eb9af294SRichard Sandiford return decodeUImmOperand<8>(Inst, Imm);
219eb9af294SRichard Sandiford }
220eb9af294SRichard Sandiford
decodeU12ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)221a8b04e1cSUlrich Weigand static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
2224ae9745aSMaksim Panchenko uint64_t Address,
2234ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
224a8b04e1cSUlrich Weigand return decodeUImmOperand<12>(Inst, Imm);
225a8b04e1cSUlrich Weigand }
226a8b04e1cSUlrich Weigand
decodeU16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)227eb9af294SRichard Sandiford static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
2284ae9745aSMaksim Panchenko uint64_t Address,
2294ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
230eb9af294SRichard Sandiford return decodeUImmOperand<16>(Inst, Imm);
231eb9af294SRichard Sandiford }
232eb9af294SRichard Sandiford
decodeU32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)233eb9af294SRichard Sandiford static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
2344ae9745aSMaksim Panchenko uint64_t Address,
2354ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
236eb9af294SRichard Sandiford return decodeUImmOperand<32>(Inst, Imm);
237eb9af294SRichard Sandiford }
238eb9af294SRichard Sandiford
decodeS8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)239eb9af294SRichard Sandiford static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
2404ae9745aSMaksim Panchenko uint64_t Address,
2414ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
242eb9af294SRichard Sandiford return decodeSImmOperand<8>(Inst, Imm);
243eb9af294SRichard Sandiford }
244eb9af294SRichard Sandiford
decodeS16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)245eb9af294SRichard Sandiford static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
2464ae9745aSMaksim Panchenko uint64_t Address,
2474ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
248eb9af294SRichard Sandiford return decodeSImmOperand<16>(Inst, Imm);
249eb9af294SRichard Sandiford }
250eb9af294SRichard Sandiford
decodeS32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)251eb9af294SRichard Sandiford static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
2524ae9745aSMaksim Panchenko uint64_t Address,
2534ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
254eb9af294SRichard Sandiford return decodeSImmOperand<32>(Inst, Imm);
255eb9af294SRichard Sandiford }
256eb9af294SRichard Sandiford
257eb9af294SRichard Sandiford template <unsigned N>
decodePCDBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,bool isBranch,const MCDisassembler * Decoder)258eb9af294SRichard Sandiford static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
2594ae9745aSMaksim Panchenko uint64_t Address, bool isBranch,
2604ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
261eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
2626e648ea5SUlrich Weigand uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
2636e648ea5SUlrich Weigand
2646e648ea5SUlrich Weigand if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
2656e648ea5SUlrich Weigand Inst, Decoder))
2666e648ea5SUlrich Weigand Inst.addOperand(MCOperand::createImm(Value));
2676e648ea5SUlrich Weigand
268eb9af294SRichard Sandiford return MCDisassembler::Success;
269eb9af294SRichard Sandiford }
270eb9af294SRichard Sandiford
decodePC12DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)27184404f30SUlrich Weigand static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm,
27284404f30SUlrich Weigand uint64_t Address,
2734ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
27484404f30SUlrich Weigand return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
27584404f30SUlrich Weigand }
27684404f30SUlrich Weigand
decodePC16DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)2776e648ea5SUlrich Weigand static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
278eb9af294SRichard Sandiford uint64_t Address,
2794ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
2806e648ea5SUlrich Weigand return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
2816e648ea5SUlrich Weigand }
2826e648ea5SUlrich Weigand
decodePC24DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)28384404f30SUlrich Weigand static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm,
28484404f30SUlrich Weigand uint64_t Address,
2854ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
28684404f30SUlrich Weigand return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
28784404f30SUlrich Weigand }
28884404f30SUlrich Weigand
decodePC32DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)2896e648ea5SUlrich Weigand static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
2906e648ea5SUlrich Weigand uint64_t Address,
2914ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
2926e648ea5SUlrich Weigand return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
293eb9af294SRichard Sandiford }
294eb9af294SRichard Sandiford
decodePC32DBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const MCDisassembler * Decoder)295eb9af294SRichard Sandiford static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
296eb9af294SRichard Sandiford uint64_t Address,
2974ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
2986e648ea5SUlrich Weigand return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
299eb9af294SRichard Sandiford }
300eb9af294SRichard Sandiford
decodeBDAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)301eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
302eb9af294SRichard Sandiford const unsigned *Regs) {
303eb9af294SRichard Sandiford uint64_t Base = Field >> 12;
304eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff;
305eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr12");
306e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
307e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp));
308eb9af294SRichard Sandiford return MCDisassembler::Success;
309eb9af294SRichard Sandiford }
310eb9af294SRichard Sandiford
decodeBDAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)311eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
312eb9af294SRichard Sandiford const unsigned *Regs) {
313eb9af294SRichard Sandiford uint64_t Base = Field >> 20;
314eb9af294SRichard Sandiford uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
315eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr20");
316e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
317e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
318eb9af294SRichard Sandiford return MCDisassembler::Success;
319eb9af294SRichard Sandiford }
320eb9af294SRichard Sandiford
decodeBDXAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)321eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
322eb9af294SRichard Sandiford const unsigned *Regs) {
323eb9af294SRichard Sandiford uint64_t Index = Field >> 16;
324eb9af294SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf;
325eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff;
326eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr12");
327e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
328e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp));
329e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
330eb9af294SRichard Sandiford return MCDisassembler::Success;
331eb9af294SRichard Sandiford }
332eb9af294SRichard Sandiford
decodeBDXAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)333eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
334eb9af294SRichard Sandiford const unsigned *Regs) {
335eb9af294SRichard Sandiford uint64_t Index = Field >> 24;
336eb9af294SRichard Sandiford uint64_t Base = (Field >> 20) & 0xf;
337eb9af294SRichard Sandiford uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
338eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr20");
339e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
340e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
341e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
342eb9af294SRichard Sandiford return MCDisassembler::Success;
343eb9af294SRichard Sandiford }
344eb9af294SRichard Sandiford
decodeBDLAddr12Len4Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)345c7eb5a95SUlrich Weigand static DecodeStatus decodeBDLAddr12Len4Operand(MCInst &Inst, uint64_t Field,
346c7eb5a95SUlrich Weigand const unsigned *Regs) {
347c7eb5a95SUlrich Weigand uint64_t Length = Field >> 16;
348c7eb5a95SUlrich Weigand uint64_t Base = (Field >> 12) & 0xf;
349c7eb5a95SUlrich Weigand uint64_t Disp = Field & 0xfff;
350c7eb5a95SUlrich Weigand assert(Length < 16 && "Invalid BDLAddr12Len4");
351c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
352c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createImm(Disp));
353c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createImm(Length + 1));
354c7eb5a95SUlrich Weigand return MCDisassembler::Success;
355c7eb5a95SUlrich Weigand }
356c7eb5a95SUlrich Weigand
decodeBDLAddr12Len8Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)3571d959008SRichard Sandiford static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
3581d959008SRichard Sandiford const unsigned *Regs) {
3591d959008SRichard Sandiford uint64_t Length = Field >> 16;
3601d959008SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf;
3611d959008SRichard Sandiford uint64_t Disp = Field & 0xfff;
3621d959008SRichard Sandiford assert(Length < 256 && "Invalid BDLAddr12Len8");
363e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
364e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp));
365e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Length + 1));
3661d959008SRichard Sandiford return MCDisassembler::Success;
3671d959008SRichard Sandiford }
3681d959008SRichard Sandiford
decodeBDRAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)369ec5d779eSUlrich Weigand static DecodeStatus decodeBDRAddr12Operand(MCInst &Inst, uint64_t Field,
370ec5d779eSUlrich Weigand const unsigned *Regs) {
371ec5d779eSUlrich Weigand uint64_t Length = Field >> 16;
372ec5d779eSUlrich Weigand uint64_t Base = (Field >> 12) & 0xf;
373ec5d779eSUlrich Weigand uint64_t Disp = Field & 0xfff;
374ec5d779eSUlrich Weigand assert(Length < 16 && "Invalid BDRAddr12");
375ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
376ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createImm(Disp));
377ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createReg(Regs[Length]));
378ec5d779eSUlrich Weigand return MCDisassembler::Success;
379ec5d779eSUlrich Weigand }
380ec5d779eSUlrich Weigand
decodeBDVAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)381a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
382a8b04e1cSUlrich Weigand const unsigned *Regs) {
383a8b04e1cSUlrich Weigand uint64_t Index = Field >> 16;
384a8b04e1cSUlrich Weigand uint64_t Base = (Field >> 12) & 0xf;
385a8b04e1cSUlrich Weigand uint64_t Disp = Field & 0xfff;
386a8b04e1cSUlrich Weigand assert(Index < 32 && "Invalid BDVAddr12");
387e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
388e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp));
389e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
390a8b04e1cSUlrich Weigand return MCDisassembler::Success;
391a8b04e1cSUlrich Weigand }
392a8b04e1cSUlrich Weigand
decodeBDAddr32Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)393eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
394eb9af294SRichard Sandiford uint64_t Address,
3954ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
396eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
397eb9af294SRichard Sandiford }
398eb9af294SRichard Sandiford
decodeBDAddr32Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)399eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
400eb9af294SRichard Sandiford uint64_t Address,
4014ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
402eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
403eb9af294SRichard Sandiford }
404eb9af294SRichard Sandiford
decodeBDAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)405eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
406eb9af294SRichard Sandiford uint64_t Address,
4074ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
408eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
409eb9af294SRichard Sandiford }
410eb9af294SRichard Sandiford
decodeBDAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)411eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
412eb9af294SRichard Sandiford uint64_t Address,
4134ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
414eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
415eb9af294SRichard Sandiford }
416eb9af294SRichard Sandiford
4174ae9745aSMaksim Panchenko static DecodeStatus
decodeBDXAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)4184ae9745aSMaksim Panchenko decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address,
4194ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
420eb9af294SRichard Sandiford return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
421eb9af294SRichard Sandiford }
422eb9af294SRichard Sandiford
4234ae9745aSMaksim Panchenko static DecodeStatus
decodeBDXAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)4244ae9745aSMaksim Panchenko decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, uint64_t Address,
4254ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
426eb9af294SRichard Sandiford return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
427eb9af294SRichard Sandiford }
428eb9af294SRichard Sandiford
4294ae9745aSMaksim Panchenko static DecodeStatus
decodeBDLAddr64Disp12Len4Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)4304ae9745aSMaksim Panchenko decodeBDLAddr64Disp12Len4Operand(MCInst &Inst, uint64_t Field, uint64_t Address,
4314ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
432c7eb5a95SUlrich Weigand return decodeBDLAddr12Len4Operand(Inst, Field, SystemZMC::GR64Regs);
433c7eb5a95SUlrich Weigand }
434c7eb5a95SUlrich Weigand
4354ae9745aSMaksim Panchenko static DecodeStatus
decodeBDLAddr64Disp12Len8Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)4364ae9745aSMaksim Panchenko decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, uint64_t Field, uint64_t Address,
4374ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
4381d959008SRichard Sandiford return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
4391d959008SRichard Sandiford }
4401d959008SRichard Sandiford
4414ae9745aSMaksim Panchenko static DecodeStatus
decodeBDRAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)4424ae9745aSMaksim Panchenko decodeBDRAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address,
4434ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
444ec5d779eSUlrich Weigand return decodeBDRAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
445ec5d779eSUlrich Weigand }
446ec5d779eSUlrich Weigand
4474ae9745aSMaksim Panchenko static DecodeStatus
decodeBDVAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const MCDisassembler * Decoder)4484ae9745aSMaksim Panchenko decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address,
4494ae9745aSMaksim Panchenko const MCDisassembler *Decoder) {
450a8b04e1cSUlrich Weigand return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
451a8b04e1cSUlrich Weigand }
452a8b04e1cSUlrich Weigand
453eb9af294SRichard Sandiford #include "SystemZGenDisassemblerTables.inc"
454eb9af294SRichard Sandiford
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const455eb9af294SRichard Sandiford DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
4567fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes,
457eb9af294SRichard Sandiford uint64_t Address,
4584aa6bea7SRafael Espindola raw_ostream &CS) const {
459eb9af294SRichard Sandiford // Get the first two bytes of the instruction.
460eb9af294SRichard Sandiford Size = 0;
4617fc5b874SRafael Espindola if (Bytes.size() < 2)
462eb9af294SRichard Sandiford return MCDisassembler::Fail;
463eb9af294SRichard Sandiford
464eb9af294SRichard Sandiford // The top 2 bits of the first byte specify the size.
465eb9af294SRichard Sandiford const uint8_t *Table;
466eb9af294SRichard Sandiford if (Bytes[0] < 0x40) {
467eb9af294SRichard Sandiford Size = 2;
468eb9af294SRichard Sandiford Table = DecoderTable16;
469eb9af294SRichard Sandiford } else if (Bytes[0] < 0xc0) {
470eb9af294SRichard Sandiford Size = 4;
471eb9af294SRichard Sandiford Table = DecoderTable32;
472eb9af294SRichard Sandiford } else {
473eb9af294SRichard Sandiford Size = 6;
474eb9af294SRichard Sandiford Table = DecoderTable48;
475eb9af294SRichard Sandiford }
476eb9af294SRichard Sandiford
477eb9af294SRichard Sandiford // Read any remaining bytes.
478c299f355SUlrich Weigand if (Bytes.size() < Size) {
479c299f355SUlrich Weigand Size = Bytes.size();
480eb9af294SRichard Sandiford return MCDisassembler::Fail;
481c299f355SUlrich Weigand }
482eb9af294SRichard Sandiford
483eb9af294SRichard Sandiford // Construct the instruction.
484eb9af294SRichard Sandiford uint64_t Inst = 0;
485eb9af294SRichard Sandiford for (uint64_t I = 0; I < Size; ++I)
486eb9af294SRichard Sandiford Inst = (Inst << 8) | Bytes[I];
487eb9af294SRichard Sandiford
488eb9af294SRichard Sandiford return decodeInstruction(Table, MI, Inst, Address, this, STI);
489eb9af294SRichard Sandiford }
490