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