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