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