1*9880d681SAndroid Build Coastguard Worker //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "PPC.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCDisassembler/MCDisassembler.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixedLenDisassembler.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInst.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSubtargetInfo.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Endian.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard Worker using namespace llvm;
19*9880d681SAndroid Build Coastguard Worker
20*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "ppc-disassembler"
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker typedef MCDisassembler::DecodeStatus DecodeStatus;
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker namespace {
25*9880d681SAndroid Build Coastguard Worker class PPCDisassembler : public MCDisassembler {
26*9880d681SAndroid Build Coastguard Worker bool IsLittleEndian;
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker public:
PPCDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx,bool IsLittleEndian)29*9880d681SAndroid Build Coastguard Worker PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
30*9880d681SAndroid Build Coastguard Worker bool IsLittleEndian)
31*9880d681SAndroid Build Coastguard Worker : MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {}
32*9880d681SAndroid Build Coastguard Worker
33*9880d681SAndroid Build Coastguard Worker DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
34*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes, uint64_t Address,
35*9880d681SAndroid Build Coastguard Worker raw_ostream &VStream,
36*9880d681SAndroid Build Coastguard Worker raw_ostream &CStream) const override;
37*9880d681SAndroid Build Coastguard Worker };
38*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
39*9880d681SAndroid Build Coastguard Worker
createPPCDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)40*9880d681SAndroid Build Coastguard Worker static MCDisassembler *createPPCDisassembler(const Target &T,
41*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
42*9880d681SAndroid Build Coastguard Worker MCContext &Ctx) {
43*9880d681SAndroid Build Coastguard Worker return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker
createPPCLEDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)46*9880d681SAndroid Build Coastguard Worker static MCDisassembler *createPPCLEDisassembler(const Target &T,
47*9880d681SAndroid Build Coastguard Worker const MCSubtargetInfo &STI,
48*9880d681SAndroid Build Coastguard Worker MCContext &Ctx) {
49*9880d681SAndroid Build Coastguard Worker return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
50*9880d681SAndroid Build Coastguard Worker }
51*9880d681SAndroid Build Coastguard Worker
LLVMInitializePowerPCDisassembler()52*9880d681SAndroid Build Coastguard Worker extern "C" void LLVMInitializePowerPCDisassembler() {
53*9880d681SAndroid Build Coastguard Worker // Register the disassembler for each target.
54*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCDisassembler(ThePPC32Target,
55*9880d681SAndroid Build Coastguard Worker createPPCDisassembler);
56*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCDisassembler(ThePPC64Target,
57*9880d681SAndroid Build Coastguard Worker createPPCDisassembler);
58*9880d681SAndroid Build Coastguard Worker TargetRegistry::RegisterMCDisassembler(ThePPC64LETarget,
59*9880d681SAndroid Build Coastguard Worker createPPCLEDisassembler);
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker // FIXME: These can be generated by TableGen from the existing register
63*9880d681SAndroid Build Coastguard Worker // encoding values!
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker static const unsigned CRRegs[] = {
66*9880d681SAndroid Build Coastguard Worker PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3,
67*9880d681SAndroid Build Coastguard Worker PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7
68*9880d681SAndroid Build Coastguard Worker };
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker static const unsigned CRBITRegs[] = {
71*9880d681SAndroid Build Coastguard Worker PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN,
72*9880d681SAndroid Build Coastguard Worker PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN,
73*9880d681SAndroid Build Coastguard Worker PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN,
74*9880d681SAndroid Build Coastguard Worker PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN,
75*9880d681SAndroid Build Coastguard Worker PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN,
76*9880d681SAndroid Build Coastguard Worker PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN,
77*9880d681SAndroid Build Coastguard Worker PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN,
78*9880d681SAndroid Build Coastguard Worker PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN
79*9880d681SAndroid Build Coastguard Worker };
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker static const unsigned FRegs[] = {
82*9880d681SAndroid Build Coastguard Worker PPC::F0, PPC::F1, PPC::F2, PPC::F3,
83*9880d681SAndroid Build Coastguard Worker PPC::F4, PPC::F5, PPC::F6, PPC::F7,
84*9880d681SAndroid Build Coastguard Worker PPC::F8, PPC::F9, PPC::F10, PPC::F11,
85*9880d681SAndroid Build Coastguard Worker PPC::F12, PPC::F13, PPC::F14, PPC::F15,
86*9880d681SAndroid Build Coastguard Worker PPC::F16, PPC::F17, PPC::F18, PPC::F19,
87*9880d681SAndroid Build Coastguard Worker PPC::F20, PPC::F21, PPC::F22, PPC::F23,
88*9880d681SAndroid Build Coastguard Worker PPC::F24, PPC::F25, PPC::F26, PPC::F27,
89*9880d681SAndroid Build Coastguard Worker PPC::F28, PPC::F29, PPC::F30, PPC::F31
90*9880d681SAndroid Build Coastguard Worker };
91*9880d681SAndroid Build Coastguard Worker
92*9880d681SAndroid Build Coastguard Worker static const unsigned VRegs[] = {
93*9880d681SAndroid Build Coastguard Worker PPC::V0, PPC::V1, PPC::V2, PPC::V3,
94*9880d681SAndroid Build Coastguard Worker PPC::V4, PPC::V5, PPC::V6, PPC::V7,
95*9880d681SAndroid Build Coastguard Worker PPC::V8, PPC::V9, PPC::V10, PPC::V11,
96*9880d681SAndroid Build Coastguard Worker PPC::V12, PPC::V13, PPC::V14, PPC::V15,
97*9880d681SAndroid Build Coastguard Worker PPC::V16, PPC::V17, PPC::V18, PPC::V19,
98*9880d681SAndroid Build Coastguard Worker PPC::V20, PPC::V21, PPC::V22, PPC::V23,
99*9880d681SAndroid Build Coastguard Worker PPC::V24, PPC::V25, PPC::V26, PPC::V27,
100*9880d681SAndroid Build Coastguard Worker PPC::V28, PPC::V29, PPC::V30, PPC::V31
101*9880d681SAndroid Build Coastguard Worker };
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker static const unsigned VSRegs[] = {
104*9880d681SAndroid Build Coastguard Worker PPC::VSL0, PPC::VSL1, PPC::VSL2, PPC::VSL3,
105*9880d681SAndroid Build Coastguard Worker PPC::VSL4, PPC::VSL5, PPC::VSL6, PPC::VSL7,
106*9880d681SAndroid Build Coastguard Worker PPC::VSL8, PPC::VSL9, PPC::VSL10, PPC::VSL11,
107*9880d681SAndroid Build Coastguard Worker PPC::VSL12, PPC::VSL13, PPC::VSL14, PPC::VSL15,
108*9880d681SAndroid Build Coastguard Worker PPC::VSL16, PPC::VSL17, PPC::VSL18, PPC::VSL19,
109*9880d681SAndroid Build Coastguard Worker PPC::VSL20, PPC::VSL21, PPC::VSL22, PPC::VSL23,
110*9880d681SAndroid Build Coastguard Worker PPC::VSL24, PPC::VSL25, PPC::VSL26, PPC::VSL27,
111*9880d681SAndroid Build Coastguard Worker PPC::VSL28, PPC::VSL29, PPC::VSL30, PPC::VSL31,
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker PPC::VSH0, PPC::VSH1, PPC::VSH2, PPC::VSH3,
114*9880d681SAndroid Build Coastguard Worker PPC::VSH4, PPC::VSH5, PPC::VSH6, PPC::VSH7,
115*9880d681SAndroid Build Coastguard Worker PPC::VSH8, PPC::VSH9, PPC::VSH10, PPC::VSH11,
116*9880d681SAndroid Build Coastguard Worker PPC::VSH12, PPC::VSH13, PPC::VSH14, PPC::VSH15,
117*9880d681SAndroid Build Coastguard Worker PPC::VSH16, PPC::VSH17, PPC::VSH18, PPC::VSH19,
118*9880d681SAndroid Build Coastguard Worker PPC::VSH20, PPC::VSH21, PPC::VSH22, PPC::VSH23,
119*9880d681SAndroid Build Coastguard Worker PPC::VSH24, PPC::VSH25, PPC::VSH26, PPC::VSH27,
120*9880d681SAndroid Build Coastguard Worker PPC::VSH28, PPC::VSH29, PPC::VSH30, PPC::VSH31
121*9880d681SAndroid Build Coastguard Worker };
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker static const unsigned VSFRegs[] = {
124*9880d681SAndroid Build Coastguard Worker PPC::F0, PPC::F1, PPC::F2, PPC::F3,
125*9880d681SAndroid Build Coastguard Worker PPC::F4, PPC::F5, PPC::F6, PPC::F7,
126*9880d681SAndroid Build Coastguard Worker PPC::F8, PPC::F9, PPC::F10, PPC::F11,
127*9880d681SAndroid Build Coastguard Worker PPC::F12, PPC::F13, PPC::F14, PPC::F15,
128*9880d681SAndroid Build Coastguard Worker PPC::F16, PPC::F17, PPC::F18, PPC::F19,
129*9880d681SAndroid Build Coastguard Worker PPC::F20, PPC::F21, PPC::F22, PPC::F23,
130*9880d681SAndroid Build Coastguard Worker PPC::F24, PPC::F25, PPC::F26, PPC::F27,
131*9880d681SAndroid Build Coastguard Worker PPC::F28, PPC::F29, PPC::F30, PPC::F31,
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
134*9880d681SAndroid Build Coastguard Worker PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
135*9880d681SAndroid Build Coastguard Worker PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
136*9880d681SAndroid Build Coastguard Worker PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
137*9880d681SAndroid Build Coastguard Worker PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
138*9880d681SAndroid Build Coastguard Worker PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
139*9880d681SAndroid Build Coastguard Worker PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
140*9880d681SAndroid Build Coastguard Worker PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
141*9880d681SAndroid Build Coastguard Worker };
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker static const unsigned VSSRegs[] = {
144*9880d681SAndroid Build Coastguard Worker PPC::F0, PPC::F1, PPC::F2, PPC::F3,
145*9880d681SAndroid Build Coastguard Worker PPC::F4, PPC::F5, PPC::F6, PPC::F7,
146*9880d681SAndroid Build Coastguard Worker PPC::F8, PPC::F9, PPC::F10, PPC::F11,
147*9880d681SAndroid Build Coastguard Worker PPC::F12, PPC::F13, PPC::F14, PPC::F15,
148*9880d681SAndroid Build Coastguard Worker PPC::F16, PPC::F17, PPC::F18, PPC::F19,
149*9880d681SAndroid Build Coastguard Worker PPC::F20, PPC::F21, PPC::F22, PPC::F23,
150*9880d681SAndroid Build Coastguard Worker PPC::F24, PPC::F25, PPC::F26, PPC::F27,
151*9880d681SAndroid Build Coastguard Worker PPC::F28, PPC::F29, PPC::F30, PPC::F31,
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
154*9880d681SAndroid Build Coastguard Worker PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
155*9880d681SAndroid Build Coastguard Worker PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
156*9880d681SAndroid Build Coastguard Worker PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
157*9880d681SAndroid Build Coastguard Worker PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
158*9880d681SAndroid Build Coastguard Worker PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
159*9880d681SAndroid Build Coastguard Worker PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
160*9880d681SAndroid Build Coastguard Worker PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
161*9880d681SAndroid Build Coastguard Worker };
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker static const unsigned GPRegs[] = {
164*9880d681SAndroid Build Coastguard Worker PPC::R0, PPC::R1, PPC::R2, PPC::R3,
165*9880d681SAndroid Build Coastguard Worker PPC::R4, PPC::R5, PPC::R6, PPC::R7,
166*9880d681SAndroid Build Coastguard Worker PPC::R8, PPC::R9, PPC::R10, PPC::R11,
167*9880d681SAndroid Build Coastguard Worker PPC::R12, PPC::R13, PPC::R14, PPC::R15,
168*9880d681SAndroid Build Coastguard Worker PPC::R16, PPC::R17, PPC::R18, PPC::R19,
169*9880d681SAndroid Build Coastguard Worker PPC::R20, PPC::R21, PPC::R22, PPC::R23,
170*9880d681SAndroid Build Coastguard Worker PPC::R24, PPC::R25, PPC::R26, PPC::R27,
171*9880d681SAndroid Build Coastguard Worker PPC::R28, PPC::R29, PPC::R30, PPC::R31
172*9880d681SAndroid Build Coastguard Worker };
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker static const unsigned GP0Regs[] = {
175*9880d681SAndroid Build Coastguard Worker PPC::ZERO, PPC::R1, PPC::R2, PPC::R3,
176*9880d681SAndroid Build Coastguard Worker PPC::R4, PPC::R5, PPC::R6, PPC::R7,
177*9880d681SAndroid Build Coastguard Worker PPC::R8, PPC::R9, PPC::R10, PPC::R11,
178*9880d681SAndroid Build Coastguard Worker PPC::R12, PPC::R13, PPC::R14, PPC::R15,
179*9880d681SAndroid Build Coastguard Worker PPC::R16, PPC::R17, PPC::R18, PPC::R19,
180*9880d681SAndroid Build Coastguard Worker PPC::R20, PPC::R21, PPC::R22, PPC::R23,
181*9880d681SAndroid Build Coastguard Worker PPC::R24, PPC::R25, PPC::R26, PPC::R27,
182*9880d681SAndroid Build Coastguard Worker PPC::R28, PPC::R29, PPC::R30, PPC::R31
183*9880d681SAndroid Build Coastguard Worker };
184*9880d681SAndroid Build Coastguard Worker
185*9880d681SAndroid Build Coastguard Worker static const unsigned G8Regs[] = {
186*9880d681SAndroid Build Coastguard Worker PPC::X0, PPC::X1, PPC::X2, PPC::X3,
187*9880d681SAndroid Build Coastguard Worker PPC::X4, PPC::X5, PPC::X6, PPC::X7,
188*9880d681SAndroid Build Coastguard Worker PPC::X8, PPC::X9, PPC::X10, PPC::X11,
189*9880d681SAndroid Build Coastguard Worker PPC::X12, PPC::X13, PPC::X14, PPC::X15,
190*9880d681SAndroid Build Coastguard Worker PPC::X16, PPC::X17, PPC::X18, PPC::X19,
191*9880d681SAndroid Build Coastguard Worker PPC::X20, PPC::X21, PPC::X22, PPC::X23,
192*9880d681SAndroid Build Coastguard Worker PPC::X24, PPC::X25, PPC::X26, PPC::X27,
193*9880d681SAndroid Build Coastguard Worker PPC::X28, PPC::X29, PPC::X30, PPC::X31
194*9880d681SAndroid Build Coastguard Worker };
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker static const unsigned QFRegs[] = {
197*9880d681SAndroid Build Coastguard Worker PPC::QF0, PPC::QF1, PPC::QF2, PPC::QF3,
198*9880d681SAndroid Build Coastguard Worker PPC::QF4, PPC::QF5, PPC::QF6, PPC::QF7,
199*9880d681SAndroid Build Coastguard Worker PPC::QF8, PPC::QF9, PPC::QF10, PPC::QF11,
200*9880d681SAndroid Build Coastguard Worker PPC::QF12, PPC::QF13, PPC::QF14, PPC::QF15,
201*9880d681SAndroid Build Coastguard Worker PPC::QF16, PPC::QF17, PPC::QF18, PPC::QF19,
202*9880d681SAndroid Build Coastguard Worker PPC::QF20, PPC::QF21, PPC::QF22, PPC::QF23,
203*9880d681SAndroid Build Coastguard Worker PPC::QF24, PPC::QF25, PPC::QF26, PPC::QF27,
204*9880d681SAndroid Build Coastguard Worker PPC::QF28, PPC::QF29, PPC::QF30, PPC::QF31
205*9880d681SAndroid Build Coastguard Worker };
206*9880d681SAndroid Build Coastguard Worker
207*9880d681SAndroid Build Coastguard Worker template <std::size_t N>
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const unsigned (& Regs)[N])208*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
209*9880d681SAndroid Build Coastguard Worker const unsigned (&Regs)[N]) {
210*9880d681SAndroid Build Coastguard Worker assert(RegNo < N && "Invalid register number");
211*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
212*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
213*9880d681SAndroid Build Coastguard Worker }
214*9880d681SAndroid Build Coastguard Worker
DecodeCRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)215*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
216*9880d681SAndroid Build Coastguard Worker uint64_t Address,
217*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
218*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, CRRegs);
219*9880d681SAndroid Build Coastguard Worker }
220*9880d681SAndroid Build Coastguard Worker
DecodeCRRC0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)221*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo,
222*9880d681SAndroid Build Coastguard Worker uint64_t Address,
223*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
224*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, CRRegs);
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker
DecodeCRBITRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)227*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
228*9880d681SAndroid Build Coastguard Worker uint64_t Address,
229*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
230*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, CRBITRegs);
231*9880d681SAndroid Build Coastguard Worker }
232*9880d681SAndroid Build Coastguard Worker
DecodeF4RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)233*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
234*9880d681SAndroid Build Coastguard Worker uint64_t Address,
235*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
236*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, FRegs);
237*9880d681SAndroid Build Coastguard Worker }
238*9880d681SAndroid Build Coastguard Worker
DecodeF8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)239*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
240*9880d681SAndroid Build Coastguard Worker uint64_t Address,
241*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
242*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, FRegs);
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker
DecodeVRRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)245*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
246*9880d681SAndroid Build Coastguard Worker uint64_t Address,
247*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
248*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, VRegs);
249*9880d681SAndroid Build Coastguard Worker }
250*9880d681SAndroid Build Coastguard Worker
DecodeVSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)251*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
252*9880d681SAndroid Build Coastguard Worker uint64_t Address,
253*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
254*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, VSRegs);
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker
DecodeVSFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)257*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
258*9880d681SAndroid Build Coastguard Worker uint64_t Address,
259*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
260*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, VSFRegs);
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker
DecodeVSSRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)263*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
264*9880d681SAndroid Build Coastguard Worker uint64_t Address,
265*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
266*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, VSSRegs);
267*9880d681SAndroid Build Coastguard Worker }
268*9880d681SAndroid Build Coastguard Worker
DecodeGPRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)269*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
270*9880d681SAndroid Build Coastguard Worker uint64_t Address,
271*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
272*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, GPRegs);
273*9880d681SAndroid Build Coastguard Worker }
274*9880d681SAndroid Build Coastguard Worker
DecodeGPRC_NOR0RegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)275*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo,
276*9880d681SAndroid Build Coastguard Worker uint64_t Address,
277*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
278*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, GP0Regs);
279*9880d681SAndroid Build Coastguard Worker }
280*9880d681SAndroid Build Coastguard Worker
DecodeG8RCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)281*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
282*9880d681SAndroid Build Coastguard Worker uint64_t Address,
283*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
284*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, G8Regs);
285*9880d681SAndroid Build Coastguard Worker }
286*9880d681SAndroid Build Coastguard Worker
287*9880d681SAndroid Build Coastguard Worker #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
288*9880d681SAndroid Build Coastguard Worker #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
289*9880d681SAndroid Build Coastguard Worker
DecodeQFRCRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)290*9880d681SAndroid Build Coastguard Worker static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
291*9880d681SAndroid Build Coastguard Worker uint64_t Address,
292*9880d681SAndroid Build Coastguard Worker const void *Decoder) {
293*9880d681SAndroid Build Coastguard Worker return decodeRegisterClass(Inst, RegNo, QFRegs);
294*9880d681SAndroid Build Coastguard Worker }
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
297*9880d681SAndroid Build Coastguard Worker #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Worker template<unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)300*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
301*9880d681SAndroid Build Coastguard Worker int64_t Address, const void *Decoder) {
302*9880d681SAndroid Build Coastguard Worker assert(isUInt<N>(Imm) && "Invalid immediate");
303*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(Imm));
304*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
305*9880d681SAndroid Build Coastguard Worker }
306*9880d681SAndroid Build Coastguard Worker
307*9880d681SAndroid Build Coastguard Worker template<unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)308*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
309*9880d681SAndroid Build Coastguard Worker int64_t Address, const void *Decoder) {
310*9880d681SAndroid Build Coastguard Worker assert(isUInt<N>(Imm) && "Invalid immediate");
311*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
312*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
313*9880d681SAndroid Build Coastguard Worker }
314*9880d681SAndroid Build Coastguard Worker
decodeMemRIOperands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)315*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
316*9880d681SAndroid Build Coastguard Worker int64_t Address, const void *Decoder) {
317*9880d681SAndroid Build Coastguard Worker // Decode the memri field (imm, reg), which has the low 16-bits as the
318*9880d681SAndroid Build Coastguard Worker // displacement and the next 5 bits as the register #.
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker uint64_t Base = Imm >> 16;
321*9880d681SAndroid Build Coastguard Worker uint64_t Disp = Imm & 0xFFFF;
322*9880d681SAndroid Build Coastguard Worker
323*9880d681SAndroid Build Coastguard Worker assert(Base < 32 && "Invalid base register");
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker switch (Inst.getOpcode()) {
326*9880d681SAndroid Build Coastguard Worker default: break;
327*9880d681SAndroid Build Coastguard Worker case PPC::LBZU:
328*9880d681SAndroid Build Coastguard Worker case PPC::LHAU:
329*9880d681SAndroid Build Coastguard Worker case PPC::LHZU:
330*9880d681SAndroid Build Coastguard Worker case PPC::LWZU:
331*9880d681SAndroid Build Coastguard Worker case PPC::LFSU:
332*9880d681SAndroid Build Coastguard Worker case PPC::LFDU:
333*9880d681SAndroid Build Coastguard Worker // Add the tied output operand.
334*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
335*9880d681SAndroid Build Coastguard Worker break;
336*9880d681SAndroid Build Coastguard Worker case PPC::STBU:
337*9880d681SAndroid Build Coastguard Worker case PPC::STHU:
338*9880d681SAndroid Build Coastguard Worker case PPC::STWU:
339*9880d681SAndroid Build Coastguard Worker case PPC::STFSU:
340*9880d681SAndroid Build Coastguard Worker case PPC::STFDU:
341*9880d681SAndroid Build Coastguard Worker Inst.insert(Inst.begin(), MCOperand::createReg(GP0Regs[Base]));
342*9880d681SAndroid Build Coastguard Worker break;
343*9880d681SAndroid Build Coastguard Worker }
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp)));
346*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
347*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker
decodeMemRIXOperands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)350*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm,
351*9880d681SAndroid Build Coastguard Worker int64_t Address, const void *Decoder) {
352*9880d681SAndroid Build Coastguard Worker // Decode the memrix field (imm, reg), which has the low 14-bits as the
353*9880d681SAndroid Build Coastguard Worker // displacement and the next 5 bits as the register #.
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker uint64_t Base = Imm >> 14;
356*9880d681SAndroid Build Coastguard Worker uint64_t Disp = Imm & 0x3FFF;
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker assert(Base < 32 && "Invalid base register");
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Worker if (Inst.getOpcode() == PPC::LDU)
361*9880d681SAndroid Build Coastguard Worker // Add the tied output operand.
362*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
363*9880d681SAndroid Build Coastguard Worker else if (Inst.getOpcode() == PPC::STDU)
364*9880d681SAndroid Build Coastguard Worker Inst.insert(Inst.begin(), MCOperand::createReg(GP0Regs[Base]));
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2)));
367*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
368*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker
decodeMemRIX16Operands(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)371*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
372*9880d681SAndroid Build Coastguard Worker int64_t Address, const void *Decoder) {
373*9880d681SAndroid Build Coastguard Worker // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
374*9880d681SAndroid Build Coastguard Worker // displacement with 16-byte aligned, and the next 5 bits as the register #.
375*9880d681SAndroid Build Coastguard Worker
376*9880d681SAndroid Build Coastguard Worker uint64_t Base = Imm >> 12;
377*9880d681SAndroid Build Coastguard Worker uint64_t Disp = Imm & 0xFFF;
378*9880d681SAndroid Build Coastguard Worker
379*9880d681SAndroid Build Coastguard Worker assert(Base < 32 && "Invalid base register");
380*9880d681SAndroid Build Coastguard Worker
381*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4)));
382*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
383*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
384*9880d681SAndroid Build Coastguard Worker }
385*9880d681SAndroid Build Coastguard Worker
decodeCRBitMOperand(MCInst & Inst,uint64_t Imm,int64_t Address,const void * Decoder)386*9880d681SAndroid Build Coastguard Worker static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm,
387*9880d681SAndroid Build Coastguard Worker int64_t Address, const void *Decoder) {
388*9880d681SAndroid Build Coastguard Worker // The cr bit encoding is 0x80 >> cr_reg_num.
389*9880d681SAndroid Build Coastguard Worker
390*9880d681SAndroid Build Coastguard Worker unsigned Zeros = countTrailingZeros(Imm);
391*9880d681SAndroid Build Coastguard Worker assert(Zeros < 8 && "Invalid CR bit value");
392*9880d681SAndroid Build Coastguard Worker
393*9880d681SAndroid Build Coastguard Worker Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
394*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Success;
395*9880d681SAndroid Build Coastguard Worker }
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker #include "PPCGenDisassemblerTables.inc"
398*9880d681SAndroid Build Coastguard Worker
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const399*9880d681SAndroid Build Coastguard Worker DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
400*9880d681SAndroid Build Coastguard Worker ArrayRef<uint8_t> Bytes,
401*9880d681SAndroid Build Coastguard Worker uint64_t Address, raw_ostream &OS,
402*9880d681SAndroid Build Coastguard Worker raw_ostream &CS) const {
403*9880d681SAndroid Build Coastguard Worker // Get the four bytes of the instruction.
404*9880d681SAndroid Build Coastguard Worker Size = 4;
405*9880d681SAndroid Build Coastguard Worker if (Bytes.size() < 4) {
406*9880d681SAndroid Build Coastguard Worker Size = 0;
407*9880d681SAndroid Build Coastguard Worker return MCDisassembler::Fail;
408*9880d681SAndroid Build Coastguard Worker }
409*9880d681SAndroid Build Coastguard Worker
410*9880d681SAndroid Build Coastguard Worker // Read the instruction in the proper endianness.
411*9880d681SAndroid Build Coastguard Worker uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data())
412*9880d681SAndroid Build Coastguard Worker : support::endian::read32be(Bytes.data());
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker if (STI.getFeatureBits()[PPC::FeatureQPX]) {
415*9880d681SAndroid Build Coastguard Worker DecodeStatus result =
416*9880d681SAndroid Build Coastguard Worker decodeInstruction(DecoderTableQPX32, MI, Inst, Address, this, STI);
417*9880d681SAndroid Build Coastguard Worker if (result != MCDisassembler::Fail)
418*9880d681SAndroid Build Coastguard Worker return result;
419*9880d681SAndroid Build Coastguard Worker }
420*9880d681SAndroid Build Coastguard Worker
421*9880d681SAndroid Build Coastguard Worker return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
422*9880d681SAndroid Build Coastguard Worker }
423*9880d681SAndroid Build Coastguard Worker
424