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" 15c11fd3e7SBenjamin Kramer #include "llvm/Support/Endian.h" 162345347eSHal Finkel #include "llvm/Support/TargetRegistry.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); 57f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getThePPC64Target(), 582345347eSHal Finkel createPPCDisassembler); 59f42454b9SMehdi Amini TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(), 60c11fd3e7SBenjamin Kramer createPPCLEDisassembler); 612345347eSHal Finkel } 622345347eSHal Finkel 634af7560bSFangrui Song static DecodeStatus decodeCondBrTarget(MCInst &Inst, unsigned Imm, 644af7560bSFangrui Song uint64_t /*Address*/, 654af7560bSFangrui Song const void * /*Decoder*/) { 664af7560bSFangrui Song Inst.addOperand(MCOperand::createImm(SignExtend32<14>(Imm))); 674af7560bSFangrui Song return MCDisassembler::Success; 684af7560bSFangrui Song } 694af7560bSFangrui Song 70*85adce3dSFangrui Song static DecodeStatus decodeDirectBrTarget(MCInst &Inst, unsigned Imm, 71*85adce3dSFangrui Song uint64_t /*Address*/, 72*85adce3dSFangrui Song const void * /*Decoder*/) { 73c0694520SSean Fertile int32_t Offset = SignExtend32<24>(Imm); 74c0694520SSean Fertile Inst.addOperand(MCOperand::createImm(Offset)); 75c0694520SSean Fertile return MCDisassembler::Success; 76c0694520SSean Fertile } 77c0694520SSean Fertile 782345347eSHal Finkel // FIXME: These can be generated by TableGen from the existing register 792345347eSHal Finkel // encoding values! 802345347eSHal Finkel 812345347eSHal Finkel template <std::size_t N> 822345347eSHal Finkel static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo, 830dad994aSNemanja Ivanovic const MCPhysReg (&Regs)[N]) { 842345347eSHal Finkel assert(RegNo < N && "Invalid register number"); 85e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(Regs[RegNo])); 862345347eSHal Finkel return MCDisassembler::Success; 872345347eSHal Finkel } 882345347eSHal Finkel 892345347eSHal Finkel static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 902345347eSHal Finkel uint64_t Address, 912345347eSHal Finkel const void *Decoder) { 922345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, CRRegs); 932345347eSHal Finkel } 942345347eSHal Finkel 952345347eSHal Finkel static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo, 962345347eSHal Finkel uint64_t Address, 972345347eSHal Finkel const void *Decoder) { 982345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, CRBITRegs); 992345347eSHal Finkel } 1002345347eSHal Finkel 1012345347eSHal Finkel static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo, 1022345347eSHal Finkel uint64_t Address, 1032345347eSHal Finkel const void *Decoder) { 1042345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, FRegs); 1052345347eSHal Finkel } 1062345347eSHal Finkel 1072345347eSHal Finkel static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo, 1082345347eSHal Finkel uint64_t Address, 1092345347eSHal Finkel const void *Decoder) { 1102345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, FRegs); 1112345347eSHal Finkel } 1122345347eSHal Finkel 11311049f8fSNemanja Ivanovic static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo, 11411049f8fSNemanja Ivanovic uint64_t Address, 11511049f8fSNemanja Ivanovic const void *Decoder) { 11611049f8fSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, VFRegs); 11711049f8fSNemanja Ivanovic } 11811049f8fSNemanja Ivanovic 1192345347eSHal Finkel static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo, 1202345347eSHal Finkel uint64_t Address, 1212345347eSHal Finkel const void *Decoder) { 1222345347eSHal Finkel return decodeRegisterClass(Inst, RegNo, VRegs); 1232345347eSHal Finkel } 1242345347eSHal Finkel 12527774d92SHal Finkel static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo, 12627774d92SHal Finkel uint64_t Address, 12727774d92SHal Finkel const void *Decoder) { 12827774d92SHal Finkel return decodeRegisterClass(Inst, RegNo, VSRegs); 12927774d92SHal Finkel } 13027774d92SHal Finkel 13119be506aSHal Finkel static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo, 13219be506aSHal Finkel uint64_t Address, 13319be506aSHal Finkel const void *Decoder) { 13419be506aSHal Finkel return decodeRegisterClass(Inst, RegNo, VSFRegs); 13519be506aSHal Finkel } 13619be506aSHal Finkel 137f3c94b1eSNemanja Ivanovic static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo, 138f3c94b1eSNemanja Ivanovic uint64_t Address, 139f3c94b1eSNemanja Ivanovic const void *Decoder) { 140f3c94b1eSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, VSSRegs); 141f3c94b1eSNemanja Ivanovic } 142f3c94b1eSNemanja Ivanovic 1432345347eSHal Finkel static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo, 1442345347eSHal Finkel uint64_t Address, 1452345347eSHal Finkel const void *Decoder) { 1460dad994aSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, RRegs); 1472345347eSHal Finkel } 1482345347eSHal Finkel 1492345347eSHal Finkel static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo, 1502345347eSHal Finkel uint64_t Address, 1512345347eSHal Finkel const void *Decoder) { 1520dad994aSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, RRegsNoR0); 1532345347eSHal Finkel } 1542345347eSHal Finkel 1552345347eSHal Finkel static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo, 1562345347eSHal Finkel uint64_t Address, 1572345347eSHal Finkel const void *Decoder) { 1580dad994aSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, XRegs); 1592345347eSHal Finkel } 1602345347eSHal Finkel 16122e7da95SGuozhi Wei static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo, 16222e7da95SGuozhi Wei uint64_t Address, 16322e7da95SGuozhi Wei const void *Decoder) { 1640dad994aSNemanja Ivanovic return decodeRegisterClass(Inst, RegNo, XRegsNoX0); 16522e7da95SGuozhi Wei } 16622e7da95SGuozhi Wei 1672345347eSHal Finkel #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass 1682345347eSHal Finkel #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass 1692345347eSHal Finkel 170c93a9a2cSHal Finkel static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo, 171c93a9a2cSHal Finkel uint64_t Address, 172c93a9a2cSHal Finkel const void *Decoder) { 173c93a9a2cSHal Finkel return decodeRegisterClass(Inst, RegNo, QFRegs); 174c93a9a2cSHal Finkel } 175c93a9a2cSHal Finkel 176d52990c7SJustin Hibbits static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo, 177d52990c7SJustin Hibbits uint64_t Address, 178d52990c7SJustin Hibbits const void *Decoder) { 179d52990c7SJustin Hibbits return decodeRegisterClass(Inst, RegNo, SPERegs); 180d52990c7SJustin Hibbits } 181d52990c7SJustin Hibbits 182c93a9a2cSHal Finkel #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass 183c93a9a2cSHal Finkel #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass 184c93a9a2cSHal Finkel 1852345347eSHal Finkel template<unsigned N> 1862345347eSHal Finkel static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm, 1872345347eSHal Finkel int64_t Address, const void *Decoder) { 1882345347eSHal Finkel assert(isUInt<N>(Imm) && "Invalid immediate"); 189e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(Imm)); 1902345347eSHal Finkel return MCDisassembler::Success; 1912345347eSHal Finkel } 1922345347eSHal Finkel 1932345347eSHal Finkel template<unsigned N> 1942345347eSHal Finkel static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm, 1952345347eSHal Finkel int64_t Address, const void *Decoder) { 1962345347eSHal Finkel assert(isUInt<N>(Imm) && "Invalid immediate"); 197e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm))); 1982345347eSHal Finkel return MCDisassembler::Success; 1992345347eSHal Finkel } 2002345347eSHal Finkel 2015cee3401SVictor Huang static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm, 2025cee3401SVictor Huang int64_t Address, const void *Decoder) { 2035cee3401SVictor Huang if (Imm != 0) 2045cee3401SVictor Huang return MCDisassembler::Fail; 2055cee3401SVictor Huang Inst.addOperand(MCOperand::createImm(Imm)); 2065cee3401SVictor Huang return MCDisassembler::Success; 2075cee3401SVictor Huang } 2085cee3401SVictor Huang 2092345347eSHal Finkel static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm, 2102345347eSHal Finkel int64_t Address, const void *Decoder) { 2112345347eSHal Finkel // Decode the memri field (imm, reg), which has the low 16-bits as the 2122345347eSHal Finkel // displacement and the next 5 bits as the register #. 2132345347eSHal Finkel 2142345347eSHal Finkel uint64_t Base = Imm >> 16; 2152345347eSHal Finkel uint64_t Disp = Imm & 0xFFFF; 2162345347eSHal Finkel 2172345347eSHal Finkel assert(Base < 32 && "Invalid base register"); 2182345347eSHal Finkel 2192345347eSHal Finkel switch (Inst.getOpcode()) { 2202345347eSHal Finkel default: break; 2212345347eSHal Finkel case PPC::LBZU: 2222345347eSHal Finkel case PPC::LHAU: 2232345347eSHal Finkel case PPC::LHZU: 2242345347eSHal Finkel case PPC::LWZU: 2252345347eSHal Finkel case PPC::LFSU: 2262345347eSHal Finkel case PPC::LFDU: 2272345347eSHal Finkel // Add the tied output operand. 2280dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 2292345347eSHal Finkel break; 2302345347eSHal Finkel case PPC::STBU: 2312345347eSHal Finkel case PPC::STHU: 2322345347eSHal Finkel case PPC::STWU: 2332345347eSHal Finkel case PPC::STFSU: 2342345347eSHal Finkel case PPC::STFDU: 2350dad994aSNemanja Ivanovic Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base])); 2362345347eSHal Finkel break; 2372345347eSHal Finkel } 2382345347eSHal Finkel 239e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp))); 2400dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 2412345347eSHal Finkel return MCDisassembler::Success; 2422345347eSHal Finkel } 2432345347eSHal Finkel 2442345347eSHal Finkel static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm, 2452345347eSHal Finkel int64_t Address, const void *Decoder) { 2462345347eSHal Finkel // Decode the memrix field (imm, reg), which has the low 14-bits as the 2472345347eSHal Finkel // displacement and the next 5 bits as the register #. 2482345347eSHal Finkel 2492345347eSHal Finkel uint64_t Base = Imm >> 14; 2502345347eSHal Finkel uint64_t Disp = Imm & 0x3FFF; 2512345347eSHal Finkel 2522345347eSHal Finkel assert(Base < 32 && "Invalid base register"); 2532345347eSHal Finkel 2542345347eSHal Finkel if (Inst.getOpcode() == PPC::LDU) 2552345347eSHal Finkel // Add the tied output operand. 2560dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 2572345347eSHal Finkel else if (Inst.getOpcode() == PPC::STDU) 2580dad994aSNemanja Ivanovic Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base])); 2592345347eSHal Finkel 260e9119e41SJim Grosbach Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2))); 2610dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 2622345347eSHal Finkel return MCDisassembler::Success; 2632345347eSHal Finkel } 2642345347eSHal Finkel 265ba532dc8SKit Barton static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm, 266ba532dc8SKit Barton int64_t Address, const void *Decoder) { 267ba532dc8SKit Barton // Decode the memrix16 field (imm, reg), which has the low 12-bits as the 268ba532dc8SKit Barton // displacement with 16-byte aligned, and the next 5 bits as the register #. 269ba532dc8SKit Barton 270ba532dc8SKit Barton uint64_t Base = Imm >> 12; 271ba532dc8SKit Barton uint64_t Disp = Imm & 0xFFF; 272ba532dc8SKit Barton 273ba532dc8SKit Barton assert(Base < 32 && "Invalid base register"); 274ba532dc8SKit Barton 275ba532dc8SKit Barton Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4))); 2760dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 277ba532dc8SKit Barton return MCDisassembler::Success; 278ba532dc8SKit Barton } 279ba532dc8SKit Barton 2804b414d9aSVictor Huang static DecodeStatus decodeMemRI34PCRelOperands(MCInst &Inst, uint64_t Imm, 2814b414d9aSVictor Huang int64_t Address, 2824b414d9aSVictor Huang const void *Decoder) { 2834b414d9aSVictor Huang // Decode the memri34_pcrel field (imm, reg), which has the low 34-bits as the 2844b414d9aSVictor Huang // displacement, and the next 5 bits as an immediate 0. 2854b414d9aSVictor Huang uint64_t Base = Imm >> 34; 2864b414d9aSVictor Huang uint64_t Disp = Imm & 0x3FFFFFFFFUL; 2874b414d9aSVictor Huang 2884b414d9aSVictor Huang assert(Base < 32 && "Invalid base register"); 2894b414d9aSVictor Huang 2904b414d9aSVictor Huang Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp))); 2914b414d9aSVictor Huang return decodeImmZeroOperand(Inst, Base, Address, Decoder); 2924b414d9aSVictor Huang } 2934b414d9aSVictor Huang 2944b414d9aSVictor Huang static DecodeStatus decodeMemRI34Operands(MCInst &Inst, uint64_t Imm, 2954b414d9aSVictor Huang int64_t Address, 2964b414d9aSVictor Huang const void *Decoder) { 2974b414d9aSVictor Huang // Decode the memri34 field (imm, reg), which has the low 34-bits as the 2984b414d9aSVictor Huang // displacement, and the next 5 bits as the register #. 2994b414d9aSVictor Huang uint64_t Base = Imm >> 34; 3004b414d9aSVictor Huang uint64_t Disp = Imm & 0x3FFFFFFFFUL; 3014b414d9aSVictor Huang 3024b414d9aSVictor Huang assert(Base < 32 && "Invalid base register"); 3034b414d9aSVictor Huang 3044b414d9aSVictor Huang Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp))); 3054b414d9aSVictor Huang Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 3064b414d9aSVictor Huang return MCDisassembler::Success; 3074b414d9aSVictor Huang } 3084b414d9aSVictor Huang 3094fa4fa6aSJustin Hibbits static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm, 3104fa4fa6aSJustin Hibbits int64_t Address, const void *Decoder) { 3114fa4fa6aSJustin Hibbits // Decode the spe8disp field (imm, reg), which has the low 5-bits as the 3124fa4fa6aSJustin Hibbits // displacement with 8-byte aligned, and the next 5 bits as the register #. 3134fa4fa6aSJustin Hibbits 3144fa4fa6aSJustin Hibbits uint64_t Base = Imm >> 5; 3154fa4fa6aSJustin Hibbits uint64_t Disp = Imm & 0x1F; 3164fa4fa6aSJustin Hibbits 3174fa4fa6aSJustin Hibbits assert(Base < 32 && "Invalid base register"); 3184fa4fa6aSJustin Hibbits 3194fa4fa6aSJustin Hibbits Inst.addOperand(MCOperand::createImm(Disp << 3)); 3200dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 3214fa4fa6aSJustin Hibbits return MCDisassembler::Success; 3224fa4fa6aSJustin Hibbits } 3234fa4fa6aSJustin Hibbits 3244fa4fa6aSJustin Hibbits static DecodeStatus decodeSPE4Operands(MCInst &Inst, uint64_t Imm, 3254fa4fa6aSJustin Hibbits int64_t Address, const void *Decoder) { 3264fa4fa6aSJustin Hibbits // Decode the spe4disp field (imm, reg), which has the low 5-bits as the 3274fa4fa6aSJustin Hibbits // displacement with 4-byte aligned, and the next 5 bits as the register #. 3284fa4fa6aSJustin Hibbits 3294fa4fa6aSJustin Hibbits uint64_t Base = Imm >> 5; 3304fa4fa6aSJustin Hibbits uint64_t Disp = Imm & 0x1F; 3314fa4fa6aSJustin Hibbits 3324fa4fa6aSJustin Hibbits assert(Base < 32 && "Invalid base register"); 3334fa4fa6aSJustin Hibbits 3344fa4fa6aSJustin Hibbits Inst.addOperand(MCOperand::createImm(Disp << 2)); 3350dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 3364fa4fa6aSJustin Hibbits return MCDisassembler::Success; 3374fa4fa6aSJustin Hibbits } 3384fa4fa6aSJustin Hibbits 3394fa4fa6aSJustin Hibbits static DecodeStatus decodeSPE2Operands(MCInst &Inst, uint64_t Imm, 3404fa4fa6aSJustin Hibbits int64_t Address, const void *Decoder) { 3414fa4fa6aSJustin Hibbits // Decode the spe2disp field (imm, reg), which has the low 5-bits as the 3424fa4fa6aSJustin Hibbits // displacement with 2-byte aligned, and the next 5 bits as the register #. 3434fa4fa6aSJustin Hibbits 3444fa4fa6aSJustin Hibbits uint64_t Base = Imm >> 5; 3454fa4fa6aSJustin Hibbits uint64_t Disp = Imm & 0x1F; 3464fa4fa6aSJustin Hibbits 3474fa4fa6aSJustin Hibbits assert(Base < 32 && "Invalid base register"); 3484fa4fa6aSJustin Hibbits 3494fa4fa6aSJustin Hibbits Inst.addOperand(MCOperand::createImm(Disp << 1)); 3500dad994aSNemanja Ivanovic Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base])); 3514fa4fa6aSJustin Hibbits return MCDisassembler::Success; 3524fa4fa6aSJustin Hibbits } 3534fa4fa6aSJustin Hibbits 3542345347eSHal Finkel static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm, 3552345347eSHal Finkel int64_t Address, const void *Decoder) { 3562345347eSHal Finkel // The cr bit encoding is 0x80 >> cr_reg_num. 3572345347eSHal Finkel 3582345347eSHal Finkel unsigned Zeros = countTrailingZeros(Imm); 3592345347eSHal Finkel assert(Zeros < 8 && "Invalid CR bit value"); 3602345347eSHal Finkel 361e9119e41SJim Grosbach Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros])); 3622345347eSHal Finkel return MCDisassembler::Success; 3632345347eSHal Finkel } 3642345347eSHal Finkel 3652345347eSHal Finkel #include "PPCGenDisassemblerTables.inc" 3662345347eSHal Finkel 3672345347eSHal Finkel DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size, 3687fc5b874SRafael Espindola ArrayRef<uint8_t> Bytes, 3696fdd6a7bSFangrui Song uint64_t Address, 3704aa6bea7SRafael Espindola raw_ostream &CS) const { 3715cee3401SVictor Huang auto *ReadFunc = IsLittleEndian ? support::endian::read32le 3725cee3401SVictor Huang : support::endian::read32be; 3735cee3401SVictor Huang 3745cee3401SVictor Huang // If this is an 8-byte prefixed instruction, handle it here. 3755cee3401SVictor Huang // Note: prefixed instructions aren't technically 8-byte entities - the prefix 3765cee3401SVictor Huang // appears in memory at an address 4 bytes prior to that of the base 3775cee3401SVictor Huang // instruction regardless of endianness. So we read the two pieces and 3785cee3401SVictor Huang // rebuild the 8-byte instruction. 3795cee3401SVictor Huang // TODO: In this function we call decodeInstruction several times with 3805cee3401SVictor Huang // different decoder tables. It may be possible to only call once by 3815cee3401SVictor Huang // looking at the top 6 bits of the instruction. 3825cee3401SVictor Huang if (STI.getFeatureBits()[PPC::FeaturePrefixInstrs] && Bytes.size() >= 8) { 3835cee3401SVictor Huang uint32_t Prefix = ReadFunc(Bytes.data()); 3845cee3401SVictor Huang uint32_t BaseInst = ReadFunc(Bytes.data() + 4); 3855cee3401SVictor Huang uint64_t Inst = BaseInst | (uint64_t)Prefix << 32; 3865cee3401SVictor Huang DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address, 3875cee3401SVictor Huang this, STI); 3885cee3401SVictor Huang if (result != MCDisassembler::Fail) { 3895cee3401SVictor Huang Size = 8; 3905cee3401SVictor Huang return result; 3915cee3401SVictor Huang } 3925cee3401SVictor Huang } 3935cee3401SVictor Huang 3942345347eSHal Finkel // Get the four bytes of the instruction. 3952345347eSHal Finkel Size = 4; 3967fc5b874SRafael Espindola if (Bytes.size() < 4) { 3972345347eSHal Finkel Size = 0; 3982345347eSHal Finkel return MCDisassembler::Fail; 3992345347eSHal Finkel } 4002345347eSHal Finkel 401c11fd3e7SBenjamin Kramer // Read the instruction in the proper endianness. 4025cee3401SVictor Huang uint64_t Inst = ReadFunc(Bytes.data()); 4032345347eSHal Finkel 404db0712f9SMichael Kuperstein if (STI.getFeatureBits()[PPC::FeatureQPX]) { 405c93a9a2cSHal Finkel DecodeStatus result = 406c93a9a2cSHal Finkel decodeInstruction(DecoderTableQPX32, MI, Inst, Address, this, STI); 407c93a9a2cSHal Finkel if (result != MCDisassembler::Fail) 408c93a9a2cSHal Finkel return result; 4094fa4fa6aSJustin Hibbits } else if (STI.getFeatureBits()[PPC::FeatureSPE]) { 4104fa4fa6aSJustin Hibbits DecodeStatus result = 4114fa4fa6aSJustin Hibbits decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI); 4124fa4fa6aSJustin Hibbits if (result != MCDisassembler::Fail) 4134fa4fa6aSJustin Hibbits return result; 414c93a9a2cSHal Finkel } 415c93a9a2cSHal Finkel 4162345347eSHal Finkel return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI); 4172345347eSHal Finkel } 418