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"
1181ad6265SDimitry Andric #include "llvm/MC/MCDecoderOps.h"
120b57cec5SDimitry Andric #include "llvm/MC/MCDisassembler/MCDisassembler.h"
130b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
15349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
160b57cec5SDimitry Andric #include "llvm/Support/Endian.h"
170b57cec5SDimitry Andric
180b57cec5SDimitry Andric using namespace llvm;
190b57cec5SDimitry Andric
20bdd1243dSDimitry 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);
57e8d8bef9SDimitry Andric TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(),
58e8d8bef9SDimitry 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 MCDisassembler *)655ffd83dbSDimitry Andric static DecodeStatus decodeCondBrTarget(MCInst &Inst, unsigned Imm,
665ffd83dbSDimitry Andric uint64_t /*Address*/,
6781ad6265SDimitry Andric const MCDisassembler * /*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 MCDisassembler *)725ffd83dbSDimitry Andric static DecodeStatus decodeDirectBrTarget(MCInst &Inst, unsigned Imm,
735ffd83dbSDimitry Andric uint64_t /*Address*/,
7481ad6265SDimitry Andric const MCDisassembler * /*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]) {
86*06c3fb27SDimitry Andric if (RegNo >= N)
87*06c3fb27SDimitry Andric return MCDisassembler::Fail;
880b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
890b57cec5SDimitry Andric return MCDisassembler::Success;
900b57cec5SDimitry Andric }
910b57cec5SDimitry Andric
DecodeCRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)920b57cec5SDimitry Andric static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
930b57cec5SDimitry Andric uint64_t Address,
9481ad6265SDimitry Andric const MCDisassembler *Decoder) {
950b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, CRRegs);
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric
DecodeCRBITRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)980b57cec5SDimitry Andric static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
990b57cec5SDimitry Andric uint64_t Address,
10081ad6265SDimitry Andric const MCDisassembler *Decoder) {
1010b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, CRBITRegs);
1020b57cec5SDimitry Andric }
1030b57cec5SDimitry Andric
DecodeF4RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1040b57cec5SDimitry Andric static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
1050b57cec5SDimitry Andric uint64_t Address,
10681ad6265SDimitry Andric const MCDisassembler *Decoder) {
1070b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, FRegs);
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric
DecodeF8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1100b57cec5SDimitry Andric static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
1110b57cec5SDimitry Andric uint64_t Address,
11281ad6265SDimitry Andric const MCDisassembler *Decoder) {
1130b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, FRegs);
1140b57cec5SDimitry Andric }
1150b57cec5SDimitry Andric
DecodeFpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)116*06c3fb27SDimitry Andric static DecodeStatus DecodeFpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
117*06c3fb27SDimitry Andric uint64_t Address,
118*06c3fb27SDimitry Andric const MCDisassembler *Decoder) {
119*06c3fb27SDimitry Andric if (RegNo > 30 || (RegNo & 1))
120*06c3fb27SDimitry Andric return MCDisassembler::Fail;
121*06c3fb27SDimitry Andric return decodeRegisterClass(Inst, RegNo >> 1, FpRegs);
122*06c3fb27SDimitry Andric }
123*06c3fb27SDimitry Andric
DecodeVFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1240b57cec5SDimitry Andric static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1250b57cec5SDimitry Andric uint64_t Address,
12681ad6265SDimitry Andric const MCDisassembler *Decoder) {
1270b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, VFRegs);
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric
DecodeVRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1300b57cec5SDimitry Andric static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1310b57cec5SDimitry Andric uint64_t Address,
13281ad6265SDimitry Andric const MCDisassembler *Decoder) {
1330b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, VRegs);
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric
DecodeVSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1360b57cec5SDimitry Andric static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1370b57cec5SDimitry Andric uint64_t Address,
13881ad6265SDimitry Andric const MCDisassembler *Decoder) {
1390b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, VSRegs);
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric
DecodeVSFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1420b57cec5SDimitry Andric static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1430b57cec5SDimitry Andric uint64_t Address,
14481ad6265SDimitry Andric const MCDisassembler *Decoder) {
1450b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, VSFRegs);
1460b57cec5SDimitry Andric }
1470b57cec5SDimitry Andric
DecodeVSSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1480b57cec5SDimitry Andric static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1490b57cec5SDimitry Andric uint64_t Address,
15081ad6265SDimitry Andric const MCDisassembler *Decoder) {
1510b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, VSSRegs);
1520b57cec5SDimitry Andric }
1530b57cec5SDimitry Andric
DecodeGPRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1540b57cec5SDimitry Andric static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
1550b57cec5SDimitry Andric uint64_t Address,
15681ad6265SDimitry Andric const MCDisassembler *Decoder) {
1570b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, RRegs);
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric
16081ad6265SDimitry Andric static DecodeStatus
DecodeGPRC_NOR0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)16181ad6265SDimitry Andric DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
16281ad6265SDimitry Andric const MCDisassembler *Decoder) {
1630b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric
DecodeG8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1660b57cec5SDimitry Andric static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
1670b57cec5SDimitry Andric uint64_t Address,
16881ad6265SDimitry Andric const MCDisassembler *Decoder) {
1690b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, XRegs);
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric
DecodeG8pRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)172fe6060f1SDimitry Andric static DecodeStatus DecodeG8pRCRegisterClass(MCInst &Inst, uint64_t RegNo,
173fe6060f1SDimitry Andric uint64_t Address,
17481ad6265SDimitry Andric const MCDisassembler *Decoder) {
175fe6060f1SDimitry Andric return decodeRegisterClass(Inst, RegNo, XRegs);
176fe6060f1SDimitry Andric }
177fe6060f1SDimitry Andric
17881ad6265SDimitry Andric static DecodeStatus
DecodeG8RC_NOX0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)17981ad6265SDimitry Andric DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
18081ad6265SDimitry Andric const MCDisassembler *Decoder) {
1810b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, XRegsNoX0);
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric
1840b57cec5SDimitry Andric #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
1850b57cec5SDimitry Andric #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
1860b57cec5SDimitry Andric
DecodeSPERCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)1870b57cec5SDimitry Andric static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
1880b57cec5SDimitry Andric uint64_t Address,
18981ad6265SDimitry Andric const MCDisassembler *Decoder) {
1900b57cec5SDimitry Andric return decodeRegisterClass(Inst, RegNo, SPERegs);
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric
DecodeACCRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)193e8d8bef9SDimitry Andric static DecodeStatus DecodeACCRCRegisterClass(MCInst &Inst, uint64_t RegNo,
194e8d8bef9SDimitry Andric uint64_t Address,
19581ad6265SDimitry Andric const MCDisassembler *Decoder) {
196e8d8bef9SDimitry Andric return decodeRegisterClass(Inst, RegNo, ACCRegs);
197e8d8bef9SDimitry Andric }
198e8d8bef9SDimitry Andric
DecodeWACCRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)199bdd1243dSDimitry Andric static DecodeStatus DecodeWACCRCRegisterClass(MCInst &Inst, uint64_t RegNo,
200bdd1243dSDimitry Andric uint64_t Address,
201bdd1243dSDimitry Andric const void *Decoder) {
202bdd1243dSDimitry Andric return decodeRegisterClass(Inst, RegNo, WACCRegs);
203bdd1243dSDimitry Andric }
204bdd1243dSDimitry Andric
DecodeWACC_HIRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)205bdd1243dSDimitry Andric static DecodeStatus DecodeWACC_HIRCRegisterClass(MCInst &Inst, uint64_t RegNo,
206bdd1243dSDimitry Andric uint64_t Address,
207bdd1243dSDimitry Andric const void *Decoder) {
208bdd1243dSDimitry Andric return decodeRegisterClass(Inst, RegNo, WACC_HIRegs);
209bdd1243dSDimitry Andric }
210bdd1243dSDimitry Andric
211bdd1243dSDimitry Andric // TODO: Make this function static when the register class is used by a new
212bdd1243dSDimitry Andric // instruction.
DecodeDMRROWRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)213bdd1243dSDimitry Andric DecodeStatus DecodeDMRROWRCRegisterClass(MCInst &Inst, uint64_t RegNo,
214bdd1243dSDimitry Andric uint64_t Address,
215bdd1243dSDimitry Andric const void *Decoder) {
216bdd1243dSDimitry Andric return decodeRegisterClass(Inst, RegNo, DMRROWRegs);
217bdd1243dSDimitry Andric }
218bdd1243dSDimitry Andric
DecodeDMRROWpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)219bdd1243dSDimitry Andric static DecodeStatus DecodeDMRROWpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
220bdd1243dSDimitry Andric uint64_t Address,
221bdd1243dSDimitry Andric const void *Decoder) {
222bdd1243dSDimitry Andric return decodeRegisterClass(Inst, RegNo, DMRROWpRegs);
223bdd1243dSDimitry Andric }
224bdd1243dSDimitry Andric
DecodeDMRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)225bdd1243dSDimitry Andric static DecodeStatus DecodeDMRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
226bdd1243dSDimitry Andric uint64_t Address,
227bdd1243dSDimitry Andric const void *Decoder) {
228bdd1243dSDimitry Andric return decodeRegisterClass(Inst, RegNo, DMRRegs);
229bdd1243dSDimitry Andric }
230bdd1243dSDimitry Andric
231bdd1243dSDimitry Andric // TODO: Make this function static when the register class is used by a new
232bdd1243dSDimitry Andric // instruction.
DecodeDMRpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)233bdd1243dSDimitry Andric DecodeStatus DecodeDMRpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
234bdd1243dSDimitry Andric uint64_t Address, const void *Decoder) {
235bdd1243dSDimitry Andric return decodeRegisterClass(Inst, RegNo, DMRpRegs);
236bdd1243dSDimitry Andric }
237bdd1243dSDimitry Andric
DecodeVSRpRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)238e8d8bef9SDimitry Andric static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
239e8d8bef9SDimitry Andric uint64_t Address,
24081ad6265SDimitry Andric const MCDisassembler *Decoder) {
241e8d8bef9SDimitry Andric return decodeRegisterClass(Inst, RegNo, VSRpRegs);
242e8d8bef9SDimitry Andric }
243e8d8bef9SDimitry Andric
2440b57cec5SDimitry Andric #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
2450b57cec5SDimitry Andric #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
2460b57cec5SDimitry Andric
2470b57cec5SDimitry Andric template <unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)2480b57cec5SDimitry Andric static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
24981ad6265SDimitry Andric int64_t Address,
25081ad6265SDimitry Andric const MCDisassembler *Decoder) {
251*06c3fb27SDimitry Andric if (!isUInt<N>(Imm))
252*06c3fb27SDimitry Andric return MCDisassembler::Fail;
2530b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Imm));
2540b57cec5SDimitry Andric return MCDisassembler::Success;
2550b57cec5SDimitry Andric }
2560b57cec5SDimitry Andric
2570b57cec5SDimitry Andric template <unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)2580b57cec5SDimitry Andric static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
25981ad6265SDimitry Andric int64_t Address,
26081ad6265SDimitry Andric const MCDisassembler *Decoder) {
261*06c3fb27SDimitry Andric if (!isUInt<N>(Imm))
262*06c3fb27SDimitry Andric return MCDisassembler::Fail;
2630b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
2640b57cec5SDimitry Andric return MCDisassembler::Success;
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric
decodeImmZeroOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)2675ffd83dbSDimitry Andric static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm,
26881ad6265SDimitry Andric int64_t Address,
26981ad6265SDimitry Andric const MCDisassembler *Decoder) {
2705ffd83dbSDimitry Andric if (Imm != 0)
2715ffd83dbSDimitry Andric return MCDisassembler::Fail;
2725ffd83dbSDimitry Andric Inst.addOperand(MCOperand::createImm(Imm));
2735ffd83dbSDimitry Andric return MCDisassembler::Success;
2745ffd83dbSDimitry Andric }
2755ffd83dbSDimitry Andric
decodeVSRpEvenOperands(MCInst & Inst,uint64_t RegNo,uint64_t Address,const MCDisassembler * Decoder)276e8d8bef9SDimitry Andric static DecodeStatus decodeVSRpEvenOperands(MCInst &Inst, uint64_t RegNo,
277e8d8bef9SDimitry Andric uint64_t Address,
27881ad6265SDimitry Andric const MCDisassembler *Decoder) {
279e8d8bef9SDimitry Andric if (RegNo & 1)
280e8d8bef9SDimitry Andric return MCDisassembler::Fail;
281e8d8bef9SDimitry Andric Inst.addOperand(MCOperand::createReg(VSRpRegs[RegNo >> 1]));
282e8d8bef9SDimitry Andric return MCDisassembler::Success;
283e8d8bef9SDimitry Andric }
284e8d8bef9SDimitry Andric
decodeDispRIXOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)285*06c3fb27SDimitry Andric static DecodeStatus decodeDispRIXOperand(MCInst &Inst, uint64_t Imm,
28681ad6265SDimitry Andric int64_t Address,
28781ad6265SDimitry Andric const MCDisassembler *Decoder) {
288*06c3fb27SDimitry Andric // The rix displacement is an immediate shifted by 2
289*06c3fb27SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Imm << 2)));
2900b57cec5SDimitry Andric return MCDisassembler::Success;
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric
decodeDispRIHashOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)293*06c3fb27SDimitry Andric static DecodeStatus decodeDispRIHashOperand(MCInst &Inst, uint64_t Imm,
29481ad6265SDimitry Andric int64_t Address,
29581ad6265SDimitry Andric const MCDisassembler *Decoder) {
296*06c3fb27SDimitry Andric // Decode the disp field for a hash store or hash check operation.
297*06c3fb27SDimitry Andric // The field is composed of an immediate value that is 6 bits
298fe6060f1SDimitry Andric // and covers the range -8 to -512. The immediate is always negative and 2s
299fe6060f1SDimitry Andric // complement which is why we sign extend a 7 bit value.
300fe6060f1SDimitry Andric const int64_t Disp = SignExtend64<7>((Imm & 0x3F) + 64) * 8;
301fe6060f1SDimitry Andric
302fe6060f1SDimitry Andric Inst.addOperand(MCOperand::createImm(Disp));
303fe6060f1SDimitry Andric return MCDisassembler::Success;
304fe6060f1SDimitry Andric }
305fe6060f1SDimitry Andric
decodeDispRIX16Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)306*06c3fb27SDimitry Andric static DecodeStatus decodeDispRIX16Operand(MCInst &Inst, uint64_t Imm,
30781ad6265SDimitry Andric int64_t Address,
30881ad6265SDimitry Andric const MCDisassembler *Decoder) {
309*06c3fb27SDimitry Andric // The rix16 displacement has 12-bits which are shifted by 4.
310*06c3fb27SDimitry Andric Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Imm << 4)));
3110b57cec5SDimitry Andric return MCDisassembler::Success;
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric
decodeDispSPE8Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)314*06c3fb27SDimitry Andric static DecodeStatus decodeDispSPE8Operand(MCInst &Inst, uint64_t Imm,
3155ffd83dbSDimitry Andric int64_t Address,
31681ad6265SDimitry Andric const MCDisassembler *Decoder) {
317*06c3fb27SDimitry Andric // Decode the dispSPE8 field, which has 5-bits, 8-byte aligned.
3185ffd83dbSDimitry Andric
3190b57cec5SDimitry Andric uint64_t Disp = Imm & 0x1F;
3200b57cec5SDimitry Andric
3210b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Disp << 3));
3220b57cec5SDimitry Andric return MCDisassembler::Success;
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric
decodeDispSPE4Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)325*06c3fb27SDimitry Andric static DecodeStatus decodeDispSPE4Operand(MCInst &Inst, uint64_t Imm,
32681ad6265SDimitry Andric int64_t Address,
32781ad6265SDimitry Andric const MCDisassembler *Decoder) {
328*06c3fb27SDimitry Andric // Decode the dispSPE8 field, which has 5-bits, 4-byte aligned.
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric uint64_t Disp = Imm & 0x1F;
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Disp << 2));
3330b57cec5SDimitry Andric return MCDisassembler::Success;
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric
decodeDispSPE2Operand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)336*06c3fb27SDimitry Andric static DecodeStatus decodeDispSPE2Operand(MCInst &Inst, uint64_t Imm,
33781ad6265SDimitry Andric int64_t Address,
33881ad6265SDimitry Andric const MCDisassembler *Decoder) {
339*06c3fb27SDimitry Andric // Decode the dispSPE8 field, which has 5-bits, 2-byte aligned.
3400b57cec5SDimitry Andric
3410b57cec5SDimitry Andric uint64_t Disp = Imm & 0x1F;
3420b57cec5SDimitry Andric Inst.addOperand(MCOperand::createImm(Disp << 1));
3430b57cec5SDimitry Andric return MCDisassembler::Success;
3440b57cec5SDimitry Andric }
3450b57cec5SDimitry Andric
decodeCRBitMOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const MCDisassembler * Decoder)3460b57cec5SDimitry Andric static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm,
34781ad6265SDimitry Andric int64_t Address,
34881ad6265SDimitry Andric const MCDisassembler *Decoder) {
3490b57cec5SDimitry Andric // The cr bit encoding is 0x80 >> cr_reg_num.
3500b57cec5SDimitry Andric
351*06c3fb27SDimitry Andric unsigned Zeros = llvm::countr_zero(Imm);
352*06c3fb27SDimitry Andric if (Zeros >= 8)
353*06c3fb27SDimitry Andric return MCDisassembler::Fail;
3540b57cec5SDimitry Andric
3550b57cec5SDimitry Andric Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
3560b57cec5SDimitry Andric return MCDisassembler::Success;
3570b57cec5SDimitry Andric }
3580b57cec5SDimitry Andric
3590b57cec5SDimitry Andric #include "PPCGenDisassemblerTables.inc"
3600b57cec5SDimitry Andric
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & CS) const3610b57cec5SDimitry Andric DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
3620b57cec5SDimitry Andric ArrayRef<uint8_t> Bytes,
363480093f4SDimitry Andric uint64_t Address,
3640b57cec5SDimitry Andric raw_ostream &CS) const {
3655ffd83dbSDimitry Andric auto *ReadFunc = IsLittleEndian ? support::endian::read32le
3665ffd83dbSDimitry Andric : support::endian::read32be;
3675ffd83dbSDimitry Andric
3685ffd83dbSDimitry Andric // If this is an 8-byte prefixed instruction, handle it here.
3695ffd83dbSDimitry Andric // Note: prefixed instructions aren't technically 8-byte entities - the prefix
3705ffd83dbSDimitry Andric // appears in memory at an address 4 bytes prior to that of the base
3715ffd83dbSDimitry Andric // instruction regardless of endianness. So we read the two pieces and
3725ffd83dbSDimitry Andric // rebuild the 8-byte instruction.
3735ffd83dbSDimitry Andric // TODO: In this function we call decodeInstruction several times with
3745ffd83dbSDimitry Andric // different decoder tables. It may be possible to only call once by
3755ffd83dbSDimitry Andric // looking at the top 6 bits of the instruction.
376*06c3fb27SDimitry Andric if (STI.hasFeature(PPC::FeaturePrefixInstrs) && Bytes.size() >= 8) {
3775ffd83dbSDimitry Andric uint32_t Prefix = ReadFunc(Bytes.data());
3785ffd83dbSDimitry Andric uint32_t BaseInst = ReadFunc(Bytes.data() + 4);
3795ffd83dbSDimitry Andric uint64_t Inst = BaseInst | (uint64_t)Prefix << 32;
3805ffd83dbSDimitry Andric DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address,
3815ffd83dbSDimitry Andric this, STI);
3825ffd83dbSDimitry Andric if (result != MCDisassembler::Fail) {
3835ffd83dbSDimitry Andric Size = 8;
3845ffd83dbSDimitry Andric return result;
3855ffd83dbSDimitry Andric }
3865ffd83dbSDimitry Andric }
3875ffd83dbSDimitry Andric
3880b57cec5SDimitry Andric // Get the four bytes of the instruction.
3890b57cec5SDimitry Andric Size = 4;
3900b57cec5SDimitry Andric if (Bytes.size() < 4) {
3910b57cec5SDimitry Andric Size = 0;
3920b57cec5SDimitry Andric return MCDisassembler::Fail;
3930b57cec5SDimitry Andric }
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andric // Read the instruction in the proper endianness.
3965ffd83dbSDimitry Andric uint64_t Inst = ReadFunc(Bytes.data());
3970b57cec5SDimitry Andric
398*06c3fb27SDimitry Andric if (STI.hasFeature(PPC::FeatureSPE)) {
3990b57cec5SDimitry Andric DecodeStatus result =
4000b57cec5SDimitry Andric decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI);
4010b57cec5SDimitry Andric if (result != MCDisassembler::Fail)
4020b57cec5SDimitry Andric return result;
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
4060b57cec5SDimitry Andric }
407