1f785676fSDimitry Andric //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
2f785676fSDimitry Andric //
3f785676fSDimitry Andric //                     The LLVM Compiler Infrastructure
4f785676fSDimitry Andric //
5f785676fSDimitry Andric // This file is distributed under the University of Illinois Open Source
6f785676fSDimitry Andric // License. See LICENSE.TXT for details.
7f785676fSDimitry Andric //
8f785676fSDimitry Andric //===----------------------------------------------------------------------===//
9f785676fSDimitry Andric 
107a7e6055SDimitry Andric #include "MCTargetDesc/SystemZMCTargetDesc.h"
11f785676fSDimitry Andric #include "SystemZ.h"
123ca95b02SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
13f785676fSDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
14f785676fSDimitry Andric #include "llvm/MC/MCInst.h"
15f785676fSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
167a7e6055SDimitry Andric #include "llvm/Support/MathExtras.h"
17f785676fSDimitry Andric #include "llvm/Support/TargetRegistry.h"
187a7e6055SDimitry Andric #include <cassert>
197a7e6055SDimitry Andric #include <cstdint>
20f785676fSDimitry Andric 
21f785676fSDimitry Andric using namespace llvm;
22f785676fSDimitry Andric 
2391bc56edSDimitry Andric #define DEBUG_TYPE "systemz-disassembler"
2491bc56edSDimitry Andric 
25f785676fSDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
26f785676fSDimitry Andric 
27f785676fSDimitry Andric namespace {
287a7e6055SDimitry Andric 
29f785676fSDimitry Andric class SystemZDisassembler : public MCDisassembler {
30f785676fSDimitry Andric public:
SystemZDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)3191bc56edSDimitry Andric   SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
3291bc56edSDimitry Andric     : MCDisassembler(STI, Ctx) {}
337a7e6055SDimitry Andric   ~SystemZDisassembler() override = default;
34f785676fSDimitry Andric 
3539d628a0SDimitry Andric   DecodeStatus getInstruction(MCInst &instr, uint64_t &Size,
3639d628a0SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
3739d628a0SDimitry Andric                               raw_ostream &VStream,
3839d628a0SDimitry Andric                               raw_ostream &CStream) const override;
39f785676fSDimitry Andric };
407a7e6055SDimitry Andric 
41f785676fSDimitry Andric } // end anonymous namespace
42f785676fSDimitry Andric 
createSystemZDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)43f785676fSDimitry Andric static MCDisassembler *createSystemZDisassembler(const Target &T,
4491bc56edSDimitry Andric                                                  const MCSubtargetInfo &STI,
4591bc56edSDimitry Andric                                                  MCContext &Ctx) {
4691bc56edSDimitry Andric   return new SystemZDisassembler(STI, Ctx);
47f785676fSDimitry Andric }
48f785676fSDimitry Andric 
LLVMInitializeSystemZDisassembler()49f785676fSDimitry Andric extern "C" void LLVMInitializeSystemZDisassembler() {
50f785676fSDimitry Andric   // Register the disassembler.
51d88c1a5aSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(),
52f785676fSDimitry Andric                                          createSystemZDisassembler);
53f785676fSDimitry Andric }
54f785676fSDimitry Andric 
553ca95b02SDimitry Andric /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
563ca95b02SDimitry Andric /// immediate Value in the MCInst.
573ca95b02SDimitry Andric ///
583ca95b02SDimitry Andric /// @param Value      - The immediate Value, has had any PC adjustment made by
593ca95b02SDimitry Andric ///                     the caller.
603ca95b02SDimitry Andric /// @param isBranch   - If the instruction is a branch instruction
613ca95b02SDimitry Andric /// @param Address    - The starting address of the instruction
623ca95b02SDimitry Andric /// @param Offset     - The byte offset to this immediate in the instruction
633ca95b02SDimitry Andric /// @param Width      - The byte width of this immediate in the instruction
643ca95b02SDimitry Andric ///
653ca95b02SDimitry Andric /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
663ca95b02SDimitry Andric /// called then that function is called to get any symbolic information for the
673ca95b02SDimitry Andric /// immediate in the instruction using the Address, Offset and Width.  If that
683ca95b02SDimitry Andric /// returns non-zero then the symbolic information it returns is used to create
693ca95b02SDimitry Andric /// an MCExpr and that is added as an operand to the MCInst.  If getOpInfo()
703ca95b02SDimitry Andric /// returns zero and isBranch is true then a symbol look up for immediate Value
713ca95b02SDimitry Andric /// is done and if a symbol is found an MCExpr is created with that, else
723ca95b02SDimitry Andric /// an MCExpr with the immediate Value is created.  This function returns true
733ca95b02SDimitry Andric /// 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 void * Decoder)743ca95b02SDimitry Andric static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
753ca95b02SDimitry Andric                                      uint64_t Address, uint64_t Offset,
763ca95b02SDimitry Andric                                      uint64_t Width, MCInst &MI,
773ca95b02SDimitry Andric                                      const void *Decoder) {
783ca95b02SDimitry Andric   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
793ca95b02SDimitry Andric   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
803ca95b02SDimitry Andric                                        Offset, Width);
813ca95b02SDimitry Andric }
823ca95b02SDimitry Andric 
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const unsigned * Regs,unsigned Size)83f785676fSDimitry Andric static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
84ff0cc061SDimitry Andric                                         const unsigned *Regs, unsigned Size) {
85ff0cc061SDimitry Andric   assert(RegNo < Size && "Invalid register");
86f785676fSDimitry Andric   RegNo = Regs[RegNo];
87f785676fSDimitry Andric   if (RegNo == 0)
88f785676fSDimitry Andric     return MCDisassembler::Fail;
89ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(RegNo));
90f785676fSDimitry Andric   return MCDisassembler::Success;
91f785676fSDimitry Andric }
92f785676fSDimitry Andric 
DecodeGR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)93f785676fSDimitry Andric static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
94f785676fSDimitry Andric                                                uint64_t Address,
95f785676fSDimitry Andric                                                const void *Decoder) {
96ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
97f785676fSDimitry Andric }
98f785676fSDimitry Andric 
DecodeGRH32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)99f785676fSDimitry Andric static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
100f785676fSDimitry Andric                                                 uint64_t Address,
101f785676fSDimitry Andric                                                 const void *Decoder) {
102ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
103f785676fSDimitry Andric }
104f785676fSDimitry Andric 
DecodeGR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)105f785676fSDimitry Andric static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
106f785676fSDimitry Andric                                                uint64_t Address,
107f785676fSDimitry Andric                                                const void *Decoder) {
108ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
109f785676fSDimitry Andric }
110f785676fSDimitry Andric 
DecodeGR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)111f785676fSDimitry Andric static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
112f785676fSDimitry Andric                                                 uint64_t Address,
113f785676fSDimitry Andric                                                 const void *Decoder) {
114ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
115f785676fSDimitry Andric }
116f785676fSDimitry Andric 
DecodeADDR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)117f785676fSDimitry Andric static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
118f785676fSDimitry Andric                                                  uint64_t Address,
119f785676fSDimitry Andric                                                  const void *Decoder) {
120ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
121f785676fSDimitry Andric }
122f785676fSDimitry Andric 
DecodeFP32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)123f785676fSDimitry Andric static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
124f785676fSDimitry Andric                                                uint64_t Address,
125f785676fSDimitry Andric                                                const void *Decoder) {
126ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
127f785676fSDimitry Andric }
128f785676fSDimitry Andric 
DecodeFP64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)129f785676fSDimitry Andric static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
130f785676fSDimitry Andric                                                uint64_t Address,
131f785676fSDimitry Andric                                                const void *Decoder) {
132ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
133f785676fSDimitry Andric }
134f785676fSDimitry Andric 
DecodeFP128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)135f785676fSDimitry Andric static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
136f785676fSDimitry Andric                                                 uint64_t Address,
137f785676fSDimitry Andric                                                 const void *Decoder) {
138ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
139ff0cc061SDimitry Andric }
140ff0cc061SDimitry Andric 
DecodeVR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)141ff0cc061SDimitry Andric static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
142ff0cc061SDimitry Andric                                                uint64_t Address,
143ff0cc061SDimitry Andric                                                const void *Decoder) {
144ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
145ff0cc061SDimitry Andric }
146ff0cc061SDimitry Andric 
DecodeVR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)147ff0cc061SDimitry Andric static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
148ff0cc061SDimitry Andric                                                uint64_t Address,
149ff0cc061SDimitry Andric                                                const void *Decoder) {
150ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
151ff0cc061SDimitry Andric }
152ff0cc061SDimitry Andric 
DecodeVR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)153ff0cc061SDimitry Andric static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
154ff0cc061SDimitry Andric                                                 uint64_t Address,
155ff0cc061SDimitry Andric                                                 const void *Decoder) {
156ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
157f785676fSDimitry Andric }
158f785676fSDimitry Andric 
DecodeAR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)159d88c1a5aSDimitry Andric static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
160d88c1a5aSDimitry Andric                                                uint64_t Address,
161d88c1a5aSDimitry Andric                                                const void *Decoder) {
162d88c1a5aSDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
163d88c1a5aSDimitry Andric }
164d88c1a5aSDimitry Andric 
DecodeCR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)165*a580b014SDimitry Andric static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
166*a580b014SDimitry Andric                                                uint64_t Address,
167*a580b014SDimitry Andric                                                const void *Decoder) {
168*a580b014SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);
169*a580b014SDimitry Andric }
170*a580b014SDimitry Andric 
171f785676fSDimitry Andric template<unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm)172f785676fSDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
173ff0cc061SDimitry Andric   if (!isUInt<N>(Imm))
174ff0cc061SDimitry Andric     return MCDisassembler::Fail;
175ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
176f785676fSDimitry Andric   return MCDisassembler::Success;
177f785676fSDimitry Andric }
178f785676fSDimitry Andric 
179f785676fSDimitry Andric template<unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm)180f785676fSDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
181ff0cc061SDimitry Andric   if (!isUInt<N>(Imm))
182ff0cc061SDimitry Andric     return MCDisassembler::Fail;
183ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
184f785676fSDimitry Andric   return MCDisassembler::Success;
185f785676fSDimitry Andric }
186f785676fSDimitry Andric 
decodeU1ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)187ff0cc061SDimitry Andric static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
188ff0cc061SDimitry Andric                                        uint64_t Address, const void *Decoder) {
189ff0cc061SDimitry Andric   return decodeUImmOperand<1>(Inst, Imm);
190ff0cc061SDimitry Andric }
191ff0cc061SDimitry Andric 
decodeU2ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)192ff0cc061SDimitry Andric static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
193ff0cc061SDimitry Andric                                        uint64_t Address, const void *Decoder) {
194ff0cc061SDimitry Andric   return decodeUImmOperand<2>(Inst, Imm);
195ff0cc061SDimitry Andric }
196ff0cc061SDimitry Andric 
decodeU3ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)197ff0cc061SDimitry Andric static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
198ff0cc061SDimitry Andric                                        uint64_t Address, const void *Decoder) {
199ff0cc061SDimitry Andric   return decodeUImmOperand<3>(Inst, Imm);
200ff0cc061SDimitry Andric }
201ff0cc061SDimitry Andric 
decodeU4ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)202f785676fSDimitry Andric static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
203f785676fSDimitry Andric                                        uint64_t Address, const void *Decoder) {
204f785676fSDimitry Andric   return decodeUImmOperand<4>(Inst, Imm);
205f785676fSDimitry Andric }
206f785676fSDimitry Andric 
decodeU6ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)207f785676fSDimitry Andric static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
208f785676fSDimitry Andric                                        uint64_t Address, const void *Decoder) {
209f785676fSDimitry Andric   return decodeUImmOperand<6>(Inst, Imm);
210f785676fSDimitry Andric }
211f785676fSDimitry Andric 
decodeU8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)212f785676fSDimitry Andric static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
213f785676fSDimitry Andric                                        uint64_t Address, const void *Decoder) {
214f785676fSDimitry Andric   return decodeUImmOperand<8>(Inst, Imm);
215f785676fSDimitry Andric }
216f785676fSDimitry Andric 
decodeU12ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)217ff0cc061SDimitry Andric static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
218ff0cc061SDimitry Andric                                         uint64_t Address, const void *Decoder) {
219ff0cc061SDimitry Andric   return decodeUImmOperand<12>(Inst, Imm);
220ff0cc061SDimitry Andric }
221ff0cc061SDimitry Andric 
decodeU16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)222f785676fSDimitry Andric static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
223f785676fSDimitry Andric                                         uint64_t Address, const void *Decoder) {
224f785676fSDimitry Andric   return decodeUImmOperand<16>(Inst, Imm);
225f785676fSDimitry Andric }
226f785676fSDimitry Andric 
decodeU32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)227f785676fSDimitry Andric static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
228f785676fSDimitry Andric                                         uint64_t Address, const void *Decoder) {
229f785676fSDimitry Andric   return decodeUImmOperand<32>(Inst, Imm);
230f785676fSDimitry Andric }
231f785676fSDimitry Andric 
decodeS8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)232f785676fSDimitry Andric static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
233f785676fSDimitry Andric                                        uint64_t Address, const void *Decoder) {
234f785676fSDimitry Andric   return decodeSImmOperand<8>(Inst, Imm);
235f785676fSDimitry Andric }
236f785676fSDimitry Andric 
decodeS16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)237f785676fSDimitry Andric static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
238f785676fSDimitry Andric                                         uint64_t Address, const void *Decoder) {
239f785676fSDimitry Andric   return decodeSImmOperand<16>(Inst, Imm);
240f785676fSDimitry Andric }
241f785676fSDimitry Andric 
decodeS32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)242f785676fSDimitry Andric static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
243f785676fSDimitry Andric                                         uint64_t Address, const void *Decoder) {
244f785676fSDimitry Andric   return decodeSImmOperand<32>(Inst, Imm);
245f785676fSDimitry Andric }
246f785676fSDimitry Andric 
247f785676fSDimitry Andric template<unsigned N>
decodePCDBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,bool isBranch,const void * Decoder)248f785676fSDimitry Andric static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
2493ca95b02SDimitry Andric                                        uint64_t Address,
2503ca95b02SDimitry Andric                                        bool isBranch,
2513ca95b02SDimitry Andric                                        const void *Decoder) {
252f785676fSDimitry Andric   assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
2533ca95b02SDimitry Andric   uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
2543ca95b02SDimitry Andric 
2553ca95b02SDimitry Andric   if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
2563ca95b02SDimitry Andric                                 Inst, Decoder))
2573ca95b02SDimitry Andric     Inst.addOperand(MCOperand::createImm(Value));
2583ca95b02SDimitry Andric 
259f785676fSDimitry Andric   return MCDisassembler::Success;
260f785676fSDimitry Andric }
261f785676fSDimitry Andric 
decodePC12DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)262d88c1a5aSDimitry Andric static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm,
263d88c1a5aSDimitry Andric                                                uint64_t Address,
264d88c1a5aSDimitry Andric                                                const void *Decoder) {
265d88c1a5aSDimitry Andric   return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
266d88c1a5aSDimitry Andric }
267d88c1a5aSDimitry Andric 
decodePC16DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)2683ca95b02SDimitry Andric static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
269f785676fSDimitry Andric                                                uint64_t Address,
270f785676fSDimitry Andric                                                const void *Decoder) {
2713ca95b02SDimitry Andric   return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
2723ca95b02SDimitry Andric }
2733ca95b02SDimitry Andric 
decodePC24DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)274d88c1a5aSDimitry Andric static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm,
275d88c1a5aSDimitry Andric                                                uint64_t Address,
276d88c1a5aSDimitry Andric                                                const void *Decoder) {
277d88c1a5aSDimitry Andric   return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
278d88c1a5aSDimitry Andric }
279d88c1a5aSDimitry Andric 
decodePC32DBLBranchOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)2803ca95b02SDimitry Andric static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
2813ca95b02SDimitry Andric                                                uint64_t Address,
2823ca95b02SDimitry Andric                                                const void *Decoder) {
2833ca95b02SDimitry Andric   return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
284f785676fSDimitry Andric }
285f785676fSDimitry Andric 
decodePC32DBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)286f785676fSDimitry Andric static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
287f785676fSDimitry Andric                                          uint64_t Address,
288f785676fSDimitry Andric                                          const void *Decoder) {
2893ca95b02SDimitry Andric   return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
290f785676fSDimitry Andric }
291f785676fSDimitry Andric 
decodeBDAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)292f785676fSDimitry Andric static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
293f785676fSDimitry Andric                                           const unsigned *Regs) {
294f785676fSDimitry Andric   uint64_t Base = Field >> 12;
295f785676fSDimitry Andric   uint64_t Disp = Field & 0xfff;
296f785676fSDimitry Andric   assert(Base < 16 && "Invalid BDAddr12");
297ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
298ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp));
299f785676fSDimitry Andric   return MCDisassembler::Success;
300f785676fSDimitry Andric }
301f785676fSDimitry Andric 
decodeBDAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)302f785676fSDimitry Andric static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
303f785676fSDimitry Andric                                           const unsigned *Regs) {
304f785676fSDimitry Andric   uint64_t Base = Field >> 20;
305f785676fSDimitry Andric   uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
306f785676fSDimitry Andric   assert(Base < 16 && "Invalid BDAddr20");
307ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
308ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
309f785676fSDimitry Andric   return MCDisassembler::Success;
310f785676fSDimitry Andric }
311f785676fSDimitry Andric 
decodeBDXAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)312f785676fSDimitry Andric static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
313f785676fSDimitry Andric                                            const unsigned *Regs) {
314f785676fSDimitry Andric   uint64_t Index = Field >> 16;
315f785676fSDimitry Andric   uint64_t Base = (Field >> 12) & 0xf;
316f785676fSDimitry Andric   uint64_t Disp = Field & 0xfff;
317f785676fSDimitry Andric   assert(Index < 16 && "Invalid BDXAddr12");
318ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
319ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp));
320ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
321f785676fSDimitry Andric   return MCDisassembler::Success;
322f785676fSDimitry Andric }
323f785676fSDimitry Andric 
decodeBDXAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)324f785676fSDimitry Andric static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
325f785676fSDimitry Andric                                            const unsigned *Regs) {
326f785676fSDimitry Andric   uint64_t Index = Field >> 24;
327f785676fSDimitry Andric   uint64_t Base = (Field >> 20) & 0xf;
328f785676fSDimitry Andric   uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
329f785676fSDimitry Andric   assert(Index < 16 && "Invalid BDXAddr20");
330ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
331ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
332ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
333f785676fSDimitry Andric   return MCDisassembler::Success;
334f785676fSDimitry Andric }
335f785676fSDimitry Andric 
decodeBDLAddr12Len4Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)3365517e702SDimitry Andric static DecodeStatus decodeBDLAddr12Len4Operand(MCInst &Inst, uint64_t Field,
3375517e702SDimitry Andric                                                const unsigned *Regs) {
3385517e702SDimitry Andric   uint64_t Length = Field >> 16;
3395517e702SDimitry Andric   uint64_t Base = (Field >> 12) & 0xf;
3405517e702SDimitry Andric   uint64_t Disp = Field & 0xfff;
3415517e702SDimitry Andric   assert(Length < 16 && "Invalid BDLAddr12Len4");
3425517e702SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
3435517e702SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp));
3445517e702SDimitry Andric   Inst.addOperand(MCOperand::createImm(Length + 1));
3455517e702SDimitry Andric   return MCDisassembler::Success;
3465517e702SDimitry Andric }
3475517e702SDimitry Andric 
decodeBDLAddr12Len8Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)348f785676fSDimitry Andric static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
349f785676fSDimitry Andric                                                const unsigned *Regs) {
350f785676fSDimitry Andric   uint64_t Length = Field >> 16;
351f785676fSDimitry Andric   uint64_t Base = (Field >> 12) & 0xf;
352f785676fSDimitry Andric   uint64_t Disp = Field & 0xfff;
353f785676fSDimitry Andric   assert(Length < 256 && "Invalid BDLAddr12Len8");
354ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
355ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp));
356ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Length + 1));
357ff0cc061SDimitry Andric   return MCDisassembler::Success;
358ff0cc061SDimitry Andric }
359ff0cc061SDimitry Andric 
decodeBDRAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)360d88c1a5aSDimitry Andric static DecodeStatus decodeBDRAddr12Operand(MCInst &Inst, uint64_t Field,
361d88c1a5aSDimitry Andric                                            const unsigned *Regs) {
362d88c1a5aSDimitry Andric   uint64_t Length = Field >> 16;
363d88c1a5aSDimitry Andric   uint64_t Base = (Field >> 12) & 0xf;
364d88c1a5aSDimitry Andric   uint64_t Disp = Field & 0xfff;
365d88c1a5aSDimitry Andric   assert(Length < 16 && "Invalid BDRAddr12");
366d88c1a5aSDimitry Andric   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
367d88c1a5aSDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp));
368d88c1a5aSDimitry Andric   Inst.addOperand(MCOperand::createReg(Regs[Length]));
369d88c1a5aSDimitry Andric   return MCDisassembler::Success;
370d88c1a5aSDimitry Andric }
371d88c1a5aSDimitry Andric 
decodeBDVAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)372ff0cc061SDimitry Andric static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
373ff0cc061SDimitry Andric                                            const unsigned *Regs) {
374ff0cc061SDimitry Andric   uint64_t Index = Field >> 16;
375ff0cc061SDimitry Andric   uint64_t Base = (Field >> 12) & 0xf;
376ff0cc061SDimitry Andric   uint64_t Disp = Field & 0xfff;
377ff0cc061SDimitry Andric   assert(Index < 32 && "Invalid BDVAddr12");
378ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
379ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp));
380ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
381f785676fSDimitry Andric   return MCDisassembler::Success;
382f785676fSDimitry Andric }
383f785676fSDimitry Andric 
decodeBDAddr32Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)384f785676fSDimitry Andric static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
385f785676fSDimitry Andric                                                 uint64_t Address,
386f785676fSDimitry Andric                                                 const void *Decoder) {
387f785676fSDimitry Andric   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
388f785676fSDimitry Andric }
389f785676fSDimitry Andric 
decodeBDAddr32Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)390f785676fSDimitry Andric static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
391f785676fSDimitry Andric                                                 uint64_t Address,
392f785676fSDimitry Andric                                                 const void *Decoder) {
393f785676fSDimitry Andric   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
394f785676fSDimitry Andric }
395f785676fSDimitry Andric 
decodeBDAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)396f785676fSDimitry Andric static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
397f785676fSDimitry Andric                                                 uint64_t Address,
398f785676fSDimitry Andric                                                 const void *Decoder) {
399f785676fSDimitry Andric   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
400f785676fSDimitry Andric }
401f785676fSDimitry Andric 
decodeBDAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)402f785676fSDimitry Andric static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
403f785676fSDimitry Andric                                                 uint64_t Address,
404f785676fSDimitry Andric                                                 const void *Decoder) {
405f785676fSDimitry Andric   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
406f785676fSDimitry Andric }
407f785676fSDimitry Andric 
decodeBDXAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)408f785676fSDimitry Andric static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
409f785676fSDimitry Andric                                                  uint64_t Address,
410f785676fSDimitry Andric                                                  const void *Decoder) {
411f785676fSDimitry Andric   return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
412f785676fSDimitry Andric }
413f785676fSDimitry Andric 
decodeBDXAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)414f785676fSDimitry Andric static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
415f785676fSDimitry Andric                                                  uint64_t Address,
416f785676fSDimitry Andric                                                  const void *Decoder) {
417f785676fSDimitry Andric   return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
418f785676fSDimitry Andric }
419f785676fSDimitry Andric 
decodeBDLAddr64Disp12Len4Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)4205517e702SDimitry Andric static DecodeStatus decodeBDLAddr64Disp12Len4Operand(MCInst &Inst,
4215517e702SDimitry Andric                                                      uint64_t Field,
4225517e702SDimitry Andric                                                      uint64_t Address,
4235517e702SDimitry Andric                                                      const void *Decoder) {
4245517e702SDimitry Andric   return decodeBDLAddr12Len4Operand(Inst, Field, SystemZMC::GR64Regs);
4255517e702SDimitry Andric }
4265517e702SDimitry Andric 
decodeBDLAddr64Disp12Len8Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)427f785676fSDimitry Andric static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
428f785676fSDimitry Andric                                                      uint64_t Field,
429f785676fSDimitry Andric                                                      uint64_t Address,
430f785676fSDimitry Andric                                                      const void *Decoder) {
431f785676fSDimitry Andric   return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
432f785676fSDimitry Andric }
433f785676fSDimitry Andric 
decodeBDRAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)434d88c1a5aSDimitry Andric static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst &Inst,
435d88c1a5aSDimitry Andric                                                  uint64_t Field,
436d88c1a5aSDimitry Andric                                                  uint64_t Address,
437d88c1a5aSDimitry Andric                                                  const void *Decoder) {
438d88c1a5aSDimitry Andric   return decodeBDRAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
439d88c1a5aSDimitry Andric }
440d88c1a5aSDimitry Andric 
decodeBDVAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)441ff0cc061SDimitry Andric static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
442ff0cc061SDimitry Andric                                                  uint64_t Address,
443ff0cc061SDimitry Andric                                                  const void *Decoder) {
444ff0cc061SDimitry Andric   return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
445ff0cc061SDimitry Andric }
446ff0cc061SDimitry Andric 
447f785676fSDimitry Andric #include "SystemZGenDisassemblerTables.inc"
448f785676fSDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const449f785676fSDimitry Andric DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
45039d628a0SDimitry Andric                                                  ArrayRef<uint8_t> Bytes,
451f785676fSDimitry Andric                                                  uint64_t Address,
45239d628a0SDimitry Andric                                                  raw_ostream &OS,
45339d628a0SDimitry Andric                                                  raw_ostream &CS) const {
454f785676fSDimitry Andric   // Get the first two bytes of the instruction.
455f785676fSDimitry Andric   Size = 0;
45639d628a0SDimitry Andric   if (Bytes.size() < 2)
457f785676fSDimitry Andric     return MCDisassembler::Fail;
458f785676fSDimitry Andric 
459f785676fSDimitry Andric   // The top 2 bits of the first byte specify the size.
460f785676fSDimitry Andric   const uint8_t *Table;
461f785676fSDimitry Andric   if (Bytes[0] < 0x40) {
462f785676fSDimitry Andric     Size = 2;
463f785676fSDimitry Andric     Table = DecoderTable16;
464f785676fSDimitry Andric   } else if (Bytes[0] < 0xc0) {
465f785676fSDimitry Andric     Size = 4;
466f785676fSDimitry Andric     Table = DecoderTable32;
467f785676fSDimitry Andric   } else {
468f785676fSDimitry Andric     Size = 6;
469f785676fSDimitry Andric     Table = DecoderTable48;
470f785676fSDimitry Andric   }
471f785676fSDimitry Andric 
472f785676fSDimitry Andric   // Read any remaining bytes.
47339d628a0SDimitry Andric   if (Bytes.size() < Size)
474f785676fSDimitry Andric     return MCDisassembler::Fail;
475f785676fSDimitry Andric 
476f785676fSDimitry Andric   // Construct the instruction.
477f785676fSDimitry Andric   uint64_t Inst = 0;
478f785676fSDimitry Andric   for (uint64_t I = 0; I < Size; ++I)
479f785676fSDimitry Andric     Inst = (Inst << 8) | Bytes[I];
480f785676fSDimitry Andric 
481f785676fSDimitry Andric   return decodeInstruction(Table, MI, Inst, Address, this, STI);
482f785676fSDimitry Andric }
483