Home | History | Annotate | Download | only in PowerPC
      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 (at) 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 
    147 static uint64_t getFeatureBits(int feature)
    148 {
    149 	// enable all features
    150 	return (uint64_t)-1;
    151 }
    152 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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"
    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