1 //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 /* Capstone Disassembly Engine */
11 /* By Nguyen Anh Quynh <[email protected]>, 2013-2015 */
12
13 #ifdef CAPSTONE_HAS_POWERPC
14
15 #include <stdio.h> // DEBUG
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include "../../cs_priv.h"
20 #include "../../utils.h"
21
22 #include "PPCDisassembler.h"
23
24 #include "../../MCInst.h"
25 #include "../../MCInstrDesc.h"
26 #include "../../MCFixedLenDisassembler.h"
27 #include "../../MCRegisterInfo.h"
28 #include "../../MCDisassembler.h"
29 #include "../../MathExtras.h"
30
31 #define GET_REGINFO_ENUM
32 #include "PPCGenRegisterInfo.inc"
33
34
35 // FIXME: These can be generated by TableGen from the existing register
36 // encoding values!
37
38 static const unsigned CRRegs[] = {
39 PPC_CR0, PPC_CR1, PPC_CR2, PPC_CR3,
40 PPC_CR4, PPC_CR5, PPC_CR6, PPC_CR7
41 };
42
43 static const unsigned CRBITRegs[] = {
44 PPC_CR0LT, PPC_CR0GT, PPC_CR0EQ, PPC_CR0UN,
45 PPC_CR1LT, PPC_CR1GT, PPC_CR1EQ, PPC_CR1UN,
46 PPC_CR2LT, PPC_CR2GT, PPC_CR2EQ, PPC_CR2UN,
47 PPC_CR3LT, PPC_CR3GT, PPC_CR3EQ, PPC_CR3UN,
48 PPC_CR4LT, PPC_CR4GT, PPC_CR4EQ, PPC_CR4UN,
49 PPC_CR5LT, PPC_CR5GT, PPC_CR5EQ, PPC_CR5UN,
50 PPC_CR6LT, PPC_CR6GT, PPC_CR6EQ, PPC_CR6UN,
51 PPC_CR7LT, PPC_CR7GT, PPC_CR7EQ, PPC_CR7UN
52 };
53
54 static const unsigned FRegs[] = {
55 PPC_F0, PPC_F1, PPC_F2, PPC_F3,
56 PPC_F4, PPC_F5, PPC_F6, PPC_F7,
57 PPC_F8, PPC_F9, PPC_F10, PPC_F11,
58 PPC_F12, PPC_F13, PPC_F14, PPC_F15,
59 PPC_F16, PPC_F17, PPC_F18, PPC_F19,
60 PPC_F20, PPC_F21, PPC_F22, PPC_F23,
61 PPC_F24, PPC_F25, PPC_F26, PPC_F27,
62 PPC_F28, PPC_F29, PPC_F30, PPC_F31
63 };
64
65 static const unsigned VRegs[] = {
66 PPC_V0, PPC_V1, PPC_V2, PPC_V3,
67 PPC_V4, PPC_V5, PPC_V6, PPC_V7,
68 PPC_V8, PPC_V9, PPC_V10, PPC_V11,
69 PPC_V12, PPC_V13, PPC_V14, PPC_V15,
70 PPC_V16, PPC_V17, PPC_V18, PPC_V19,
71 PPC_V20, PPC_V21, PPC_V22, PPC_V23,
72 PPC_V24, PPC_V25, PPC_V26, PPC_V27,
73 PPC_V28, PPC_V29, PPC_V30, PPC_V31
74 };
75
76 static const unsigned VSRegs[] = {
77 PPC_VSL0, PPC_VSL1, PPC_VSL2, PPC_VSL3,
78 PPC_VSL4, PPC_VSL5, PPC_VSL6, PPC_VSL7,
79 PPC_VSL8, PPC_VSL9, PPC_VSL10, PPC_VSL11,
80 PPC_VSL12, PPC_VSL13, PPC_VSL14, PPC_VSL15,
81 PPC_VSL16, PPC_VSL17, PPC_VSL18, PPC_VSL19,
82 PPC_VSL20, PPC_VSL21, PPC_VSL22, PPC_VSL23,
83 PPC_VSL24, PPC_VSL25, PPC_VSL26, PPC_VSL27,
84 PPC_VSL28, PPC_VSL29, PPC_VSL30, PPC_VSL31,
85
86 PPC_VSH0, PPC_VSH1, PPC_VSH2, PPC_VSH3,
87 PPC_VSH4, PPC_VSH5, PPC_VSH6, PPC_VSH7,
88 PPC_VSH8, PPC_VSH9, PPC_VSH10, PPC_VSH11,
89 PPC_VSH12, PPC_VSH13, PPC_VSH14, PPC_VSH15,
90 PPC_VSH16, PPC_VSH17, PPC_VSH18, PPC_VSH19,
91 PPC_VSH20, PPC_VSH21, PPC_VSH22, PPC_VSH23,
92 PPC_VSH24, PPC_VSH25, PPC_VSH26, PPC_VSH27,
93 PPC_VSH28, PPC_VSH29, PPC_VSH30, PPC_VSH31
94 };
95
96 static const unsigned VSFRegs[] = {
97 PPC_F0, PPC_F1, PPC_F2, PPC_F3,
98 PPC_F4, PPC_F5, PPC_F6, PPC_F7,
99 PPC_F8, PPC_F9, PPC_F10, PPC_F11,
100 PPC_F12, PPC_F13, PPC_F14, PPC_F15,
101 PPC_F16, PPC_F17, PPC_F18, PPC_F19,
102 PPC_F20, PPC_F21, PPC_F22, PPC_F23,
103 PPC_F24, PPC_F25, PPC_F26, PPC_F27,
104 PPC_F28, PPC_F29, PPC_F30, PPC_F31,
105
106 PPC_VF0, PPC_VF1, PPC_VF2, PPC_VF3,
107 PPC_VF4, PPC_VF5, PPC_VF6, PPC_VF7,
108 PPC_VF8, PPC_VF9, PPC_VF10, PPC_VF11,
109 PPC_VF12, PPC_VF13, PPC_VF14, PPC_VF15,
110 PPC_VF16, PPC_VF17, PPC_VF18, PPC_VF19,
111 PPC_VF20, PPC_VF21, PPC_VF22, PPC_VF23,
112 PPC_VF24, PPC_VF25, PPC_VF26, PPC_VF27,
113 PPC_VF28, PPC_VF29, PPC_VF30, PPC_VF31
114 };
115
116 static const unsigned GPRegs[] = {
117 PPC_R0, PPC_R1, PPC_R2, PPC_R3,
118 PPC_R4, PPC_R5, PPC_R6, PPC_R7,
119 PPC_R8, PPC_R9, PPC_R10, PPC_R11,
120 PPC_R12, PPC_R13, PPC_R14, PPC_R15,
121 PPC_R16, PPC_R17, PPC_R18, PPC_R19,
122 PPC_R20, PPC_R21, PPC_R22, PPC_R23,
123 PPC_R24, PPC_R25, PPC_R26, PPC_R27,
124 PPC_R28, PPC_R29, PPC_R30, PPC_R31
125 };
126
127 static const unsigned GP0Regs[] = {
128 PPC_ZERO, PPC_R1, PPC_R2, PPC_R3,
129 PPC_R4, PPC_R5, PPC_R6, PPC_R7,
130 PPC_R8, PPC_R9, PPC_R10, PPC_R11,
131 PPC_R12, PPC_R13, PPC_R14, PPC_R15,
132 PPC_R16, PPC_R17, PPC_R18, PPC_R19,
133 PPC_R20, PPC_R21, PPC_R22, PPC_R23,
134 PPC_R24, PPC_R25, PPC_R26, PPC_R27,
135 PPC_R28, PPC_R29, PPC_R30, PPC_R31
136 };
137
138 static const unsigned G8Regs[] = {
139 PPC_X0, PPC_X1, PPC_X2, PPC_X3,
140 PPC_X4, PPC_X5, PPC_X6, PPC_X7,
141 PPC_X8, PPC_X9, PPC_X10, PPC_X11,
142 PPC_X12, PPC_X13, PPC_X14, PPC_X15,
143 PPC_X16, PPC_X17, PPC_X18, PPC_X19,
144 PPC_X20, PPC_X21, PPC_X22, PPC_X23,
145 PPC_X24, PPC_X25, PPC_X26, PPC_X27,
146 PPC_X28, PPC_X29, PPC_X30, PPC_X31
147 };
148
149 static const unsigned QFRegs[] = {
150 PPC_QF0, PPC_QF1, PPC_QF2, PPC_QF3,
151 PPC_QF4, PPC_QF5, PPC_QF6, PPC_QF7,
152 PPC_QF8, PPC_QF9, PPC_QF10, PPC_QF11,
153 PPC_QF12, PPC_QF13, PPC_QF14, PPC_QF15,
154 PPC_QF16, PPC_QF17, PPC_QF18, PPC_QF19,
155 PPC_QF20, PPC_QF21, PPC_QF22, PPC_QF23,
156 PPC_QF24, PPC_QF25, PPC_QF26, PPC_QF27,
157 PPC_QF28, PPC_QF29, PPC_QF30, PPC_QF31
158 };
159
getFeatureBits(int feature)160 static uint64_t getFeatureBits(int feature)
161 {
162 // enable all features
163 return (uint64_t)-1;
164 }
165
decodeRegisterClass(MCInst * Inst,uint64_t RegNo,const unsigned * Regs,size_t RegsLen)166 static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo,
167 const unsigned *Regs, size_t RegsLen)
168 {
169 if (RegNo >= RegsLen / sizeof(unsigned)) {
170 return MCDisassembler_Fail;
171 }
172 MCOperand_CreateReg0(Inst, Regs[RegNo]);
173 return MCDisassembler_Success;
174 }
175
DecodeCRRCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)176 static DecodeStatus DecodeCRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
177 uint64_t Address,
178 const void *Decoder)
179 {
180 return decodeRegisterClass(Inst, RegNo, CRRegs, sizeof(CRRegs));
181 }
182
DecodeCRBITRCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)183 static DecodeStatus DecodeCRBITRCRegisterClass(MCInst *Inst, uint64_t RegNo,
184 uint64_t Address,
185 const void *Decoder)
186 {
187 return decodeRegisterClass(Inst, RegNo, CRBITRegs, sizeof(CRBITRegs));
188 }
189
DecodeF4RCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)190 static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, uint64_t RegNo,
191 uint64_t Address,
192 const void *Decoder)
193 {
194 return decodeRegisterClass(Inst, RegNo, FRegs, sizeof(FRegs));
195 }
196
DecodeF8RCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)197 static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
198 uint64_t Address,
199 const void *Decoder)
200 {
201 return decodeRegisterClass(Inst, RegNo, FRegs, sizeof(FRegs));
202 }
203
DecodeVRRCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)204 static DecodeStatus DecodeVRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
205 uint64_t Address,
206 const void *Decoder)
207 {
208 return decodeRegisterClass(Inst, RegNo, VRegs, sizeof(VRegs));
209 }
210
DecodeVSRCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)211 static DecodeStatus DecodeVSRCRegisterClass(MCInst *Inst, uint64_t RegNo,
212 uint64_t Address,
213 const void *Decoder)
214 {
215 return decodeRegisterClass(Inst, RegNo, VSRegs, sizeof(VSRegs));
216 }
217
DecodeVSFRCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)218 static DecodeStatus DecodeVSFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
219 uint64_t Address,
220 const void *Decoder)
221 {
222 return decodeRegisterClass(Inst, RegNo, VSFRegs, sizeof(VSFRegs));
223 }
224
DecodeGPRCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)225 static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo,
226 uint64_t Address,
227 const void *Decoder)
228 {
229 return decodeRegisterClass(Inst, RegNo, GPRegs, sizeof(GPRegs));
230 }
231
DecodeGPRC_NOR0RegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)232 static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst *Inst, uint64_t RegNo,
233 uint64_t Address,
234 const void *Decoder)
235 {
236 return decodeRegisterClass(Inst, RegNo, GP0Regs, sizeof(GP0Regs));
237 }
238
DecodeG8RCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)239 static DecodeStatus DecodeG8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
240 uint64_t Address,
241 const void *Decoder)
242 {
243 return decodeRegisterClass(Inst, RegNo, G8Regs, sizeof(G8Regs));
244 }
245
246 #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
247 #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
248
DecodeQFRCRegisterClass(MCInst * Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)249 static DecodeStatus DecodeQFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
250 uint64_t Address,
251 const void *Decoder)
252 {
253 return decodeRegisterClass(Inst, RegNo, QFRegs, sizeof(QFRegs));
254 }
255
256 #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
257 #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
258
decodeUImmOperand(MCInst * Inst,uint64_t Imm,int64_t Address,const void * Decoder,unsigned N)259 static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm,
260 int64_t Address, const void *Decoder, unsigned N)
261 {
262 //assert(isUInt<N>(Imm) && "Invalid immediate");
263 MCOperand_CreateImm0(Inst, Imm);
264 return MCDisassembler_Success;
265 }
266
decodeSImmOperand(MCInst * Inst,uint64_t Imm,int64_t Address,const void * Decoder,unsigned N)267 static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm,
268 int64_t Address, const void *Decoder, unsigned N)
269 {
270 // assert(isUInt<N>(Imm) && "Invalid immediate");
271 MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
272 return MCDisassembler_Success;
273 }
274
275
276 #define GET_INSTRINFO_ENUM
277 #include "PPCGenInstrInfo.inc"
278
decodeMemRIOperands(MCInst * Inst,uint64_t Imm,int64_t Address,const void * Decoder)279 static DecodeStatus decodeMemRIOperands(MCInst *Inst, uint64_t Imm,
280 int64_t Address, const void *Decoder)
281 {
282 // Decode the memri field (imm, reg), which has the low 16-bits as the
283 // displacement and the next 5 bits as the register #.
284
285 uint64_t Base = Imm >> 16;
286 uint64_t Disp = Imm & 0xFFFF;
287
288 // assert(Base < 32 && "Invalid base register");
289 if (Base >= 32)
290 return MCDisassembler_Fail;
291
292 switch (MCInst_getOpcode(Inst)) {
293 default: break;
294 case PPC_LBZU:
295 case PPC_LHAU:
296 case PPC_LHZU:
297 case PPC_LWZU:
298 case PPC_LFSU:
299 case PPC_LFDU:
300 // Add the tied output operand.
301 MCOperand_CreateReg0(Inst, GP0Regs[Base]);
302 break;
303 case PPC_STBU:
304 case PPC_STHU:
305 case PPC_STWU:
306 case PPC_STFSU:
307 case PPC_STFDU:
308 MCInst_insert0(Inst, 0, MCOperand_CreateReg1(Inst, GP0Regs[Base]));
309 break;
310 }
311
312 MCOperand_CreateImm0(Inst, SignExtend64(Disp, 16));
313 MCOperand_CreateReg0(Inst, GP0Regs[Base]);
314 return MCDisassembler_Success;
315 }
316
decodeMemRIXOperands(MCInst * Inst,uint64_t Imm,int64_t Address,const void * Decoder)317 static DecodeStatus decodeMemRIXOperands(MCInst *Inst, uint64_t Imm,
318 int64_t Address, const void *Decoder)
319 {
320 // Decode the memrix field (imm, reg), which has the low 14-bits as the
321 // displacement and the next 5 bits as the register #.
322
323 uint64_t Base = Imm >> 14;
324 uint64_t Disp = Imm & 0x3FFF;
325
326 // assert(Base < 32 && "Invalid base register");
327
328 if (MCInst_getOpcode(Inst) == PPC_LDU)
329 // Add the tied output operand.
330 MCOperand_CreateReg0(Inst, GP0Regs[Base]);
331 else if (MCInst_getOpcode(Inst) == PPC_STDU)
332 MCInst_insert0(Inst, 0, MCOperand_CreateReg1(Inst, GP0Regs[Base]));
333
334 MCOperand_CreateImm0(Inst, SignExtend64(Disp << 2, 16));
335 MCOperand_CreateReg0(Inst, GP0Regs[Base]);
336 return MCDisassembler_Success;
337 }
338
decodeCRBitMOperand(MCInst * Inst,uint64_t Imm,int64_t Address,const void * Decoder)339 static DecodeStatus decodeCRBitMOperand(MCInst *Inst, uint64_t Imm,
340 int64_t Address, const void *Decoder)
341 {
342 // The cr bit encoding is 0x80 >> cr_reg_num.
343
344 unsigned Zeros = CountTrailingZeros_64(Imm);
345 // assert(Zeros < 8 && "Invalid CR bit value");
346 if (Zeros >=8)
347 return MCDisassembler_Fail;
348
349 MCOperand_CreateReg0(Inst, CRRegs[7 - Zeros]);
350 return MCDisassembler_Success;
351 }
352
353 #include "PPCGenDisassemblerTables.inc"
354
getInstruction(MCInst * MI,const uint8_t * code,size_t code_len,uint16_t * Size,uint64_t Address,MCRegisterInfo * MRI)355 static DecodeStatus getInstruction(MCInst *MI,
356 const uint8_t *code, size_t code_len,
357 uint16_t *Size,
358 uint64_t Address, MCRegisterInfo *MRI)
359 {
360 uint32_t insn;
361 DecodeStatus result;
362 // Get the four bytes of the instruction.
363 if (code_len < 4) {
364 // not enough data
365 *Size = 0;
366 return MCDisassembler_Fail;
367 }
368
369 // The instruction is big-endian encoded.
370 if (MODE_IS_BIG_ENDIAN(MI->csh->mode))
371 insn = ((uint32_t) code[0] << 24) | (code[1] << 16) |
372 (code[2] << 8) | (code[3] << 0);
373 else
374 insn = ((uint32_t) code[3] << 24) | (code[2] << 16) |
375 (code[1] << 8) | (code[0] << 0);
376
377 if (MI->flat_insn->detail) {
378 memset(MI->flat_insn->detail, 0, offsetof(cs_detail, ppc)+sizeof(cs_ppc));
379 }
380
381 if (MI->csh->mode & CS_MODE_QPX) {
382 result = decodeInstruction_4(DecoderTableQPX32, MI, insn, Address, 4);
383 if (result != MCDisassembler_Fail) {
384 *Size = 4;
385 return result;
386 }
387
388 MCInst_clear(MI);
389 }
390
391 result = decodeInstruction_4(DecoderTable32, MI, insn, Address, 4);
392 if (result != MCDisassembler_Fail) {
393 *Size = 4;
394 return result;
395 }
396
397 // report error
398 MCInst_clear(MI);
399 *Size = 0;
400 return MCDisassembler_Fail;
401 }
402
PPC_getInstruction(csh ud,const uint8_t * code,size_t code_len,MCInst * instr,uint16_t * size,uint64_t address,void * info)403 bool PPC_getInstruction(csh ud, const uint8_t *code, size_t code_len,
404 MCInst *instr, uint16_t *size, uint64_t address, void *info)
405 {
406 DecodeStatus status = getInstruction(instr,
407 code, code_len,
408 size,
409 address, (MCRegisterInfo *)info);
410
411 return status == MCDisassembler_Success;
412 }
413
414 #define GET_REGINFO_MC_DESC
415 #include "PPCGenRegisterInfo.inc"
PPC_init(MCRegisterInfo * MRI)416 void PPC_init(MCRegisterInfo *MRI)
417 {
418 /*
419 InitMCRegisterInfo(PPCRegDesc, 310, RA, PC,
420 PPCMCRegisterClasses, 23,
421 PPCRegUnitRoots,
422 138,
423 PPCRegDiffLists,
424 PPCLaneMaskLists,
425 PPCRegStrings,
426 PPCRegClassStrings,
427 PPCSubRegIdxLists,
428 8,
429 PPCSubRegIdxRanges,
430 PPCRegEncodingTable);
431 */
432
433
434 MCRegisterInfo_InitMCRegisterInfo(MRI, PPCRegDesc, 310,
435 0, 0,
436 PPCMCRegisterClasses, 23,
437 0, 0,
438 PPCRegDiffLists,
439 0,
440 PPCSubRegIdxLists, 8,
441 0);
442 }
443
444 #endif
445