xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MCTargetDesc/SystemZMCTargetDesc.h"
100b57cec5SDimitry Andric #include "SystemZ.h"
110b57cec5SDimitry Andric #include "TargetInfo/SystemZTargetInfo.h"
1281ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
16349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
170b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
180b57cec5SDimitry Andric #include <cassert>
190b57cec5SDimitry Andric #include <cstdint>
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace llvm;
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric #define DEBUG_TYPE "systemz-disassembler"
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric namespace {
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric class SystemZDisassembler : public MCDisassembler {
300b57cec5SDimitry Andric public:
310b57cec5SDimitry Andric   SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
320b57cec5SDimitry Andric     : MCDisassembler(STI, Ctx) {}
330b57cec5SDimitry Andric   ~SystemZDisassembler() override = default;
340b57cec5SDimitry Andric 
35*5f757f3fSDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
360b57cec5SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
370b57cec5SDimitry Andric                               raw_ostream &CStream) const override;
380b57cec5SDimitry Andric };
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric } // end anonymous namespace
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric static MCDisassembler *createSystemZDisassembler(const Target &T,
430b57cec5SDimitry Andric                                                  const MCSubtargetInfo &STI,
440b57cec5SDimitry Andric                                                  MCContext &Ctx) {
450b57cec5SDimitry Andric   return new SystemZDisassembler(STI, Ctx);
460b57cec5SDimitry Andric }
470b57cec5SDimitry Andric 
48*5f757f3fSDimitry Andric // NOLINTNEXTLINE(readability-identifier-naming)
49480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZDisassembler() {
500b57cec5SDimitry Andric   // Register the disassembler.
510b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(),
520b57cec5SDimitry Andric                                          createSystemZDisassembler);
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
560b57cec5SDimitry Andric /// immediate Value in the MCInst.
570b57cec5SDimitry Andric ///
580b57cec5SDimitry Andric /// @param Value      - The immediate Value, has had any PC adjustment made by
590b57cec5SDimitry Andric ///                     the caller.
600b57cec5SDimitry Andric /// @param isBranch   - If the instruction is a branch instruction
610b57cec5SDimitry Andric /// @param Address    - The starting address of the instruction
620b57cec5SDimitry Andric /// @param Offset     - The byte offset to this immediate in the instruction
630b57cec5SDimitry Andric /// @param Width      - The byte width of this immediate in the instruction
640b57cec5SDimitry Andric ///
650b57cec5SDimitry Andric /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
660b57cec5SDimitry Andric /// called then that function is called to get any symbolic information for the
670b57cec5SDimitry Andric /// immediate in the instruction using the Address, Offset and Width.  If that
680b57cec5SDimitry Andric /// returns non-zero then the symbolic information it returns is used to create
690b57cec5SDimitry Andric /// an MCExpr and that is added as an operand to the MCInst.  If getOpInfo()
700b57cec5SDimitry Andric /// returns zero and isBranch is true then a symbol look up for immediate Value
710b57cec5SDimitry Andric /// is done and if a symbol is found an MCExpr is created with that, else
720b57cec5SDimitry Andric /// an MCExpr with the immediate Value is created.  This function returns true
730b57cec5SDimitry Andric /// if it adds an operand to the MCInst and false otherwise.
74*5f757f3fSDimitry Andric static bool tryAddingSymbolicOperand(int64_t Value, bool IsBranch,
750b57cec5SDimitry Andric                                      uint64_t Address, uint64_t Offset,
760b57cec5SDimitry Andric                                      uint64_t Width, MCInst &MI,
7781ad6265SDimitry Andric                                      const MCDisassembler *Decoder) {
78*5f757f3fSDimitry Andric   return Decoder->tryAddingSymbolicOperand(MI, Value, Address, IsBranch, Offset,
7981ad6265SDimitry Andric                                            Width, /*InstSize=*/0);
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
8306c3fb27SDimitry Andric                                         const unsigned *Regs, unsigned Size,
8406c3fb27SDimitry Andric                                         bool IsAddr = false) {
850b57cec5SDimitry Andric   assert(RegNo < Size && "Invalid register");
8606c3fb27SDimitry Andric   if (IsAddr && RegNo == 0) {
8706c3fb27SDimitry Andric     RegNo = SystemZ::NoRegister;
8806c3fb27SDimitry Andric   } else {
890b57cec5SDimitry Andric     RegNo = Regs[RegNo];
900b57cec5SDimitry Andric     if (RegNo == 0)
910b57cec5SDimitry Andric       return MCDisassembler::Fail;
9206c3fb27SDimitry Andric   }
930b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RegNo));
940b57cec5SDimitry Andric   return MCDisassembler::Success;
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
980b57cec5SDimitry Andric                                                uint64_t Address,
9981ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1000b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1040b57cec5SDimitry Andric                                                 uint64_t Address,
10581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
1060b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1100b57cec5SDimitry Andric                                                uint64_t Address,
11181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1120b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1160b57cec5SDimitry Andric                                                 uint64_t Address,
11781ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
1180b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
12181ad6265SDimitry Andric static DecodeStatus
12206c3fb27SDimitry Andric DecodeADDR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
12306c3fb27SDimitry Andric                              const MCDisassembler *Decoder) {
12406c3fb27SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16, true);
12506c3fb27SDimitry Andric }
12606c3fb27SDimitry Andric 
12706c3fb27SDimitry Andric static DecodeStatus
12881ad6265SDimitry Andric DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
12981ad6265SDimitry Andric                              const MCDisassembler *Decoder) {
13006c3fb27SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16, true);
1310b57cec5SDimitry Andric }
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1340b57cec5SDimitry Andric                                                uint64_t Address,
13581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1360b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1400b57cec5SDimitry Andric                                                uint64_t Address,
14181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1420b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1460b57cec5SDimitry Andric                                                 uint64_t Address,
14781ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
1480b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1520b57cec5SDimitry Andric                                                uint64_t Address,
15381ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1540b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1580b57cec5SDimitry Andric                                                uint64_t Address,
15981ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1600b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1640b57cec5SDimitry Andric                                                 uint64_t Address,
16581ad6265SDimitry Andric                                                 const MCDisassembler *Decoder) {
1660b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1700b57cec5SDimitry Andric                                                uint64_t Address,
17181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1720b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
1760b57cec5SDimitry Andric                                                uint64_t Address,
17781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
1780b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16);
1790b57cec5SDimitry Andric }
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric template<unsigned N>
1820b57cec5SDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
1830b57cec5SDimitry Andric   if (!isUInt<N>(Imm))
1840b57cec5SDimitry Andric     return MCDisassembler::Fail;
1850b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
1860b57cec5SDimitry Andric   return MCDisassembler::Success;
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric template<unsigned N>
1900b57cec5SDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
1910b57cec5SDimitry Andric   if (!isUInt<N>(Imm))
1920b57cec5SDimitry Andric     return MCDisassembler::Fail;
1930b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
1940b57cec5SDimitry Andric   return MCDisassembler::Success;
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
19881ad6265SDimitry Andric                                        uint64_t Address,
19981ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
2000b57cec5SDimitry Andric   return decodeUImmOperand<1>(Inst, Imm);
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
20481ad6265SDimitry Andric                                        uint64_t Address,
20581ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
2060b57cec5SDimitry Andric   return decodeUImmOperand<2>(Inst, Imm);
2070b57cec5SDimitry Andric }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
21081ad6265SDimitry Andric                                        uint64_t Address,
21181ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
2120b57cec5SDimitry Andric   return decodeUImmOperand<3>(Inst, Imm);
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
21681ad6265SDimitry Andric                                        uint64_t Address,
21781ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
2180b57cec5SDimitry Andric   return decodeUImmOperand<4>(Inst, Imm);
2190b57cec5SDimitry Andric }
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
22281ad6265SDimitry Andric                                        uint64_t Address,
22381ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
2240b57cec5SDimitry Andric   return decodeUImmOperand<8>(Inst, Imm);
2250b57cec5SDimitry Andric }
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
22881ad6265SDimitry Andric                                         uint64_t Address,
22981ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
2300b57cec5SDimitry Andric   return decodeUImmOperand<12>(Inst, Imm);
2310b57cec5SDimitry Andric }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
23481ad6265SDimitry Andric                                         uint64_t Address,
23581ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
2360b57cec5SDimitry Andric   return decodeUImmOperand<16>(Inst, Imm);
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
24081ad6265SDimitry Andric                                         uint64_t Address,
24181ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
2420b57cec5SDimitry Andric   return decodeUImmOperand<32>(Inst, Imm);
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric 
2450b57cec5SDimitry Andric static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
24681ad6265SDimitry Andric                                        uint64_t Address,
24781ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
2480b57cec5SDimitry Andric   return decodeSImmOperand<8>(Inst, Imm);
2490b57cec5SDimitry Andric }
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
25281ad6265SDimitry Andric                                         uint64_t Address,
25381ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
2540b57cec5SDimitry Andric   return decodeSImmOperand<16>(Inst, Imm);
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric 
25706c3fb27SDimitry Andric static DecodeStatus decodeS20ImmOperand(MCInst &Inst, uint64_t Imm,
25806c3fb27SDimitry Andric                                         uint64_t Address,
25906c3fb27SDimitry Andric                                         const MCDisassembler *Decoder) {
26006c3fb27SDimitry Andric   return decodeSImmOperand<20>(Inst, Imm);
26106c3fb27SDimitry Andric }
26206c3fb27SDimitry Andric 
2630b57cec5SDimitry Andric static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
26481ad6265SDimitry Andric                                         uint64_t Address,
26581ad6265SDimitry Andric                                         const MCDisassembler *Decoder) {
2660b57cec5SDimitry Andric   return decodeSImmOperand<32>(Inst, Imm);
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric template <unsigned N>
27006c3fb27SDimitry Andric static DecodeStatus decodeLenOperand(MCInst &Inst, uint64_t Imm,
27106c3fb27SDimitry Andric                                      uint64_t Address,
27206c3fb27SDimitry Andric                                      const MCDisassembler *Decoder) {
27306c3fb27SDimitry Andric   if (!isUInt<N>(Imm))
27406c3fb27SDimitry Andric     return MCDisassembler::Fail;
27506c3fb27SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm + 1));
27606c3fb27SDimitry Andric   return MCDisassembler::Success;
27706c3fb27SDimitry Andric }
27806c3fb27SDimitry Andric 
27906c3fb27SDimitry Andric template <unsigned N>
2800b57cec5SDimitry Andric static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
28181ad6265SDimitry Andric                                        uint64_t Address, bool isBranch,
28281ad6265SDimitry Andric                                        const MCDisassembler *Decoder) {
2830b57cec5SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
2840b57cec5SDimitry Andric   uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
2870b57cec5SDimitry Andric                                 Inst, Decoder))
2880b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(Value));
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   return MCDisassembler::Success;
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm,
2940b57cec5SDimitry Andric                                                uint64_t Address,
29581ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
2960b57cec5SDimitry Andric   return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
2970b57cec5SDimitry Andric }
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
3000b57cec5SDimitry Andric                                                uint64_t Address,
30181ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
3020b57cec5SDimitry Andric   return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm,
3060b57cec5SDimitry Andric                                                uint64_t Address,
30781ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
3080b57cec5SDimitry Andric   return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
3120b57cec5SDimitry Andric                                                uint64_t Address,
31381ad6265SDimitry Andric                                                const MCDisassembler *Decoder) {
3140b57cec5SDimitry Andric   return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
3150b57cec5SDimitry Andric }
3160b57cec5SDimitry Andric 
3170b57cec5SDimitry Andric static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
3180b57cec5SDimitry Andric                                          uint64_t Address,
31981ad6265SDimitry Andric                                          const MCDisassembler *Decoder) {
3200b57cec5SDimitry Andric   return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric #include "SystemZGenDisassemblerTables.inc"
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
3260b57cec5SDimitry Andric                                                  ArrayRef<uint8_t> Bytes,
3270b57cec5SDimitry Andric                                                  uint64_t Address,
3280b57cec5SDimitry Andric                                                  raw_ostream &CS) const {
3290b57cec5SDimitry Andric   // Get the first two bytes of the instruction.
3300b57cec5SDimitry Andric   Size = 0;
3310b57cec5SDimitry Andric   if (Bytes.size() < 2)
3320b57cec5SDimitry Andric     return MCDisassembler::Fail;
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric   // The top 2 bits of the first byte specify the size.
3350b57cec5SDimitry Andric   const uint8_t *Table;
3360b57cec5SDimitry Andric   if (Bytes[0] < 0x40) {
3370b57cec5SDimitry Andric     Size = 2;
3380b57cec5SDimitry Andric     Table = DecoderTable16;
3390b57cec5SDimitry Andric   } else if (Bytes[0] < 0xc0) {
3400b57cec5SDimitry Andric     Size = 4;
3410b57cec5SDimitry Andric     Table = DecoderTable32;
3420b57cec5SDimitry Andric   } else {
3430b57cec5SDimitry Andric     Size = 6;
3440b57cec5SDimitry Andric     Table = DecoderTable48;
3450b57cec5SDimitry Andric   }
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   // Read any remaining bytes.
348e8d8bef9SDimitry Andric   if (Bytes.size() < Size) {
349e8d8bef9SDimitry Andric     Size = Bytes.size();
3500b57cec5SDimitry Andric     return MCDisassembler::Fail;
351e8d8bef9SDimitry Andric   }
3520b57cec5SDimitry Andric 
3530b57cec5SDimitry Andric   // Construct the instruction.
3540b57cec5SDimitry Andric   uint64_t Inst = 0;
3550b57cec5SDimitry Andric   for (uint64_t I = 0; I < Size; ++I)
3560b57cec5SDimitry Andric     Inst = (Inst << 8) | Bytes[I];
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   return decodeInstruction(Table, MI, Inst, Address, this, STI);
3590b57cec5SDimitry Andric }
360