1eb9af294SRichard Sandiford //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===// 2eb9af294SRichard Sandiford // 3eb9af294SRichard Sandiford // The LLVM Compiler Infrastructure 4eb9af294SRichard Sandiford // 5eb9af294SRichard Sandiford // This file is distributed under the University of Illinois Open Source 6eb9af294SRichard Sandiford // License. See LICENSE.TXT for details. 7eb9af294SRichard Sandiford // 8eb9af294SRichard Sandiford //===----------------------------------------------------------------------===// 9eb9af294SRichard Sandiford 10eb9af294SRichard Sandiford #include "SystemZ.h" 11eb9af294SRichard Sandiford #include "llvm/MC/MCDisassembler.h" 12eb9af294SRichard Sandiford #include "llvm/MC/MCFixedLenDisassembler.h" 13eb9af294SRichard Sandiford #include "llvm/MC/MCInst.h" 14eb9af294SRichard Sandiford #include "llvm/MC/MCSubtargetInfo.h" 15eb9af294SRichard Sandiford #include "llvm/Support/TargetRegistry.h" 16eb9af294SRichard Sandiford 17eb9af294SRichard Sandiford using namespace llvm; 18eb9af294SRichard Sandiford 19e96dd897SChandler Carruth #define DEBUG_TYPE "systemz-disassembler" 20e96dd897SChandler Carruth 21eb9af294SRichard Sandiford typedef MCDisassembler::DecodeStatus DecodeStatus; 22eb9af294SRichard Sandiford 23eb9af294SRichard Sandiford namespace { 24eb9af294SRichard Sandiford class SystemZDisassembler : public MCDisassembler { 25eb9af294SRichard Sandiford public: 26a1bc0f56SLang Hames SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) 27a1bc0f56SLang Hames : MCDisassembler(STI, Ctx) {} 28*f817c1cbSAlexander Kornienko ~SystemZDisassembler() override {} 29eb9af294SRichard Sandiford 307fc5b874SRafael Espindola DecodeStatus getInstruction(MCInst &instr, uint64_t &Size, 317fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 324aa6bea7SRafael Espindola raw_ostream &VStream, 334aa6bea7SRafael Espindola raw_ostream &CStream) const override; 34eb9af294SRichard Sandiford }; 35eb9af294SRichard Sandiford } // end anonymous namespace 36eb9af294SRichard Sandiford 37eb9af294SRichard Sandiford static MCDisassembler *createSystemZDisassembler(const Target &T, 38a1bc0f56SLang Hames const MCSubtargetInfo &STI, 39a1bc0f56SLang Hames MCContext &Ctx) { 40a1bc0f56SLang Hames return new SystemZDisassembler(STI, Ctx); 41eb9af294SRichard Sandiford } 42eb9af294SRichard Sandiford 43eb9af294SRichard Sandiford extern "C" void LLVMInitializeSystemZDisassembler() { 44eb9af294SRichard Sandiford // Register the disassembler. 45eb9af294SRichard Sandiford TargetRegistry::RegisterMCDisassembler(TheSystemZTarget, 46eb9af294SRichard Sandiford createSystemZDisassembler); 47eb9af294SRichard Sandiford } 48eb9af294SRichard Sandiford 49eb9af294SRichard Sandiford static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 5009de091cSRichard Sandiford const unsigned *Regs) { 51eb9af294SRichard Sandiford assert(RegNo < 16 && "Invalid register"); 52eb9af294SRichard Sandiford RegNo = Regs[RegNo]; 53eb9af294SRichard Sandiford if (RegNo == 0) 54eb9af294SRichard Sandiford return MCDisassembler::Fail; 55eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(RegNo)); 56eb9af294SRichard Sandiford return MCDisassembler::Success; 57eb9af294SRichard Sandiford } 58eb9af294SRichard Sandiford 59eb9af294SRichard Sandiford static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 60eb9af294SRichard Sandiford uint64_t Address, 61eb9af294SRichard Sandiford const void *Decoder) { 62eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs); 63eb9af294SRichard Sandiford } 64eb9af294SRichard Sandiford 65f9496060SRichard Sandiford static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 66f9496060SRichard Sandiford uint64_t Address, 67f9496060SRichard Sandiford const void *Decoder) { 68f9496060SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs); 69f9496060SRichard Sandiford } 70f9496060SRichard Sandiford 71eb9af294SRichard Sandiford static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 72eb9af294SRichard Sandiford uint64_t Address, 73eb9af294SRichard Sandiford const void *Decoder) { 74eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs); 75eb9af294SRichard Sandiford } 76eb9af294SRichard Sandiford 77eb9af294SRichard Sandiford static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 78eb9af294SRichard Sandiford uint64_t Address, 79eb9af294SRichard Sandiford const void *Decoder) { 80eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs); 81eb9af294SRichard Sandiford } 82eb9af294SRichard Sandiford 83eb9af294SRichard Sandiford static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 84eb9af294SRichard Sandiford uint64_t Address, 85eb9af294SRichard Sandiford const void *Decoder) { 8609de091cSRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs); 87eb9af294SRichard Sandiford } 88eb9af294SRichard Sandiford 89eb9af294SRichard Sandiford static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 90eb9af294SRichard Sandiford uint64_t Address, 91eb9af294SRichard Sandiford const void *Decoder) { 92eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs); 93eb9af294SRichard Sandiford } 94eb9af294SRichard Sandiford 95eb9af294SRichard Sandiford static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 96eb9af294SRichard Sandiford uint64_t Address, 97eb9af294SRichard Sandiford const void *Decoder) { 98eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs); 99eb9af294SRichard Sandiford } 100eb9af294SRichard Sandiford 101eb9af294SRichard Sandiford static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 102eb9af294SRichard Sandiford uint64_t Address, 103eb9af294SRichard Sandiford const void *Decoder) { 104eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs); 105eb9af294SRichard Sandiford } 106eb9af294SRichard Sandiford 107eb9af294SRichard Sandiford template<unsigned N> 108eb9af294SRichard Sandiford static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 109eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid immediate"); 110eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(Imm)); 111eb9af294SRichard Sandiford return MCDisassembler::Success; 112eb9af294SRichard Sandiford } 113eb9af294SRichard Sandiford 114eb9af294SRichard Sandiford template<unsigned N> 115eb9af294SRichard Sandiford static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 116eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid immediate"); 117eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm))); 118eb9af294SRichard Sandiford return MCDisassembler::Success; 119eb9af294SRichard Sandiford } 120eb9af294SRichard Sandiford 121eb9af294SRichard Sandiford static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm, 122eb9af294SRichard Sandiford uint64_t Address, 123eb9af294SRichard Sandiford const void *Decoder) { 124eb9af294SRichard Sandiford return decodeUImmOperand<4>(Inst, Imm); 125eb9af294SRichard Sandiford } 126eb9af294SRichard Sandiford 127eb9af294SRichard Sandiford static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 128eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 129eb9af294SRichard Sandiford return decodeUImmOperand<4>(Inst, Imm); 130eb9af294SRichard Sandiford } 131eb9af294SRichard Sandiford 132eb9af294SRichard Sandiford static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 133eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 134eb9af294SRichard Sandiford return decodeUImmOperand<6>(Inst, Imm); 135eb9af294SRichard Sandiford } 136eb9af294SRichard Sandiford 137eb9af294SRichard Sandiford static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 138eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 139eb9af294SRichard Sandiford return decodeUImmOperand<8>(Inst, Imm); 140eb9af294SRichard Sandiford } 141eb9af294SRichard Sandiford 142eb9af294SRichard Sandiford static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 143eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 144eb9af294SRichard Sandiford return decodeUImmOperand<16>(Inst, Imm); 145eb9af294SRichard Sandiford } 146eb9af294SRichard Sandiford 147eb9af294SRichard Sandiford static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 148eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 149eb9af294SRichard Sandiford return decodeUImmOperand<32>(Inst, Imm); 150eb9af294SRichard Sandiford } 151eb9af294SRichard Sandiford 152eb9af294SRichard Sandiford static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 153eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 154eb9af294SRichard Sandiford return decodeSImmOperand<8>(Inst, Imm); 155eb9af294SRichard Sandiford } 156eb9af294SRichard Sandiford 157eb9af294SRichard Sandiford static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 158eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 159eb9af294SRichard Sandiford return decodeSImmOperand<16>(Inst, Imm); 160eb9af294SRichard Sandiford } 161eb9af294SRichard Sandiford 162eb9af294SRichard Sandiford static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 163eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 164eb9af294SRichard Sandiford return decodeSImmOperand<32>(Inst, Imm); 165eb9af294SRichard Sandiford } 166eb9af294SRichard Sandiford 167eb9af294SRichard Sandiford template<unsigned N> 168eb9af294SRichard Sandiford static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 169eb9af294SRichard Sandiford uint64_t Address) { 170eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 171eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address)); 172eb9af294SRichard Sandiford return MCDisassembler::Success; 173eb9af294SRichard Sandiford } 174eb9af294SRichard Sandiford 175eb9af294SRichard Sandiford static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm, 176eb9af294SRichard Sandiford uint64_t Address, 177eb9af294SRichard Sandiford const void *Decoder) { 178eb9af294SRichard Sandiford return decodePCDBLOperand<16>(Inst, Imm, Address); 179eb9af294SRichard Sandiford } 180eb9af294SRichard Sandiford 181eb9af294SRichard Sandiford static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 182eb9af294SRichard Sandiford uint64_t Address, 183eb9af294SRichard Sandiford const void *Decoder) { 184eb9af294SRichard Sandiford return decodePCDBLOperand<32>(Inst, Imm, Address); 185eb9af294SRichard Sandiford } 186eb9af294SRichard Sandiford 187eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 188eb9af294SRichard Sandiford const unsigned *Regs) { 189eb9af294SRichard Sandiford uint64_t Base = Field >> 12; 190eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff; 191eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr12"); 192eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 193eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(Disp)); 194eb9af294SRichard Sandiford return MCDisassembler::Success; 195eb9af294SRichard Sandiford } 196eb9af294SRichard Sandiford 197eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 198eb9af294SRichard Sandiford const unsigned *Regs) { 199eb9af294SRichard Sandiford uint64_t Base = Field >> 20; 200eb9af294SRichard Sandiford uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 201eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr20"); 202eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 203eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp))); 204eb9af294SRichard Sandiford return MCDisassembler::Success; 205eb9af294SRichard Sandiford } 206eb9af294SRichard Sandiford 207eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 208eb9af294SRichard Sandiford const unsigned *Regs) { 209eb9af294SRichard Sandiford uint64_t Index = Field >> 16; 210eb9af294SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf; 211eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff; 212eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr12"); 213eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 214eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(Disp)); 215eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index])); 216eb9af294SRichard Sandiford return MCDisassembler::Success; 217eb9af294SRichard Sandiford } 218eb9af294SRichard Sandiford 219eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 220eb9af294SRichard Sandiford const unsigned *Regs) { 221eb9af294SRichard Sandiford uint64_t Index = Field >> 24; 222eb9af294SRichard Sandiford uint64_t Base = (Field >> 20) & 0xf; 223eb9af294SRichard Sandiford uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 224eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr20"); 225eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 226eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp))); 227eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index])); 228eb9af294SRichard Sandiford return MCDisassembler::Success; 229eb9af294SRichard Sandiford } 230eb9af294SRichard Sandiford 2311d959008SRichard Sandiford static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field, 2321d959008SRichard Sandiford const unsigned *Regs) { 2331d959008SRichard Sandiford uint64_t Length = Field >> 16; 2341d959008SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf; 2351d959008SRichard Sandiford uint64_t Disp = Field & 0xfff; 2361d959008SRichard Sandiford assert(Length < 256 && "Invalid BDLAddr12Len8"); 2371d959008SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 2381d959008SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(Disp)); 2391d959008SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(Length + 1)); 2401d959008SRichard Sandiford return MCDisassembler::Success; 2411d959008SRichard Sandiford } 2421d959008SRichard Sandiford 243eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 244eb9af294SRichard Sandiford uint64_t Address, 245eb9af294SRichard Sandiford const void *Decoder) { 246eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 247eb9af294SRichard Sandiford } 248eb9af294SRichard Sandiford 249eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 250eb9af294SRichard Sandiford uint64_t Address, 251eb9af294SRichard Sandiford const void *Decoder) { 252eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 253eb9af294SRichard Sandiford } 254eb9af294SRichard Sandiford 255eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 256eb9af294SRichard Sandiford uint64_t Address, 257eb9af294SRichard Sandiford const void *Decoder) { 258eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 259eb9af294SRichard Sandiford } 260eb9af294SRichard Sandiford 261eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 262eb9af294SRichard Sandiford uint64_t Address, 263eb9af294SRichard Sandiford const void *Decoder) { 264eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 265eb9af294SRichard Sandiford } 266eb9af294SRichard Sandiford 267eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 268eb9af294SRichard Sandiford uint64_t Address, 269eb9af294SRichard Sandiford const void *Decoder) { 270eb9af294SRichard Sandiford return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 271eb9af294SRichard Sandiford } 272eb9af294SRichard Sandiford 273eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 274eb9af294SRichard Sandiford uint64_t Address, 275eb9af294SRichard Sandiford const void *Decoder) { 276eb9af294SRichard Sandiford return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 277eb9af294SRichard Sandiford } 278eb9af294SRichard Sandiford 2791d959008SRichard Sandiford static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst, 2801d959008SRichard Sandiford uint64_t Field, 2811d959008SRichard Sandiford uint64_t Address, 2821d959008SRichard Sandiford const void *Decoder) { 2831d959008SRichard Sandiford return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs); 2841d959008SRichard Sandiford } 2851d959008SRichard Sandiford 286eb9af294SRichard Sandiford #include "SystemZGenDisassemblerTables.inc" 287eb9af294SRichard Sandiford 288eb9af294SRichard Sandiford DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 2897fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 290eb9af294SRichard Sandiford uint64_t Address, 2914aa6bea7SRafael Espindola raw_ostream &OS, 2924aa6bea7SRafael Espindola raw_ostream &CS) const { 293eb9af294SRichard Sandiford // Get the first two bytes of the instruction. 294eb9af294SRichard Sandiford Size = 0; 2957fc5b874SRafael Espindola if (Bytes.size() < 2) 296eb9af294SRichard Sandiford return MCDisassembler::Fail; 297eb9af294SRichard Sandiford 298eb9af294SRichard Sandiford // The top 2 bits of the first byte specify the size. 299eb9af294SRichard Sandiford const uint8_t *Table; 300eb9af294SRichard Sandiford if (Bytes[0] < 0x40) { 301eb9af294SRichard Sandiford Size = 2; 302eb9af294SRichard Sandiford Table = DecoderTable16; 303eb9af294SRichard Sandiford } else if (Bytes[0] < 0xc0) { 304eb9af294SRichard Sandiford Size = 4; 305eb9af294SRichard Sandiford Table = DecoderTable32; 306eb9af294SRichard Sandiford } else { 307eb9af294SRichard Sandiford Size = 6; 308eb9af294SRichard Sandiford Table = DecoderTable48; 309eb9af294SRichard Sandiford } 310eb9af294SRichard Sandiford 311eb9af294SRichard Sandiford // Read any remaining bytes. 3127fc5b874SRafael Espindola if (Bytes.size() < Size) 313eb9af294SRichard Sandiford return MCDisassembler::Fail; 314eb9af294SRichard Sandiford 315eb9af294SRichard Sandiford // Construct the instruction. 316eb9af294SRichard Sandiford uint64_t Inst = 0; 317eb9af294SRichard Sandiford for (uint64_t I = 0; I < Size; ++I) 318eb9af294SRichard Sandiford Inst = (Inst << 8) | Bytes[I]; 319eb9af294SRichard Sandiford 320eb9af294SRichard Sandiford return decodeInstruction(Table, MI, Inst, Address, this, STI); 321eb9af294SRichard Sandiford } 322