1*2345347eSHal Finkel //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===// 2*2345347eSHal Finkel // 3*2345347eSHal Finkel // The LLVM Compiler Infrastructure 4*2345347eSHal Finkel // 5*2345347eSHal Finkel // This file is distributed under the University of Illinois Open Source 6*2345347eSHal Finkel // License. See LICENSE.TXT for details. 7*2345347eSHal Finkel // 8*2345347eSHal Finkel //===----------------------------------------------------------------------===// 9*2345347eSHal Finkel 10*2345347eSHal Finkel #include "PPC.h" 11*2345347eSHal Finkel #include "llvm/MC/MCDisassembler.h" 12*2345347eSHal Finkel #include "llvm/MC/MCFixedLenDisassembler.h" 13*2345347eSHal Finkel #include "llvm/MC/MCInst.h" 14*2345347eSHal Finkel #include "llvm/MC/MCSubtargetInfo.h" 15*2345347eSHal Finkel #include "llvm/Support/MemoryObject.h" 16*2345347eSHal Finkel #include "llvm/Support/TargetRegistry.h" 17*2345347eSHal Finkel 18*2345347eSHal Finkel using namespace llvm; 19*2345347eSHal Finkel 20*2345347eSHal Finkel typedef MCDisassembler::DecodeStatus DecodeStatus; 21*2345347eSHal Finkel 22*2345347eSHal Finkel namespace { 23*2345347eSHal Finkel class PPCDisassembler : public MCDisassembler { 24*2345347eSHal Finkel public: 25*2345347eSHal Finkel PPCDisassembler(const MCSubtargetInfo &STI) 26*2345347eSHal Finkel : MCDisassembler(STI) {} 27*2345347eSHal Finkel virtual ~PPCDisassembler() {} 28*2345347eSHal Finkel 29*2345347eSHal Finkel // Override MCDisassembler. 30*2345347eSHal Finkel virtual DecodeStatus getInstruction(MCInst &instr, 31*2345347eSHal Finkel uint64_t &size, 32*2345347eSHal Finkel const MemoryObject ®ion, 33*2345347eSHal Finkel uint64_t address, 34*2345347eSHal Finkel raw_ostream &vStream, 35*2345347eSHal Finkel raw_ostream &cStream) const LLVM_OVERRIDE; 36*2345347eSHal Finkel }; 37*2345347eSHal Finkel } // end anonymous namespace 38*2345347eSHal Finkel 39*2345347eSHal Finkel static MCDisassembler *createPPCDisassembler(const Target &T, 40*2345347eSHal Finkel const MCSubtargetInfo &STI) { 41*2345347eSHal Finkel return new PPCDisassembler(STI); 42*2345347eSHal Finkel } 43*2345347eSHal Finkel 44*2345347eSHal Finkel extern "C" void LLVMInitializePowerPCDisassembler() { 45*2345347eSHal Finkel // Register the disassembler for each target. 46*2345347eSHal Finkel TargetRegistry::RegisterMCDisassembler(ThePPC32Target, 47*2345347eSHal Finkel createPPCDisassembler); 48*2345347eSHal Finkel TargetRegistry::RegisterMCDisassembler(ThePPC64Target, 49*2345347eSHal Finkel createPPCDisassembler); 50*2345347eSHal Finkel TargetRegistry::RegisterMCDisassembler(ThePPC64LETarget, 51*2345347eSHal Finkel createPPCDisassembler); 52*2345347eSHal Finkel } 53*2345347eSHal Finkel 54*2345347eSHal Finkel // FIXME: These can be generated by TableGen from the existing register 55*2345347eSHal Finkel // encoding values! 56*2345347eSHal Finkel 57*2345347eSHal Finkel static const unsigned CRRegs[] = { 58*2345347eSHal Finkel PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3, 59*2345347eSHal Finkel PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7 60*2345347eSHal Finkel }; 61*2345347eSHal Finkel 62*2345347eSHal Finkel static const unsigned CRBITRegs[] = { 63*2345347eSHal Finkel PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN, 64*2345347eSHal Finkel PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN, 65*2345347eSHal Finkel PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN, 66*2345347eSHal Finkel PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN, 67*2345347eSHal Finkel PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN, 68*2345347eSHal Finkel PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN, 69*2345347eSHal Finkel PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN, 70*2345347eSHal Finkel PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN 71*2345347eSHal Finkel }; 72*2345347eSHal Finkel 73*2345347eSHal Finkel static const unsigned FRegs[] = { 74*2345347eSHal Finkel PPC::F0, PPC::F1, PPC::F2, PPC::F3, 75*2345347eSHal Finkel PPC::F4, PPC::F5, PPC::F6, PPC::F7, 76*2345347eSHal Finkel PPC::F8, PPC::F9, PPC::F10, PPC::F11, 77*2345347eSHal Finkel PPC::F12, PPC::F13, PPC::F14, PPC::F15, 78*2345347eSHal Finkel PPC::F16, PPC::F17, PPC::F18, PPC::F19, 79*2345347eSHal Finkel PPC::F20, PPC::F21, PPC::F22, PPC::F23, 80*2345347eSHal Finkel PPC::F24, PPC::F25, PPC::F26, PPC::F27, 81*2345347eSHal Finkel PPC::F28, PPC::F29, PPC::F30, PPC::F31 82*2345347eSHal Finkel }; 83*2345347eSHal Finkel 84*2345347eSHal Finkel static const unsigned VRegs[] = { 85*2345347eSHal Finkel PPC::V0, PPC::V1, PPC::V2, PPC::V3, 86*2345347eSHal Finkel PPC::V4, PPC::V5, PPC::V6, PPC::V7, 87*2345347eSHal Finkel PPC::V8, PPC::V9, PPC::V10, PPC::V11, 88*2345347eSHal Finkel PPC::V12, PPC::V13, PPC::V14, PPC::V15, 89*2345347eSHal Finkel PPC::V16, PPC::V17, PPC::V18, PPC::V19, 90*2345347eSHal Finkel PPC::V20, PPC::V21, PPC::V22, PPC::V23, 91*2345347eSHal Finkel PPC::V24, PPC::V25, PPC::V26, PPC::V27, 92*2345347eSHal Finkel PPC::V28, PPC::V29, PPC::V30, PPC::V31 93*2345347eSHal Finkel }; 94*2345347eSHal Finkel 95*2345347eSHal Finkel static const unsigned GPRegs[] = { 96*2345347eSHal Finkel PPC::R0, PPC::R1, PPC::R2, PPC::R3, 97*2345347eSHal Finkel PPC::R4, PPC::R5, PPC::R6, PPC::R7, 98*2345347eSHal Finkel PPC::R8, PPC::R9, PPC::R10, PPC::R11, 99*2345347eSHal Finkel PPC::R12, PPC::R13, PPC::R14, PPC::R15, 100*2345347eSHal Finkel PPC::R16, PPC::R17, PPC::R18, PPC::R19, 101*2345347eSHal Finkel PPC::R20, PPC::R21, PPC::R22, PPC::R23, 102*2345347eSHal Finkel PPC::R24, PPC::R25, PPC::R26, PPC::R27, 103*2345347eSHal Finkel PPC::R28, PPC::R29, PPC::R30, PPC::R31 104*2345347eSHal Finkel }; 105*2345347eSHal Finkel 106*2345347eSHal Finkel static const unsigned GP0Regs[] = { 107*2345347eSHal Finkel PPC::ZERO, PPC::R1, PPC::R2, PPC::R3, 108*2345347eSHal Finkel PPC::R4, PPC::R5, PPC::R6, PPC::R7, 109*2345347eSHal Finkel PPC::R8, PPC::R9, PPC::R10, PPC::R11, 110*2345347eSHal Finkel PPC::R12, PPC::R13, PPC::R14, PPC::R15, 111*2345347eSHal Finkel PPC::R16, PPC::R17, PPC::R18, PPC::R19, 112*2345347eSHal Finkel PPC::R20, PPC::R21, PPC::R22, PPC::R23, 113*2345347eSHal Finkel PPC::R24, PPC::R25, PPC::R26, PPC::R27, 114*2345347eSHal Finkel PPC::R28, PPC::R29, PPC::R30, PPC::R31 115*2345347eSHal Finkel }; 116*2345347eSHal Finkel 117*2345347eSHal Finkel static const unsigned G8Regs[] = { 118*2345347eSHal Finkel PPC::X0, PPC::X1, PPC::X2, PPC::X3, 119*2345347eSHal Finkel PPC::X4, PPC::X5, PPC::X6, PPC::X7, 120*2345347eSHal Finkel PPC::X8, PPC::X9, PPC::X10, PPC::X11, 121*2345347eSHal Finkel PPC::X12, PPC::X13, PPC::X14, PPC::X15, 122*2345347eSHal Finkel PPC::X16, PPC::X17, PPC::X18, PPC::X19, 123*2345347eSHal Finkel PPC::X20, PPC::X21, PPC::X22, PPC::X23, 124*2345347eSHal Finkel PPC::X24, PPC::X25, PPC::X26, PPC::X27, 125*2345347eSHal Finkel PPC::X28, PPC::X29, PPC::X30, PPC::X31 126*2345347eSHal Finkel }; 127*2345347eSHal Finkel 128*2345347eSHal Finkel template <std::size_t N> 129*2345347eSHal Finkel static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 130*2345347eSHal Finkel const unsigned (&Regs)[N]) { 131*2345347eSHal Finkel assert(RegNo < N && "Invalid register number"); 132*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateReg(Regs[RegNo])); 133*2345347eSHal Finkel return MCDisassembler::Success; 134*2345347eSHal Finkel } 135*2345347eSHal Finkel 136*2345347eSHal Finkel static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 137*2345347eSHal Finkel uint64_t Address, 138*2345347eSHal Finkel const void *Decoder) { 139*2345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, CRRegs); 140*2345347eSHal Finkel } 141*2345347eSHal Finkel 142*2345347eSHal Finkel static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo, 143*2345347eSHal Finkel uint64_t Address, 144*2345347eSHal Finkel const void *Decoder) { 145*2345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, CRBITRegs); 146*2345347eSHal Finkel } 147*2345347eSHal Finkel 148*2345347eSHal Finkel static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo, 149*2345347eSHal Finkel uint64_t Address, 150*2345347eSHal Finkel const void *Decoder) { 151*2345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, FRegs); 152*2345347eSHal Finkel } 153*2345347eSHal Finkel 154*2345347eSHal Finkel static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo, 155*2345347eSHal Finkel uint64_t Address, 156*2345347eSHal Finkel const void *Decoder) { 157*2345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, FRegs); 158*2345347eSHal Finkel } 159*2345347eSHal Finkel 160*2345347eSHal Finkel static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 161*2345347eSHal Finkel uint64_t Address, 162*2345347eSHal Finkel const void *Decoder) { 163*2345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, VRegs); 164*2345347eSHal Finkel } 165*2345347eSHal Finkel 166*2345347eSHal Finkel static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 167*2345347eSHal Finkel uint64_t Address, 168*2345347eSHal Finkel const void *Decoder) { 169*2345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, GPRegs); 170*2345347eSHal Finkel } 171*2345347eSHal Finkel 172*2345347eSHal Finkel static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo, 173*2345347eSHal Finkel uint64_t Address, 174*2345347eSHal Finkel const void *Decoder) { 175*2345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, GP0Regs); 176*2345347eSHal Finkel } 177*2345347eSHal Finkel 178*2345347eSHal Finkel static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo, 179*2345347eSHal Finkel uint64_t Address, 180*2345347eSHal Finkel const void *Decoder) { 181*2345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, G8Regs); 182*2345347eSHal Finkel } 183*2345347eSHal Finkel 184*2345347eSHal Finkel #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass 185*2345347eSHal Finkel #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass 186*2345347eSHal Finkel 187*2345347eSHal Finkel template<unsigned N> 188*2345347eSHal Finkel static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 189*2345347eSHal Finkel int64_t Address, const void *Decoder) { 190*2345347eSHal Finkel assert(isUInt<N>(Imm) && "Invalid immediate"); 191*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateImm(Imm)); 192*2345347eSHal Finkel return MCDisassembler::Success; 193*2345347eSHal Finkel } 194*2345347eSHal Finkel 195*2345347eSHal Finkel template<unsigned N> 196*2345347eSHal Finkel static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 197*2345347eSHal Finkel int64_t Address, const void *Decoder) { 198*2345347eSHal Finkel assert(isUInt<N>(Imm) && "Invalid immediate"); 199*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm))); 200*2345347eSHal Finkel return MCDisassembler::Success; 201*2345347eSHal Finkel } 202*2345347eSHal Finkel 203*2345347eSHal Finkel static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm, 204*2345347eSHal Finkel int64_t Address, const void *Decoder) { 205*2345347eSHal Finkel // Decode the memri field (imm, reg), which has the low 16-bits as the 206*2345347eSHal Finkel // displacement and the next 5 bits as the register #. 207*2345347eSHal Finkel 208*2345347eSHal Finkel uint64_t Base = Imm >> 16; 209*2345347eSHal Finkel uint64_t Disp = Imm & 0xFFFF; 210*2345347eSHal Finkel 211*2345347eSHal Finkel assert(Base < 32 && "Invalid base register"); 212*2345347eSHal Finkel 213*2345347eSHal Finkel switch (Inst.getOpcode()) { 214*2345347eSHal Finkel default: break; 215*2345347eSHal Finkel case PPC::LBZU: 216*2345347eSHal Finkel case PPC::LHAU: 217*2345347eSHal Finkel case PPC::LHZU: 218*2345347eSHal Finkel case PPC::LWZU: 219*2345347eSHal Finkel case PPC::LFSU: 220*2345347eSHal Finkel case PPC::LFDU: 221*2345347eSHal Finkel // Add the tied output operand. 222*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateReg(GP0Regs[Base])); 223*2345347eSHal Finkel break; 224*2345347eSHal Finkel case PPC::STBU: 225*2345347eSHal Finkel case PPC::STHU: 226*2345347eSHal Finkel case PPC::STWU: 227*2345347eSHal Finkel case PPC::STFSU: 228*2345347eSHal Finkel case PPC::STFDU: 229*2345347eSHal Finkel Inst.insert(Inst.begin(), MCOperand::CreateReg(GP0Regs[Base])); 230*2345347eSHal Finkel break; 231*2345347eSHal Finkel } 232*2345347eSHal Finkel 233*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateImm(SignExtend64<16>(Disp))); 234*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateReg(GP0Regs[Base])); 235*2345347eSHal Finkel return MCDisassembler::Success; 236*2345347eSHal Finkel } 237*2345347eSHal Finkel 238*2345347eSHal Finkel static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm, 239*2345347eSHal Finkel int64_t Address, const void *Decoder) { 240*2345347eSHal Finkel // Decode the memrix field (imm, reg), which has the low 14-bits as the 241*2345347eSHal Finkel // displacement and the next 5 bits as the register #. 242*2345347eSHal Finkel 243*2345347eSHal Finkel uint64_t Base = Imm >> 14; 244*2345347eSHal Finkel uint64_t Disp = Imm & 0x3FFF; 245*2345347eSHal Finkel 246*2345347eSHal Finkel assert(Base < 32 && "Invalid base register"); 247*2345347eSHal Finkel 248*2345347eSHal Finkel if (Inst.getOpcode() == PPC::LDU) 249*2345347eSHal Finkel // Add the tied output operand. 250*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateReg(GP0Regs[Base])); 251*2345347eSHal Finkel else if (Inst.getOpcode() == PPC::STDU) 252*2345347eSHal Finkel Inst.insert(Inst.begin(), MCOperand::CreateReg(GP0Regs[Base])); 253*2345347eSHal Finkel 254*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateImm(SignExtend64<16>(Disp << 2))); 255*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateReg(GP0Regs[Base])); 256*2345347eSHal Finkel return MCDisassembler::Success; 257*2345347eSHal Finkel } 258*2345347eSHal Finkel 259*2345347eSHal Finkel static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm, 260*2345347eSHal Finkel int64_t Address, const void *Decoder) { 261*2345347eSHal Finkel // The cr bit encoding is 0x80 >> cr_reg_num. 262*2345347eSHal Finkel 263*2345347eSHal Finkel unsigned Zeros = countTrailingZeros(Imm); 264*2345347eSHal Finkel assert(Zeros < 8 && "Invalid CR bit value"); 265*2345347eSHal Finkel 266*2345347eSHal Finkel Inst.addOperand(MCOperand::CreateReg(CRRegs[7 - Zeros])); 267*2345347eSHal Finkel return MCDisassembler::Success; 268*2345347eSHal Finkel } 269*2345347eSHal Finkel 270*2345347eSHal Finkel #include "PPCGenDisassemblerTables.inc" 271*2345347eSHal Finkel 272*2345347eSHal Finkel DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 273*2345347eSHal Finkel const MemoryObject &Region, 274*2345347eSHal Finkel uint64_t Address, 275*2345347eSHal Finkel raw_ostream &os, 276*2345347eSHal Finkel raw_ostream &cs) const { 277*2345347eSHal Finkel // Get the four bytes of the instruction. 278*2345347eSHal Finkel uint8_t Bytes[4]; 279*2345347eSHal Finkel Size = 4; 280*2345347eSHal Finkel if (Region.readBytes(Address, Size, Bytes) == -1) { 281*2345347eSHal Finkel Size = 0; 282*2345347eSHal Finkel return MCDisassembler::Fail; 283*2345347eSHal Finkel } 284*2345347eSHal Finkel 285*2345347eSHal Finkel // The instruction is big-endian encoded. 286*2345347eSHal Finkel uint32_t Inst = (Bytes[0] << 24) | 287*2345347eSHal Finkel (Bytes[1] << 16) | 288*2345347eSHal Finkel (Bytes[2] << 8) | 289*2345347eSHal Finkel (Bytes[3] << 0); 290*2345347eSHal Finkel 291*2345347eSHal Finkel return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI); 292*2345347eSHal Finkel } 293*2345347eSHal Finkel 294