12345347eSHal Finkel //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===// 22345347eSHal Finkel // 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 62345347eSHal Finkel // 72345347eSHal Finkel //===----------------------------------------------------------------------===// 82345347eSHal Finkel 927c769d2SBenjamin Kramer #include "MCTargetDesc/PPCMCTargetDesc.h" 10ee6ced19SRichard Trieu #include "TargetInfo/PowerPCTargetInfo.h" 11f57c1977SBenjamin Kramer #include "llvm/MC/MCDisassembler/MCDisassembler.h" 122345347eSHal Finkel #include "llvm/MC/MCFixedLenDisassembler.h" 132345347eSHal Finkel #include "llvm/MC/MCInst.h" 142345347eSHal Finkel #include "llvm/MC/MCSubtargetInfo.h" 1589b57061SReid Kleckner #include "llvm/MC/TargetRegistry.h" 16c11fd3e7SBenjamin Kramer #include "llvm/Support/Endian.h" 172345347eSHal Finkel 182345347eSHal Finkel using namespace llvm; 192345347eSHal Finkel 200dad994aSNemanja Ivanovic DEFINE_PPC_REGCLASSES; 210dad994aSNemanja Ivanovic 22e96dd897SChandler Carruth #define DEBUG_TYPE "ppc-disassembler" 23e96dd897SChandler Carruth 242345347eSHal Finkel typedef MCDisassembler::DecodeStatus DecodeStatus; 252345347eSHal Finkel 262345347eSHal Finkel namespace { 272345347eSHal Finkel class PPCDisassembler : public MCDisassembler { 28c11fd3e7SBenjamin Kramer bool IsLittleEndian; 29c11fd3e7SBenjamin Kramer 302345347eSHal Finkel public: 31c11fd3e7SBenjamin Kramer PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx, 32c11fd3e7SBenjamin Kramer bool IsLittleEndian) 33c11fd3e7SBenjamin Kramer : MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {} 342345347eSHal Finkel 354aa6bea7SRafael Espindola DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size, 367fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, uint64_t Address, 374aa6bea7SRafael Espindola raw_ostream &CStream) const override; 382345347eSHal Finkel }; 392345347eSHal Finkel } // end anonymous namespace 402345347eSHal Finkel 412345347eSHal Finkel static MCDisassembler *createPPCDisassembler(const Target &T, 42a1bc0f56SLang Hames const MCSubtargetInfo &STI, 43a1bc0f56SLang Hames MCContext &Ctx) { 44c11fd3e7SBenjamin Kramer return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false); 45c11fd3e7SBenjamin Kramer } 46c11fd3e7SBenjamin Kramer 47c11fd3e7SBenjamin Kramer static MCDisassembler *createPPCLEDisassembler(const Target &T, 48c11fd3e7SBenjamin Kramer const MCSubtargetInfo &STI, 49c11fd3e7SBenjamin Kramer MCContext &Ctx) { 50c11fd3e7SBenjamin Kramer return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true); 512345347eSHal Finkel } 522345347eSHal Finkel 530dbcb363STom Stellard extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCDisassembler() { 542345347eSHal Finkel // Register the disassembler for each target. 55f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getThePPC32Target(), 562345347eSHal Finkel createPPCDisassembler); 578f004471SBrandon Bergren TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(), 588f004471SBrandon Bergren createPPCLEDisassembler); 59f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getThePPC64Target(), 602345347eSHal Finkel createPPCDisassembler); 61f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(), 62c11fd3e7SBenjamin Kramer createPPCLEDisassembler); 632345347eSHal Finkel } 642345347eSHal Finkel 654af7560bSFangrui Song static DecodeStatus decodeCondBrTarget(MCInst &Inst, unsigned Imm, 664af7560bSFangrui Song uint64_t /*Address*/, 67*4ae9745aSMaksim Panchenko const MCDisassembler * /*Decoder*/) { 684af7560bSFangrui Song Inst.addOperand(MCOperand::createImm(SignExtend32<14>(Imm))); 694af7560bSFangrui Song return MCDisassembler::Success; 704af7560bSFangrui Song } 714af7560bSFangrui Song 7285adce3dSFangrui Song static DecodeStatus decodeDirectBrTarget(MCInst &Inst, unsigned Imm, 7385adce3dSFangrui Song uint64_t /*Address*/, 74*4ae9745aSMaksim Panchenko const MCDisassembler * /*Decoder*/) { 75c0694520SSean Fertile int32_t Offset = SignExtend32<24>(Imm); 76c0694520SSean Fertile Inst.addOperand(MCOperand::createImm(Offset)); 77c0694520SSean Fertile return MCDisassembler::Success; 78c0694520SSean Fertile } 79c0694520SSean Fertile 802345347eSHal Finkel // FIXME: These can be generated by TableGen from the existing register 812345347eSHal Finkel // encoding values! 822345347eSHal Finkel 832345347eSHal Finkel template <std::size_t N> 842345347eSHal Finkel static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 850dad994aSNemanja Ivanovic const MCPhysReg (&Regs)[N]) { 862345347eSHal Finkel assert(RegNo < N && "Invalid register number"); 87e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[RegNo])); 882345347eSHal Finkel return MCDisassembler::Success; 892345347eSHal Finkel } 902345347eSHal Finkel 912345347eSHal Finkel static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 922345347eSHal Finkel uint64_t Address, 93*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 942345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, CRRegs); 952345347eSHal Finkel } 962345347eSHal Finkel 972345347eSHal Finkel static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo, 982345347eSHal Finkel uint64_t Address, 99*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1002345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, CRBITRegs); 1012345347eSHal Finkel } 1022345347eSHal Finkel 1032345347eSHal Finkel static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo, 1042345347eSHal Finkel uint64_t Address, 105*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1062345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, FRegs); 1072345347eSHal Finkel } 1082345347eSHal Finkel 1092345347eSHal Finkel static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo, 1102345347eSHal Finkel uint64_t Address, 111*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1122345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, FRegs); 1132345347eSHal Finkel } 1142345347eSHal Finkel 11511049f8fSNemanja Ivanovic static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo, 11611049f8fSNemanja Ivanovic uint64_t Address, 117*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 11811049f8fSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, VFRegs); 11911049f8fSNemanja Ivanovic } 12011049f8fSNemanja Ivanovic 1212345347eSHal Finkel static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 1222345347eSHal Finkel uint64_t Address, 123*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1242345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, VRegs); 1252345347eSHal Finkel } 1262345347eSHal Finkel 12727774d92SHal Finkel static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo, 12827774d92SHal Finkel uint64_t Address, 129*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 13027774d92SHal Finkel return decodeRegisterClass(Inst, RegNo, VSRegs); 13127774d92SHal Finkel } 13227774d92SHal Finkel 13319be506aSHal Finkel static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo, 13419be506aSHal Finkel uint64_t Address, 135*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 13619be506aSHal Finkel return decodeRegisterClass(Inst, RegNo, VSFRegs); 13719be506aSHal Finkel } 13819be506aSHal Finkel 139f3c94b1eSNemanja Ivanovic static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo, 140f3c94b1eSNemanja Ivanovic uint64_t Address, 141*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 142f3c94b1eSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, VSSRegs); 143f3c94b1eSNemanja Ivanovic } 144f3c94b1eSNemanja Ivanovic 1452345347eSHal Finkel static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 1462345347eSHal Finkel uint64_t Address, 147*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1480dad994aSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, RRegs); 1492345347eSHal Finkel } 1502345347eSHal Finkel 151*4ae9745aSMaksim Panchenko static DecodeStatus 152*4ae9745aSMaksim Panchenko DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 153*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1540dad994aSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, RRegsNoR0); 1552345347eSHal Finkel } 1562345347eSHal Finkel 1572345347eSHal Finkel static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo, 1582345347eSHal Finkel uint64_t Address, 159*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1600dad994aSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, XRegs); 1612345347eSHal Finkel } 1622345347eSHal Finkel 1631c450c3dSKai Luo static DecodeStatus DecodeG8pRCRegisterClass(MCInst &Inst, uint64_t RegNo, 1641c450c3dSKai Luo uint64_t Address, 165*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1661c450c3dSKai Luo return decodeRegisterClass(Inst, RegNo, XRegs); 1671c450c3dSKai Luo } 1681c450c3dSKai Luo 169*4ae9745aSMaksim Panchenko static DecodeStatus 170*4ae9745aSMaksim Panchenko DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, 171*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1720dad994aSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, XRegsNoX0); 17322e7da95SGuozhi Wei } 17422e7da95SGuozhi Wei 1752345347eSHal Finkel #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass 1762345347eSHal Finkel #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass 1772345347eSHal Finkel 178d52990c7SJustin Hibbits static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo, 179d52990c7SJustin Hibbits uint64_t Address, 180*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 181d52990c7SJustin Hibbits return decodeRegisterClass(Inst, RegNo, SPERegs); 182d52990c7SJustin Hibbits } 183d52990c7SJustin Hibbits 1849b86b700SBaptiste Saleil static DecodeStatus DecodeACCRCRegisterClass(MCInst &Inst, uint64_t RegNo, 1859b86b700SBaptiste Saleil uint64_t Address, 186*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1879b86b700SBaptiste Saleil return decodeRegisterClass(Inst, RegNo, ACCRegs); 1889b86b700SBaptiste Saleil } 1899b86b700SBaptiste Saleil 1901372e23cSBaptiste Saleil static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo, 1911372e23cSBaptiste Saleil uint64_t Address, 192*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 1931372e23cSBaptiste Saleil return decodeRegisterClass(Inst, RegNo, VSRpRegs); 1941372e23cSBaptiste Saleil } 1951372e23cSBaptiste Saleil 196c93a9a2cSHal Finkel #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass 197c93a9a2cSHal Finkel #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass 198c93a9a2cSHal Finkel 1992345347eSHal Finkel template <unsigned N> 2002345347eSHal Finkel static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 201*4ae9745aSMaksim Panchenko int64_t Address, 202*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 2032345347eSHal Finkel assert(isUInt<N>(Imm) && "Invalid immediate"); 204e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Imm)); 2052345347eSHal Finkel return MCDisassembler::Success; 2062345347eSHal Finkel } 2072345347eSHal Finkel 2082345347eSHal Finkel template <unsigned N> 2092345347eSHal Finkel static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 210*4ae9745aSMaksim Panchenko int64_t Address, 211*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 2122345347eSHal Finkel assert(isUInt<N>(Imm) && "Invalid immediate"); 213e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 2142345347eSHal Finkel return MCDisassembler::Success; 2152345347eSHal Finkel } 2162345347eSHal Finkel 2175cee3401SVictor Huang static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm, 218*4ae9745aSMaksim Panchenko int64_t Address, 219*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 2205cee3401SVictor Huang if (Imm != 0) 2215cee3401SVictor Huang return MCDisassembler::Fail; 2225cee3401SVictor Huang Inst.addOperand(MCOperand::createImm(Imm)); 2235cee3401SVictor Huang return MCDisassembler::Success; 2245cee3401SVictor Huang } 2255cee3401SVictor Huang 22666d2e3f4SAhsan Saghir static DecodeStatus decodeVSRpEvenOperands(MCInst &Inst, uint64_t RegNo, 22766d2e3f4SAhsan Saghir uint64_t Address, 228*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 22966d2e3f4SAhsan Saghir if (RegNo & 1) 23066d2e3f4SAhsan Saghir return MCDisassembler::Fail; 23166d2e3f4SAhsan Saghir Inst.addOperand(MCOperand::createReg(VSRpRegs[RegNo >> 1])); 23266d2e3f4SAhsan Saghir return MCDisassembler::Success; 23366d2e3f4SAhsan Saghir } 23466d2e3f4SAhsan Saghir 2352345347eSHal Finkel static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm, 236*4ae9745aSMaksim Panchenko int64_t Address, 237*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 2382345347eSHal Finkel // Decode the memri field (imm, reg), which has the low 16-bits as the 2392345347eSHal Finkel // displacement and the next 5 bits as the register #. 2402345347eSHal Finkel 2412345347eSHal Finkel uint64_t Base = Imm >> 16; 2422345347eSHal Finkel uint64_t Disp = Imm & 0xFFFF; 2432345347eSHal Finkel 2442345347eSHal Finkel assert(Base < 32 && "Invalid base register"); 2452345347eSHal Finkel 2462345347eSHal Finkel switch (Inst.getOpcode()) { 2472345347eSHal Finkel default: break; 2482345347eSHal Finkel case PPC::LBZU: 2492345347eSHal Finkel case PPC::LHAU: 2502345347eSHal Finkel case PPC::LHZU: 2512345347eSHal Finkel case PPC::LWZU: 2522345347eSHal Finkel case PPC::LFSU: 2532345347eSHal Finkel case PPC::LFDU: 2542345347eSHal Finkel // Add the tied output operand. 2550dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 2562345347eSHal Finkel break; 2572345347eSHal Finkel case PPC::STBU: 2582345347eSHal Finkel case PPC::STHU: 2592345347eSHal Finkel case PPC::STWU: 2602345347eSHal Finkel case PPC::STFSU: 2612345347eSHal Finkel case PPC::STFDU: 2620dad994aSNemanja Ivanovic Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base])); 2632345347eSHal Finkel break; 2642345347eSHal Finkel } 2652345347eSHal Finkel 266e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp))); 2670dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 2682345347eSHal Finkel return MCDisassembler::Success; 2692345347eSHal Finkel } 2702345347eSHal Finkel 2712345347eSHal Finkel static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm, 272*4ae9745aSMaksim Panchenko int64_t Address, 273*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 2742345347eSHal Finkel // Decode the memrix field (imm, reg), which has the low 14-bits as the 2752345347eSHal Finkel // displacement and the next 5 bits as the register #. 2762345347eSHal Finkel 2772345347eSHal Finkel uint64_t Base = Imm >> 14; 2782345347eSHal Finkel uint64_t Disp = Imm & 0x3FFF; 2792345347eSHal Finkel 2802345347eSHal Finkel assert(Base < 32 && "Invalid base register"); 2812345347eSHal Finkel 2822345347eSHal Finkel if (Inst.getOpcode() == PPC::LDU) 2832345347eSHal Finkel // Add the tied output operand. 2840dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 2852345347eSHal Finkel else if (Inst.getOpcode() == PPC::STDU) 2860dad994aSNemanja Ivanovic Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base])); 2872345347eSHal Finkel 288e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2))); 2890dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 2902345347eSHal Finkel return MCDisassembler::Success; 2912345347eSHal Finkel } 2922345347eSHal Finkel 293f28cb01bSStefan Pintilie static DecodeStatus decodeMemRIHashOperands(MCInst &Inst, uint64_t Imm, 294f28cb01bSStefan Pintilie int64_t Address, 295*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 296f28cb01bSStefan Pintilie // Decode the memrix field for a hash store or hash check operation. 297f28cb01bSStefan Pintilie // The field is composed of a register and an immediate value that is 6 bits 298f28cb01bSStefan Pintilie // and covers the range -8 to -512. The immediate is always negative and 2s 299f28cb01bSStefan Pintilie // complement which is why we sign extend a 7 bit value. 300f28cb01bSStefan Pintilie const uint64_t Base = Imm >> 6; 301f28cb01bSStefan Pintilie const int64_t Disp = SignExtend64<7>((Imm & 0x3F) + 64) * 8; 302f28cb01bSStefan Pintilie 303f28cb01bSStefan Pintilie assert(Base < 32 && "Invalid base register"); 304f28cb01bSStefan Pintilie 305f28cb01bSStefan Pintilie Inst.addOperand(MCOperand::createImm(Disp)); 306f28cb01bSStefan Pintilie Inst.addOperand(MCOperand::createReg(RRegs[Base])); 307f28cb01bSStefan Pintilie return MCDisassembler::Success; 308f28cb01bSStefan Pintilie } 309f28cb01bSStefan Pintilie 310ba532dc8SKit Barton static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm, 311*4ae9745aSMaksim Panchenko int64_t Address, 312*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 313ba532dc8SKit Barton // Decode the memrix16 field (imm, reg), which has the low 12-bits as the 314ba532dc8SKit Barton // displacement with 16-byte aligned, and the next 5 bits as the register #. 315ba532dc8SKit Barton 316ba532dc8SKit Barton uint64_t Base = Imm >> 12; 317ba532dc8SKit Barton uint64_t Disp = Imm & 0xFFF; 318ba532dc8SKit Barton 319ba532dc8SKit Barton assert(Base < 32 && "Invalid base register"); 320ba532dc8SKit Barton 321ba532dc8SKit Barton Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4))); 3220dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 323ba532dc8SKit Barton return MCDisassembler::Success; 324ba532dc8SKit Barton } 325ba532dc8SKit Barton 3264b414d9aSVictor Huang static DecodeStatus decodeMemRI34PCRelOperands(MCInst &Inst, uint64_t Imm, 3274b414d9aSVictor Huang int64_t Address, 328*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 3294b414d9aSVictor Huang // Decode the memri34_pcrel field (imm, reg), which has the low 34-bits as the 3304b414d9aSVictor Huang // displacement, and the next 5 bits as an immediate 0. 3314b414d9aSVictor Huang uint64_t Base = Imm >> 34; 3324b414d9aSVictor Huang uint64_t Disp = Imm & 0x3FFFFFFFFUL; 3334b414d9aSVictor Huang 3344b414d9aSVictor Huang assert(Base < 32 && "Invalid base register"); 3354b414d9aSVictor Huang 3364b414d9aSVictor Huang Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp))); 3374b414d9aSVictor Huang return decodeImmZeroOperand(Inst, Base, Address, Decoder); 3384b414d9aSVictor Huang } 3394b414d9aSVictor Huang 3404b414d9aSVictor Huang static DecodeStatus decodeMemRI34Operands(MCInst &Inst, uint64_t Imm, 3414b414d9aSVictor Huang int64_t Address, 342*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 3434b414d9aSVictor Huang // Decode the memri34 field (imm, reg), which has the low 34-bits as the 3444b414d9aSVictor Huang // displacement, and the next 5 bits as the register #. 3454b414d9aSVictor Huang uint64_t Base = Imm >> 34; 3464b414d9aSVictor Huang uint64_t Disp = Imm & 0x3FFFFFFFFUL; 3474b414d9aSVictor Huang 3484b414d9aSVictor Huang assert(Base < 32 && "Invalid base register"); 3494b414d9aSVictor Huang 3504b414d9aSVictor Huang Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp))); 3514b414d9aSVictor Huang Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 3524b414d9aSVictor Huang return MCDisassembler::Success; 3534b414d9aSVictor Huang } 3544b414d9aSVictor Huang 3554fa4fa6aSJustin Hibbits static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm, 356*4ae9745aSMaksim Panchenko int64_t Address, 357*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 3584fa4fa6aSJustin Hibbits // Decode the spe8disp field (imm, reg), which has the low 5-bits as the 3594fa4fa6aSJustin Hibbits // displacement with 8-byte aligned, and the next 5 bits as the register #. 3604fa4fa6aSJustin Hibbits 3614fa4fa6aSJustin Hibbits uint64_t Base = Imm >> 5; 3624fa4fa6aSJustin Hibbits uint64_t Disp = Imm & 0x1F; 3634fa4fa6aSJustin Hibbits 3644fa4fa6aSJustin Hibbits assert(Base < 32 && "Invalid base register"); 3654fa4fa6aSJustin Hibbits 3664fa4fa6aSJustin Hibbits Inst.addOperand(MCOperand::createImm(Disp << 3)); 3670dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 3684fa4fa6aSJustin Hibbits return MCDisassembler::Success; 3694fa4fa6aSJustin Hibbits } 3704fa4fa6aSJustin Hibbits 3714fa4fa6aSJustin Hibbits static DecodeStatus decodeSPE4Operands(MCInst &Inst, uint64_t Imm, 372*4ae9745aSMaksim Panchenko int64_t Address, 373*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 3744fa4fa6aSJustin Hibbits // Decode the spe4disp field (imm, reg), which has the low 5-bits as the 3754fa4fa6aSJustin Hibbits // displacement with 4-byte aligned, and the next 5 bits as the register #. 3764fa4fa6aSJustin Hibbits 3774fa4fa6aSJustin Hibbits uint64_t Base = Imm >> 5; 3784fa4fa6aSJustin Hibbits uint64_t Disp = Imm & 0x1F; 3794fa4fa6aSJustin Hibbits 3804fa4fa6aSJustin Hibbits assert(Base < 32 && "Invalid base register"); 3814fa4fa6aSJustin Hibbits 3824fa4fa6aSJustin Hibbits Inst.addOperand(MCOperand::createImm(Disp << 2)); 3830dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 3844fa4fa6aSJustin Hibbits return MCDisassembler::Success; 3854fa4fa6aSJustin Hibbits } 3864fa4fa6aSJustin Hibbits 3874fa4fa6aSJustin Hibbits static DecodeStatus decodeSPE2Operands(MCInst &Inst, uint64_t Imm, 388*4ae9745aSMaksim Panchenko int64_t Address, 389*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 3904fa4fa6aSJustin Hibbits // Decode the spe2disp field (imm, reg), which has the low 5-bits as the 3914fa4fa6aSJustin Hibbits // displacement with 2-byte aligned, and the next 5 bits as the register #. 3924fa4fa6aSJustin Hibbits 3934fa4fa6aSJustin Hibbits uint64_t Base = Imm >> 5; 3944fa4fa6aSJustin Hibbits uint64_t Disp = Imm & 0x1F; 3954fa4fa6aSJustin Hibbits 3964fa4fa6aSJustin Hibbits assert(Base < 32 && "Invalid base register"); 3974fa4fa6aSJustin Hibbits 3984fa4fa6aSJustin Hibbits Inst.addOperand(MCOperand::createImm(Disp << 1)); 3990dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 4004fa4fa6aSJustin Hibbits return MCDisassembler::Success; 4014fa4fa6aSJustin Hibbits } 4024fa4fa6aSJustin Hibbits 4032345347eSHal Finkel static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm, 404*4ae9745aSMaksim Panchenko int64_t Address, 405*4ae9745aSMaksim Panchenko const MCDisassembler *Decoder) { 4062345347eSHal Finkel // The cr bit encoding is 0x80 >> cr_reg_num. 4072345347eSHal Finkel 4082345347eSHal Finkel unsigned Zeros = countTrailingZeros(Imm); 4092345347eSHal Finkel assert(Zeros < 8 && "Invalid CR bit value"); 4102345347eSHal Finkel 411e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros])); 4122345347eSHal Finkel return MCDisassembler::Success; 4132345347eSHal Finkel } 4142345347eSHal Finkel 4152345347eSHal Finkel #include "PPCGenDisassemblerTables.inc" 4162345347eSHal Finkel 4172345347eSHal Finkel DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 4187fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 4196fdd6a7bSFangrui Song uint64_t Address, 4204aa6bea7SRafael Espindola raw_ostream &CS) const { 4215cee3401SVictor Huang auto *ReadFunc = IsLittleEndian ? support::endian::read32le 4225cee3401SVictor Huang : support::endian::read32be; 4235cee3401SVictor Huang 4245cee3401SVictor Huang // If this is an 8-byte prefixed instruction, handle it here. 4255cee3401SVictor Huang // Note: prefixed instructions aren't technically 8-byte entities - the prefix 4265cee3401SVictor Huang // appears in memory at an address 4 bytes prior to that of the base 4275cee3401SVictor Huang // instruction regardless of endianness. So we read the two pieces and 4285cee3401SVictor Huang // rebuild the 8-byte instruction. 4295cee3401SVictor Huang // TODO: In this function we call decodeInstruction several times with 4305cee3401SVictor Huang // different decoder tables. It may be possible to only call once by 4315cee3401SVictor Huang // looking at the top 6 bits of the instruction. 4325cee3401SVictor Huang if (STI.getFeatureBits()[PPC::FeaturePrefixInstrs] && Bytes.size() >= 8) { 4335cee3401SVictor Huang uint32_t Prefix = ReadFunc(Bytes.data()); 4345cee3401SVictor Huang uint32_t BaseInst = ReadFunc(Bytes.data() + 4); 4355cee3401SVictor Huang uint64_t Inst = BaseInst | (uint64_t)Prefix << 32; 4365cee3401SVictor Huang DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address, 4375cee3401SVictor Huang this, STI); 4385cee3401SVictor Huang if (result != MCDisassembler::Fail) { 4395cee3401SVictor Huang Size = 8; 4405cee3401SVictor Huang return result; 4415cee3401SVictor Huang } 4425cee3401SVictor Huang } 4435cee3401SVictor Huang 4442345347eSHal Finkel // Get the four bytes of the instruction. 4452345347eSHal Finkel Size = 4; 4467fc5b874SRafael Espindola if (Bytes.size() < 4) { 4472345347eSHal Finkel Size = 0; 4482345347eSHal Finkel return MCDisassembler::Fail; 4492345347eSHal Finkel } 4502345347eSHal Finkel 451c11fd3e7SBenjamin Kramer // Read the instruction in the proper endianness. 4525cee3401SVictor Huang uint64_t Inst = ReadFunc(Bytes.data()); 4532345347eSHal Finkel 454d28f8672SJinsong Ji if (STI.getFeatureBits()[PPC::FeatureSPE]) { 4554fa4fa6aSJustin Hibbits DecodeStatus result = 4564fa4fa6aSJustin Hibbits decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI); 4574fa4fa6aSJustin Hibbits if (result != MCDisassembler::Fail) 4584fa4fa6aSJustin Hibbits return result; 459c93a9a2cSHal Finkel } 460c93a9a2cSHal Finkel 4612345347eSHal Finkel return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI); 4622345347eSHal Finkel } 463