1*eb9af294SRichard Sandiford //===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===// 2*eb9af294SRichard Sandiford // 3*eb9af294SRichard Sandiford // The LLVM Compiler Infrastructure 4*eb9af294SRichard Sandiford // 5*eb9af294SRichard Sandiford // This file is distributed under the University of Illinois Open Source 6*eb9af294SRichard Sandiford // License. See LICENSE.TXT for details. 7*eb9af294SRichard Sandiford // 8*eb9af294SRichard Sandiford //===----------------------------------------------------------------------===// 9*eb9af294SRichard Sandiford 10*eb9af294SRichard Sandiford #include "SystemZ.h" 11*eb9af294SRichard Sandiford #include "llvm/MC/MCDisassembler.h" 12*eb9af294SRichard Sandiford #include "llvm/MC/MCFixedLenDisassembler.h" 13*eb9af294SRichard Sandiford #include "llvm/MC/MCInst.h" 14*eb9af294SRichard Sandiford #include "llvm/MC/MCSubtargetInfo.h" 15*eb9af294SRichard Sandiford #include "llvm/Support/MemoryObject.h" 16*eb9af294SRichard Sandiford #include "llvm/Support/TargetRegistry.h" 17*eb9af294SRichard Sandiford 18*eb9af294SRichard Sandiford using namespace llvm; 19*eb9af294SRichard Sandiford 20*eb9af294SRichard Sandiford typedef MCDisassembler::DecodeStatus DecodeStatus; 21*eb9af294SRichard Sandiford 22*eb9af294SRichard Sandiford namespace { 23*eb9af294SRichard Sandiford class SystemZDisassembler : public MCDisassembler { 24*eb9af294SRichard Sandiford public: 25*eb9af294SRichard Sandiford SystemZDisassembler(const MCSubtargetInfo &STI) 26*eb9af294SRichard Sandiford : MCDisassembler(STI) {} 27*eb9af294SRichard Sandiford virtual ~SystemZDisassembler() {} 28*eb9af294SRichard Sandiford 29*eb9af294SRichard Sandiford // Override MCDisassembler. 30*eb9af294SRichard Sandiford virtual DecodeStatus getInstruction(MCInst &instr, 31*eb9af294SRichard Sandiford uint64_t &size, 32*eb9af294SRichard Sandiford const MemoryObject ®ion, 33*eb9af294SRichard Sandiford uint64_t address, 34*eb9af294SRichard Sandiford raw_ostream &vStream, 35*eb9af294SRichard Sandiford raw_ostream &cStream) const LLVM_OVERRIDE; 36*eb9af294SRichard Sandiford }; 37*eb9af294SRichard Sandiford } // end anonymous namespace 38*eb9af294SRichard Sandiford 39*eb9af294SRichard Sandiford static MCDisassembler *createSystemZDisassembler(const Target &T, 40*eb9af294SRichard Sandiford const MCSubtargetInfo &STI) { 41*eb9af294SRichard Sandiford return new SystemZDisassembler(STI); 42*eb9af294SRichard Sandiford } 43*eb9af294SRichard Sandiford 44*eb9af294SRichard Sandiford extern "C" void LLVMInitializeSystemZDisassembler() { 45*eb9af294SRichard Sandiford // Register the disassembler. 46*eb9af294SRichard Sandiford TargetRegistry::RegisterMCDisassembler(TheSystemZTarget, 47*eb9af294SRichard Sandiford createSystemZDisassembler); 48*eb9af294SRichard Sandiford } 49*eb9af294SRichard Sandiford 50*eb9af294SRichard Sandiford static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 51*eb9af294SRichard Sandiford const unsigned *Regs, 52*eb9af294SRichard Sandiford bool isAddress = false) { 53*eb9af294SRichard Sandiford assert(RegNo < 16 && "Invalid register"); 54*eb9af294SRichard Sandiford if (!isAddress || RegNo) { 55*eb9af294SRichard Sandiford RegNo = Regs[RegNo]; 56*eb9af294SRichard Sandiford if (RegNo == 0) 57*eb9af294SRichard Sandiford return MCDisassembler::Fail; 58*eb9af294SRichard Sandiford } 59*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(RegNo)); 60*eb9af294SRichard Sandiford return MCDisassembler::Success; 61*eb9af294SRichard Sandiford } 62*eb9af294SRichard Sandiford 63*eb9af294SRichard Sandiford static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 64*eb9af294SRichard Sandiford uint64_t Address, 65*eb9af294SRichard Sandiford const void *Decoder) { 66*eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs); 67*eb9af294SRichard Sandiford } 68*eb9af294SRichard Sandiford 69*eb9af294SRichard Sandiford static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 70*eb9af294SRichard Sandiford uint64_t Address, 71*eb9af294SRichard Sandiford const void *Decoder) { 72*eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs); 73*eb9af294SRichard Sandiford } 74*eb9af294SRichard Sandiford 75*eb9af294SRichard Sandiford static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 76*eb9af294SRichard Sandiford uint64_t Address, 77*eb9af294SRichard Sandiford const void *Decoder) { 78*eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs); 79*eb9af294SRichard Sandiford } 80*eb9af294SRichard Sandiford 81*eb9af294SRichard Sandiford static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 82*eb9af294SRichard Sandiford uint64_t Address, 83*eb9af294SRichard Sandiford const void *Decoder) { 84*eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, true); 85*eb9af294SRichard Sandiford } 86*eb9af294SRichard Sandiford 87*eb9af294SRichard Sandiford static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo, 88*eb9af294SRichard Sandiford uint64_t Address, 89*eb9af294SRichard Sandiford const void *Decoder) { 90*eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs); 91*eb9af294SRichard Sandiford } 92*eb9af294SRichard Sandiford 93*eb9af294SRichard Sandiford static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo, 94*eb9af294SRichard Sandiford uint64_t Address, 95*eb9af294SRichard Sandiford const void *Decoder) { 96*eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs); 97*eb9af294SRichard Sandiford } 98*eb9af294SRichard Sandiford 99*eb9af294SRichard Sandiford static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo, 100*eb9af294SRichard Sandiford uint64_t Address, 101*eb9af294SRichard Sandiford const void *Decoder) { 102*eb9af294SRichard Sandiford return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs); 103*eb9af294SRichard Sandiford } 104*eb9af294SRichard Sandiford 105*eb9af294SRichard Sandiford template<unsigned N> 106*eb9af294SRichard Sandiford static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) { 107*eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid immediate"); 108*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(Imm)); 109*eb9af294SRichard Sandiford return MCDisassembler::Success; 110*eb9af294SRichard Sandiford } 111*eb9af294SRichard Sandiford 112*eb9af294SRichard Sandiford template<unsigned N> 113*eb9af294SRichard Sandiford static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) { 114*eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid immediate"); 115*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm))); 116*eb9af294SRichard Sandiford return MCDisassembler::Success; 117*eb9af294SRichard Sandiford } 118*eb9af294SRichard Sandiford 119*eb9af294SRichard Sandiford static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm, 120*eb9af294SRichard Sandiford uint64_t Address, 121*eb9af294SRichard Sandiford const void *Decoder) { 122*eb9af294SRichard Sandiford return decodeUImmOperand<4>(Inst, Imm); 123*eb9af294SRichard Sandiford } 124*eb9af294SRichard Sandiford 125*eb9af294SRichard Sandiford static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm, 126*eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 127*eb9af294SRichard Sandiford return decodeUImmOperand<4>(Inst, Imm); 128*eb9af294SRichard Sandiford } 129*eb9af294SRichard Sandiford 130*eb9af294SRichard Sandiford static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm, 131*eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 132*eb9af294SRichard Sandiford return decodeUImmOperand<6>(Inst, Imm); 133*eb9af294SRichard Sandiford } 134*eb9af294SRichard Sandiford 135*eb9af294SRichard Sandiford static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm, 136*eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 137*eb9af294SRichard Sandiford return decodeUImmOperand<8>(Inst, Imm); 138*eb9af294SRichard Sandiford } 139*eb9af294SRichard Sandiford 140*eb9af294SRichard Sandiford static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm, 141*eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 142*eb9af294SRichard Sandiford return decodeUImmOperand<16>(Inst, Imm); 143*eb9af294SRichard Sandiford } 144*eb9af294SRichard Sandiford 145*eb9af294SRichard Sandiford static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm, 146*eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 147*eb9af294SRichard Sandiford return decodeUImmOperand<32>(Inst, Imm); 148*eb9af294SRichard Sandiford } 149*eb9af294SRichard Sandiford 150*eb9af294SRichard Sandiford static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm, 151*eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 152*eb9af294SRichard Sandiford return decodeSImmOperand<8>(Inst, Imm); 153*eb9af294SRichard Sandiford } 154*eb9af294SRichard Sandiford 155*eb9af294SRichard Sandiford static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm, 156*eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 157*eb9af294SRichard Sandiford return decodeSImmOperand<16>(Inst, Imm); 158*eb9af294SRichard Sandiford } 159*eb9af294SRichard Sandiford 160*eb9af294SRichard Sandiford static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm, 161*eb9af294SRichard Sandiford uint64_t Address, const void *Decoder) { 162*eb9af294SRichard Sandiford return decodeSImmOperand<32>(Inst, Imm); 163*eb9af294SRichard Sandiford } 164*eb9af294SRichard Sandiford 165*eb9af294SRichard Sandiford template<unsigned N> 166*eb9af294SRichard Sandiford static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm, 167*eb9af294SRichard Sandiford uint64_t Address) { 168*eb9af294SRichard Sandiford assert(isUInt<N>(Imm) && "Invalid PC-relative offset"); 169*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address)); 170*eb9af294SRichard Sandiford return MCDisassembler::Success; 171*eb9af294SRichard Sandiford } 172*eb9af294SRichard Sandiford 173*eb9af294SRichard Sandiford static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm, 174*eb9af294SRichard Sandiford uint64_t Address, 175*eb9af294SRichard Sandiford const void *Decoder) { 176*eb9af294SRichard Sandiford return decodePCDBLOperand<16>(Inst, Imm, Address); 177*eb9af294SRichard Sandiford } 178*eb9af294SRichard Sandiford 179*eb9af294SRichard Sandiford static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm, 180*eb9af294SRichard Sandiford uint64_t Address, 181*eb9af294SRichard Sandiford const void *Decoder) { 182*eb9af294SRichard Sandiford return decodePCDBLOperand<32>(Inst, Imm, Address); 183*eb9af294SRichard Sandiford } 184*eb9af294SRichard Sandiford 185*eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field, 186*eb9af294SRichard Sandiford const unsigned *Regs) { 187*eb9af294SRichard Sandiford uint64_t Base = Field >> 12; 188*eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff; 189*eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr12"); 190*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 191*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(Disp)); 192*eb9af294SRichard Sandiford return MCDisassembler::Success; 193*eb9af294SRichard Sandiford } 194*eb9af294SRichard Sandiford 195*eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field, 196*eb9af294SRichard Sandiford const unsigned *Regs) { 197*eb9af294SRichard Sandiford uint64_t Base = Field >> 20; 198*eb9af294SRichard Sandiford uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff); 199*eb9af294SRichard Sandiford assert(Base < 16 && "Invalid BDAddr20"); 200*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 201*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp))); 202*eb9af294SRichard Sandiford return MCDisassembler::Success; 203*eb9af294SRichard Sandiford } 204*eb9af294SRichard Sandiford 205*eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field, 206*eb9af294SRichard Sandiford const unsigned *Regs) { 207*eb9af294SRichard Sandiford uint64_t Index = Field >> 16; 208*eb9af294SRichard Sandiford uint64_t Base = (Field >> 12) & 0xf; 209*eb9af294SRichard Sandiford uint64_t Disp = Field & 0xfff; 210*eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr12"); 211*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 212*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(Disp)); 213*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index])); 214*eb9af294SRichard Sandiford return MCDisassembler::Success; 215*eb9af294SRichard Sandiford } 216*eb9af294SRichard Sandiford 217*eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field, 218*eb9af294SRichard Sandiford const unsigned *Regs) { 219*eb9af294SRichard Sandiford uint64_t Index = Field >> 24; 220*eb9af294SRichard Sandiford uint64_t Base = (Field >> 20) & 0xf; 221*eb9af294SRichard Sandiford uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12); 222*eb9af294SRichard Sandiford assert(Index < 16 && "Invalid BDXAddr20"); 223*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base])); 224*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp))); 225*eb9af294SRichard Sandiford Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index])); 226*eb9af294SRichard Sandiford return MCDisassembler::Success; 227*eb9af294SRichard Sandiford } 228*eb9af294SRichard Sandiford 229*eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field, 230*eb9af294SRichard Sandiford uint64_t Address, 231*eb9af294SRichard Sandiford const void *Decoder) { 232*eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs); 233*eb9af294SRichard Sandiford } 234*eb9af294SRichard Sandiford 235*eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field, 236*eb9af294SRichard Sandiford uint64_t Address, 237*eb9af294SRichard Sandiford const void *Decoder) { 238*eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs); 239*eb9af294SRichard Sandiford } 240*eb9af294SRichard Sandiford 241*eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 242*eb9af294SRichard Sandiford uint64_t Address, 243*eb9af294SRichard Sandiford const void *Decoder) { 244*eb9af294SRichard Sandiford return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 245*eb9af294SRichard Sandiford } 246*eb9af294SRichard Sandiford 247*eb9af294SRichard Sandiford static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 248*eb9af294SRichard Sandiford uint64_t Address, 249*eb9af294SRichard Sandiford const void *Decoder) { 250*eb9af294SRichard Sandiford return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 251*eb9af294SRichard Sandiford } 252*eb9af294SRichard Sandiford 253*eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field, 254*eb9af294SRichard Sandiford uint64_t Address, 255*eb9af294SRichard Sandiford const void *Decoder) { 256*eb9af294SRichard Sandiford return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs); 257*eb9af294SRichard Sandiford } 258*eb9af294SRichard Sandiford 259*eb9af294SRichard Sandiford static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field, 260*eb9af294SRichard Sandiford uint64_t Address, 261*eb9af294SRichard Sandiford const void *Decoder) { 262*eb9af294SRichard Sandiford return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs); 263*eb9af294SRichard Sandiford } 264*eb9af294SRichard Sandiford 265*eb9af294SRichard Sandiford #include "SystemZGenDisassemblerTables.inc" 266*eb9af294SRichard Sandiford 267*eb9af294SRichard Sandiford DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 268*eb9af294SRichard Sandiford const MemoryObject &Region, 269*eb9af294SRichard Sandiford uint64_t Address, 270*eb9af294SRichard Sandiford raw_ostream &os, 271*eb9af294SRichard Sandiford raw_ostream &cs) const { 272*eb9af294SRichard Sandiford // Get the first two bytes of the instruction. 273*eb9af294SRichard Sandiford uint8_t Bytes[6]; 274*eb9af294SRichard Sandiford Size = 0; 275*eb9af294SRichard Sandiford if (Region.readBytes(Address, 2, Bytes, 0) == -1) 276*eb9af294SRichard Sandiford return MCDisassembler::Fail; 277*eb9af294SRichard Sandiford 278*eb9af294SRichard Sandiford // The top 2 bits of the first byte specify the size. 279*eb9af294SRichard Sandiford const uint8_t *Table; 280*eb9af294SRichard Sandiford if (Bytes[0] < 0x40) { 281*eb9af294SRichard Sandiford Size = 2; 282*eb9af294SRichard Sandiford Table = DecoderTable16; 283*eb9af294SRichard Sandiford } else if (Bytes[0] < 0xc0) { 284*eb9af294SRichard Sandiford Size = 4; 285*eb9af294SRichard Sandiford Table = DecoderTable32; 286*eb9af294SRichard Sandiford } else { 287*eb9af294SRichard Sandiford Size = 6; 288*eb9af294SRichard Sandiford Table = DecoderTable48; 289*eb9af294SRichard Sandiford } 290*eb9af294SRichard Sandiford 291*eb9af294SRichard Sandiford // Read any remaining bytes. 292*eb9af294SRichard Sandiford if (Size > 2 && Region.readBytes(Address + 2, Size - 2, Bytes + 2, 0) == -1) 293*eb9af294SRichard Sandiford return MCDisassembler::Fail; 294*eb9af294SRichard Sandiford 295*eb9af294SRichard Sandiford // Construct the instruction. 296*eb9af294SRichard Sandiford uint64_t Inst = 0; 297*eb9af294SRichard Sandiford for (uint64_t I = 0; I < Size; ++I) 298*eb9af294SRichard Sandiford Inst = (Inst << 8) | Bytes[I]; 299*eb9af294SRichard Sandiford 300*eb9af294SRichard Sandiford return decodeInstruction(Table, MI, Inst, Address, this, STI); 301*eb9af294SRichard Sandiford } 302