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"
12f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/MCDisassembler.h"
13eb9af294SRichard Sandiford #include "llvm/MC/MCFixedLenDisassembler.h"
14eb9af294SRichard Sandiford #include "llvm/MC/MCInst.h"
15eb9af294SRichard Sandiford #include "llvm/MC/MCSubtargetInfo.h"
163943d2b0SEugene Zelenko #include "llvm/Support/MathExtras.h"
17eb9af294SRichard Sandiford #include "llvm/Support/TargetRegistry.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:
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 
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 
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.
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,
766e648ea5SUlrich Weigand                                      const void *Decoder) {
776e648ea5SUlrich Weigand   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
786e648ea5SUlrich Weigand   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
796e648ea5SUlrich Weigand                                        Offset, Width);
806e648ea5SUlrich Weigand }
816e648ea5SUlrich Weigand 
82eb9af294SRichard Sandiford static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
83a8b04e1cSUlrich Weigand                                         const unsigned *Regs, unsigned Size) {
84a8b04e1cSUlrich Weigand   assert(RegNo < Size && "Invalid register");
85eb9af294SRichard Sandiford   RegNo = Regs[RegNo];
86eb9af294SRichard Sandiford   if (RegNo == 0)
87eb9af294SRichard Sandiford     return MCDisassembler::Fail;
88e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(RegNo));
89eb9af294SRichard Sandiford   return MCDisassembler::Success;
90eb9af294SRichard Sandiford }
91eb9af294SRichard Sandiford 
92eb9af294SRichard Sandiford static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
93eb9af294SRichard Sandiford                                                uint64_t Address,
94eb9af294SRichard Sandiford                                                const void *Decoder) {
95a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
96eb9af294SRichard Sandiford }
97eb9af294SRichard Sandiford 
98f9496060SRichard Sandiford static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
99f9496060SRichard Sandiford                                                 uint64_t Address,
100f9496060SRichard Sandiford                                                 const void *Decoder) {
101a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
102f9496060SRichard Sandiford }
103f9496060SRichard Sandiford 
104eb9af294SRichard Sandiford static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
105eb9af294SRichard Sandiford                                                uint64_t Address,
106eb9af294SRichard Sandiford                                                const void *Decoder) {
107a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
108eb9af294SRichard Sandiford }
109eb9af294SRichard Sandiford 
110eb9af294SRichard Sandiford static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
111eb9af294SRichard Sandiford                                                 uint64_t Address,
112eb9af294SRichard Sandiford                                                 const void *Decoder) {
113a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
114eb9af294SRichard Sandiford }
115eb9af294SRichard Sandiford 
116eb9af294SRichard Sandiford static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
117eb9af294SRichard Sandiford                                                  uint64_t Address,
118eb9af294SRichard Sandiford                                                  const void *Decoder) {
119a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
120eb9af294SRichard Sandiford }
121eb9af294SRichard Sandiford 
122eb9af294SRichard Sandiford static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
123eb9af294SRichard Sandiford                                                uint64_t Address,
124eb9af294SRichard Sandiford                                                const void *Decoder) {
125a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
126eb9af294SRichard Sandiford }
127eb9af294SRichard Sandiford 
128eb9af294SRichard Sandiford static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
129eb9af294SRichard Sandiford                                                uint64_t Address,
130eb9af294SRichard Sandiford                                                const void *Decoder) {
131a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
132eb9af294SRichard Sandiford }
133eb9af294SRichard Sandiford 
134eb9af294SRichard Sandiford static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
135eb9af294SRichard Sandiford                                                 uint64_t Address,
136eb9af294SRichard Sandiford                                                 const void *Decoder) {
137a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
138a8b04e1cSUlrich Weigand }
139a8b04e1cSUlrich Weigand 
140a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
141a8b04e1cSUlrich Weigand                                                uint64_t Address,
142a8b04e1cSUlrich Weigand                                                const void *Decoder) {
143a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
144a8b04e1cSUlrich Weigand }
145a8b04e1cSUlrich Weigand 
146a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
147a8b04e1cSUlrich Weigand                                                uint64_t Address,
148a8b04e1cSUlrich Weigand                                                const void *Decoder) {
149a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
150a8b04e1cSUlrich Weigand }
151a8b04e1cSUlrich Weigand 
152a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
153a8b04e1cSUlrich Weigand                                                 uint64_t Address,
154a8b04e1cSUlrich Weigand                                                 const void *Decoder) {
155a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
156eb9af294SRichard Sandiford }
157eb9af294SRichard Sandiford 
158fffc7110SUlrich Weigand static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
159fffc7110SUlrich Weigand                                                uint64_t Address,
160fffc7110SUlrich Weigand                                                const void *Decoder) {
161fffc7110SUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
162fffc7110SUlrich Weigand }
163fffc7110SUlrich Weigand 
16403ab2e2bSUlrich Weigand static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
16503ab2e2bSUlrich Weigand                                                uint64_t Address,
16603ab2e2bSUlrich Weigand                                                const void *Decoder) {
16703ab2e2bSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);
16803ab2e2bSUlrich Weigand }
16903ab2e2bSUlrich Weigand 
170eb9af294SRichard Sandiford template<unsigned N>
171eb9af294SRichard Sandiford static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
172a8b04e1cSUlrich Weigand   if (!isUInt<N>(Imm))
173a8b04e1cSUlrich Weigand     return MCDisassembler::Fail;
174e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Imm));
175eb9af294SRichard Sandiford   return MCDisassembler::Success;
176eb9af294SRichard Sandiford }
177eb9af294SRichard Sandiford 
178eb9af294SRichard Sandiford template<unsigned N>
179eb9af294SRichard Sandiford static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
180a8b04e1cSUlrich Weigand   if (!isUInt<N>(Imm))
181a8b04e1cSUlrich Weigand     return MCDisassembler::Fail;
182e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
183eb9af294SRichard Sandiford   return MCDisassembler::Success;
184eb9af294SRichard Sandiford }
185eb9af294SRichard Sandiford 
186a8b04e1cSUlrich Weigand static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
187a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
188a8b04e1cSUlrich Weigand   return decodeUImmOperand<1>(Inst, Imm);
189a8b04e1cSUlrich Weigand }
190a8b04e1cSUlrich Weigand 
191a8b04e1cSUlrich Weigand static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
192a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
193a8b04e1cSUlrich Weigand   return decodeUImmOperand<2>(Inst, Imm);
194a8b04e1cSUlrich Weigand }
195a8b04e1cSUlrich Weigand 
196a8b04e1cSUlrich Weigand static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
197a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
198a8b04e1cSUlrich Weigand   return decodeUImmOperand<3>(Inst, Imm);
199a8b04e1cSUlrich Weigand }
200a8b04e1cSUlrich Weigand 
201eb9af294SRichard Sandiford static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
202eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
203eb9af294SRichard Sandiford   return decodeUImmOperand<4>(Inst, Imm);
204eb9af294SRichard Sandiford }
205eb9af294SRichard Sandiford 
206eb9af294SRichard Sandiford static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
207eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
208eb9af294SRichard Sandiford   return decodeUImmOperand<6>(Inst, Imm);
209eb9af294SRichard Sandiford }
210eb9af294SRichard Sandiford 
211eb9af294SRichard Sandiford static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
212eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
213eb9af294SRichard Sandiford   return decodeUImmOperand<8>(Inst, Imm);
214eb9af294SRichard Sandiford }
215eb9af294SRichard Sandiford 
216a8b04e1cSUlrich Weigand static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
217a8b04e1cSUlrich Weigand                                         uint64_t Address, const void *Decoder) {
218a8b04e1cSUlrich Weigand   return decodeUImmOperand<12>(Inst, Imm);
219a8b04e1cSUlrich Weigand }
220a8b04e1cSUlrich Weigand 
221eb9af294SRichard Sandiford static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
222eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
223eb9af294SRichard Sandiford   return decodeUImmOperand<16>(Inst, Imm);
224eb9af294SRichard Sandiford }
225eb9af294SRichard Sandiford 
226eb9af294SRichard Sandiford static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
227eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
228eb9af294SRichard Sandiford   return decodeUImmOperand<32>(Inst, Imm);
229eb9af294SRichard Sandiford }
230eb9af294SRichard Sandiford 
231eb9af294SRichard Sandiford static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
232eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
233eb9af294SRichard Sandiford   return decodeSImmOperand<8>(Inst, Imm);
234eb9af294SRichard Sandiford }
235eb9af294SRichard Sandiford 
236eb9af294SRichard Sandiford static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
237eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
238eb9af294SRichard Sandiford   return decodeSImmOperand<16>(Inst, Imm);
239eb9af294SRichard Sandiford }
240eb9af294SRichard Sandiford 
241eb9af294SRichard Sandiford static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
242eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
243eb9af294SRichard Sandiford   return decodeSImmOperand<32>(Inst, Imm);
244eb9af294SRichard Sandiford }
245eb9af294SRichard Sandiford 
246eb9af294SRichard Sandiford template<unsigned N>
247eb9af294SRichard Sandiford static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
2486e648ea5SUlrich Weigand                                        uint64_t Address,
2496e648ea5SUlrich Weigand                                        bool isBranch,
2506e648ea5SUlrich Weigand                                        const void *Decoder) {
251eb9af294SRichard Sandiford   assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
2526e648ea5SUlrich Weigand   uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
2536e648ea5SUlrich Weigand 
2546e648ea5SUlrich Weigand   if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
2556e648ea5SUlrich Weigand                                 Inst, Decoder))
2566e648ea5SUlrich Weigand     Inst.addOperand(MCOperand::createImm(Value));
2576e648ea5SUlrich Weigand 
258eb9af294SRichard Sandiford   return MCDisassembler::Success;
259eb9af294SRichard Sandiford }
260eb9af294SRichard Sandiford 
26184404f30SUlrich Weigand static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm,
26284404f30SUlrich Weigand                                                uint64_t Address,
26384404f30SUlrich Weigand                                                const void *Decoder) {
26484404f30SUlrich Weigand   return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
26584404f30SUlrich Weigand }
26684404f30SUlrich Weigand 
2676e648ea5SUlrich Weigand static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
268eb9af294SRichard Sandiford                                                uint64_t Address,
269eb9af294SRichard Sandiford                                                const void *Decoder) {
2706e648ea5SUlrich Weigand   return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
2716e648ea5SUlrich Weigand }
2726e648ea5SUlrich Weigand 
27384404f30SUlrich Weigand static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm,
27484404f30SUlrich Weigand                                                uint64_t Address,
27584404f30SUlrich Weigand                                                const void *Decoder) {
27684404f30SUlrich Weigand   return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
27784404f30SUlrich Weigand }
27884404f30SUlrich Weigand 
2796e648ea5SUlrich Weigand static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
2806e648ea5SUlrich Weigand                                                uint64_t Address,
2816e648ea5SUlrich Weigand                                                const void *Decoder) {
2826e648ea5SUlrich Weigand   return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
283eb9af294SRichard Sandiford }
284eb9af294SRichard Sandiford 
285eb9af294SRichard Sandiford static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
286eb9af294SRichard Sandiford                                          uint64_t Address,
287eb9af294SRichard Sandiford                                          const void *Decoder) {
2886e648ea5SUlrich Weigand   return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
289eb9af294SRichard Sandiford }
290eb9af294SRichard Sandiford 
291eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
292eb9af294SRichard Sandiford                                           const unsigned *Regs) {
293eb9af294SRichard Sandiford   uint64_t Base = Field >> 12;
294eb9af294SRichard Sandiford   uint64_t Disp = Field & 0xfff;
295eb9af294SRichard Sandiford   assert(Base < 16 && "Invalid BDAddr12");
296e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
297e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
298eb9af294SRichard Sandiford   return MCDisassembler::Success;
299eb9af294SRichard Sandiford }
300eb9af294SRichard Sandiford 
301eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
302eb9af294SRichard Sandiford                                           const unsigned *Regs) {
303eb9af294SRichard Sandiford   uint64_t Base = Field >> 20;
304eb9af294SRichard Sandiford   uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
305eb9af294SRichard Sandiford   assert(Base < 16 && "Invalid BDAddr20");
306e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
307e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
308eb9af294SRichard Sandiford   return MCDisassembler::Success;
309eb9af294SRichard Sandiford }
310eb9af294SRichard Sandiford 
311eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
312eb9af294SRichard Sandiford                                            const unsigned *Regs) {
313eb9af294SRichard Sandiford   uint64_t Index = Field >> 16;
314eb9af294SRichard Sandiford   uint64_t Base = (Field >> 12) & 0xf;
315eb9af294SRichard Sandiford   uint64_t Disp = Field & 0xfff;
316eb9af294SRichard Sandiford   assert(Index < 16 && "Invalid BDXAddr12");
317e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
318e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
319e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
320eb9af294SRichard Sandiford   return MCDisassembler::Success;
321eb9af294SRichard Sandiford }
322eb9af294SRichard Sandiford 
323eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
324eb9af294SRichard Sandiford                                            const unsigned *Regs) {
325eb9af294SRichard Sandiford   uint64_t Index = Field >> 24;
326eb9af294SRichard Sandiford   uint64_t Base = (Field >> 20) & 0xf;
327eb9af294SRichard Sandiford   uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
328eb9af294SRichard Sandiford   assert(Index < 16 && "Invalid BDXAddr20");
329e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
330e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
331e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
332eb9af294SRichard Sandiford   return MCDisassembler::Success;
333eb9af294SRichard Sandiford }
334eb9af294SRichard Sandiford 
335c7eb5a95SUlrich Weigand static DecodeStatus decodeBDLAddr12Len4Operand(MCInst &Inst, uint64_t Field,
336c7eb5a95SUlrich Weigand                                                const unsigned *Regs) {
337c7eb5a95SUlrich Weigand   uint64_t Length = Field >> 16;
338c7eb5a95SUlrich Weigand   uint64_t Base = (Field >> 12) & 0xf;
339c7eb5a95SUlrich Weigand   uint64_t Disp = Field & 0xfff;
340c7eb5a95SUlrich Weigand   assert(Length < 16 && "Invalid BDLAddr12Len4");
341c7eb5a95SUlrich Weigand   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
342c7eb5a95SUlrich Weigand   Inst.addOperand(MCOperand::createImm(Disp));
343c7eb5a95SUlrich Weigand   Inst.addOperand(MCOperand::createImm(Length + 1));
344c7eb5a95SUlrich Weigand   return MCDisassembler::Success;
345c7eb5a95SUlrich Weigand }
346c7eb5a95SUlrich Weigand 
3471d959008SRichard Sandiford static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
3481d959008SRichard Sandiford                                                const unsigned *Regs) {
3491d959008SRichard Sandiford   uint64_t Length = Field >> 16;
3501d959008SRichard Sandiford   uint64_t Base = (Field >> 12) & 0xf;
3511d959008SRichard Sandiford   uint64_t Disp = Field & 0xfff;
3521d959008SRichard Sandiford   assert(Length < 256 && "Invalid BDLAddr12Len8");
353e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
354e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
355e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Length + 1));
3561d959008SRichard Sandiford   return MCDisassembler::Success;
3571d959008SRichard Sandiford }
3581d959008SRichard Sandiford 
359ec5d779eSUlrich Weigand static DecodeStatus decodeBDRAddr12Operand(MCInst &Inst, uint64_t Field,
360ec5d779eSUlrich Weigand                                            const unsigned *Regs) {
361ec5d779eSUlrich Weigand   uint64_t Length = Field >> 16;
362ec5d779eSUlrich Weigand   uint64_t Base = (Field >> 12) & 0xf;
363ec5d779eSUlrich Weigand   uint64_t Disp = Field & 0xfff;
364ec5d779eSUlrich Weigand   assert(Length < 16 && "Invalid BDRAddr12");
365ec5d779eSUlrich Weigand   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
366ec5d779eSUlrich Weigand   Inst.addOperand(MCOperand::createImm(Disp));
367ec5d779eSUlrich Weigand   Inst.addOperand(MCOperand::createReg(Regs[Length]));
368ec5d779eSUlrich Weigand   return MCDisassembler::Success;
369ec5d779eSUlrich Weigand }
370ec5d779eSUlrich Weigand 
371a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
372a8b04e1cSUlrich Weigand                                            const unsigned *Regs) {
373a8b04e1cSUlrich Weigand   uint64_t Index = Field >> 16;
374a8b04e1cSUlrich Weigand   uint64_t Base = (Field >> 12) & 0xf;
375a8b04e1cSUlrich Weigand   uint64_t Disp = Field & 0xfff;
376a8b04e1cSUlrich Weigand   assert(Index < 32 && "Invalid BDVAddr12");
377e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
378e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
379e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
380a8b04e1cSUlrich Weigand   return MCDisassembler::Success;
381a8b04e1cSUlrich Weigand }
382a8b04e1cSUlrich Weigand 
383eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
384eb9af294SRichard Sandiford                                                 uint64_t Address,
385eb9af294SRichard Sandiford                                                 const void *Decoder) {
386eb9af294SRichard Sandiford   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
387eb9af294SRichard Sandiford }
388eb9af294SRichard Sandiford 
389eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
390eb9af294SRichard Sandiford                                                 uint64_t Address,
391eb9af294SRichard Sandiford                                                 const void *Decoder) {
392eb9af294SRichard Sandiford   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
393eb9af294SRichard Sandiford }
394eb9af294SRichard Sandiford 
395eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
396eb9af294SRichard Sandiford                                                 uint64_t Address,
397eb9af294SRichard Sandiford                                                 const void *Decoder) {
398eb9af294SRichard Sandiford   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
399eb9af294SRichard Sandiford }
400eb9af294SRichard Sandiford 
401eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
402eb9af294SRichard Sandiford                                                 uint64_t Address,
403eb9af294SRichard Sandiford                                                 const void *Decoder) {
404eb9af294SRichard Sandiford   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
405eb9af294SRichard Sandiford }
406eb9af294SRichard Sandiford 
407eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
408eb9af294SRichard Sandiford                                                  uint64_t Address,
409eb9af294SRichard Sandiford                                                  const void *Decoder) {
410eb9af294SRichard Sandiford   return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
411eb9af294SRichard Sandiford }
412eb9af294SRichard Sandiford 
413eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
414eb9af294SRichard Sandiford                                                  uint64_t Address,
415eb9af294SRichard Sandiford                                                  const void *Decoder) {
416eb9af294SRichard Sandiford   return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
417eb9af294SRichard Sandiford }
418eb9af294SRichard Sandiford 
419c7eb5a95SUlrich Weigand static DecodeStatus decodeBDLAddr64Disp12Len4Operand(MCInst &Inst,
420c7eb5a95SUlrich Weigand                                                      uint64_t Field,
421c7eb5a95SUlrich Weigand                                                      uint64_t Address,
422c7eb5a95SUlrich Weigand                                                      const void *Decoder) {
423c7eb5a95SUlrich Weigand   return decodeBDLAddr12Len4Operand(Inst, Field, SystemZMC::GR64Regs);
424c7eb5a95SUlrich Weigand }
425c7eb5a95SUlrich Weigand 
4261d959008SRichard Sandiford static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
4271d959008SRichard Sandiford                                                      uint64_t Field,
4281d959008SRichard Sandiford                                                      uint64_t Address,
4291d959008SRichard Sandiford                                                      const void *Decoder) {
4301d959008SRichard Sandiford   return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
4311d959008SRichard Sandiford }
4321d959008SRichard Sandiford 
433ec5d779eSUlrich Weigand static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst &Inst,
434ec5d779eSUlrich Weigand                                                  uint64_t Field,
435ec5d779eSUlrich Weigand                                                  uint64_t Address,
436ec5d779eSUlrich Weigand                                                  const void *Decoder) {
437ec5d779eSUlrich Weigand   return decodeBDRAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
438ec5d779eSUlrich Weigand }
439ec5d779eSUlrich Weigand 
440a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
441a8b04e1cSUlrich Weigand                                                  uint64_t Address,
442a8b04e1cSUlrich Weigand                                                  const void *Decoder) {
443a8b04e1cSUlrich Weigand   return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
444a8b04e1cSUlrich Weigand }
445a8b04e1cSUlrich Weigand 
446eb9af294SRichard Sandiford #include "SystemZGenDisassemblerTables.inc"
447eb9af294SRichard Sandiford 
448eb9af294SRichard Sandiford DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
4497fc5b874SRafael Espindola                                                  ArrayRef<uint8_t> Bytes,
450eb9af294SRichard Sandiford                                                  uint64_t Address,
4514aa6bea7SRafael Espindola                                                  raw_ostream &CS) const {
452eb9af294SRichard Sandiford   // Get the first two bytes of the instruction.
453eb9af294SRichard Sandiford   Size = 0;
4547fc5b874SRafael Espindola   if (Bytes.size() < 2)
455eb9af294SRichard Sandiford     return MCDisassembler::Fail;
456eb9af294SRichard Sandiford 
457eb9af294SRichard Sandiford   // The top 2 bits of the first byte specify the size.
458eb9af294SRichard Sandiford   const uint8_t *Table;
459eb9af294SRichard Sandiford   if (Bytes[0] < 0x40) {
460eb9af294SRichard Sandiford     Size = 2;
461eb9af294SRichard Sandiford     Table = DecoderTable16;
462eb9af294SRichard Sandiford   } else if (Bytes[0] < 0xc0) {
463eb9af294SRichard Sandiford     Size = 4;
464eb9af294SRichard Sandiford     Table = DecoderTable32;
465eb9af294SRichard Sandiford   } else {
466eb9af294SRichard Sandiford     Size = 6;
467eb9af294SRichard Sandiford     Table = DecoderTable48;
468eb9af294SRichard Sandiford   }
469eb9af294SRichard Sandiford 
470eb9af294SRichard Sandiford   // Read any remaining bytes.
471*c299f355SUlrich Weigand   if (Bytes.size() < Size) {
472*c299f355SUlrich Weigand     Size = Bytes.size();
473eb9af294SRichard Sandiford     return MCDisassembler::Fail;
474*c299f355SUlrich Weigand   }
475eb9af294SRichard Sandiford 
476eb9af294SRichard Sandiford   // Construct the instruction.
477eb9af294SRichard Sandiford   uint64_t Inst = 0;
478eb9af294SRichard Sandiford   for (uint64_t I = 0; I < Size; ++I)
479eb9af294SRichard Sandiford     Inst = (Inst << 8) | Bytes[I];
480eb9af294SRichard Sandiford 
481eb9af294SRichard Sandiford   return decodeInstruction(Table, MI, Inst, Address, this, STI);
482eb9af294SRichard Sandiford }
483