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"
11f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/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 
49*6e648ea5SUlrich Weigand /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
50*6e648ea5SUlrich Weigand /// immediate Value in the MCInst.
51*6e648ea5SUlrich Weigand ///
52*6e648ea5SUlrich Weigand /// @param Value      - The immediate Value, has had any PC adjustment made by
53*6e648ea5SUlrich Weigand ///                     the caller.
54*6e648ea5SUlrich Weigand /// @param isBranch   - If the instruction is a branch instruction
55*6e648ea5SUlrich Weigand /// @param Address    - The starting address of the instruction
56*6e648ea5SUlrich Weigand /// @param Offset     - The byte offset to this immediate in the instruction
57*6e648ea5SUlrich Weigand /// @param Width      - The byte width of this immediate in the instruction
58*6e648ea5SUlrich Weigand ///
59*6e648ea5SUlrich Weigand /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
60*6e648ea5SUlrich Weigand /// called then that function is called to get any symbolic information for the
61*6e648ea5SUlrich Weigand /// immediate in the instruction using the Address, Offset and Width.  If that
62*6e648ea5SUlrich Weigand /// returns non-zero then the symbolic information it returns is used to create
63*6e648ea5SUlrich Weigand /// an MCExpr and that is added as an operand to the MCInst.  If getOpInfo()
64*6e648ea5SUlrich Weigand /// returns zero and isBranch is true then a symbol look up for immediate Value
65*6e648ea5SUlrich Weigand /// is done and if a symbol is found an MCExpr is created with that, else
66*6e648ea5SUlrich Weigand /// an MCExpr with the immediate Value is created.  This function returns true
67*6e648ea5SUlrich Weigand /// if it adds an operand to the MCInst and false otherwise.
68*6e648ea5SUlrich Weigand static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
69*6e648ea5SUlrich Weigand                                      uint64_t Address, uint64_t Offset,
70*6e648ea5SUlrich Weigand                                      uint64_t Width, MCInst &MI,
71*6e648ea5SUlrich Weigand                                      const void *Decoder) {
72*6e648ea5SUlrich Weigand   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
73*6e648ea5SUlrich Weigand   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
74*6e648ea5SUlrich Weigand                                        Offset, Width);
75*6e648ea5SUlrich Weigand }
76*6e648ea5SUlrich Weigand 
77eb9af294SRichard Sandiford static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
78a8b04e1cSUlrich Weigand                                         const unsigned *Regs, unsigned Size) {
79a8b04e1cSUlrich Weigand   assert(RegNo < Size && "Invalid register");
80eb9af294SRichard Sandiford   RegNo = Regs[RegNo];
81eb9af294SRichard Sandiford   if (RegNo == 0)
82eb9af294SRichard Sandiford     return MCDisassembler::Fail;
83e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(RegNo));
84eb9af294SRichard Sandiford   return MCDisassembler::Success;
85eb9af294SRichard Sandiford }
86eb9af294SRichard Sandiford 
87eb9af294SRichard Sandiford static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
88eb9af294SRichard Sandiford                                                uint64_t Address,
89eb9af294SRichard Sandiford                                                const void *Decoder) {
90a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
91eb9af294SRichard Sandiford }
92eb9af294SRichard Sandiford 
93f9496060SRichard Sandiford static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
94f9496060SRichard Sandiford                                                 uint64_t Address,
95f9496060SRichard Sandiford                                                 const void *Decoder) {
96a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
97f9496060SRichard Sandiford }
98f9496060SRichard Sandiford 
99eb9af294SRichard Sandiford static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
100eb9af294SRichard Sandiford                                                uint64_t Address,
101eb9af294SRichard Sandiford                                                const void *Decoder) {
102a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
103eb9af294SRichard Sandiford }
104eb9af294SRichard Sandiford 
105eb9af294SRichard Sandiford static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
106eb9af294SRichard Sandiford                                                 uint64_t Address,
107eb9af294SRichard Sandiford                                                 const void *Decoder) {
108a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
109eb9af294SRichard Sandiford }
110eb9af294SRichard Sandiford 
111eb9af294SRichard Sandiford static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
112eb9af294SRichard Sandiford                                                  uint64_t Address,
113eb9af294SRichard Sandiford                                                  const void *Decoder) {
114a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
115eb9af294SRichard Sandiford }
116eb9af294SRichard Sandiford 
117eb9af294SRichard Sandiford static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
118eb9af294SRichard Sandiford                                                uint64_t Address,
119eb9af294SRichard Sandiford                                                const void *Decoder) {
120a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
121eb9af294SRichard Sandiford }
122eb9af294SRichard Sandiford 
123eb9af294SRichard Sandiford static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
124eb9af294SRichard Sandiford                                                uint64_t Address,
125eb9af294SRichard Sandiford                                                const void *Decoder) {
126a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
127eb9af294SRichard Sandiford }
128eb9af294SRichard Sandiford 
129eb9af294SRichard Sandiford static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
130eb9af294SRichard Sandiford                                                 uint64_t Address,
131eb9af294SRichard Sandiford                                                 const void *Decoder) {
132a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
133a8b04e1cSUlrich Weigand }
134a8b04e1cSUlrich Weigand 
135a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
136a8b04e1cSUlrich Weigand                                                uint64_t Address,
137a8b04e1cSUlrich Weigand                                                const void *Decoder) {
138a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
139a8b04e1cSUlrich Weigand }
140a8b04e1cSUlrich Weigand 
141a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
142a8b04e1cSUlrich Weigand                                                uint64_t Address,
143a8b04e1cSUlrich Weigand                                                const void *Decoder) {
144a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
145a8b04e1cSUlrich Weigand }
146a8b04e1cSUlrich Weigand 
147a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
148a8b04e1cSUlrich Weigand                                                 uint64_t Address,
149a8b04e1cSUlrich Weigand                                                 const void *Decoder) {
150a8b04e1cSUlrich Weigand   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
151eb9af294SRichard Sandiford }
152eb9af294SRichard Sandiford 
153eb9af294SRichard Sandiford template<unsigned N>
154eb9af294SRichard Sandiford static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
155a8b04e1cSUlrich Weigand   if (!isUInt<N>(Imm))
156a8b04e1cSUlrich Weigand     return MCDisassembler::Fail;
157e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Imm));
158eb9af294SRichard Sandiford   return MCDisassembler::Success;
159eb9af294SRichard Sandiford }
160eb9af294SRichard Sandiford 
161eb9af294SRichard Sandiford template<unsigned N>
162eb9af294SRichard Sandiford static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
163a8b04e1cSUlrich Weigand   if (!isUInt<N>(Imm))
164a8b04e1cSUlrich Weigand     return MCDisassembler::Fail;
165e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
166eb9af294SRichard Sandiford   return MCDisassembler::Success;
167eb9af294SRichard Sandiford }
168eb9af294SRichard Sandiford 
169eb9af294SRichard Sandiford static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
170eb9af294SRichard Sandiford                                            uint64_t Address,
171eb9af294SRichard Sandiford                                            const void *Decoder) {
172eb9af294SRichard Sandiford   return decodeUImmOperand<4>(Inst, Imm);
173eb9af294SRichard Sandiford }
174eb9af294SRichard Sandiford 
175a8b04e1cSUlrich Weigand static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
176a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
177a8b04e1cSUlrich Weigand   return decodeUImmOperand<1>(Inst, Imm);
178a8b04e1cSUlrich Weigand }
179a8b04e1cSUlrich Weigand 
180a8b04e1cSUlrich Weigand static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
181a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
182a8b04e1cSUlrich Weigand   return decodeUImmOperand<2>(Inst, Imm);
183a8b04e1cSUlrich Weigand }
184a8b04e1cSUlrich Weigand 
185a8b04e1cSUlrich Weigand static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
186a8b04e1cSUlrich Weigand                                        uint64_t Address, const void *Decoder) {
187a8b04e1cSUlrich Weigand   return decodeUImmOperand<3>(Inst, Imm);
188a8b04e1cSUlrich Weigand }
189a8b04e1cSUlrich Weigand 
190eb9af294SRichard Sandiford static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
191eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
192eb9af294SRichard Sandiford   return decodeUImmOperand<4>(Inst, Imm);
193eb9af294SRichard Sandiford }
194eb9af294SRichard Sandiford 
195eb9af294SRichard Sandiford static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
196eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
197eb9af294SRichard Sandiford   return decodeUImmOperand<6>(Inst, Imm);
198eb9af294SRichard Sandiford }
199eb9af294SRichard Sandiford 
200eb9af294SRichard Sandiford static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
201eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
202eb9af294SRichard Sandiford   return decodeUImmOperand<8>(Inst, Imm);
203eb9af294SRichard Sandiford }
204eb9af294SRichard Sandiford 
205a8b04e1cSUlrich Weigand static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
206a8b04e1cSUlrich Weigand                                         uint64_t Address, const void *Decoder) {
207a8b04e1cSUlrich Weigand   return decodeUImmOperand<12>(Inst, Imm);
208a8b04e1cSUlrich Weigand }
209a8b04e1cSUlrich Weigand 
210eb9af294SRichard Sandiford static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
211eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
212eb9af294SRichard Sandiford   return decodeUImmOperand<16>(Inst, Imm);
213eb9af294SRichard Sandiford }
214eb9af294SRichard Sandiford 
215eb9af294SRichard Sandiford static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
216eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
217eb9af294SRichard Sandiford   return decodeUImmOperand<32>(Inst, Imm);
218eb9af294SRichard Sandiford }
219eb9af294SRichard Sandiford 
220eb9af294SRichard Sandiford static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
221eb9af294SRichard Sandiford                                        uint64_t Address, const void *Decoder) {
222eb9af294SRichard Sandiford   return decodeSImmOperand<8>(Inst, Imm);
223eb9af294SRichard Sandiford }
224eb9af294SRichard Sandiford 
225eb9af294SRichard Sandiford static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
226eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
227eb9af294SRichard Sandiford   return decodeSImmOperand<16>(Inst, Imm);
228eb9af294SRichard Sandiford }
229eb9af294SRichard Sandiford 
230eb9af294SRichard Sandiford static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
231eb9af294SRichard Sandiford                                         uint64_t Address, const void *Decoder) {
232eb9af294SRichard Sandiford   return decodeSImmOperand<32>(Inst, Imm);
233eb9af294SRichard Sandiford }
234eb9af294SRichard Sandiford 
235eb9af294SRichard Sandiford template<unsigned N>
236eb9af294SRichard Sandiford static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
237*6e648ea5SUlrich Weigand                                        uint64_t Address,
238*6e648ea5SUlrich Weigand                                        bool isBranch,
239*6e648ea5SUlrich Weigand                                        const void *Decoder) {
240eb9af294SRichard Sandiford   assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
241*6e648ea5SUlrich Weigand   uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
242*6e648ea5SUlrich Weigand 
243*6e648ea5SUlrich Weigand   if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
244*6e648ea5SUlrich Weigand                                 Inst, Decoder))
245*6e648ea5SUlrich Weigand     Inst.addOperand(MCOperand::createImm(Value));
246*6e648ea5SUlrich Weigand 
247eb9af294SRichard Sandiford   return MCDisassembler::Success;
248eb9af294SRichard Sandiford }
249eb9af294SRichard Sandiford 
250*6e648ea5SUlrich Weigand static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
251eb9af294SRichard Sandiford                                                uint64_t Address,
252eb9af294SRichard Sandiford                                                const void *Decoder) {
253*6e648ea5SUlrich Weigand   return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
254*6e648ea5SUlrich Weigand }
255*6e648ea5SUlrich Weigand 
256*6e648ea5SUlrich Weigand static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
257*6e648ea5SUlrich Weigand                                                uint64_t Address,
258*6e648ea5SUlrich Weigand                                                const void *Decoder) {
259*6e648ea5SUlrich Weigand   return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
260eb9af294SRichard Sandiford }
261eb9af294SRichard Sandiford 
262eb9af294SRichard Sandiford static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
263eb9af294SRichard Sandiford                                          uint64_t Address,
264eb9af294SRichard Sandiford                                          const void *Decoder) {
265*6e648ea5SUlrich Weigand   return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
266eb9af294SRichard Sandiford }
267eb9af294SRichard Sandiford 
268eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
269eb9af294SRichard Sandiford                                           const unsigned *Regs) {
270eb9af294SRichard Sandiford   uint64_t Base = Field >> 12;
271eb9af294SRichard Sandiford   uint64_t Disp = Field & 0xfff;
272eb9af294SRichard Sandiford   assert(Base < 16 && "Invalid BDAddr12");
273e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
274e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
275eb9af294SRichard Sandiford   return MCDisassembler::Success;
276eb9af294SRichard Sandiford }
277eb9af294SRichard Sandiford 
278eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
279eb9af294SRichard Sandiford                                           const unsigned *Regs) {
280eb9af294SRichard Sandiford   uint64_t Base = Field >> 20;
281eb9af294SRichard Sandiford   uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
282eb9af294SRichard Sandiford   assert(Base < 16 && "Invalid BDAddr20");
283e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
284e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
285eb9af294SRichard Sandiford   return MCDisassembler::Success;
286eb9af294SRichard Sandiford }
287eb9af294SRichard Sandiford 
288eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
289eb9af294SRichard Sandiford                                            const unsigned *Regs) {
290eb9af294SRichard Sandiford   uint64_t Index = Field >> 16;
291eb9af294SRichard Sandiford   uint64_t Base = (Field >> 12) & 0xf;
292eb9af294SRichard Sandiford   uint64_t Disp = Field & 0xfff;
293eb9af294SRichard Sandiford   assert(Index < 16 && "Invalid BDXAddr12");
294e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
295e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
296e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
297eb9af294SRichard Sandiford   return MCDisassembler::Success;
298eb9af294SRichard Sandiford }
299eb9af294SRichard Sandiford 
300eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
301eb9af294SRichard Sandiford                                            const unsigned *Regs) {
302eb9af294SRichard Sandiford   uint64_t Index = Field >> 24;
303eb9af294SRichard Sandiford   uint64_t Base = (Field >> 20) & 0xf;
304eb9af294SRichard Sandiford   uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
305eb9af294SRichard Sandiford   assert(Index < 16 && "Invalid BDXAddr20");
306e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
307e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
308e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
309eb9af294SRichard Sandiford   return MCDisassembler::Success;
310eb9af294SRichard Sandiford }
311eb9af294SRichard Sandiford 
3121d959008SRichard Sandiford static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
3131d959008SRichard Sandiford                                                const unsigned *Regs) {
3141d959008SRichard Sandiford   uint64_t Length = Field >> 16;
3151d959008SRichard Sandiford   uint64_t Base = (Field >> 12) & 0xf;
3161d959008SRichard Sandiford   uint64_t Disp = Field & 0xfff;
3171d959008SRichard Sandiford   assert(Length < 256 && "Invalid BDLAddr12Len8");
318e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
319e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
320e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Length + 1));
3211d959008SRichard Sandiford   return MCDisassembler::Success;
3221d959008SRichard Sandiford }
3231d959008SRichard Sandiford 
324a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
325a8b04e1cSUlrich Weigand                                            const unsigned *Regs) {
326a8b04e1cSUlrich Weigand   uint64_t Index = Field >> 16;
327a8b04e1cSUlrich Weigand   uint64_t Base = (Field >> 12) & 0xf;
328a8b04e1cSUlrich Weigand   uint64_t Disp = Field & 0xfff;
329a8b04e1cSUlrich Weigand   assert(Index < 32 && "Invalid BDVAddr12");
330e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
331e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createImm(Disp));
332e9119e41SJim Grosbach   Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
333a8b04e1cSUlrich Weigand   return MCDisassembler::Success;
334a8b04e1cSUlrich Weigand }
335a8b04e1cSUlrich Weigand 
336eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
337eb9af294SRichard Sandiford                                                 uint64_t Address,
338eb9af294SRichard Sandiford                                                 const void *Decoder) {
339eb9af294SRichard Sandiford   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
340eb9af294SRichard Sandiford }
341eb9af294SRichard Sandiford 
342eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
343eb9af294SRichard Sandiford                                                 uint64_t Address,
344eb9af294SRichard Sandiford                                                 const void *Decoder) {
345eb9af294SRichard Sandiford   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
346eb9af294SRichard Sandiford }
347eb9af294SRichard Sandiford 
348eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
349eb9af294SRichard Sandiford                                                 uint64_t Address,
350eb9af294SRichard Sandiford                                                 const void *Decoder) {
351eb9af294SRichard Sandiford   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
352eb9af294SRichard Sandiford }
353eb9af294SRichard Sandiford 
354eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
355eb9af294SRichard Sandiford                                                 uint64_t Address,
356eb9af294SRichard Sandiford                                                 const void *Decoder) {
357eb9af294SRichard Sandiford   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
358eb9af294SRichard Sandiford }
359eb9af294SRichard Sandiford 
360eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
361eb9af294SRichard Sandiford                                                  uint64_t Address,
362eb9af294SRichard Sandiford                                                  const void *Decoder) {
363eb9af294SRichard Sandiford   return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
364eb9af294SRichard Sandiford }
365eb9af294SRichard Sandiford 
366eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
367eb9af294SRichard Sandiford                                                  uint64_t Address,
368eb9af294SRichard Sandiford                                                  const void *Decoder) {
369eb9af294SRichard Sandiford   return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
370eb9af294SRichard Sandiford }
371eb9af294SRichard Sandiford 
3721d959008SRichard Sandiford static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
3731d959008SRichard Sandiford                                                      uint64_t Field,
3741d959008SRichard Sandiford                                                      uint64_t Address,
3751d959008SRichard Sandiford                                                      const void *Decoder) {
3761d959008SRichard Sandiford   return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
3771d959008SRichard Sandiford }
3781d959008SRichard Sandiford 
379a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
380a8b04e1cSUlrich Weigand                                                  uint64_t Address,
381a8b04e1cSUlrich Weigand                                                  const void *Decoder) {
382a8b04e1cSUlrich Weigand   return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
383a8b04e1cSUlrich Weigand }
384a8b04e1cSUlrich Weigand 
385eb9af294SRichard Sandiford #include "SystemZGenDisassemblerTables.inc"
386eb9af294SRichard Sandiford 
387eb9af294SRichard Sandiford DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
3887fc5b874SRafael Espindola                                                  ArrayRef<uint8_t> Bytes,
389eb9af294SRichard Sandiford                                                  uint64_t Address,
3904aa6bea7SRafael Espindola                                                  raw_ostream &OS,
3914aa6bea7SRafael Espindola                                                  raw_ostream &CS) const {
392eb9af294SRichard Sandiford   // Get the first two bytes of the instruction.
393eb9af294SRichard Sandiford   Size = 0;
3947fc5b874SRafael Espindola   if (Bytes.size() < 2)
395eb9af294SRichard Sandiford     return MCDisassembler::Fail;
396eb9af294SRichard Sandiford 
397eb9af294SRichard Sandiford   // The top 2 bits of the first byte specify the size.
398eb9af294SRichard Sandiford   const uint8_t *Table;
399eb9af294SRichard Sandiford   if (Bytes[0] < 0x40) {
400eb9af294SRichard Sandiford     Size = 2;
401eb9af294SRichard Sandiford     Table = DecoderTable16;
402eb9af294SRichard Sandiford   } else if (Bytes[0] < 0xc0) {
403eb9af294SRichard Sandiford     Size = 4;
404eb9af294SRichard Sandiford     Table = DecoderTable32;
405eb9af294SRichard Sandiford   } else {
406eb9af294SRichard Sandiford     Size = 6;
407eb9af294SRichard Sandiford     Table = DecoderTable48;
408eb9af294SRichard Sandiford   }
409eb9af294SRichard Sandiford 
410eb9af294SRichard Sandiford   // Read any remaining bytes.
4117fc5b874SRafael Espindola   if (Bytes.size() < Size)
412eb9af294SRichard Sandiford     return MCDisassembler::Fail;
413eb9af294SRichard Sandiford 
414eb9af294SRichard Sandiford   // Construct the instruction.
415eb9af294SRichard Sandiford   uint64_t Inst = 0;
416eb9af294SRichard Sandiford   for (uint64_t I = 0; I < Size; ++I)
417eb9af294SRichard Sandiford     Inst = (Inst << 8) | Bytes[I];
418eb9af294SRichard Sandiford 
419eb9af294SRichard Sandiford   return decodeInstruction(Table, MI, Inst, Address, this, STI);
420eb9af294SRichard Sandiford }
421