10b57cec5SDimitry Andric //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
100b57cec5SDimitry Andric #include "TargetInfo/PowerPCTargetInfo.h"
110b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
120b57cec5SDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
150b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
160b57cec5SDimitry Andric #include "llvm/Support/TargetRegistry.h"
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric using namespace llvm;
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric DEFINE_PPC_REGCLASSES;
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #define DEBUG_TYPE "ppc-disassembler"
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric namespace {
270b57cec5SDimitry Andric class PPCDisassembler : public MCDisassembler {
280b57cec5SDimitry Andric   bool IsLittleEndian;
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric public:
PPCDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsLittleEndian)310b57cec5SDimitry Andric   PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
320b57cec5SDimitry Andric                   bool IsLittleEndian)
330b57cec5SDimitry Andric       : MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {}
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
360b57cec5SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
370b57cec5SDimitry Andric                               raw_ostream &CStream) const override;
380b57cec5SDimitry Andric };
390b57cec5SDimitry Andric } // end anonymous namespace
400b57cec5SDimitry Andric 
createPPCDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)410b57cec5SDimitry Andric static MCDisassembler *createPPCDisassembler(const Target &T,
420b57cec5SDimitry Andric                                              const MCSubtargetInfo &STI,
430b57cec5SDimitry Andric                                              MCContext &Ctx) {
440b57cec5SDimitry Andric   return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
createPPCLEDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)470b57cec5SDimitry Andric static MCDisassembler *createPPCLEDisassembler(const Target &T,
480b57cec5SDimitry Andric                                                const MCSubtargetInfo &STI,
490b57cec5SDimitry Andric                                                MCContext &Ctx) {
500b57cec5SDimitry Andric   return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric 
LLVMInitializePowerPCDisassembler()53480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCDisassembler() {
540b57cec5SDimitry Andric   // Register the disassembler for each target.
550b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
560b57cec5SDimitry Andric                                          createPPCDisassembler);
57af732203SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(),
58af732203SDimitry Andric                                          createPPCLEDisassembler);
590b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
600b57cec5SDimitry Andric                                          createPPCDisassembler);
610b57cec5SDimitry Andric   TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
620b57cec5SDimitry Andric                                          createPPCLEDisassembler);
630b57cec5SDimitry Andric }
640b57cec5SDimitry Andric 
decodeCondBrTarget(MCInst & Inst,unsigned Imm,uint64_t,const void *)655ffd83dbSDimitry Andric static DecodeStatus decodeCondBrTarget(MCInst &Inst, unsigned Imm,
665ffd83dbSDimitry Andric                                        uint64_t /*Address*/,
675ffd83dbSDimitry Andric                                        const void * /*Decoder*/) {
685ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend32<14>(Imm)));
695ffd83dbSDimitry Andric   return MCDisassembler::Success;
705ffd83dbSDimitry Andric }
715ffd83dbSDimitry Andric 
decodeDirectBrTarget(MCInst & Inst,unsigned Imm,uint64_t,const void *)725ffd83dbSDimitry Andric static DecodeStatus decodeDirectBrTarget(MCInst &Inst, unsigned Imm,
735ffd83dbSDimitry Andric                                          uint64_t /*Address*/,
745ffd83dbSDimitry Andric                                          const void * /*Decoder*/) {
750b57cec5SDimitry Andric   int32_t Offset = SignExtend32<24>(Imm);
760b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
770b57cec5SDimitry Andric   return MCDisassembler::Success;
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric // FIXME: These can be generated by TableGen from the existing register
810b57cec5SDimitry Andric // encoding values!
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric template <std::size_t N>
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const MCPhysReg (& Regs)[N])840b57cec5SDimitry Andric static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
850b57cec5SDimitry Andric                                         const MCPhysReg (&Regs)[N]) {
860b57cec5SDimitry Andric   assert(RegNo < N && "Invalid register number");
870b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
880b57cec5SDimitry Andric   return MCDisassembler::Success;
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric 
DecodeCRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)910b57cec5SDimitry Andric static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
920b57cec5SDimitry Andric                                             uint64_t Address,
930b57cec5SDimitry Andric                                             const void *Decoder) {
940b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, CRRegs);
950b57cec5SDimitry Andric }
960b57cec5SDimitry Andric 
DecodeCRBITRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)970b57cec5SDimitry Andric static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
980b57cec5SDimitry Andric                                             uint64_t Address,
990b57cec5SDimitry Andric                                             const void *Decoder) {
1000b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, CRBITRegs);
1010b57cec5SDimitry Andric }
1020b57cec5SDimitry Andric 
DecodeF4RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1030b57cec5SDimitry Andric static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
1040b57cec5SDimitry Andric                                             uint64_t Address,
1050b57cec5SDimitry Andric                                             const void *Decoder) {
1060b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, FRegs);
1070b57cec5SDimitry Andric }
1080b57cec5SDimitry Andric 
DecodeF8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1090b57cec5SDimitry Andric static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
1100b57cec5SDimitry Andric                                             uint64_t Address,
1110b57cec5SDimitry Andric                                             const void *Decoder) {
1120b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, FRegs);
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
DecodeVFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1150b57cec5SDimitry Andric static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1160b57cec5SDimitry Andric                                             uint64_t Address,
1170b57cec5SDimitry Andric                                             const void *Decoder) {
1180b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, VFRegs);
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
DecodeVRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1210b57cec5SDimitry Andric static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1220b57cec5SDimitry Andric                                             uint64_t Address,
1230b57cec5SDimitry Andric                                             const void *Decoder) {
1240b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, VRegs);
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
DecodeVSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1270b57cec5SDimitry Andric static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1280b57cec5SDimitry Andric                                             uint64_t Address,
1290b57cec5SDimitry Andric                                             const void *Decoder) {
1300b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, VSRegs);
1310b57cec5SDimitry Andric }
1320b57cec5SDimitry Andric 
DecodeVSFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1330b57cec5SDimitry Andric static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1340b57cec5SDimitry Andric                                             uint64_t Address,
1350b57cec5SDimitry Andric                                             const void *Decoder) {
1360b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, VSFRegs);
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
DecodeVSSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1390b57cec5SDimitry Andric static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1400b57cec5SDimitry Andric                                             uint64_t Address,
1410b57cec5SDimitry Andric                                             const void *Decoder) {
1420b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, VSSRegs);
1430b57cec5SDimitry Andric }
1440b57cec5SDimitry Andric 
DecodeGPRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1450b57cec5SDimitry Andric static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1460b57cec5SDimitry Andric                                             uint64_t Address,
1470b57cec5SDimitry Andric                                             const void *Decoder) {
1480b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, RRegs);
1490b57cec5SDimitry Andric }
1500b57cec5SDimitry Andric 
DecodeGPRC_NOR0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1510b57cec5SDimitry Andric static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo,
1520b57cec5SDimitry Andric                                             uint64_t Address,
1530b57cec5SDimitry Andric                                             const void *Decoder) {
1540b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
DecodeG8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1570b57cec5SDimitry Andric static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
1580b57cec5SDimitry Andric                                             uint64_t Address,
1590b57cec5SDimitry Andric                                             const void *Decoder) {
1600b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, XRegs);
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
DecodeG8pRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)163*5f7ddb14SDimitry Andric static DecodeStatus DecodeG8pRCRegisterClass(MCInst &Inst, uint64_t RegNo,
164*5f7ddb14SDimitry Andric                                              uint64_t Address,
165*5f7ddb14SDimitry Andric                                              const void *Decoder) {
166*5f7ddb14SDimitry Andric   return decodeRegisterClass(Inst, RegNo, XRegs);
167*5f7ddb14SDimitry Andric }
168*5f7ddb14SDimitry Andric 
DecodeG8RC_NOX0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1690b57cec5SDimitry Andric static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo,
1700b57cec5SDimitry Andric                                             uint64_t Address,
1710b57cec5SDimitry Andric                                             const void *Decoder) {
1720b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, XRegsNoX0);
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
1760b57cec5SDimitry Andric #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
1770b57cec5SDimitry Andric 
DecodeSPERCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1780b57cec5SDimitry Andric static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
1790b57cec5SDimitry Andric                                             uint64_t Address,
1800b57cec5SDimitry Andric                                             const void *Decoder) {
1810b57cec5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SPERegs);
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric 
DecodeACCRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)184af732203SDimitry Andric static DecodeStatus DecodeACCRCRegisterClass(MCInst &Inst, uint64_t RegNo,
185af732203SDimitry Andric                                              uint64_t Address,
186af732203SDimitry Andric                                              const void *Decoder) {
187af732203SDimitry Andric   return decodeRegisterClass(Inst, RegNo, ACCRegs);
188af732203SDimitry Andric }
189af732203SDimitry Andric 
DecodeVSRpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)190af732203SDimitry Andric static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
191af732203SDimitry Andric                                               uint64_t Address,
192af732203SDimitry Andric                                               const void *Decoder) {
193af732203SDimitry Andric   return decodeRegisterClass(Inst, RegNo, VSRpRegs);
194af732203SDimitry Andric }
195af732203SDimitry Andric 
1960b57cec5SDimitry Andric #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
1970b57cec5SDimitry Andric #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
1980b57cec5SDimitry Andric 
1990b57cec5SDimitry Andric template<unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)2000b57cec5SDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
2010b57cec5SDimitry Andric                                       int64_t Address, const void *Decoder) {
2020b57cec5SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
2030b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
2040b57cec5SDimitry Andric   return MCDisassembler::Success;
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric template<unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)2080b57cec5SDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
2090b57cec5SDimitry Andric                                       int64_t Address, const void *Decoder) {
2100b57cec5SDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
2110b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
2120b57cec5SDimitry Andric   return MCDisassembler::Success;
2130b57cec5SDimitry Andric }
2140b57cec5SDimitry Andric 
decodeImmZeroOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)2155ffd83dbSDimitry Andric static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm,
2165ffd83dbSDimitry Andric                                          int64_t Address, const void *Decoder) {
2175ffd83dbSDimitry Andric   if (Imm != 0)
2185ffd83dbSDimitry Andric     return MCDisassembler::Fail;
2195ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
2205ffd83dbSDimitry Andric   return MCDisassembler::Success;
2215ffd83dbSDimitry Andric }
2225ffd83dbSDimitry Andric 
decodeVSRpEvenOperands(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)223af732203SDimitry Andric static DecodeStatus decodeVSRpEvenOperands(MCInst &Inst, uint64_t RegNo,
224af732203SDimitry Andric                                            uint64_t Address,
225af732203SDimitry Andric                                            const void *Decoder) {
226af732203SDimitry Andric   if (RegNo & 1)
227af732203SDimitry Andric     return MCDisassembler::Fail;
228af732203SDimitry Andric   Inst.addOperand(MCOperand::createReg(VSRpRegs[RegNo >> 1]));
229af732203SDimitry Andric   return MCDisassembler::Success;
230af732203SDimitry Andric }
231af732203SDimitry Andric 
decodeMemRIOperands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)2320b57cec5SDimitry Andric static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
2330b57cec5SDimitry Andric                                         int64_t Address, const void *Decoder) {
2340b57cec5SDimitry Andric   // Decode the memri field (imm, reg), which has the low 16-bits as the
2350b57cec5SDimitry Andric   // displacement and the next 5 bits as the register #.
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   uint64_t Base = Imm >> 16;
2380b57cec5SDimitry Andric   uint64_t Disp = Imm & 0xFFFF;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric   assert(Base < 32 && "Invalid base register");
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   switch (Inst.getOpcode()) {
2430b57cec5SDimitry Andric   default: break;
2440b57cec5SDimitry Andric   case PPC::LBZU:
2450b57cec5SDimitry Andric   case PPC::LHAU:
2460b57cec5SDimitry Andric   case PPC::LHZU:
2470b57cec5SDimitry Andric   case PPC::LWZU:
2480b57cec5SDimitry Andric   case PPC::LFSU:
2490b57cec5SDimitry Andric   case PPC::LFDU:
2500b57cec5SDimitry Andric     // Add the tied output operand.
2510b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
2520b57cec5SDimitry Andric     break;
2530b57cec5SDimitry Andric   case PPC::STBU:
2540b57cec5SDimitry Andric   case PPC::STHU:
2550b57cec5SDimitry Andric   case PPC::STWU:
2560b57cec5SDimitry Andric   case PPC::STFSU:
2570b57cec5SDimitry Andric   case PPC::STFDU:
2580b57cec5SDimitry Andric     Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
2590b57cec5SDimitry Andric     break;
2600b57cec5SDimitry Andric   }
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp)));
2630b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
2640b57cec5SDimitry Andric   return MCDisassembler::Success;
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric 
decodeMemRIXOperands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)2670b57cec5SDimitry Andric static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm,
2680b57cec5SDimitry Andric                                          int64_t Address, const void *Decoder) {
2690b57cec5SDimitry Andric   // Decode the memrix field (imm, reg), which has the low 14-bits as the
2700b57cec5SDimitry Andric   // displacement and the next 5 bits as the register #.
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   uint64_t Base = Imm >> 14;
2730b57cec5SDimitry Andric   uint64_t Disp = Imm & 0x3FFF;
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   assert(Base < 32 && "Invalid base register");
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   if (Inst.getOpcode() == PPC::LDU)
2780b57cec5SDimitry Andric     // Add the tied output operand.
2790b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
2800b57cec5SDimitry Andric   else if (Inst.getOpcode() == PPC::STDU)
2810b57cec5SDimitry Andric     Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2)));
2840b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
2850b57cec5SDimitry Andric   return MCDisassembler::Success;
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
decodeMemRIHashOperands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)288*5f7ddb14SDimitry Andric static DecodeStatus decodeMemRIHashOperands(MCInst &Inst, uint64_t Imm,
289*5f7ddb14SDimitry Andric                                             int64_t Address,
290*5f7ddb14SDimitry Andric                                             const void *Decoder) {
291*5f7ddb14SDimitry Andric   // Decode the memrix field for a hash store or hash check operation.
292*5f7ddb14SDimitry Andric   // The field is composed of a register and an immediate value that is 6 bits
293*5f7ddb14SDimitry Andric   // and covers the range -8 to -512. The immediate is always negative and 2s
294*5f7ddb14SDimitry Andric   // complement which is why we sign extend a 7 bit value.
295*5f7ddb14SDimitry Andric   const uint64_t Base = Imm >> 6;
296*5f7ddb14SDimitry Andric   const int64_t Disp = SignExtend64<7>((Imm & 0x3F) + 64) * 8;
297*5f7ddb14SDimitry Andric 
298*5f7ddb14SDimitry Andric   assert(Base < 32 && "Invalid base register");
299*5f7ddb14SDimitry Andric 
300*5f7ddb14SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp));
301*5f7ddb14SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegs[Base]));
302*5f7ddb14SDimitry Andric   return MCDisassembler::Success;
303*5f7ddb14SDimitry Andric }
304*5f7ddb14SDimitry Andric 
decodeMemRIX16Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)3050b57cec5SDimitry Andric static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
3060b57cec5SDimitry Andric                                          int64_t Address, const void *Decoder) {
3070b57cec5SDimitry Andric   // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
3080b57cec5SDimitry Andric   // displacement with 16-byte aligned, and the next 5 bits as the register #.
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   uint64_t Base = Imm >> 12;
3110b57cec5SDimitry Andric   uint64_t Disp = Imm & 0xFFF;
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric   assert(Base < 32 && "Invalid base register");
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4)));
3160b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
3170b57cec5SDimitry Andric   return MCDisassembler::Success;
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric 
decodeMemRI34PCRelOperands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)3205ffd83dbSDimitry Andric static DecodeStatus decodeMemRI34PCRelOperands(MCInst &Inst, uint64_t Imm,
3215ffd83dbSDimitry Andric                                                int64_t Address,
3225ffd83dbSDimitry Andric                                                const void *Decoder) {
3235ffd83dbSDimitry Andric   // Decode the memri34_pcrel field (imm, reg), which has the low 34-bits as the
3245ffd83dbSDimitry Andric   // displacement, and the next 5 bits as an immediate 0.
3255ffd83dbSDimitry Andric   uint64_t Base = Imm >> 34;
3265ffd83dbSDimitry Andric   uint64_t Disp = Imm & 0x3FFFFFFFFUL;
3275ffd83dbSDimitry Andric 
3285ffd83dbSDimitry Andric   assert(Base < 32 && "Invalid base register");
3295ffd83dbSDimitry Andric 
3305ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp)));
3315ffd83dbSDimitry Andric   return decodeImmZeroOperand(Inst, Base, Address, Decoder);
3325ffd83dbSDimitry Andric }
3335ffd83dbSDimitry Andric 
decodeMemRI34Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)3345ffd83dbSDimitry Andric static DecodeStatus decodeMemRI34Operands(MCInst &Inst, uint64_t Imm,
3355ffd83dbSDimitry Andric                                           int64_t Address,
3365ffd83dbSDimitry Andric                                           const void *Decoder) {
3375ffd83dbSDimitry Andric   // Decode the memri34 field (imm, reg), which has the low 34-bits as the
3385ffd83dbSDimitry Andric   // displacement, and the next 5 bits as the register #.
3395ffd83dbSDimitry Andric   uint64_t Base = Imm >> 34;
3405ffd83dbSDimitry Andric   uint64_t Disp = Imm & 0x3FFFFFFFFUL;
3415ffd83dbSDimitry Andric 
3425ffd83dbSDimitry Andric   assert(Base < 32 && "Invalid base register");
3435ffd83dbSDimitry Andric 
3445ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp)));
3455ffd83dbSDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
3465ffd83dbSDimitry Andric   return MCDisassembler::Success;
3475ffd83dbSDimitry Andric }
3485ffd83dbSDimitry Andric 
decodeSPE8Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)3490b57cec5SDimitry Andric static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm,
3500b57cec5SDimitry Andric                                          int64_t Address, const void *Decoder) {
3510b57cec5SDimitry Andric   // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
3520b57cec5SDimitry Andric   // displacement with 8-byte aligned, and the next 5 bits as the register #.
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   uint64_t Base = Imm >> 5;
3550b57cec5SDimitry Andric   uint64_t Disp = Imm & 0x1F;
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric   assert(Base < 32 && "Invalid base register");
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp << 3));
3600b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
3610b57cec5SDimitry Andric   return MCDisassembler::Success;
3620b57cec5SDimitry Andric }
3630b57cec5SDimitry Andric 
decodeSPE4Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)3640b57cec5SDimitry Andric static DecodeStatus decodeSPE4Operands(MCInst &Inst, uint64_t Imm,
3650b57cec5SDimitry Andric                                          int64_t Address, const void *Decoder) {
3660b57cec5SDimitry Andric   // Decode the spe4disp field (imm, reg), which has the low 5-bits as the
3670b57cec5SDimitry Andric   // displacement with 4-byte aligned, and the next 5 bits as the register #.
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric   uint64_t Base = Imm >> 5;
3700b57cec5SDimitry Andric   uint64_t Disp = Imm & 0x1F;
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric   assert(Base < 32 && "Invalid base register");
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp << 2));
3750b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
3760b57cec5SDimitry Andric   return MCDisassembler::Success;
3770b57cec5SDimitry Andric }
3780b57cec5SDimitry Andric 
decodeSPE2Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)3790b57cec5SDimitry Andric static DecodeStatus decodeSPE2Operands(MCInst &Inst, uint64_t Imm,
3800b57cec5SDimitry Andric                                          int64_t Address, const void *Decoder) {
3810b57cec5SDimitry Andric   // Decode the spe2disp field (imm, reg), which has the low 5-bits as the
3820b57cec5SDimitry Andric   // displacement with 2-byte aligned, and the next 5 bits as the register #.
3830b57cec5SDimitry Andric 
3840b57cec5SDimitry Andric   uint64_t Base = Imm >> 5;
3850b57cec5SDimitry Andric   uint64_t Disp = Imm & 0x1F;
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric   assert(Base < 32 && "Invalid base register");
3880b57cec5SDimitry Andric 
3890b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp << 1));
3900b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
3910b57cec5SDimitry Andric   return MCDisassembler::Success;
3920b57cec5SDimitry Andric }
3930b57cec5SDimitry Andric 
decodeCRBitMOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)3940b57cec5SDimitry Andric static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm,
3950b57cec5SDimitry Andric                                         int64_t Address, const void *Decoder) {
3960b57cec5SDimitry Andric   // The cr bit encoding is 0x80 >> cr_reg_num.
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric   unsigned Zeros = countTrailingZeros(Imm);
3990b57cec5SDimitry Andric   assert(Zeros < 8 && "Invalid CR bit value");
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric   Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
4020b57cec5SDimitry Andric   return MCDisassembler::Success;
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric #include "PPCGenDisassemblerTables.inc"
4060b57cec5SDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const4070b57cec5SDimitry Andric DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
4080b57cec5SDimitry Andric                                              ArrayRef<uint8_t> Bytes,
409480093f4SDimitry Andric                                              uint64_t Address,
4100b57cec5SDimitry Andric                                              raw_ostream &CS) const {
4115ffd83dbSDimitry Andric   auto *ReadFunc = IsLittleEndian ? support::endian::read32le
4125ffd83dbSDimitry Andric                                   : support::endian::read32be;
4135ffd83dbSDimitry Andric 
4145ffd83dbSDimitry Andric   // If this is an 8-byte prefixed instruction, handle it here.
4155ffd83dbSDimitry Andric   // Note: prefixed instructions aren't technically 8-byte entities - the prefix
4165ffd83dbSDimitry Andric   //       appears in memory at an address 4 bytes prior to that of the base
4175ffd83dbSDimitry Andric   //       instruction regardless of endianness. So we read the two pieces and
4185ffd83dbSDimitry Andric   //       rebuild the 8-byte instruction.
4195ffd83dbSDimitry Andric   // TODO: In this function we call decodeInstruction several times with
4205ffd83dbSDimitry Andric   //       different decoder tables. It may be possible to only call once by
4215ffd83dbSDimitry Andric   //       looking at the top 6 bits of the instruction.
4225ffd83dbSDimitry Andric   if (STI.getFeatureBits()[PPC::FeaturePrefixInstrs] && Bytes.size() >= 8) {
4235ffd83dbSDimitry Andric     uint32_t Prefix = ReadFunc(Bytes.data());
4245ffd83dbSDimitry Andric     uint32_t BaseInst = ReadFunc(Bytes.data() + 4);
4255ffd83dbSDimitry Andric     uint64_t Inst = BaseInst | (uint64_t)Prefix << 32;
4265ffd83dbSDimitry Andric     DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address,
4275ffd83dbSDimitry Andric                                             this, STI);
4285ffd83dbSDimitry Andric     if (result != MCDisassembler::Fail) {
4295ffd83dbSDimitry Andric       Size = 8;
4305ffd83dbSDimitry Andric       return result;
4315ffd83dbSDimitry Andric     }
4325ffd83dbSDimitry Andric   }
4335ffd83dbSDimitry Andric 
4340b57cec5SDimitry Andric   // Get the four bytes of the instruction.
4350b57cec5SDimitry Andric   Size = 4;
4360b57cec5SDimitry Andric   if (Bytes.size() < 4) {
4370b57cec5SDimitry Andric     Size = 0;
4380b57cec5SDimitry Andric     return MCDisassembler::Fail;
4390b57cec5SDimitry Andric   }
4400b57cec5SDimitry Andric 
4410b57cec5SDimitry Andric   // Read the instruction in the proper endianness.
4425ffd83dbSDimitry Andric   uint64_t Inst = ReadFunc(Bytes.data());
4430b57cec5SDimitry Andric 
444af732203SDimitry Andric   if (STI.getFeatureBits()[PPC::FeatureSPE]) {
4450b57cec5SDimitry Andric     DecodeStatus result =
4460b57cec5SDimitry Andric         decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI);
4470b57cec5SDimitry Andric     if (result != MCDisassembler::Fail)
4480b57cec5SDimitry Andric       return result;
4490b57cec5SDimitry Andric   }
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
4520b57cec5SDimitry Andric }
453