191bc56edSDimitry Andric //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
291bc56edSDimitry Andric //
391bc56edSDimitry Andric //                     The LLVM Compiler Infrastructure
491bc56edSDimitry Andric //
591bc56edSDimitry Andric // This file is distributed under the University of Illinois Open Source
691bc56edSDimitry Andric // License. See LICENSE.TXT for details.
791bc56edSDimitry Andric //
891bc56edSDimitry Andric //===----------------------------------------------------------------------===//
991bc56edSDimitry Andric 
10b5893f02SDimitry Andric #include "MCTargetDesc/PPCMCTargetDesc.h"
113ca95b02SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
1291bc56edSDimitry Andric #include "llvm/MC/MCFixedLenDisassembler.h"
1391bc56edSDimitry Andric #include "llvm/MC/MCInst.h"
1491bc56edSDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
15b6c25e0eSDimitry Andric #include "llvm/Support/Endian.h"
1691bc56edSDimitry Andric #include "llvm/Support/TargetRegistry.h"
1791bc56edSDimitry Andric 
1891bc56edSDimitry Andric using namespace llvm;
1991bc56edSDimitry Andric 
20b5893f02SDimitry Andric DEFINE_PPC_REGCLASSES;
21b5893f02SDimitry Andric 
2291bc56edSDimitry Andric #define DEBUG_TYPE "ppc-disassembler"
2391bc56edSDimitry Andric 
2491bc56edSDimitry Andric typedef MCDisassembler::DecodeStatus DecodeStatus;
2591bc56edSDimitry Andric 
2691bc56edSDimitry Andric namespace {
2791bc56edSDimitry Andric class PPCDisassembler : public MCDisassembler {
28b6c25e0eSDimitry Andric   bool IsLittleEndian;
29b6c25e0eSDimitry Andric 
3091bc56edSDimitry Andric public:
PPCDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsLittleEndian)31b6c25e0eSDimitry Andric   PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
32b6c25e0eSDimitry Andric                   bool IsLittleEndian)
33b6c25e0eSDimitry Andric       : MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {}
3491bc56edSDimitry Andric 
3539d628a0SDimitry Andric   DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
3639d628a0SDimitry Andric                               ArrayRef<uint8_t> Bytes, uint64_t Address,
3739d628a0SDimitry Andric                               raw_ostream &VStream,
3839d628a0SDimitry Andric                               raw_ostream &CStream) const override;
3991bc56edSDimitry Andric };
4091bc56edSDimitry Andric } // end anonymous namespace
4191bc56edSDimitry Andric 
createPPCDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)4291bc56edSDimitry Andric static MCDisassembler *createPPCDisassembler(const Target &T,
4391bc56edSDimitry Andric                                              const MCSubtargetInfo &STI,
4491bc56edSDimitry Andric                                              MCContext &Ctx) {
45b6c25e0eSDimitry Andric   return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
46b6c25e0eSDimitry Andric }
47b6c25e0eSDimitry Andric 
createPPCLEDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)48b6c25e0eSDimitry Andric static MCDisassembler *createPPCLEDisassembler(const Target &T,
49b6c25e0eSDimitry Andric                                                const MCSubtargetInfo &STI,
50b6c25e0eSDimitry Andric                                                MCContext &Ctx) {
51b6c25e0eSDimitry Andric   return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
5291bc56edSDimitry Andric }
5391bc56edSDimitry Andric 
LLVMInitializePowerPCDisassembler()5491bc56edSDimitry Andric extern "C" void LLVMInitializePowerPCDisassembler() {
5591bc56edSDimitry Andric   // Register the disassembler for each target.
56d88c1a5aSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
5791bc56edSDimitry Andric                                          createPPCDisassembler);
58d88c1a5aSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
5991bc56edSDimitry Andric                                          createPPCDisassembler);
60d88c1a5aSDimitry Andric   TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
61b6c25e0eSDimitry Andric                                          createPPCLEDisassembler);
6291bc56edSDimitry Andric }
6391bc56edSDimitry Andric 
DecodePCRel24BranchTarget(MCInst & Inst,unsigned Imm,uint64_t Addr,const void * Decoder)64*85573313SDimitry Andric static DecodeStatus DecodePCRel24BranchTarget(MCInst &Inst, unsigned Imm,
65*85573313SDimitry Andric                                               uint64_t Addr,
66*85573313SDimitry Andric                                               const void *Decoder) {
67*85573313SDimitry Andric   int32_t Offset = SignExtend32<24>(Imm);
68*85573313SDimitry Andric   Inst.addOperand(MCOperand::createImm(Offset));
69*85573313SDimitry Andric   return MCDisassembler::Success;
70*85573313SDimitry Andric }
71*85573313SDimitry Andric 
7291bc56edSDimitry Andric // FIXME: These can be generated by TableGen from the existing register
7391bc56edSDimitry Andric // encoding values!
7491bc56edSDimitry Andric 
7591bc56edSDimitry Andric template <std::size_t N>
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const MCPhysReg (& Regs)[N])7691bc56edSDimitry Andric static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
77b5893f02SDimitry Andric                                         const MCPhysReg (&Regs)[N]) {
7891bc56edSDimitry Andric   assert(RegNo < N && "Invalid register number");
79ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
8091bc56edSDimitry Andric   return MCDisassembler::Success;
8191bc56edSDimitry Andric }
8291bc56edSDimitry Andric 
DecodeCRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)8391bc56edSDimitry Andric static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
8491bc56edSDimitry Andric                                             uint64_t Address,
8591bc56edSDimitry Andric                                             const void *Decoder) {
8691bc56edSDimitry Andric   return decodeRegisterClass(Inst, RegNo, CRRegs);
8791bc56edSDimitry Andric }
8891bc56edSDimitry Andric 
DecodeCRRC0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)89ff0cc061SDimitry Andric static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo,
90ff0cc061SDimitry Andric                                             uint64_t Address,
91ff0cc061SDimitry Andric                                             const void *Decoder) {
92ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, CRRegs);
93ff0cc061SDimitry Andric }
94ff0cc061SDimitry Andric 
DecodeCRBITRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)9591bc56edSDimitry Andric static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
9691bc56edSDimitry Andric                                             uint64_t Address,
9791bc56edSDimitry Andric                                             const void *Decoder) {
9891bc56edSDimitry Andric   return decodeRegisterClass(Inst, RegNo, CRBITRegs);
9991bc56edSDimitry Andric }
10091bc56edSDimitry Andric 
DecodeF4RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)10191bc56edSDimitry Andric static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
10291bc56edSDimitry Andric                                             uint64_t Address,
10391bc56edSDimitry Andric                                             const void *Decoder) {
10491bc56edSDimitry Andric   return decodeRegisterClass(Inst, RegNo, FRegs);
10591bc56edSDimitry Andric }
10691bc56edSDimitry Andric 
DecodeF8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)10791bc56edSDimitry Andric static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
10891bc56edSDimitry Andric                                             uint64_t Address,
10991bc56edSDimitry Andric                                             const void *Decoder) {
11091bc56edSDimitry Andric   return decodeRegisterClass(Inst, RegNo, FRegs);
11191bc56edSDimitry Andric }
11291bc56edSDimitry Andric 
DecodeVFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)113d88c1a5aSDimitry Andric static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
114d88c1a5aSDimitry Andric                                             uint64_t Address,
115d88c1a5aSDimitry Andric                                             const void *Decoder) {
116d88c1a5aSDimitry Andric   return decodeRegisterClass(Inst, RegNo, VFRegs);
117d88c1a5aSDimitry Andric }
118d88c1a5aSDimitry Andric 
DecodeVRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)11991bc56edSDimitry Andric static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
12091bc56edSDimitry Andric                                             uint64_t Address,
12191bc56edSDimitry Andric                                             const void *Decoder) {
12291bc56edSDimitry Andric   return decodeRegisterClass(Inst, RegNo, VRegs);
12391bc56edSDimitry Andric }
12491bc56edSDimitry Andric 
DecodeVSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)12591bc56edSDimitry Andric static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
12691bc56edSDimitry Andric                                             uint64_t Address,
12791bc56edSDimitry Andric                                             const void *Decoder) {
12891bc56edSDimitry Andric   return decodeRegisterClass(Inst, RegNo, VSRegs);
12991bc56edSDimitry Andric }
13091bc56edSDimitry Andric 
DecodeVSFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)13191bc56edSDimitry Andric static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
13291bc56edSDimitry Andric                                             uint64_t Address,
13391bc56edSDimitry Andric                                             const void *Decoder) {
13491bc56edSDimitry Andric   return decodeRegisterClass(Inst, RegNo, VSFRegs);
13591bc56edSDimitry Andric }
13691bc56edSDimitry Andric 
DecodeVSSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)137ff0cc061SDimitry Andric static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
138ff0cc061SDimitry Andric                                             uint64_t Address,
139ff0cc061SDimitry Andric                                             const void *Decoder) {
140ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, VSSRegs);
141ff0cc061SDimitry Andric }
142ff0cc061SDimitry Andric 
DecodeGPRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)14391bc56edSDimitry Andric static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
14491bc56edSDimitry Andric                                             uint64_t Address,
14591bc56edSDimitry Andric                                             const void *Decoder) {
146b5893f02SDimitry Andric   return decodeRegisterClass(Inst, RegNo, RRegs);
14791bc56edSDimitry Andric }
14891bc56edSDimitry Andric 
DecodeGPRC_NOR0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)14991bc56edSDimitry Andric static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo,
15091bc56edSDimitry Andric                                             uint64_t Address,
15191bc56edSDimitry Andric                                             const void *Decoder) {
152b5893f02SDimitry Andric   return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
15391bc56edSDimitry Andric }
15491bc56edSDimitry Andric 
DecodeG8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)15591bc56edSDimitry Andric static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
15691bc56edSDimitry Andric                                             uint64_t Address,
15791bc56edSDimitry Andric                                             const void *Decoder) {
158b5893f02SDimitry Andric   return decodeRegisterClass(Inst, RegNo, XRegs);
15991bc56edSDimitry Andric }
16091bc56edSDimitry Andric 
DecodeG8RC_NOX0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1615517e702SDimitry Andric static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo,
1625517e702SDimitry Andric                                             uint64_t Address,
1635517e702SDimitry Andric                                             const void *Decoder) {
164b5893f02SDimitry Andric   return decodeRegisterClass(Inst, RegNo, XRegsNoX0);
1655517e702SDimitry Andric }
1665517e702SDimitry Andric 
16791bc56edSDimitry Andric #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
16891bc56edSDimitry Andric #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
16991bc56edSDimitry Andric 
DecodeQFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)170ff0cc061SDimitry Andric static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
171ff0cc061SDimitry Andric                                             uint64_t Address,
172ff0cc061SDimitry Andric                                             const void *Decoder) {
173ff0cc061SDimitry Andric   return decodeRegisterClass(Inst, RegNo, QFRegs);
174ff0cc061SDimitry Andric }
175ff0cc061SDimitry Andric 
DecodeSPE4RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1764ba319b5SDimitry Andric static DecodeStatus DecodeSPE4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
1774ba319b5SDimitry Andric                                             uint64_t Address,
1784ba319b5SDimitry Andric                                             const void *Decoder) {
179b5893f02SDimitry Andric   return decodeRegisterClass(Inst, RegNo, RRegs);
1804ba319b5SDimitry Andric }
1814ba319b5SDimitry Andric 
DecodeSPERCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)1824ba319b5SDimitry Andric static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
1834ba319b5SDimitry Andric                                             uint64_t Address,
1844ba319b5SDimitry Andric                                             const void *Decoder) {
1854ba319b5SDimitry Andric   return decodeRegisterClass(Inst, RegNo, SPERegs);
1864ba319b5SDimitry Andric }
1874ba319b5SDimitry Andric 
188ff0cc061SDimitry Andric #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
189ff0cc061SDimitry Andric #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
190ff0cc061SDimitry Andric 
19191bc56edSDimitry Andric template<unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)19291bc56edSDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
19391bc56edSDimitry Andric                                       int64_t Address, const void *Decoder) {
19491bc56edSDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
195ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(Imm));
19691bc56edSDimitry Andric   return MCDisassembler::Success;
19791bc56edSDimitry Andric }
19891bc56edSDimitry Andric 
19991bc56edSDimitry Andric template<unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)20091bc56edSDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
20191bc56edSDimitry Andric                                       int64_t Address, const void *Decoder) {
20291bc56edSDimitry Andric   assert(isUInt<N>(Imm) && "Invalid immediate");
203ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
20491bc56edSDimitry Andric   return MCDisassembler::Success;
20591bc56edSDimitry Andric }
20691bc56edSDimitry Andric 
decodeMemRIOperands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)20791bc56edSDimitry Andric static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
20891bc56edSDimitry Andric                                         int64_t Address, const void *Decoder) {
20991bc56edSDimitry Andric   // Decode the memri field (imm, reg), which has the low 16-bits as the
21091bc56edSDimitry Andric   // displacement and the next 5 bits as the register #.
21191bc56edSDimitry Andric 
21291bc56edSDimitry Andric   uint64_t Base = Imm >> 16;
21391bc56edSDimitry Andric   uint64_t Disp = Imm & 0xFFFF;
21491bc56edSDimitry Andric 
21591bc56edSDimitry Andric   assert(Base < 32 && "Invalid base register");
21691bc56edSDimitry Andric 
21791bc56edSDimitry Andric   switch (Inst.getOpcode()) {
21891bc56edSDimitry Andric   default: break;
21991bc56edSDimitry Andric   case PPC::LBZU:
22091bc56edSDimitry Andric   case PPC::LHAU:
22191bc56edSDimitry Andric   case PPC::LHZU:
22291bc56edSDimitry Andric   case PPC::LWZU:
22391bc56edSDimitry Andric   case PPC::LFSU:
22491bc56edSDimitry Andric   case PPC::LFDU:
22591bc56edSDimitry Andric     // Add the tied output operand.
226b5893f02SDimitry Andric     Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
22791bc56edSDimitry Andric     break;
22891bc56edSDimitry Andric   case PPC::STBU:
22991bc56edSDimitry Andric   case PPC::STHU:
23091bc56edSDimitry Andric   case PPC::STWU:
23191bc56edSDimitry Andric   case PPC::STFSU:
23291bc56edSDimitry Andric   case PPC::STFDU:
233b5893f02SDimitry Andric     Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
23491bc56edSDimitry Andric     break;
23591bc56edSDimitry Andric   }
23691bc56edSDimitry Andric 
237ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp)));
238b5893f02SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
23991bc56edSDimitry Andric   return MCDisassembler::Success;
24091bc56edSDimitry Andric }
24191bc56edSDimitry Andric 
decodeMemRIXOperands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)24291bc56edSDimitry Andric static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm,
24391bc56edSDimitry Andric                                          int64_t Address, const void *Decoder) {
24491bc56edSDimitry Andric   // Decode the memrix field (imm, reg), which has the low 14-bits as the
24591bc56edSDimitry Andric   // displacement and the next 5 bits as the register #.
24691bc56edSDimitry Andric 
24791bc56edSDimitry Andric   uint64_t Base = Imm >> 14;
24891bc56edSDimitry Andric   uint64_t Disp = Imm & 0x3FFF;
24991bc56edSDimitry Andric 
25091bc56edSDimitry Andric   assert(Base < 32 && "Invalid base register");
25191bc56edSDimitry Andric 
25291bc56edSDimitry Andric   if (Inst.getOpcode() == PPC::LDU)
25391bc56edSDimitry Andric     // Add the tied output operand.
254b5893f02SDimitry Andric     Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
25591bc56edSDimitry Andric   else if (Inst.getOpcode() == PPC::STDU)
256b5893f02SDimitry Andric     Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
25791bc56edSDimitry Andric 
258ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2)));
259b5893f02SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
26091bc56edSDimitry Andric   return MCDisassembler::Success;
26191bc56edSDimitry Andric }
26291bc56edSDimitry Andric 
decodeMemRIX16Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)2633ca95b02SDimitry Andric static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
2643ca95b02SDimitry Andric                                          int64_t Address, const void *Decoder) {
2653ca95b02SDimitry Andric   // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
2663ca95b02SDimitry Andric   // displacement with 16-byte aligned, and the next 5 bits as the register #.
2673ca95b02SDimitry Andric 
2683ca95b02SDimitry Andric   uint64_t Base = Imm >> 12;
2693ca95b02SDimitry Andric   uint64_t Disp = Imm & 0xFFF;
2703ca95b02SDimitry Andric 
2713ca95b02SDimitry Andric   assert(Base < 32 && "Invalid base register");
2723ca95b02SDimitry Andric 
2733ca95b02SDimitry Andric   Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4)));
274b5893f02SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
2753ca95b02SDimitry Andric   return MCDisassembler::Success;
2763ca95b02SDimitry Andric }
2773ca95b02SDimitry Andric 
decodeSPE8Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)2784ba319b5SDimitry Andric static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm,
2794ba319b5SDimitry Andric                                          int64_t Address, const void *Decoder) {
2804ba319b5SDimitry Andric   // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
2814ba319b5SDimitry Andric   // displacement with 8-byte aligned, and the next 5 bits as the register #.
2824ba319b5SDimitry Andric 
2834ba319b5SDimitry Andric   uint64_t Base = Imm >> 5;
2844ba319b5SDimitry Andric   uint64_t Disp = Imm & 0x1F;
2854ba319b5SDimitry Andric 
2864ba319b5SDimitry Andric   assert(Base < 32 && "Invalid base register");
2874ba319b5SDimitry Andric 
2884ba319b5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp << 3));
289b5893f02SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
2904ba319b5SDimitry Andric   return MCDisassembler::Success;
2914ba319b5SDimitry Andric }
2924ba319b5SDimitry Andric 
decodeSPE4Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)2934ba319b5SDimitry Andric static DecodeStatus decodeSPE4Operands(MCInst &Inst, uint64_t Imm,
2944ba319b5SDimitry Andric                                          int64_t Address, const void *Decoder) {
2954ba319b5SDimitry Andric   // Decode the spe4disp field (imm, reg), which has the low 5-bits as the
2964ba319b5SDimitry Andric   // displacement with 4-byte aligned, and the next 5 bits as the register #.
2974ba319b5SDimitry Andric 
2984ba319b5SDimitry Andric   uint64_t Base = Imm >> 5;
2994ba319b5SDimitry Andric   uint64_t Disp = Imm & 0x1F;
3004ba319b5SDimitry Andric 
3014ba319b5SDimitry Andric   assert(Base < 32 && "Invalid base register");
3024ba319b5SDimitry Andric 
3034ba319b5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp << 2));
304b5893f02SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
3054ba319b5SDimitry Andric   return MCDisassembler::Success;
3064ba319b5SDimitry Andric }
3074ba319b5SDimitry Andric 
decodeSPE2Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)3084ba319b5SDimitry Andric static DecodeStatus decodeSPE2Operands(MCInst &Inst, uint64_t Imm,
3094ba319b5SDimitry Andric                                          int64_t Address, const void *Decoder) {
3104ba319b5SDimitry Andric   // Decode the spe2disp field (imm, reg), which has the low 5-bits as the
3114ba319b5SDimitry Andric   // displacement with 2-byte aligned, and the next 5 bits as the register #.
3124ba319b5SDimitry Andric 
3134ba319b5SDimitry Andric   uint64_t Base = Imm >> 5;
3144ba319b5SDimitry Andric   uint64_t Disp = Imm & 0x1F;
3154ba319b5SDimitry Andric 
3164ba319b5SDimitry Andric   assert(Base < 32 && "Invalid base register");
3174ba319b5SDimitry Andric 
3184ba319b5SDimitry Andric   Inst.addOperand(MCOperand::createImm(Disp << 1));
319b5893f02SDimitry Andric   Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
3204ba319b5SDimitry Andric   return MCDisassembler::Success;
3214ba319b5SDimitry Andric }
3224ba319b5SDimitry Andric 
decodeCRBitMOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)32391bc56edSDimitry Andric static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm,
32491bc56edSDimitry Andric                                         int64_t Address, const void *Decoder) {
32591bc56edSDimitry Andric   // The cr bit encoding is 0x80 >> cr_reg_num.
32691bc56edSDimitry Andric 
32791bc56edSDimitry Andric   unsigned Zeros = countTrailingZeros(Imm);
32891bc56edSDimitry Andric   assert(Zeros < 8 && "Invalid CR bit value");
32991bc56edSDimitry Andric 
330ff0cc061SDimitry Andric   Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
33191bc56edSDimitry Andric   return MCDisassembler::Success;
33291bc56edSDimitry Andric }
33391bc56edSDimitry Andric 
33491bc56edSDimitry Andric #include "PPCGenDisassemblerTables.inc"
33591bc56edSDimitry Andric 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const33691bc56edSDimitry Andric DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
33739d628a0SDimitry Andric                                              ArrayRef<uint8_t> Bytes,
33839d628a0SDimitry Andric                                              uint64_t Address, raw_ostream &OS,
33939d628a0SDimitry Andric                                              raw_ostream &CS) const {
34091bc56edSDimitry Andric   // Get the four bytes of the instruction.
34191bc56edSDimitry Andric   Size = 4;
34239d628a0SDimitry Andric   if (Bytes.size() < 4) {
34391bc56edSDimitry Andric     Size = 0;
34491bc56edSDimitry Andric     return MCDisassembler::Fail;
34591bc56edSDimitry Andric   }
34691bc56edSDimitry Andric 
347b6c25e0eSDimitry Andric   // Read the instruction in the proper endianness.
348b6c25e0eSDimitry Andric   uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data())
349b6c25e0eSDimitry Andric                                  : support::endian::read32be(Bytes.data());
35091bc56edSDimitry Andric 
351ff0cc061SDimitry Andric   if (STI.getFeatureBits()[PPC::FeatureQPX]) {
352ff0cc061SDimitry Andric     DecodeStatus result =
353ff0cc061SDimitry Andric       decodeInstruction(DecoderTableQPX32, MI, Inst, Address, this, STI);
354ff0cc061SDimitry Andric     if (result != MCDisassembler::Fail)
355ff0cc061SDimitry Andric       return result;
3564ba319b5SDimitry Andric   } else if (STI.getFeatureBits()[PPC::FeatureSPE]) {
3574ba319b5SDimitry Andric     DecodeStatus result =
3584ba319b5SDimitry Andric       decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI);
3594ba319b5SDimitry Andric     if (result != MCDisassembler::Fail)
3604ba319b5SDimitry Andric       return result;
361ff0cc061SDimitry Andric   }
362ff0cc061SDimitry Andric 
36391bc56edSDimitry Andric   return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
36491bc56edSDimitry Andric }
36591bc56edSDimitry Andric 
366