1eb9af294SRichard Sandiford //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
2eb9af294SRichard Sandiford //
3eb9af294SRichard Sandiford //                     The LLVM Compiler Infrastructure
4eb9af294SRichard Sandiford //
5eb9af294SRichard Sandiford // This file is distributed under the University of Illinois Open Source
6eb9af294SRichard Sandiford // License. See LICENSE.TXT for details.
7eb9af294SRichard Sandiford //
8eb9af294SRichard Sandiford //===----------------------------------------------------------------------===//
9eb9af294SRichard Sandiford 
10eb9af294SRichard Sandiford #include "SystemZ.h"
11eb9af294SRichard Sandiford #include "llvm/MC/MCDisassembler.h"
12eb9af294SRichard Sandiford #include "llvm/MC/MCFixedLenDisassembler.h"
13eb9af294SRichard Sandiford #include "llvm/MC/MCInst.h"
14eb9af294SRichard Sandiford #include "llvm/MC/MCSubtargetInfo.h"
15eb9af294SRichard Sandiford #include "llvm/Support/TargetRegistry.h"
16eb9af294SRichard Sandiford 
17eb9af294SRichard Sandiford using namespace llvm;
18eb9af294SRichard Sandiford 
19e96dd897SChandler Carruth #define DEBUG_TYPE "systemz-disassembler"
20e96dd897SChandler Carruth 
21eb9af294SRichard Sandiford typedef MCDisassembler::DecodeStatus DecodeStatus;
22eb9af294SRichard Sandiford 
23eb9af294SRichard Sandiford namespace {
24eb9af294SRichard Sandiford class SystemZDisassembler : public MCDisassembler {
25eb9af294SRichard Sandiford public:
26a1bc0f56SLang Hames   SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
27a1bc0f56SLang Hames     : MCDisassembler(STI, Ctx) {}
28f817c1cbSAlexander Kornienko   ~SystemZDisassembler() override {}
29eb9af294SRichard Sandiford 
307fc5b874SRafael Espindola   DecodeStatus getInstruction(MCInst &instr, uint64_t &Size,
317fc5b874SRafael Espindola                               ArrayRef<uint8_t> Bytes, uint64_t Address,
324aa6bea7SRafael Espindola                               raw_ostream &VStream,
334aa6bea7SRafael Espindola                               raw_ostream &CStream) const override;
34eb9af294SRichard Sandiford };
35eb9af294SRichard Sandiford } // end anonymous namespace
36eb9af294SRichard Sandiford 
37eb9af294SRichard Sandiford static MCDisassembler *createSystemZDisassembler(const Target &T,
38a1bc0f56SLang Hames                                                  const MCSubtargetInfo &STI,
39a1bc0f56SLang Hames                                                  MCContext &Ctx) {
40a1bc0f56SLang Hames   return new SystemZDisassembler(STI, Ctx);
41eb9af294SRichard Sandiford }
42eb9af294SRichard Sandiford 
43eb9af294SRichard Sandiford extern "C" void LLVMInitializeSystemZDisassembler() {
44eb9af294SRichard Sandiford   // Register the disassembler.
45eb9af294SRichard Sandiford   TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
46eb9af294SRichard Sandiford                                          createSystemZDisassembler);
47eb9af294SRichard Sandiford }
48eb9af294SRichard Sandiford 
49eb9af294SRichard Sandiford static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
50a8b04e1cSUlrich Weigand                                         const unsigned *Regs, unsigned Size) {
51a8b04e1cSUlrich Weigand   assert(RegNo < Size && "Invalid register");
52eb9af294SRichard Sandiford   RegNo = Regs[RegNo];
53eb9af294SRichard Sandiford   if (RegNo == 0)
54eb9af294SRichard Sandiford     return MCDisassembler::Fail;
55*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(RegNo));
56eb9af294SRichard Sandiford   return MCDisassembler::Success;
57eb9af294SRichard Sandiford }
58eb9af294SRichard Sandiford 
59eb9af294SRichard Sandiford static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
60eb9af294SRichard Sandiford                                                uint64_t Address,
61eb9af294SRichard Sandiford                                                const void *Decoder) {
62a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
63eb9af294SRichard Sandiford }
64eb9af294SRichard Sandiford 
65f9496060SRichard Sandiford static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
66f9496060SRichard Sandiford                                                 uint64_t Address,
67f9496060SRichard Sandiford                                                 const void *Decoder) {
68a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
69f9496060SRichard Sandiford }
70f9496060SRichard Sandiford 
71eb9af294SRichard Sandiford static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
72eb9af294SRichard Sandiford                                                uint64_t Address,
73eb9af294SRichard Sandiford                                                const void *Decoder) {
74a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
75eb9af294SRichard Sandiford }
76eb9af294SRichard Sandiford 
77eb9af294SRichard Sandiford static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
78eb9af294SRichard Sandiford                                                 uint64_t Address,
79eb9af294SRichard Sandiford                                                 const void *Decoder) {
80a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
81eb9af294SRichard Sandiford }
82eb9af294SRichard Sandiford 
83eb9af294SRichard Sandiford static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
84eb9af294SRichard Sandiford                                                  uint64_t Address,
85eb9af294SRichard Sandiford                                                  const void *Decoder) {
86a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
87eb9af294SRichard Sandiford }
88eb9af294SRichard Sandiford 
89eb9af294SRichard Sandiford static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
90eb9af294SRichard Sandiford                                                uint64_t Address,
91eb9af294SRichard Sandiford                                                const void *Decoder) {
92a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
93eb9af294SRichard Sandiford }
94eb9af294SRichard Sandiford 
95eb9af294SRichard Sandiford static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
96eb9af294SRichard Sandiford                                                uint64_t Address,
97eb9af294SRichard Sandiford                                                const void *Decoder) {
98a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
99eb9af294SRichard Sandiford }
100eb9af294SRichard Sandiford 
101eb9af294SRichard Sandiford static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
102eb9af294SRichard Sandiford                                                 uint64_t Address,
103eb9af294SRichard Sandiford                                                 const void *Decoder) {
104a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
105a8b04e1cSUlrich Weigand }
106a8b04e1cSUlrich Weigand 
107a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
108a8b04e1cSUlrich Weigand                                                uint64_t Address,
109a8b04e1cSUlrich Weigand                                                const void *Decoder) {
110a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
111a8b04e1cSUlrich Weigand }
112a8b04e1cSUlrich Weigand 
113a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
114a8b04e1cSUlrich Weigand                                                uint64_t Address,
115a8b04e1cSUlrich Weigand                                                const void *Decoder) {
116a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
117a8b04e1cSUlrich Weigand }
118a8b04e1cSUlrich Weigand 
119a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
120a8b04e1cSUlrich Weigand                                                 uint64_t Address,
121a8b04e1cSUlrich Weigand                                                 const void *Decoder) {
122a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
123eb9af294SRichard Sandiford }
124eb9af294SRichard Sandiford 
125eb9af294SRichard Sandiford template<unsigned N>
126eb9af294SRichard Sandiford static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
127a8b04e1cSUlrich Weigand   if (!isUInt<N>(Imm))
128a8b04e1cSUlrich Weigand     return MCDisassembler::Fail;
129*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Imm));
130eb9af294SRichard Sandiford   return MCDisassembler::Success;
131eb9af294SRichard Sandiford }
132eb9af294SRichard Sandiford 
133eb9af294SRichard Sandiford template<unsigned N>
134eb9af294SRichard Sandiford static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
135a8b04e1cSUlrich Weigand   if (!isUInt<N>(Imm))
136a8b04e1cSUlrich Weigand     return MCDisassembler::Fail;
137*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
138eb9af294SRichard Sandiford   return MCDisassembler::Success;
139eb9af294SRichard Sandiford }
140eb9af294SRichard Sandiford 
141eb9af294SRichard Sandiford static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
142eb9af294SRichard Sandiford                                            uint64_t Address,
143eb9af294SRichard Sandiford                                            const void *Decoder) {
144eb9af294SRichard Sandiford   return decodeUImmOperand<4>(Inst, Imm);
145eb9af294SRichard Sandiford }
146eb9af294SRichard Sandiford 
147a8b04e1cSUlrich Weigand static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
148a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
149a8b04e1cSUlrich Weigand   return decodeUImmOperand<1>(Inst, Imm);
150a8b04e1cSUlrich Weigand }
151a8b04e1cSUlrich Weigand 
152a8b04e1cSUlrich Weigand static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
153a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
154a8b04e1cSUlrich Weigand   return decodeUImmOperand<2>(Inst, Imm);
155a8b04e1cSUlrich Weigand }
156a8b04e1cSUlrich Weigand 
157a8b04e1cSUlrich Weigand static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
158a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
159a8b04e1cSUlrich Weigand   return decodeUImmOperand<3>(Inst, Imm);
160a8b04e1cSUlrich Weigand }
161a8b04e1cSUlrich Weigand 
162eb9af294SRichard Sandiford static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
163eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
164eb9af294SRichard Sandiford   return decodeUImmOperand<4>(Inst, Imm);
165eb9af294SRichard Sandiford }
166eb9af294SRichard Sandiford 
167eb9af294SRichard Sandiford static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
168eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
169eb9af294SRichard Sandiford   return decodeUImmOperand<6>(Inst, Imm);
170eb9af294SRichard Sandiford }
171eb9af294SRichard Sandiford 
172eb9af294SRichard Sandiford static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
173eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
174eb9af294SRichard Sandiford   return decodeUImmOperand<8>(Inst, Imm);
175eb9af294SRichard Sandiford }
176eb9af294SRichard Sandiford 
177a8b04e1cSUlrich Weigand static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
178a8b04e1cSUlrich Weigand                                         uint64_t Address, const void *Decoder) {
179a8b04e1cSUlrich Weigand   return decodeUImmOperand<12>(Inst, Imm);
180a8b04e1cSUlrich Weigand }
181a8b04e1cSUlrich Weigand 
182eb9af294SRichard Sandiford static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
183eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
184eb9af294SRichard Sandiford   return decodeUImmOperand<16>(Inst, Imm);
185eb9af294SRichard Sandiford }
186eb9af294SRichard Sandiford 
187eb9af294SRichard Sandiford static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
188eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
189eb9af294SRichard Sandiford   return decodeUImmOperand<32>(Inst, Imm);
190eb9af294SRichard Sandiford }
191eb9af294SRichard Sandiford 
192eb9af294SRichard Sandiford static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
193eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
194eb9af294SRichard Sandiford   return decodeSImmOperand<8>(Inst, Imm);
195eb9af294SRichard Sandiford }
196eb9af294SRichard Sandiford 
197eb9af294SRichard Sandiford static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
198eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
199eb9af294SRichard Sandiford   return decodeSImmOperand<16>(Inst, Imm);
200eb9af294SRichard Sandiford }
201eb9af294SRichard Sandiford 
202eb9af294SRichard Sandiford static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
203eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
204eb9af294SRichard Sandiford   return decodeSImmOperand<32>(Inst, Imm);
205eb9af294SRichard Sandiford }
206eb9af294SRichard Sandiford 
207eb9af294SRichard Sandiford template<unsigned N>
208eb9af294SRichard Sandiford static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
209eb9af294SRichard Sandiford                                        uint64_t Address) {
210eb9af294SRichard Sandiford   assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
211*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) * 2 + Address));
212eb9af294SRichard Sandiford   return MCDisassembler::Success;
213eb9af294SRichard Sandiford }
214eb9af294SRichard Sandiford 
215eb9af294SRichard Sandiford static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
216eb9af294SRichard Sandiford                                          uint64_t Address,
217eb9af294SRichard Sandiford                                          const void *Decoder) {
218eb9af294SRichard Sandiford   return decodePCDBLOperand<16>(Inst, Imm, Address);
219eb9af294SRichard Sandiford }
220eb9af294SRichard Sandiford 
221eb9af294SRichard Sandiford static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
222eb9af294SRichard Sandiford                                          uint64_t Address,
223eb9af294SRichard Sandiford                                          const void *Decoder) {
224eb9af294SRichard Sandiford   return decodePCDBLOperand<32>(Inst, Imm, Address);
225eb9af294SRichard Sandiford }
226eb9af294SRichard Sandiford 
227eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
228eb9af294SRichard Sandiford                                           const unsigned *Regs) {
229eb9af294SRichard Sandiford   uint64_t Base = Field >> 12;
230eb9af294SRichard Sandiford   uint64_t Disp = Field & 0xfff;
231eb9af294SRichard Sandiford   assert(Base < 16 && "Invalid BDAddr12");
232*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
233*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
234eb9af294SRichard Sandiford   return MCDisassembler::Success;
235eb9af294SRichard Sandiford }
236eb9af294SRichard Sandiford 
237eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
238eb9af294SRichard Sandiford                                           const unsigned *Regs) {
239eb9af294SRichard Sandiford   uint64_t Base = Field >> 20;
240eb9af294SRichard Sandiford   uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
241eb9af294SRichard Sandiford   assert(Base < 16 && "Invalid BDAddr20");
242*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
243*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
244eb9af294SRichard Sandiford   return MCDisassembler::Success;
245eb9af294SRichard Sandiford }
246eb9af294SRichard Sandiford 
247eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
248eb9af294SRichard Sandiford                                            const unsigned *Regs) {
249eb9af294SRichard Sandiford   uint64_t Index = Field >> 16;
250eb9af294SRichard Sandiford   uint64_t Base = (Field >> 12) & 0xf;
251eb9af294SRichard Sandiford   uint64_t Disp = Field & 0xfff;
252eb9af294SRichard Sandiford   assert(Index < 16 && "Invalid BDXAddr12");
253*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
254*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
255*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
256eb9af294SRichard Sandiford   return MCDisassembler::Success;
257eb9af294SRichard Sandiford }
258eb9af294SRichard Sandiford 
259eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
260eb9af294SRichard Sandiford                                            const unsigned *Regs) {
261eb9af294SRichard Sandiford   uint64_t Index = Field >> 24;
262eb9af294SRichard Sandiford   uint64_t Base = (Field >> 20) & 0xf;
263eb9af294SRichard Sandiford   uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
264eb9af294SRichard Sandiford   assert(Index < 16 && "Invalid BDXAddr20");
265*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
266*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
267*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
268eb9af294SRichard Sandiford   return MCDisassembler::Success;
269eb9af294SRichard Sandiford }
270eb9af294SRichard Sandiford 
2711d959008SRichard Sandiford static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
2721d959008SRichard Sandiford                                                const unsigned *Regs) {
2731d959008SRichard Sandiford   uint64_t Length = Field >> 16;
2741d959008SRichard Sandiford   uint64_t Base = (Field >> 12) & 0xf;
2751d959008SRichard Sandiford   uint64_t Disp = Field & 0xfff;
2761d959008SRichard Sandiford   assert(Length < 256 && "Invalid BDLAddr12Len8");
277*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
278*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
279*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Length + 1));
2801d959008SRichard Sandiford   return MCDisassembler::Success;
2811d959008SRichard Sandiford }
2821d959008SRichard Sandiford 
283a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
284a8b04e1cSUlrich Weigand                                            const unsigned *Regs) {
285a8b04e1cSUlrich Weigand   uint64_t Index = Field >> 16;
286a8b04e1cSUlrich Weigand   uint64_t Base = (Field >> 12) & 0xf;
287a8b04e1cSUlrich Weigand   uint64_t Disp = Field & 0xfff;
288a8b04e1cSUlrich Weigand   assert(Index < 32 && "Invalid BDVAddr12");
289*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
290*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
291*e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
292a8b04e1cSUlrich Weigand   return MCDisassembler::Success;
293a8b04e1cSUlrich Weigand }
294a8b04e1cSUlrich Weigand 
295eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
296eb9af294SRichard Sandiford                                                 uint64_t Address,
297eb9af294SRichard Sandiford                                                 const void *Decoder) {
298eb9af294SRichard Sandiford   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
299eb9af294SRichard Sandiford }
300eb9af294SRichard Sandiford 
301eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
302eb9af294SRichard Sandiford                                                 uint64_t Address,
303eb9af294SRichard Sandiford                                                 const void *Decoder) {
304eb9af294SRichard Sandiford   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
305eb9af294SRichard Sandiford }
306eb9af294SRichard Sandiford 
307eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
308eb9af294SRichard Sandiford                                                 uint64_t Address,
309eb9af294SRichard Sandiford                                                 const void *Decoder) {
310eb9af294SRichard Sandiford   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
311eb9af294SRichard Sandiford }
312eb9af294SRichard Sandiford 
313eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
314eb9af294SRichard Sandiford                                                 uint64_t Address,
315eb9af294SRichard Sandiford                                                 const void *Decoder) {
316eb9af294SRichard Sandiford   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
317eb9af294SRichard Sandiford }
318eb9af294SRichard Sandiford 
319eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
320eb9af294SRichard Sandiford                                                  uint64_t Address,
321eb9af294SRichard Sandiford                                                  const void *Decoder) {
322eb9af294SRichard Sandiford   return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
323eb9af294SRichard Sandiford }
324eb9af294SRichard Sandiford 
325eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
326eb9af294SRichard Sandiford                                                  uint64_t Address,
327eb9af294SRichard Sandiford                                                  const void *Decoder) {
328eb9af294SRichard Sandiford   return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
329eb9af294SRichard Sandiford }
330eb9af294SRichard Sandiford 
3311d959008SRichard Sandiford static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
3321d959008SRichard Sandiford                                                      uint64_t Field,
3331d959008SRichard Sandiford                                                      uint64_t Address,
3341d959008SRichard Sandiford                                                      const void *Decoder) {
3351d959008SRichard Sandiford   return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
3361d959008SRichard Sandiford }
3371d959008SRichard Sandiford 
338a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
339a8b04e1cSUlrich Weigand                                                  uint64_t Address,
340a8b04e1cSUlrich Weigand                                                  const void *Decoder) {
341a8b04e1cSUlrich Weigand   return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
342a8b04e1cSUlrich Weigand }
343a8b04e1cSUlrich Weigand 
344eb9af294SRichard Sandiford #include "SystemZGenDisassemblerTables.inc"
345eb9af294SRichard Sandiford 
346eb9af294SRichard Sandiford DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
3477fc5b874SRafael Espindola                                                  ArrayRef<uint8_t> Bytes,
348eb9af294SRichard Sandiford                                                  uint64_t Address,
3494aa6bea7SRafael Espindola                                                  raw_ostream &OS,
3504aa6bea7SRafael Espindola                                                  raw_ostream &CS) const {
351eb9af294SRichard Sandiford   // Get the first two bytes of the instruction.
352eb9af294SRichard Sandiford   Size = 0;
3537fc5b874SRafael Espindola   if (Bytes.size() < 2)
354eb9af294SRichard Sandiford     return MCDisassembler::Fail;
355eb9af294SRichard Sandiford 
356eb9af294SRichard Sandiford   // The top 2 bits of the first byte specify the size.
357eb9af294SRichard Sandiford   const uint8_t *Table;
358eb9af294SRichard Sandiford   if (Bytes[0] < 0x40) {
359eb9af294SRichard Sandiford     Size = 2;
360eb9af294SRichard Sandiford     Table = DecoderTable16;
361eb9af294SRichard Sandiford   } else if (Bytes[0] < 0xc0) {
362eb9af294SRichard Sandiford     Size = 4;
363eb9af294SRichard Sandiford     Table = DecoderTable32;
364eb9af294SRichard Sandiford   } else {
365eb9af294SRichard Sandiford     Size = 6;
366eb9af294SRichard Sandiford     Table = DecoderTable48;
367eb9af294SRichard Sandiford   }
368eb9af294SRichard Sandiford 
369eb9af294SRichard Sandiford   // Read any remaining bytes.
3707fc5b874SRafael Espindola   if (Bytes.size() < Size)
371eb9af294SRichard Sandiford     return MCDisassembler::Fail;
372eb9af294SRichard Sandiford 
373eb9af294SRichard Sandiford   // Construct the instruction.
374eb9af294SRichard Sandiford   uint64_t Inst = 0;
375eb9af294SRichard Sandiford   for (uint64_t I = 0; I < Size; ++I)
376eb9af294SRichard Sandiford     Inst = (Inst << 8) | Bytes[I];
377eb9af294SRichard Sandiford 
378eb9af294SRichard Sandiford   return decodeInstruction(Table, MI, Inst, Address, this, STI);
379eb9af294SRichard Sandiford }
380