1eb9af294SRichard Sandiford //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===// 2eb9af294SRichard Sandiford // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6eb9af294SRichard Sandiford // 7eb9af294SRichard Sandiford //===----------------------------------------------------------------------===// 8eb9af294SRichard Sandiford 93943d2b0SEugene Zelenko #include "MCTargetDesc/SystemZMCTargetDesc.h" 10eb9af294SRichard Sandiford #include "SystemZ.h" 111e6f98b8SRichard Trieu #include "TargetInfo/SystemZTargetInfo.h" 12f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/MCDisassembler.h" 13eb9af294SRichard Sandiford #include "llvm/MC/MCFixedLenDisassembler.h" 14eb9af294SRichard Sandiford #include "llvm/MC/MCInst.h" 15eb9af294SRichard Sandiford #include "llvm/MC/MCSubtargetInfo.h" 1689b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h" 173943d2b0SEugene Zelenko #include "llvm/Support/MathExtras.h" 183943d2b0SEugene Zelenko #include <cassert> 193943d2b0SEugene Zelenko #include <cstdint> 20eb9af294SRichard Sandiford 21eb9af294SRichard Sandiford using namespace llvm; 22eb9af294SRichard Sandiford 23e96dd897SChandler Carruth #define DEBUG_TYPE "systemz-disassembler" 24e96dd897SChandler Carruth 25eb9af294SRichard Sandiford typedef MCDisassembler::DecodeStatus DecodeStatus; 26eb9af294SRichard Sandiford 27eb9af294SRichard Sandiford namespace { 283943d2b0SEugene Zelenko 29eb9af294SRichard Sandiford class SystemZDisassembler : public MCDisassembler { 30eb9af294SRichard Sandiford public: 31a1bc0f56SLang Hames SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 32a1bc0f56SLang Hames : MCDisassembler(STI, Ctx) {} 333943d2b0SEugene Zelenko ~SystemZDisassembler() override = default; 34eb9af294SRichard Sandiford 357fc5b874SRafael Espindola DecodeStatus getInstruction(MCInst &instr, uint64_t &Size, 367fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 374aa6bea7SRafael Espindola raw_ostream &CStream) const override; 38eb9af294SRichard Sandiford }; 393943d2b0SEugene Zelenko 40eb9af294SRichard Sandiford } // end anonymous namespace 41eb9af294SRichard Sandiford 42eb9af294SRichard Sandiford static MCDisassembler *createSystemZDisassembler(const Target &T, 43a1bc0f56SLang Hames const MCSubtargetInfo &STI, 44a1bc0f56SLang Hames MCContext &Ctx) { 45a1bc0f56SLang Hames return new SystemZDisassembler(STI, Ctx); 46eb9af294SRichard Sandiford } 47eb9af294SRichard Sandiford 480dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZDisassembler() { 49eb9af294SRichard Sandiford // Register the disassembler. 50f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(), 51eb9af294SRichard Sandiford createSystemZDisassembler); 52eb9af294SRichard Sandiford } 53eb9af294SRichard Sandiford 546e648ea5SUlrich Weigand /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the 556e648ea5SUlrich Weigand /// immediate Value in the MCInst. 566e648ea5SUlrich Weigand /// 576e648ea5SUlrich Weigand /// @param Value - The immediate Value, has had any PC adjustment made by 586e648ea5SUlrich Weigand /// the caller. 596e648ea5SUlrich Weigand /// @param isBranch - If the instruction is a branch instruction 606e648ea5SUlrich Weigand /// @param Address - The starting address of the instruction 616e648ea5SUlrich Weigand /// @param Offset - The byte offset to this immediate in the instruction 626e648ea5SUlrich Weigand /// @param Width - The byte width of this immediate in the instruction 636e648ea5SUlrich Weigand /// 646e648ea5SUlrich Weigand /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was 656e648ea5SUlrich Weigand /// called then that function is called to get any symbolic information for the 666e648ea5SUlrich Weigand /// immediate in the instruction using the Address, Offset and Width. If that 676e648ea5SUlrich Weigand /// returns non-zero then the symbolic information it returns is used to create 686e648ea5SUlrich Weigand /// an MCExpr and that is added as an operand to the MCInst. If getOpInfo() 696e648ea5SUlrich Weigand /// returns zero and isBranch is true then a symbol look up for immediate Value 706e648ea5SUlrich Weigand /// is done and if a symbol is found an MCExpr is created with that, else 716e648ea5SUlrich Weigand /// an MCExpr with the immediate Value is created. This function returns true 726e648ea5SUlrich Weigand /// if it adds an operand to the MCInst and false otherwise. 736e648ea5SUlrich Weigand static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch, 746e648ea5SUlrich Weigand uint64_t Address, uint64_t Offset, 756e648ea5SUlrich Weigand uint64_t Width, MCInst &MI, 76*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 77*4ae9745aSMaksim Panchenko return Decoder->tryAddingSymbolicOperand(MI, Value, Address, isBranch, Offset, 78*4ae9745aSMaksim Panchenko Width); 796e648ea5SUlrich Weigand } 806e648ea5SUlrich Weigand 81eb9af294SRichard Sandiford static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 82a8b04e1cSUlrich Weigand const unsigned *Regs, unsigned Size) { 83a8b04e1cSUlrich Weigand assert(RegNo < Size && "Invalid register"); 84eb9af294SRichard Sandiford RegNo = Regs[RegNo]; 85eb9af294SRichard Sandiford if (RegNo == 0) 86eb9af294SRichard Sandiford return MCDisassembler::Fail; 87e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(RegNo)); 88eb9af294SRichard Sandiford return MCDisassembler::Success; 89eb9af294SRichard Sandiford } 90eb9af294SRichard Sandiford 91eb9af294SRichard Sandiford static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 92eb9af294SRichard Sandiford uint64_t Address, 93*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 94a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16); 95eb9af294SRichard Sandiford } 96eb9af294SRichard Sandiford 97f9496060SRichard Sandiford static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 98f9496060SRichard Sandiford uint64_t Address, 99*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 100a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16); 101f9496060SRichard Sandiford } 102f9496060SRichard Sandiford 103eb9af294SRichard Sandiford static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 104eb9af294SRichard Sandiford uint64_t Address, 105*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 106a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 107eb9af294SRichard Sandiford } 108eb9af294SRichard Sandiford 109eb9af294SRichard Sandiford static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 110eb9af294SRichard Sandiford uint64_t Address, 111*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 112a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16); 113eb9af294SRichard Sandiford } 114eb9af294SRichard Sandiford 115*4ae9745aSMaksim Panchenko static DecodeStatus 116*4ae9745aSMaksim Panchenko DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 117*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 118a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 119eb9af294SRichard Sandiford } 120eb9af294SRichard Sandiford 121eb9af294SRichard Sandiford static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 122eb9af294SRichard Sandiford uint64_t Address, 123*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 124a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16); 125eb9af294SRichard Sandiford } 126eb9af294SRichard Sandiford 127eb9af294SRichard Sandiford static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 128eb9af294SRichard Sandiford uint64_t Address, 129*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 130a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16); 131eb9af294SRichard Sandiford } 132eb9af294SRichard Sandiford 133eb9af294SRichard Sandiford static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 134eb9af294SRichard Sandiford uint64_t Address, 135*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 136a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16); 137a8b04e1cSUlrich Weigand } 138a8b04e1cSUlrich Weigand 139a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 140a8b04e1cSUlrich Weigand uint64_t Address, 141*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 142a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32); 143a8b04e1cSUlrich Weigand } 144a8b04e1cSUlrich Weigand 145a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 146a8b04e1cSUlrich Weigand uint64_t Address, 147*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 148a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32); 149a8b04e1cSUlrich Weigand } 150a8b04e1cSUlrich Weigand 151a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 152a8b04e1cSUlrich Weigand uint64_t Address, 153*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 154a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32); 155eb9af294SRichard Sandiford } 156eb9af294SRichard Sandiford 157fffc7110SUlrich Weigand static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 158fffc7110SUlrich Weigand uint64_t Address, 159*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 160fffc7110SUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16); 161fffc7110SUlrich Weigand } 162fffc7110SUlrich Weigand 16303ab2e2bSUlrich Weigand static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 16403ab2e2bSUlrich Weigand uint64_t Address, 165*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 16603ab2e2bSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16); 16703ab2e2bSUlrich Weigand } 16803ab2e2bSUlrich Weigand 169eb9af294SRichard Sandiford template<unsigned N> 170eb9af294SRichard Sandiford static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 171a8b04e1cSUlrich Weigand if (!isUInt<N>(Imm)) 172a8b04e1cSUlrich Weigand return MCDisassembler::Fail; 173e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Imm)); 174eb9af294SRichard Sandiford return MCDisassembler::Success; 175eb9af294SRichard Sandiford } 176eb9af294SRichard Sandiford 177eb9af294SRichard Sandiford template<unsigned N> 178eb9af294SRichard Sandiford static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 179a8b04e1cSUlrich Weigand if (!isUInt<N>(Imm)) 180a8b04e1cSUlrich Weigand return MCDisassembler::Fail; 181e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 182eb9af294SRichard Sandiford return MCDisassembler::Success; 183eb9af294SRichard Sandiford } 184eb9af294SRichard Sandiford 185a8b04e1cSUlrich Weigand static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, 186*4ae9745aSMaksim Panchenko uint64_t Address, 187*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 188a8b04e1cSUlrich Weigand return decodeUImmOperand<1>(Inst, Imm); 189a8b04e1cSUlrich Weigand } 190a8b04e1cSUlrich Weigand 191a8b04e1cSUlrich Weigand static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, 192*4ae9745aSMaksim Panchenko uint64_t Address, 193*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 194a8b04e1cSUlrich Weigand return decodeUImmOperand<2>(Inst, Imm); 195a8b04e1cSUlrich Weigand } 196a8b04e1cSUlrich Weigand 197a8b04e1cSUlrich Weigand static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, 198*4ae9745aSMaksim Panchenko uint64_t Address, 199*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 200a8b04e1cSUlrich Weigand return decodeUImmOperand<3>(Inst, Imm); 201a8b04e1cSUlrich Weigand } 202a8b04e1cSUlrich Weigand 203eb9af294SRichard Sandiford static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 204*4ae9745aSMaksim Panchenko uint64_t Address, 205*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 206eb9af294SRichard Sandiford return decodeUImmOperand<4>(Inst, Imm); 207eb9af294SRichard Sandiford } 208eb9af294SRichard Sandiford 209eb9af294SRichard Sandiford static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 210*4ae9745aSMaksim Panchenko uint64_t Address, 211*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 212eb9af294SRichard Sandiford return decodeUImmOperand<6>(Inst, Imm); 213eb9af294SRichard Sandiford } 214eb9af294SRichard Sandiford 215eb9af294SRichard Sandiford static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 216*4ae9745aSMaksim Panchenko uint64_t Address, 217*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 218eb9af294SRichard Sandiford return decodeUImmOperand<8>(Inst, Imm); 219eb9af294SRichard Sandiford } 220eb9af294SRichard Sandiford 221a8b04e1cSUlrich Weigand static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, 222*4ae9745aSMaksim Panchenko uint64_t Address, 223*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 224a8b04e1cSUlrich Weigand return decodeUImmOperand<12>(Inst, Imm); 225a8b04e1cSUlrich Weigand } 226a8b04e1cSUlrich Weigand 227eb9af294SRichard Sandiford static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 228*4ae9745aSMaksim Panchenko uint64_t Address, 229*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 230eb9af294SRichard Sandiford return decodeUImmOperand<16>(Inst, Imm); 231eb9af294SRichard Sandiford } 232eb9af294SRichard Sandiford 233eb9af294SRichard Sandiford static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 234*4ae9745aSMaksim Panchenko uint64_t Address, 235*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 236eb9af294SRichard Sandiford return decodeUImmOperand<32>(Inst, Imm); 237eb9af294SRichard Sandiford } 238eb9af294SRichard Sandiford 239eb9af294SRichard Sandiford static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 240*4ae9745aSMaksim Panchenko uint64_t Address, 241*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 242eb9af294SRichard Sandiford return decodeSImmOperand<8>(Inst, Imm); 243eb9af294SRichard Sandiford } 244eb9af294SRichard Sandiford 245eb9af294SRichard Sandiford static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 246*4ae9745aSMaksim Panchenko uint64_t Address, 247*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 248eb9af294SRichard Sandiford return decodeSImmOperand<16>(Inst, Imm); 249eb9af294SRichard Sandiford } 250eb9af294SRichard Sandiford 251eb9af294SRichard Sandiford static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 252*4ae9745aSMaksim Panchenko uint64_t Address, 253*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 254eb9af294SRichard Sandiford return decodeSImmOperand<32>(Inst, Imm); 255eb9af294SRichard Sandiford } 256eb9af294SRichard Sandiford 257eb9af294SRichard Sandiford template <unsigned N> 258eb9af294SRichard Sandiford static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 259*4ae9745aSMaksim Panchenko uint64_t Address, bool isBranch, 260*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 261eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 2626e648ea5SUlrich Weigand uint64_t Value = SignExtend64<N>(Imm) * 2 + Address; 2636e648ea5SUlrich Weigand 2646e648ea5SUlrich Weigand if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8, 2656e648ea5SUlrich Weigand Inst, Decoder)) 2666e648ea5SUlrich Weigand Inst.addOperand(MCOperand::createImm(Value)); 2676e648ea5SUlrich Weigand 268eb9af294SRichard Sandiford return MCDisassembler::Success; 269eb9af294SRichard Sandiford } 270eb9af294SRichard Sandiford 27184404f30SUlrich Weigand static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm, 27284404f30SUlrich Weigand uint64_t Address, 273*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 27484404f30SUlrich Weigand return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder); 27584404f30SUlrich Weigand } 27684404f30SUlrich Weigand 2776e648ea5SUlrich Weigand static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm, 278eb9af294SRichard Sandiford uint64_t Address, 279*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 2806e648ea5SUlrich Weigand return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder); 2816e648ea5SUlrich Weigand } 2826e648ea5SUlrich Weigand 28384404f30SUlrich Weigand static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm, 28484404f30SUlrich Weigand uint64_t Address, 285*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 28684404f30SUlrich Weigand return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder); 28784404f30SUlrich Weigand } 28884404f30SUlrich Weigand 2896e648ea5SUlrich Weigand static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm, 2906e648ea5SUlrich Weigand uint64_t Address, 291*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 2926e648ea5SUlrich Weigand return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder); 293eb9af294SRichard Sandiford } 294eb9af294SRichard Sandiford 295eb9af294SRichard Sandiford static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 296eb9af294SRichard Sandiford uint64_t Address, 297*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 2986e648ea5SUlrich Weigand return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder); 299eb9af294SRichard Sandiford } 300eb9af294SRichard Sandiford 301eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 302eb9af294SRichard Sandiford const unsigned *Regs) { 303eb9af294SRichard Sandiford uint64_t Base = Field >> 12; 304eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff; 305eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr12"); 306e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 307e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp)); 308eb9af294SRichard Sandiford return MCDisassembler::Success; 309eb9af294SRichard Sandiford } 310eb9af294SRichard Sandiford 311eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 312eb9af294SRichard Sandiford const unsigned *Regs) { 313eb9af294SRichard Sandiford uint64_t Base = Field >> 20; 314eb9af294SRichard Sandiford uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 315eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr20"); 316e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 317e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 318eb9af294SRichard Sandiford return MCDisassembler::Success; 319eb9af294SRichard Sandiford } 320eb9af294SRichard Sandiford 321eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 322eb9af294SRichard Sandiford const unsigned *Regs) { 323eb9af294SRichard Sandiford uint64_t Index = Field >> 16; 324eb9af294SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf; 325eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff; 326eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr12"); 327e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 328e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp)); 329e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 330eb9af294SRichard Sandiford return MCDisassembler::Success; 331eb9af294SRichard Sandiford } 332eb9af294SRichard Sandiford 333eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 334eb9af294SRichard Sandiford const unsigned *Regs) { 335eb9af294SRichard Sandiford uint64_t Index = Field >> 24; 336eb9af294SRichard Sandiford uint64_t Base = (Field >> 20) & 0xf; 337eb9af294SRichard Sandiford uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 338eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr20"); 339e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 340e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 341e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 342eb9af294SRichard Sandiford return MCDisassembler::Success; 343eb9af294SRichard Sandiford } 344eb9af294SRichard Sandiford 345c7eb5a95SUlrich Weigand static DecodeStatus decodeBDLAddr12Len4Operand(MCInst &Inst, uint64_t Field, 346c7eb5a95SUlrich Weigand const unsigned *Regs) { 347c7eb5a95SUlrich Weigand uint64_t Length = Field >> 16; 348c7eb5a95SUlrich Weigand uint64_t Base = (Field >> 12) & 0xf; 349c7eb5a95SUlrich Weigand uint64_t Disp = Field & 0xfff; 350c7eb5a95SUlrich Weigand assert(Length < 16 && "Invalid BDLAddr12Len4"); 351c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 352c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createImm(Disp)); 353c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createImm(Length + 1)); 354c7eb5a95SUlrich Weigand return MCDisassembler::Success; 355c7eb5a95SUlrich Weigand } 356c7eb5a95SUlrich Weigand 3571d959008SRichard Sandiford static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, 3581d959008SRichard Sandiford const unsigned *Regs) { 3591d959008SRichard Sandiford uint64_t Length = Field >> 16; 3601d959008SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf; 3611d959008SRichard Sandiford uint64_t Disp = Field & 0xfff; 3621d959008SRichard Sandiford assert(Length < 256 && "Invalid BDLAddr12Len8"); 363e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 364e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp)); 365e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Length + 1)); 3661d959008SRichard Sandiford return MCDisassembler::Success; 3671d959008SRichard Sandiford } 3681d959008SRichard Sandiford 369ec5d779eSUlrich Weigand static DecodeStatus decodeBDRAddr12Operand(MCInst &Inst, uint64_t Field, 370ec5d779eSUlrich Weigand const unsigned *Regs) { 371ec5d779eSUlrich Weigand uint64_t Length = Field >> 16; 372ec5d779eSUlrich Weigand uint64_t Base = (Field >> 12) & 0xf; 373ec5d779eSUlrich Weigand uint64_t Disp = Field & 0xfff; 374ec5d779eSUlrich Weigand assert(Length < 16 && "Invalid BDRAddr12"); 375ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 376ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createImm(Disp)); 377ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createReg(Regs[Length])); 378ec5d779eSUlrich Weigand return MCDisassembler::Success; 379ec5d779eSUlrich Weigand } 380ec5d779eSUlrich Weigand 381a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field, 382a8b04e1cSUlrich Weigand const unsigned *Regs) { 383a8b04e1cSUlrich Weigand uint64_t Index = Field >> 16; 384a8b04e1cSUlrich Weigand uint64_t Base = (Field >> 12) & 0xf; 385a8b04e1cSUlrich Weigand uint64_t Disp = Field & 0xfff; 386a8b04e1cSUlrich Weigand assert(Index < 32 && "Invalid BDVAddr12"); 387e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 388e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp)); 389e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index])); 390a8b04e1cSUlrich Weigand return MCDisassembler::Success; 391a8b04e1cSUlrich Weigand } 392a8b04e1cSUlrich Weigand 393eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 394eb9af294SRichard Sandiford uint64_t Address, 395*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 396eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 397eb9af294SRichard Sandiford } 398eb9af294SRichard Sandiford 399eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 400eb9af294SRichard Sandiford uint64_t Address, 401*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 402eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 403eb9af294SRichard Sandiford } 404eb9af294SRichard Sandiford 405eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 406eb9af294SRichard Sandiford uint64_t Address, 407*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 408eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 409eb9af294SRichard Sandiford } 410eb9af294SRichard Sandiford 411eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 412eb9af294SRichard Sandiford uint64_t Address, 413*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 414eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 415eb9af294SRichard Sandiford } 416eb9af294SRichard Sandiford 417*4ae9745aSMaksim Panchenko static DecodeStatus 418*4ae9745aSMaksim Panchenko decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address, 419*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 420eb9af294SRichard Sandiford return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 421eb9af294SRichard Sandiford } 422eb9af294SRichard Sandiford 423*4ae9745aSMaksim Panchenko static DecodeStatus 424*4ae9745aSMaksim Panchenko decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, uint64_t Address, 425*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 426eb9af294SRichard Sandiford return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 427eb9af294SRichard Sandiford } 428eb9af294SRichard Sandiford 429*4ae9745aSMaksim Panchenko static DecodeStatus 430*4ae9745aSMaksim Panchenko decodeBDLAddr64Disp12Len4Operand(MCInst &Inst, uint64_t Field, uint64_t Address, 431*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 432c7eb5a95SUlrich Weigand return decodeBDLAddr12Len4Operand(Inst, Field, SystemZMC::GR64Regs); 433c7eb5a95SUlrich Weigand } 434c7eb5a95SUlrich Weigand 435*4ae9745aSMaksim Panchenko static DecodeStatus 436*4ae9745aSMaksim Panchenko decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, uint64_t Field, uint64_t Address, 437*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 4381d959008SRichard Sandiford return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs); 4391d959008SRichard Sandiford } 4401d959008SRichard Sandiford 441*4ae9745aSMaksim Panchenko static DecodeStatus 442*4ae9745aSMaksim Panchenko decodeBDRAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address, 443*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 444ec5d779eSUlrich Weigand return decodeBDRAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 445ec5d779eSUlrich Weigand } 446ec5d779eSUlrich Weigand 447*4ae9745aSMaksim Panchenko static DecodeStatus 448*4ae9745aSMaksim Panchenko decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field, uint64_t Address, 449*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 450a8b04e1cSUlrich Weigand return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 451a8b04e1cSUlrich Weigand } 452a8b04e1cSUlrich Weigand 453eb9af294SRichard Sandiford #include "SystemZGenDisassemblerTables.inc" 454eb9af294SRichard Sandiford 455eb9af294SRichard Sandiford DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 4567fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 457eb9af294SRichard Sandiford uint64_t Address, 4584aa6bea7SRafael Espindola raw_ostream &CS) const { 459eb9af294SRichard Sandiford // Get the first two bytes of the instruction. 460eb9af294SRichard Sandiford Size = 0; 4617fc5b874SRafael Espindola if (Bytes.size() < 2) 462eb9af294SRichard Sandiford return MCDisassembler::Fail; 463eb9af294SRichard Sandiford 464eb9af294SRichard Sandiford // The top 2 bits of the first byte specify the size. 465eb9af294SRichard Sandiford const uint8_t *Table; 466eb9af294SRichard Sandiford if (Bytes[0] < 0x40) { 467eb9af294SRichard Sandiford Size = 2; 468eb9af294SRichard Sandiford Table = DecoderTable16; 469eb9af294SRichard Sandiford } else if (Bytes[0] < 0xc0) { 470eb9af294SRichard Sandiford Size = 4; 471eb9af294SRichard Sandiford Table = DecoderTable32; 472eb9af294SRichard Sandiford } else { 473eb9af294SRichard Sandiford Size = 6; 474eb9af294SRichard Sandiford Table = DecoderTable48; 475eb9af294SRichard Sandiford } 476eb9af294SRichard Sandiford 477eb9af294SRichard Sandiford // Read any remaining bytes. 478c299f355SUlrich Weigand if (Bytes.size() < Size) { 479c299f355SUlrich Weigand Size = Bytes.size(); 480eb9af294SRichard Sandiford return MCDisassembler::Fail; 481c299f355SUlrich Weigand } 482eb9af294SRichard Sandiford 483eb9af294SRichard Sandiford // Construct the instruction. 484eb9af294SRichard Sandiford uint64_t Inst = 0; 485eb9af294SRichard Sandiford for (uint64_t I = 0; I < Size; ++I) 486eb9af294SRichard Sandiford Inst = (Inst << 8) | Bytes[I]; 487eb9af294SRichard Sandiford 488eb9af294SRichard Sandiford return decodeInstruction(Table, MI, Inst, Address, this, STI); 489eb9af294SRichard Sandiford } 490