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" 163943d2b0SEugene Zelenko #include "llvm/Support/MathExtras.h" 17eb9af294SRichard Sandiford #include "llvm/Support/TargetRegistry.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, 766e648ea5SUlrich Weigand const void *Decoder) { 776e648ea5SUlrich Weigand const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder); 786e648ea5SUlrich Weigand return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch, 796e648ea5SUlrich Weigand Offset, Width); 806e648ea5SUlrich Weigand } 816e648ea5SUlrich Weigand 82eb9af294SRichard Sandiford static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 83a8b04e1cSUlrich Weigand const unsigned *Regs, unsigned Size) { 84a8b04e1cSUlrich Weigand assert(RegNo < Size && "Invalid register"); 85eb9af294SRichard Sandiford RegNo = Regs[RegNo]; 86eb9af294SRichard Sandiford if (RegNo == 0) 87eb9af294SRichard Sandiford return MCDisassembler::Fail; 88e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(RegNo)); 89eb9af294SRichard Sandiford return MCDisassembler::Success; 90eb9af294SRichard Sandiford } 91eb9af294SRichard Sandiford 92eb9af294SRichard Sandiford static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 93eb9af294SRichard Sandiford uint64_t Address, 94eb9af294SRichard Sandiford const void *Decoder) { 95a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16); 96eb9af294SRichard Sandiford } 97eb9af294SRichard Sandiford 98f9496060SRichard Sandiford static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 99f9496060SRichard Sandiford uint64_t Address, 100f9496060SRichard Sandiford const void *Decoder) { 101a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16); 102f9496060SRichard Sandiford } 103f9496060SRichard Sandiford 104eb9af294SRichard Sandiford static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 105eb9af294SRichard Sandiford uint64_t Address, 106eb9af294SRichard Sandiford const void *Decoder) { 107a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 108eb9af294SRichard Sandiford } 109eb9af294SRichard Sandiford 110eb9af294SRichard Sandiford static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 111eb9af294SRichard Sandiford uint64_t Address, 112eb9af294SRichard Sandiford const void *Decoder) { 113a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16); 114eb9af294SRichard Sandiford } 115eb9af294SRichard Sandiford 116eb9af294SRichard Sandiford static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 117eb9af294SRichard Sandiford uint64_t Address, 118eb9af294SRichard Sandiford const void *Decoder) { 119a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16); 120eb9af294SRichard Sandiford } 121eb9af294SRichard Sandiford 122eb9af294SRichard Sandiford static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 123eb9af294SRichard Sandiford uint64_t Address, 124eb9af294SRichard Sandiford const void *Decoder) { 125a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16); 126eb9af294SRichard Sandiford } 127eb9af294SRichard Sandiford 128eb9af294SRichard Sandiford static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 129eb9af294SRichard Sandiford uint64_t Address, 130eb9af294SRichard Sandiford const void *Decoder) { 131a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16); 132eb9af294SRichard Sandiford } 133eb9af294SRichard Sandiford 134eb9af294SRichard Sandiford static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 135eb9af294SRichard Sandiford uint64_t Address, 136eb9af294SRichard Sandiford const void *Decoder) { 137a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16); 138a8b04e1cSUlrich Weigand } 139a8b04e1cSUlrich Weigand 140a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 141a8b04e1cSUlrich Weigand uint64_t Address, 142a8b04e1cSUlrich Weigand const void *Decoder) { 143a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32); 144a8b04e1cSUlrich Weigand } 145a8b04e1cSUlrich Weigand 146a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 147a8b04e1cSUlrich Weigand uint64_t Address, 148a8b04e1cSUlrich Weigand const void *Decoder) { 149a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32); 150a8b04e1cSUlrich Weigand } 151a8b04e1cSUlrich Weigand 152a8b04e1cSUlrich Weigand static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 153a8b04e1cSUlrich Weigand uint64_t Address, 154a8b04e1cSUlrich Weigand const void *Decoder) { 155a8b04e1cSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32); 156eb9af294SRichard Sandiford } 157eb9af294SRichard Sandiford 158fffc7110SUlrich Weigand static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 159fffc7110SUlrich Weigand uint64_t Address, 160fffc7110SUlrich Weigand const void *Decoder) { 161fffc7110SUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16); 162fffc7110SUlrich Weigand } 163fffc7110SUlrich Weigand 16403ab2e2bSUlrich Weigand static DecodeStatus DecodeCR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 16503ab2e2bSUlrich Weigand uint64_t Address, 16603ab2e2bSUlrich Weigand const void *Decoder) { 16703ab2e2bSUlrich Weigand return decodeRegisterClass(Inst, RegNo, SystemZMC::CR64Regs, 16); 16803ab2e2bSUlrich Weigand } 16903ab2e2bSUlrich Weigand 170eb9af294SRichard Sandiford template<unsigned N> 171eb9af294SRichard Sandiford static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 172a8b04e1cSUlrich Weigand if (!isUInt<N>(Imm)) 173a8b04e1cSUlrich Weigand return MCDisassembler::Fail; 174e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Imm)); 175eb9af294SRichard Sandiford return MCDisassembler::Success; 176eb9af294SRichard Sandiford } 177eb9af294SRichard Sandiford 178eb9af294SRichard Sandiford template<unsigned N> 179eb9af294SRichard Sandiford static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 180a8b04e1cSUlrich Weigand if (!isUInt<N>(Imm)) 181a8b04e1cSUlrich Weigand return MCDisassembler::Fail; 182e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 183eb9af294SRichard Sandiford return MCDisassembler::Success; 184eb9af294SRichard Sandiford } 185eb9af294SRichard Sandiford 186a8b04e1cSUlrich Weigand static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm, 187a8b04e1cSUlrich Weigand uint64_t Address, const void *Decoder) { 188a8b04e1cSUlrich Weigand return decodeUImmOperand<1>(Inst, Imm); 189a8b04e1cSUlrich Weigand } 190a8b04e1cSUlrich Weigand 191a8b04e1cSUlrich Weigand static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm, 192a8b04e1cSUlrich Weigand uint64_t Address, const void *Decoder) { 193a8b04e1cSUlrich Weigand return decodeUImmOperand<2>(Inst, Imm); 194a8b04e1cSUlrich Weigand } 195a8b04e1cSUlrich Weigand 196a8b04e1cSUlrich Weigand static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm, 197a8b04e1cSUlrich Weigand uint64_t Address, const void *Decoder) { 198a8b04e1cSUlrich Weigand return decodeUImmOperand<3>(Inst, Imm); 199a8b04e1cSUlrich Weigand } 200a8b04e1cSUlrich Weigand 201eb9af294SRichard Sandiford static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 202eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 203eb9af294SRichard Sandiford return decodeUImmOperand<4>(Inst, Imm); 204eb9af294SRichard Sandiford } 205eb9af294SRichard Sandiford 206eb9af294SRichard Sandiford static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 207eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 208eb9af294SRichard Sandiford return decodeUImmOperand<6>(Inst, Imm); 209eb9af294SRichard Sandiford } 210eb9af294SRichard Sandiford 211eb9af294SRichard Sandiford static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 212eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 213eb9af294SRichard Sandiford return decodeUImmOperand<8>(Inst, Imm); 214eb9af294SRichard Sandiford } 215eb9af294SRichard Sandiford 216a8b04e1cSUlrich Weigand static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm, 217a8b04e1cSUlrich Weigand uint64_t Address, const void *Decoder) { 218a8b04e1cSUlrich Weigand return decodeUImmOperand<12>(Inst, Imm); 219a8b04e1cSUlrich Weigand } 220a8b04e1cSUlrich Weigand 221eb9af294SRichard Sandiford static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 222eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 223eb9af294SRichard Sandiford return decodeUImmOperand<16>(Inst, Imm); 224eb9af294SRichard Sandiford } 225eb9af294SRichard Sandiford 226eb9af294SRichard Sandiford static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 227eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 228eb9af294SRichard Sandiford return decodeUImmOperand<32>(Inst, Imm); 229eb9af294SRichard Sandiford } 230eb9af294SRichard Sandiford 231eb9af294SRichard Sandiford static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 232eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 233eb9af294SRichard Sandiford return decodeSImmOperand<8>(Inst, Imm); 234eb9af294SRichard Sandiford } 235eb9af294SRichard Sandiford 236eb9af294SRichard Sandiford static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 237eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 238eb9af294SRichard Sandiford return decodeSImmOperand<16>(Inst, Imm); 239eb9af294SRichard Sandiford } 240eb9af294SRichard Sandiford 241eb9af294SRichard Sandiford static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 242eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 243eb9af294SRichard Sandiford return decodeSImmOperand<32>(Inst, Imm); 244eb9af294SRichard Sandiford } 245eb9af294SRichard Sandiford 246eb9af294SRichard Sandiford template<unsigned N> 247eb9af294SRichard Sandiford static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 2486e648ea5SUlrich Weigand uint64_t Address, 2496e648ea5SUlrich Weigand bool isBranch, 2506e648ea5SUlrich Weigand const void *Decoder) { 251eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 2526e648ea5SUlrich Weigand uint64_t Value = SignExtend64<N>(Imm) * 2 + Address; 2536e648ea5SUlrich Weigand 2546e648ea5SUlrich Weigand if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8, 2556e648ea5SUlrich Weigand Inst, Decoder)) 2566e648ea5SUlrich Weigand Inst.addOperand(MCOperand::createImm(Value)); 2576e648ea5SUlrich Weigand 258eb9af294SRichard Sandiford return MCDisassembler::Success; 259eb9af294SRichard Sandiford } 260eb9af294SRichard Sandiford 26184404f30SUlrich Weigand static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm, 26284404f30SUlrich Weigand uint64_t Address, 26384404f30SUlrich Weigand const void *Decoder) { 26484404f30SUlrich Weigand return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder); 26584404f30SUlrich Weigand } 26684404f30SUlrich Weigand 2676e648ea5SUlrich Weigand static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm, 268eb9af294SRichard Sandiford uint64_t Address, 269eb9af294SRichard Sandiford const void *Decoder) { 2706e648ea5SUlrich Weigand return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder); 2716e648ea5SUlrich Weigand } 2726e648ea5SUlrich Weigand 27384404f30SUlrich Weigand static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm, 27484404f30SUlrich Weigand uint64_t Address, 27584404f30SUlrich Weigand const void *Decoder) { 27684404f30SUlrich Weigand return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder); 27784404f30SUlrich Weigand } 27884404f30SUlrich Weigand 2796e648ea5SUlrich Weigand static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm, 2806e648ea5SUlrich Weigand uint64_t Address, 2816e648ea5SUlrich Weigand const void *Decoder) { 2826e648ea5SUlrich Weigand return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder); 283eb9af294SRichard Sandiford } 284eb9af294SRichard Sandiford 285eb9af294SRichard Sandiford static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 286eb9af294SRichard Sandiford uint64_t Address, 287eb9af294SRichard Sandiford const void *Decoder) { 2886e648ea5SUlrich Weigand return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder); 289eb9af294SRichard Sandiford } 290eb9af294SRichard Sandiford 291eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 292eb9af294SRichard Sandiford const unsigned *Regs) { 293eb9af294SRichard Sandiford uint64_t Base = Field >> 12; 294eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff; 295eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr12"); 296e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 297e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp)); 298eb9af294SRichard Sandiford return MCDisassembler::Success; 299eb9af294SRichard Sandiford } 300eb9af294SRichard Sandiford 301eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 302eb9af294SRichard Sandiford const unsigned *Regs) { 303eb9af294SRichard Sandiford uint64_t Base = Field >> 20; 304eb9af294SRichard Sandiford uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 305eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr20"); 306e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 307e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 308eb9af294SRichard Sandiford return MCDisassembler::Success; 309eb9af294SRichard Sandiford } 310eb9af294SRichard Sandiford 311eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 312eb9af294SRichard Sandiford const unsigned *Regs) { 313eb9af294SRichard Sandiford uint64_t Index = Field >> 16; 314eb9af294SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf; 315eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff; 316eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr12"); 317e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 318e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp)); 319e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 320eb9af294SRichard Sandiford return MCDisassembler::Success; 321eb9af294SRichard Sandiford } 322eb9af294SRichard Sandiford 323eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 324eb9af294SRichard Sandiford const unsigned *Regs) { 325eb9af294SRichard Sandiford uint64_t Index = Field >> 24; 326eb9af294SRichard Sandiford uint64_t Base = (Field >> 20) & 0xf; 327eb9af294SRichard Sandiford uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 328eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr20"); 329e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 330e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp))); 331e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index])); 332eb9af294SRichard Sandiford return MCDisassembler::Success; 333eb9af294SRichard Sandiford } 334eb9af294SRichard Sandiford 335c7eb5a95SUlrich Weigand static DecodeStatus decodeBDLAddr12Len4Operand(MCInst &Inst, uint64_t Field, 336c7eb5a95SUlrich Weigand const unsigned *Regs) { 337c7eb5a95SUlrich Weigand uint64_t Length = Field >> 16; 338c7eb5a95SUlrich Weigand uint64_t Base = (Field >> 12) & 0xf; 339c7eb5a95SUlrich Weigand uint64_t Disp = Field & 0xfff; 340c7eb5a95SUlrich Weigand assert(Length < 16 && "Invalid BDLAddr12Len4"); 341c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 342c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createImm(Disp)); 343c7eb5a95SUlrich Weigand Inst.addOperand(MCOperand::createImm(Length + 1)); 344c7eb5a95SUlrich Weigand return MCDisassembler::Success; 345c7eb5a95SUlrich Weigand } 346c7eb5a95SUlrich Weigand 3471d959008SRichard Sandiford static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, 3481d959008SRichard Sandiford const unsigned *Regs) { 3491d959008SRichard Sandiford uint64_t Length = Field >> 16; 3501d959008SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf; 3511d959008SRichard Sandiford uint64_t Disp = Field & 0xfff; 3521d959008SRichard Sandiford assert(Length < 256 && "Invalid BDLAddr12Len8"); 353e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 354e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp)); 355e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Length + 1)); 3561d959008SRichard Sandiford return MCDisassembler::Success; 3571d959008SRichard Sandiford } 3581d959008SRichard Sandiford 359ec5d779eSUlrich Weigand static DecodeStatus decodeBDRAddr12Operand(MCInst &Inst, uint64_t Field, 360ec5d779eSUlrich Weigand const unsigned *Regs) { 361ec5d779eSUlrich Weigand uint64_t Length = Field >> 16; 362ec5d779eSUlrich Weigand uint64_t Base = (Field >> 12) & 0xf; 363ec5d779eSUlrich Weigand uint64_t Disp = Field & 0xfff; 364ec5d779eSUlrich Weigand assert(Length < 16 && "Invalid BDRAddr12"); 365ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 366ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createImm(Disp)); 367ec5d779eSUlrich Weigand Inst.addOperand(MCOperand::createReg(Regs[Length])); 368ec5d779eSUlrich Weigand return MCDisassembler::Success; 369ec5d779eSUlrich Weigand } 370ec5d779eSUlrich Weigand 371a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field, 372a8b04e1cSUlrich Weigand const unsigned *Regs) { 373a8b04e1cSUlrich Weigand uint64_t Index = Field >> 16; 374a8b04e1cSUlrich Weigand uint64_t Base = (Field >> 12) & 0xf; 375a8b04e1cSUlrich Weigand uint64_t Disp = Field & 0xfff; 376a8b04e1cSUlrich Weigand assert(Index < 32 && "Invalid BDVAddr12"); 377e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base])); 378e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Disp)); 379e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index])); 380a8b04e1cSUlrich Weigand return MCDisassembler::Success; 381a8b04e1cSUlrich Weigand } 382a8b04e1cSUlrich Weigand 383eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 384eb9af294SRichard Sandiford uint64_t Address, 385eb9af294SRichard Sandiford const void *Decoder) { 386eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 387eb9af294SRichard Sandiford } 388eb9af294SRichard Sandiford 389eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 390eb9af294SRichard Sandiford uint64_t Address, 391eb9af294SRichard Sandiford const void *Decoder) { 392eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 393eb9af294SRichard Sandiford } 394eb9af294SRichard Sandiford 395eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 396eb9af294SRichard Sandiford uint64_t Address, 397eb9af294SRichard Sandiford const void *Decoder) { 398eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 399eb9af294SRichard Sandiford } 400eb9af294SRichard Sandiford 401eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 402eb9af294SRichard Sandiford uint64_t Address, 403eb9af294SRichard Sandiford const void *Decoder) { 404eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 405eb9af294SRichard Sandiford } 406eb9af294SRichard Sandiford 407eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 408eb9af294SRichard Sandiford uint64_t Address, 409eb9af294SRichard Sandiford const void *Decoder) { 410eb9af294SRichard Sandiford return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 411eb9af294SRichard Sandiford } 412eb9af294SRichard Sandiford 413eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 414eb9af294SRichard Sandiford uint64_t Address, 415eb9af294SRichard Sandiford const void *Decoder) { 416eb9af294SRichard Sandiford return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 417eb9af294SRichard Sandiford } 418eb9af294SRichard Sandiford 419c7eb5a95SUlrich Weigand static DecodeStatus decodeBDLAddr64Disp12Len4Operand(MCInst &Inst, 420c7eb5a95SUlrich Weigand uint64_t Field, 421c7eb5a95SUlrich Weigand uint64_t Address, 422c7eb5a95SUlrich Weigand const void *Decoder) { 423c7eb5a95SUlrich Weigand return decodeBDLAddr12Len4Operand(Inst, Field, SystemZMC::GR64Regs); 424c7eb5a95SUlrich Weigand } 425c7eb5a95SUlrich Weigand 4261d959008SRichard Sandiford static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, 4271d959008SRichard Sandiford uint64_t Field, 4281d959008SRichard Sandiford uint64_t Address, 4291d959008SRichard Sandiford const void *Decoder) { 4301d959008SRichard Sandiford return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs); 4311d959008SRichard Sandiford } 4321d959008SRichard Sandiford 433ec5d779eSUlrich Weigand static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst &Inst, 434ec5d779eSUlrich Weigand uint64_t Field, 435ec5d779eSUlrich Weigand uint64_t Address, 436ec5d779eSUlrich Weigand const void *Decoder) { 437ec5d779eSUlrich Weigand return decodeBDRAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 438ec5d779eSUlrich Weigand } 439ec5d779eSUlrich Weigand 440a8b04e1cSUlrich Weigand static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 441a8b04e1cSUlrich Weigand uint64_t Address, 442a8b04e1cSUlrich Weigand const void *Decoder) { 443a8b04e1cSUlrich Weigand return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 444a8b04e1cSUlrich Weigand } 445a8b04e1cSUlrich Weigand 446eb9af294SRichard Sandiford #include "SystemZGenDisassemblerTables.inc" 447eb9af294SRichard Sandiford 448eb9af294SRichard Sandiford DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 4497fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 450eb9af294SRichard Sandiford uint64_t Address, 4514aa6bea7SRafael Espindola raw_ostream &CS) const { 452eb9af294SRichard Sandiford // Get the first two bytes of the instruction. 453eb9af294SRichard Sandiford Size = 0; 4547fc5b874SRafael Espindola if (Bytes.size() < 2) 455eb9af294SRichard Sandiford return MCDisassembler::Fail; 456eb9af294SRichard Sandiford 457eb9af294SRichard Sandiford // The top 2 bits of the first byte specify the size. 458eb9af294SRichard Sandiford const uint8_t *Table; 459eb9af294SRichard Sandiford if (Bytes[0] < 0x40) { 460eb9af294SRichard Sandiford Size = 2; 461eb9af294SRichard Sandiford Table = DecoderTable16; 462eb9af294SRichard Sandiford } else if (Bytes[0] < 0xc0) { 463eb9af294SRichard Sandiford Size = 4; 464eb9af294SRichard Sandiford Table = DecoderTable32; 465eb9af294SRichard Sandiford } else { 466eb9af294SRichard Sandiford Size = 6; 467eb9af294SRichard Sandiford Table = DecoderTable48; 468eb9af294SRichard Sandiford } 469eb9af294SRichard Sandiford 470eb9af294SRichard Sandiford // Read any remaining bytes. 471*c299f355SUlrich Weigand if (Bytes.size() < Size) { 472*c299f355SUlrich Weigand Size = Bytes.size(); 473eb9af294SRichard Sandiford return MCDisassembler::Fail; 474*c299f355SUlrich Weigand } 475eb9af294SRichard Sandiford 476eb9af294SRichard Sandiford // Construct the instruction. 477eb9af294SRichard Sandiford uint64_t Inst = 0; 478eb9af294SRichard Sandiford for (uint64_t I = 0; I < Size; ++I) 479eb9af294SRichard Sandiford Inst = (Inst << 8) | Bytes[I]; 480eb9af294SRichard Sandiford 481eb9af294SRichard Sandiford return decodeInstruction(Table, MI, Inst, Address, this, STI); 482eb9af294SRichard Sandiford } 483