ppc: sync with llvm 7.0.1

This commit is contained in:
Nguyen Anh Quynh 2019-04-30 13:50:42 +08:00
parent 8216e8fab8
commit 11206deb78
21 changed files with 30463 additions and 16142 deletions

View File

@ -226,25 +226,17 @@ if (CAPSTONE_PPC_SUPPORT)
set(HEADERS_PPC
arch/PowerPC/PPCDisassembler.h
arch/PowerPC/PPCGenAsmWriter.inc
arch/PowerPC/PPCGenDisassemblerTables.inc
arch/PowerPC/PPCGenInstrInfo.inc
arch/PowerPC/PPCGenRegisterInfo.inc
arch/PowerPC/PPCGenSubtargetInfo.inc
arch/PowerPC/PPCInstPrinter.h
arch/PowerPC/PPCMapping.h
arch/PowerPC/PPCMappingInsn.inc
arch/PowerPC/PPCPredicates.h
)
set(HEADERS_PPC
arch/PowerPC/PPCDisassembler.h
arch/PowerPC/PPCGenAsmWriter.inc
arch/PowerPC/PPCGenRegisterName.inc
arch/PowerPC/PPCGenDisassemblerTables.inc
arch/PowerPC/PPCGenInstrInfo.inc
arch/PowerPC/PPCGenRegisterInfo.inc
arch/PowerPC/PPCMappingInsn.inc
arch/PowerPC/PPCMappingInsnName.inc
arch/PowerPC/PPCGenSubtargetInfo.inc
arch/PowerPC/PPCInstPrinter.h
arch/PowerPC/PPCMapping.h
arch/PowerPC/PPCPredicates.h
arch/PowerPC/PPCGenRegisterInfo.inc
arch/PowerPC/PPCGenInstrInfo.inc
)
set(TEST_SOURCES ${TEST_SOURCES} test_ppc.c)
endif ()

View File

@ -107,6 +107,14 @@ void printInt64(SStream *O, int64_t val)
}
}
void printUInt64(SStream *O, uint64_t val)
{
if (val > HEX_THRESHOLD)
SStream_concat(O, "0x%"PRIx64, val);
else
SStream_concat(O, "%"PRIu64, val);
}
// print number in decimal mode
void printInt32BangDec(SStream *O, int32_t val)
{

View File

@ -24,6 +24,7 @@ void printInt64Bang(SStream *O, int64_t val);
void printUInt64Bang(SStream *O, uint64_t val);
void printInt64(SStream *O, int64_t val);
void printUInt64(SStream *O, uint64_t val);
void printInt32Bang(SStream *O, int32_t val);

View File

@ -62,6 +62,17 @@ static const unsigned FRegs[] = {
PPC_F28, PPC_F29, PPC_F30, PPC_F31
};
static const unsigned VFRegs[] = {
PPC_VF0, PPC_VF1, PPC_VF2, PPC_VF3,
PPC_VF4, PPC_VF5, PPC_VF6, PPC_VF7,
PPC_VF8, PPC_VF9, PPC_VF10, PPC_VF11,
PPC_VF12, PPC_VF13, PPC_VF14, PPC_VF15,
PPC_VF16, PPC_VF17, PPC_VF18, PPC_VF19,
PPC_VF20, PPC_VF21, PPC_VF22, PPC_VF23,
PPC_VF24, PPC_VF25, PPC_VF26, PPC_VF27,
PPC_VF28, PPC_VF29, PPC_VF30, PPC_VF31
};
static const unsigned VRegs[] = {
PPC_V0, PPC_V1, PPC_V2, PPC_V3,
PPC_V4, PPC_V5, PPC_V6, PPC_V7,
@ -83,14 +94,14 @@ static const unsigned VSRegs[] = {
PPC_VSL24, PPC_VSL25, PPC_VSL26, PPC_VSL27,
PPC_VSL28, PPC_VSL29, PPC_VSL30, PPC_VSL31,
PPC_VSH0, PPC_VSH1, PPC_VSH2, PPC_VSH3,
PPC_VSH4, PPC_VSH5, PPC_VSH6, PPC_VSH7,
PPC_VSH8, PPC_VSH9, PPC_VSH10, PPC_VSH11,
PPC_VSH12, PPC_VSH13, PPC_VSH14, PPC_VSH15,
PPC_VSH16, PPC_VSH17, PPC_VSH18, PPC_VSH19,
PPC_VSH20, PPC_VSH21, PPC_VSH22, PPC_VSH23,
PPC_VSH24, PPC_VSH25, PPC_VSH26, PPC_VSH27,
PPC_VSH28, PPC_VSH29, PPC_VSH30, PPC_VSH31
PPC_V0, PPC_V1, PPC_V2, PPC_V3,
PPC_V4, PPC_V5, PPC_V6, PPC_V7,
PPC_V8, PPC_V9, PPC_V10, PPC_V11,
PPC_V12, PPC_V13, PPC_V14, PPC_V15,
PPC_V16, PPC_V17, PPC_V18, PPC_V19,
PPC_V20, PPC_V21, PPC_V22, PPC_V23,
PPC_V24, PPC_V25, PPC_V26, PPC_V27,
PPC_V28, PPC_V29, PPC_V30, PPC_V31
};
static const unsigned VSFRegs[] = {
@ -113,6 +124,26 @@ static const unsigned VSFRegs[] = {
PPC_VF28, PPC_VF29, PPC_VF30, PPC_VF31
};
static const unsigned VSSRegs[] = {
PPC_F0, PPC_F1, PPC_F2, PPC_F3,
PPC_F4, PPC_F5, PPC_F6, PPC_F7,
PPC_F8, PPC_F9, PPC_F10, PPC_F11,
PPC_F12, PPC_F13, PPC_F14, PPC_F15,
PPC_F16, PPC_F17, PPC_F18, PPC_F19,
PPC_F20, PPC_F21, PPC_F22, PPC_F23,
PPC_F24, PPC_F25, PPC_F26, PPC_F27,
PPC_F28, PPC_F29, PPC_F30, PPC_F31,
PPC_VF0, PPC_VF1, PPC_VF2, PPC_VF3,
PPC_VF4, PPC_VF5, PPC_VF6, PPC_VF7,
PPC_VF8, PPC_VF9, PPC_VF10, PPC_VF11,
PPC_VF12, PPC_VF13, PPC_VF14, PPC_VF15,
PPC_VF16, PPC_VF17, PPC_VF18, PPC_VF19,
PPC_VF20, PPC_VF21, PPC_VF22, PPC_VF23,
PPC_VF24, PPC_VF25, PPC_VF26, PPC_VF27,
PPC_VF28, PPC_VF29, PPC_VF30, PPC_VF31
};
static const unsigned GPRegs[] = {
PPC_R0, PPC_R1, PPC_R2, PPC_R3,
PPC_R4, PPC_R5, PPC_R6, PPC_R7,
@ -146,6 +177,17 @@ static const unsigned G8Regs[] = {
PPC_X28, PPC_X29, PPC_X30, PPC_X31
};
static const unsigned G80Regs[] = {
PPC_ZERO8, PPC_X1, PPC_X2, PPC_X3,
PPC_X4, PPC_X5, PPC_X6, PPC_X7,
PPC_X8, PPC_X9, PPC_X10, PPC_X11,
PPC_X12, PPC_X13, PPC_X14, PPC_X15,
PPC_X16, PPC_X17, PPC_X18, PPC_X19,
PPC_X20, PPC_X21, PPC_X22, PPC_X23,
PPC_X24, PPC_X25, PPC_X26, PPC_X27,
PPC_X28, PPC_X29, PPC_X30, PPC_X31
};
static const unsigned QFRegs[] = {
PPC_QF0, PPC_QF1, PPC_QF2, PPC_QF3,
PPC_QF4, PPC_QF5, PPC_QF6, PPC_QF7,
@ -157,11 +199,24 @@ static const unsigned QFRegs[] = {
PPC_QF28, PPC_QF29, PPC_QF30, PPC_QF31
};
static const unsigned SPERegs[] = {
PPC_S0, PPC_S1, PPC_S2, PPC_S3,
PPC_S4, PPC_S5, PPC_S6, PPC_S7,
PPC_S8, PPC_S9, PPC_S10, PPC_S11,
PPC_S12, PPC_S13, PPC_S14, PPC_S15,
PPC_S16, PPC_S17, PPC_S18, PPC_S19,
PPC_S20, PPC_S21, PPC_S22, PPC_S23,
PPC_S24, PPC_S25, PPC_S26, PPC_S27,
PPC_S28, PPC_S29, PPC_S30, PPC_S31
};
#if 0
static uint64_t getFeatureBits(int feature)
{
// enable all features
return (uint64_t)-1;
}
#endif
static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo,
const unsigned *Regs)
@ -172,85 +227,110 @@ static DecodeStatus decodeRegisterClass(MCInst *Inst, uint64_t RegNo,
}
static DecodeStatus DecodeCRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, CRRegs);
}
static DecodeStatus DecodeCRRC0RegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, CRRegs);
}
static DecodeStatus DecodeCRBITRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, CRBITRegs);
}
static DecodeStatus DecodeF4RCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, FRegs);
}
static DecodeStatus DecodeF8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, FRegs);
}
static DecodeStatus DecodeVFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, VFRegs);
}
static DecodeStatus DecodeVRRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, VRegs);
}
static DecodeStatus DecodeVSRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, VSRegs);
}
static DecodeStatus DecodeVSFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, VSFRegs);
}
static DecodeStatus DecodeVSSRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, VSSRegs);
}
static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, GPRegs);
}
static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, GP0Regs);
}
static DecodeStatus DecodeG8RCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, G8Regs);
}
static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, G80Regs);
}
#define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
#define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
static DecodeStatus DecodeQFRCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address,
const void *Decoder)
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, QFRegs);
}
static DecodeStatus DecodeSPE4RCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, GPRegs);
}
static DecodeStatus DecodeSPERCRegisterClass(MCInst *Inst, uint64_t RegNo,
uint64_t Address, const void *Decoder)
{
return decodeRegisterClass(Inst, RegNo, SPERegs);
}
#define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
#define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
@ -259,6 +339,7 @@ static DecodeStatus decodeUImmOperand(MCInst *Inst, uint64_t Imm,
{
//assert(isUInt<N>(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, Imm);
return MCDisassembler_Success;
}
@ -267,6 +348,7 @@ static DecodeStatus decodeSImmOperand(MCInst *Inst, uint64_t Imm,
{
// assert(isUInt<N>(Imm) && "Invalid immediate");
MCOperand_CreateImm0(Inst, SignExtend64(Imm, N));
return MCDisassembler_Success;
}
@ -309,6 +391,7 @@ static DecodeStatus decodeMemRIOperands(MCInst *Inst, uint64_t Imm,
MCOperand_CreateImm0(Inst, SignExtend64(Disp, 16));
MCOperand_CreateReg0(Inst, GP0Regs[Base]);
return MCDisassembler_Success;
}
@ -322,6 +405,8 @@ static DecodeStatus decodeMemRIXOperands(MCInst *Inst, uint64_t Imm,
uint64_t Disp = Imm & 0x3FFF;
// assert(Base < 32 && "Invalid base register");
if (Base >= 32)
return MCDisassembler_Fail;
if (MCInst_getOpcode(Inst) == PPC_LDU)
// Add the tied output operand.
@ -331,6 +416,83 @@ static DecodeStatus decodeMemRIXOperands(MCInst *Inst, uint64_t Imm,
MCOperand_CreateImm0(Inst, SignExtend64(Disp << 2, 16));
MCOperand_CreateReg0(Inst, GP0Regs[Base]);
return MCDisassembler_Success;
}
static DecodeStatus decodeMemRIX16Operands(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
// Decode the memrix16 field (imm, reg), which has the low 12-bits as the
// displacement with 16-byte aligned, and the next 5 bits as the register #.
uint64_t Base = Imm >> 12;
uint64_t Disp = Imm & 0xFFF;
// assert(Base < 32 && "Invalid base register");
if (Base >= 32)
return MCDisassembler_Fail;
MCOperand_CreateImm0(Inst, SignExtend64(Disp << 4, 16));
MCOperand_CreateReg0(Inst, GP0Regs[Base]);
return MCDisassembler_Success;
}
static DecodeStatus decodeSPE8Operands(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
// Decode the spe8disp field (imm, reg), which has the low 5-bits as the
// displacement with 8-byte aligned, and the next 5 bits as the register #.
uint64_t Base = Imm >> 5;
uint64_t Disp = Imm & 0x1F;
// assert(Base < 32 && "Invalid base register");
if (Base >= 32)
return MCDisassembler_Fail;
MCOperand_CreateImm0(Inst, Disp << 3);
MCOperand_CreateReg0(Inst, GP0Regs[Base]);
return MCDisassembler_Success;
}
static DecodeStatus decodeSPE4Operands(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
// Decode the spe4disp field (imm, reg), which has the low 5-bits as the
// displacement with 4-byte aligned, and the next 5 bits as the register #.
uint64_t Base = Imm >> 5;
uint64_t Disp = Imm & 0x1F;
// assert(Base < 32 && "Invalid base register");
if (Base >= 32)
return MCDisassembler_Fail;
MCOperand_CreateImm0(Inst, Disp << 2);
MCOperand_CreateReg0(Inst, GP0Regs[Base]);
return MCDisassembler_Success;
}
static DecodeStatus decodeSPE2Operands(MCInst *Inst, uint64_t Imm,
int64_t Address, const void *Decoder)
{
// Decode the spe2disp field (imm, reg), which has the low 5-bits as the
// displacement with 2-byte aligned, and the next 5 bits as the register #.
uint64_t Base = Imm >> 5;
uint64_t Disp = Imm & 0x1F;
// assert(Base < 32 && "Invalid base register");
if (Base >= 32)
return MCDisassembler_Fail;
MCOperand_CreateImm0(Inst, Disp << 1);
MCOperand_CreateReg0(Inst, GP0Regs[Base]);
return MCDisassembler_Success;
}
@ -341,10 +503,11 @@ static DecodeStatus decodeCRBitMOperand(MCInst *Inst, uint64_t Imm,
unsigned Zeros = CountTrailingZeros_64(Imm);
// assert(Zeros < 8 && "Invalid CR bit value");
if (Zeros >=8)
if (Zeros >= 8)
return MCDisassembler_Fail;
MCOperand_CreateReg0(Inst, CRRegs[7 - Zeros]);
return MCDisassembler_Success;
}
@ -357,6 +520,7 @@ static DecodeStatus getInstruction(MCInst *MI,
{
uint32_t insn;
DecodeStatus result;
// Get the four bytes of the instruction.
if (code_len < 4) {
// not enough data
@ -368,33 +532,47 @@ static DecodeStatus getInstruction(MCInst *MI,
if (MODE_IS_BIG_ENDIAN(MI->csh->mode))
insn = ((uint32_t) code[0] << 24) | (code[1] << 16) |
(code[2] << 8) | (code[3] << 0);
else
else // little endian
insn = ((uint32_t) code[3] << 24) | (code[2] << 16) |
(code[1] << 8) | (code[0] << 0);
if (MI->flat_insn->detail) {
memset(MI->flat_insn->detail, 0, offsetof(cs_detail, ppc)+sizeof(cs_ppc));
memset(MI->flat_insn->detail, 0, offsetof(cs_detail, ppc) + sizeof(cs_ppc));
}
if (MI->csh->mode & CS_MODE_QPX) {
result = decodeInstruction_4(DecoderTableQPX32, MI, insn, Address, 4);
result = decodeInstruction_4(DecoderTableQPX32, MI, insn, Address);
if (result != MCDisassembler_Fail) {
*Size = 4;
return result;
}
// failed to decode
MCInst_clear(MI);
} else if (MI->csh->mode & CS_MODE_SPE) {
result = decodeInstruction_4(DecoderTableSPE32, MI, insn, Address);
if (result != MCDisassembler_Fail) {
*Size = 4;
return result;
}
// failed to decode
MCInst_clear(MI);
}
result = decodeInstruction_4(DecoderTable32, MI, insn, Address, 4);
result = decodeInstruction_4(DecoderTable32, MI, insn, Address);
if (result != MCDisassembler_Fail) {
*Size = 4;
return result;
}
// report error
// cannot decode, report error
MCInst_clear(MI);
*Size = 0;
return MCDisassembler_Fail;
}
@ -414,28 +592,21 @@ bool PPC_getInstruction(csh ud, const uint8_t *code, size_t code_len,
void PPC_init(MCRegisterInfo *MRI)
{
/*
InitMCRegisterInfo(PPCRegDesc, 310, RA, PC,
PPCMCRegisterClasses, 23,
PPCRegUnitRoots,
138,
PPCRegDiffLists,
PPCLaneMaskLists,
PPCRegStrings,
PPCRegClassStrings,
PPCSubRegIdxLists,
8,
PPCSubRegIdxRanges,
PPCRegEncodingTable);
InitMCRegisterInfo(PPCRegDesc, 344,
RA, PC,
PPCMCRegisterClasses, 36,
PPCRegUnitRoots, 171, PPCRegDiffLists, PPCLaneMaskLists, PPCRegStrings, PPCRegClassStrings,
PPCSubRegIdxLists, 7,
PPCSubRegIdxRanges, PPCRegEncodingTable);
*/
MCRegisterInfo_InitMCRegisterInfo(MRI, PPCRegDesc, 310,
MCRegisterInfo_InitMCRegisterInfo(MRI, PPCRegDesc, 344,
0, 0,
PPCMCRegisterClasses, 23,
PPCMCRegisterClasses, 36,
0, 0,
PPCRegDiffLists,
0,
PPCSubRegIdxLists, 8,
PPCSubRegIdxLists, 7,
0);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,73 +1,89 @@
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
|* *|
|*Subtarget Enumeration Source Fragment *|
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
/*===- TableGen'erated file -------------------------------------*- C++ -*-===*|* *|
|* Subtarget Enumeration Source Fragment *|
|* *|
|* Automatically generated file, do not edit! *|
|* *|
\*===----------------------------------------------------------------------===*/
/* Capstone Disassembly Engine, http://www.capstone-engine.org */
/* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
enum {
PPC_DeprecatedDST = 0,
PPC_Directive32 = 1,
PPC_Directive64 = 2,
PPC_Directive440 = 3,
PPC_Directive601 = 4,
PPC_Directive602 = 5,
PPC_Directive603 = 6,
PPC_Directive604 = 7,
PPC_Directive620 = 8,
PPC_Directive750 = 9,
PPC_Directive970 = 10,
PPC_Directive7400 = 11,
PPC_DirectiveA2 = 12,
PPC_DirectiveE500 = 13,
PPC_DirectiveE500mc = 14,
PPC_DirectiveE5500 = 15,
PPC_DirectivePwr3 = 16,
PPC_DirectivePwr4 = 17,
PPC_DirectivePwr5 = 18,
PPC_DirectivePwr5x = 19,
PPC_DirectivePwr6 = 20,
PPC_DirectivePwr6x = 21,
PPC_DirectivePwr7 = 22,
PPC_DirectivePwr8 = 23,
PPC_DirectivePwr9 = 24,
PPC_Feature64Bit = 25,
PPC_Feature64BitRegs = 26,
PPC_FeatureAltivec = 27,
PPC_FeatureBPERMD = 28,
PPC_FeatureBookE = 29,
PPC_FeatureCMPB = 30,
PPC_FeatureCRBits = 31,
PPC_FeatureDirectMove = 32,
PPC_FeatureE500 = 33,
PPC_FeatureExtDiv = 34,
PPC_FeatureFCPSGN = 35,
PPC_FeatureFPCVT = 36,
PPC_FeatureFPRND = 37,
PPC_FeatureFPU = 38,
PPC_FeatureFRE = 39,
PPC_FeatureFRES = 40,
PPC_FeatureFRSQRTE = 41,
PPC_FeatureFRSQRTES = 42,
PPC_FeatureFSqrt = 43,
PPC_FeatureFloat128 = 44,
PPC_FeatureFusion = 45,
PPC_FeatureHTM = 46,
PPC_FeatureHardFloat = 47,
PPC_FeatureICBT = 48,
PPC_FeatureISA3_0 = 49,
PPC_FeatureISEL = 50,
PPC_FeatureInvariantFunctionDescriptors = 51,
PPC_FeatureLDBRX = 52,
PPC_FeatureLFIWAX = 53,
PPC_FeatureLongCall = 54,
PPC_FeatureMFOCRF = 55,
PPC_FeatureMFTB = 56,
PPC_FeatureMSYNC = 57,
PPC_FeatureP8Altivec = 58,
PPC_FeatureP8Crypto = 59,
PPC_FeatureP8Vector = 60,
PPC_FeatureP9Altivec = 61,
PPC_FeatureP9Vector = 62,
PPC_FeaturePOPCNTD = 63,
PPC_FeaturePPC4xx = 64,
PPC_FeaturePPC6xx = 65,
PPC_FeaturePartwordAtomic = 66,
PPC_FeatureQPX = 67,
PPC_FeatureRecipPrec = 68,
PPC_FeatureSPE = 69,
PPC_FeatureSTFIWX = 70,
PPC_FeatureSecurePlt = 71,
PPC_FeatureSlowPOPCNTD = 72,
PPC_FeatureVSX = 73,
};
#ifdef GET_SUBTARGETINFO_ENUM
#undef GET_SUBTARGETINFO_ENUM
#define PPC_DeprecatedDST (1ULL << 0)
#define PPC_DeprecatedMFTB (1ULL << 1)
#define PPC_Directive32 (1ULL << 2)
#define PPC_Directive64 (1ULL << 3)
#define PPC_Directive440 (1ULL << 4)
#define PPC_Directive601 (1ULL << 5)
#define PPC_Directive602 (1ULL << 6)
#define PPC_Directive603 (1ULL << 7)
#define PPC_Directive604 (1ULL << 8)
#define PPC_Directive620 (1ULL << 9)
#define PPC_Directive750 (1ULL << 10)
#define PPC_Directive970 (1ULL << 11)
#define PPC_Directive7400 (1ULL << 12)
#define PPC_DirectiveA2 (1ULL << 13)
#define PPC_DirectiveE500mc (1ULL << 14)
#define PPC_DirectiveE5500 (1ULL << 15)
#define PPC_DirectivePwr3 (1ULL << 16)
#define PPC_DirectivePwr4 (1ULL << 17)
#define PPC_DirectivePwr5 (1ULL << 18)
#define PPC_DirectivePwr5x (1ULL << 19)
#define PPC_DirectivePwr6 (1ULL << 20)
#define PPC_DirectivePwr6x (1ULL << 21)
#define PPC_DirectivePwr7 (1ULL << 22)
#define PPC_DirectivePwr8 (1ULL << 23)
#define PPC_Feature64Bit (1ULL << 24)
#define PPC_Feature64BitRegs (1ULL << 25)
#define PPC_FeatureAltivec (1ULL << 26)
#define PPC_FeatureBookE (1ULL << 27)
#define PPC_FeatureCMPB (1ULL << 28)
#define PPC_FeatureCRBits (1ULL << 29)
#define PPC_FeatureE500 (1ULL << 30)
#define PPC_FeatureFCPSGN (1ULL << 31)
#define PPC_FeatureFPCVT (1ULL << 32)
#define PPC_FeatureFPRND (1ULL << 33)
#define PPC_FeatureFRE (1ULL << 34)
#define PPC_FeatureFRES (1ULL << 35)
#define PPC_FeatureFRSQRTE (1ULL << 36)
#define PPC_FeatureFRSQRTES (1ULL << 37)
#define PPC_FeatureFSqrt (1ULL << 38)
#define PPC_FeatureICBT (1ULL << 39)
#define PPC_FeatureISEL (1ULL << 40)
#define PPC_FeatureInvariantFunctionDescriptors (1ULL << 41)
#define PPC_FeatureLDBRX (1ULL << 42)
#define PPC_FeatureLFIWAX (1ULL << 43)
#define PPC_FeatureMFOCRF (1ULL << 44)
#define PPC_FeatureMSYNC (1ULL << 45)
#define PPC_FeatureP8Altivec (1ULL << 46)
#define PPC_FeatureP8Vector (1ULL << 47)
#define PPC_FeaturePOPCNTD (1ULL << 48)
#define PPC_FeaturePPC4xx (1ULL << 49)
#define PPC_FeaturePPC6xx (1ULL << 50)
#define PPC_FeatureQPX (1ULL << 51)
#define PPC_FeatureRecipPrec (1ULL << 52)
#define PPC_FeatureSPE (1ULL << 53)
#define PPC_FeatureSTFIWX (1ULL << 54)
#define PPC_FeatureVSX (1ULL << 55)
#endif // GET_SUBTARGETINFO_ENUM

View File

@ -34,10 +34,9 @@ static const char *getRegisterName(unsigned RegNo);
#endif
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
static void printInstruction(MCInst *MI, SStream *O, const MCRegisterInfo *MRI);
static void printInstruction(MCInst *MI, SStream *O);
static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O);
static char *printAliasInstr(MCInst *MI, SStream *OS, void *info);
static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info);
static char *printAliasInstr(MCInst *MI, SStream *OS, MCRegisterInfo *MRI);
static void printCustomAliasOperand(MCInst *MI, unsigned OpIdx,
unsigned PrintMethodIdx, SStream *OS);
@ -90,39 +89,38 @@ void PPC_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
#define GET_INSTRINFO_ENUM
#include "PPCGenInstrInfo.inc"
static int isBOCTRBranch(unsigned int op)
{
return ((op >= PPC_BDNZ) && (op <= PPC_BDZp));
}
void PPC_printInst(MCInst *MI, SStream *O, void *Info)
{
char *mnem;
unsigned int opcode = MCInst_getOpcode(MI);
// printf("opcode = %u\n", opcode);
// Check for slwi/srwi mnemonics.
if (MCInst_getOpcode(MI) == PPC_RLWINM) {
if (opcode == PPC_RLWINM) {
unsigned char SH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 2));
unsigned char MB = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 3));
unsigned char ME = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 4));
bool useSubstituteMnemonic = false;
if (SH <= 31 && MB == 0 && ME == (31-SH)) {
if (SH <= 31 && MB == 0 && ME == (31 - SH)) {
SStream_concat0(O, "slwi\t");
MCInst_setOpcodePub(MI, PPC_INS_SLWI);
useSubstituteMnemonic = true;
}
if (SH <= 31 && MB == (32-SH) && ME == 31) {
if (SH <= 31 && MB == (32 - SH) && ME == 31) {
SStream_concat0(O, "srwi\t");
MCInst_setOpcodePub(MI, PPC_INS_SRWI);
useSubstituteMnemonic = true;
SH = 32-SH;
SH = 32 - SH;
}
if (useSubstituteMnemonic) {
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
if (SH > HEX_THRESHOLD)
SStream_concat(O, ", 0x%x", (unsigned int)SH);
else
@ -140,63 +138,141 @@ void PPC_printInst(MCInst *MI, SStream *O, void *Info)
}
}
if ((MCInst_getOpcode(MI) == PPC_OR || MCInst_getOpcode(MI) == PPC_OR8) &&
if ((opcode == PPC_OR || opcode == PPC_OR8) &&
MCOperand_getReg(MCInst_getOperand(MI, 1)) == MCOperand_getReg(MCInst_getOperand(MI, 2))) {
SStream_concat0(O, "mr\t");
MCInst_setOpcodePub(MI, PPC_INS_MR);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
return;
}
if (MCInst_getOpcode(MI) == PPC_RLDICR) {
if (opcode == PPC_RLDICR ||
opcode == PPC_RLDICR_32) {
unsigned char SH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 2));
unsigned char ME = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 3));
// rldicr RA, RS, SH, 63-SH == sldi RA, RS, SH
if (63-SH == ME) {
if (63 - SH == ME) {
SStream_concat0(O, "sldi\t");
MCInst_setOpcodePub(MI, PPC_INS_SLDI);
printOperand(MI, 0, O);
SStream_concat0(O, ", ");
printOperand(MI, 1, O);
if (SH > HEX_THRESHOLD)
SStream_concat(O, ", 0x%x", (unsigned int)SH);
else
SStream_concat(O, ", %u", (unsigned int)SH);
if (MI->csh->detail) {
cs_ppc *ppc = &MI->flat_insn->detail->ppc;
ppc->operands[ppc->op_count].type = PPC_OP_IMM;
ppc->operands[ppc->op_count].imm = SH;
++ppc->op_count;
}
return;
}
}
if ((MCInst_getOpcode(MI) == PPC_gBC)||(MCInst_getOpcode(MI) == PPC_gBCA)||
(MCInst_getOpcode(MI) == PPC_gBCL)||(MCInst_getOpcode(MI) == PPC_gBCLA)) {
int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 2));
bd = SignExtend64(bd, 14);
MCOperand_setImm(MCInst_getOperand(MI, 2),bd);
// dcbt[st] is printed manually here because:
// 1. The assembly syntax is different between embedded and server targets
// 2. We must print the short mnemonics for TH == 0 because the
// embedded/server syntax default will not be stable across assemblers
// The syntax for dcbt is:
// dcbt ra, rb, th [server]
// dcbt th, ra, rb [embedded]
// where th can be omitted when it is 0. dcbtst is the same.
if (opcode == PPC_DCBT || opcode == PPC_DCBTST) {
unsigned char TH = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 0));
SStream_concat0(O, "dcbt");
MCInst_setOpcodePub(MI, PPC_INS_DCBT);
if (opcode == PPC_DCBTST) {
SStream_concat0(O, "st");
MCInst_setOpcodePub(MI, PPC_INS_DCBTST);
}
if (TH == 16) {
SStream_concat0(O, "t");
MCInst_setOpcodePub(MI, PPC_INS_DCBTSTT);
}
SStream_concat0(O, "\t");
if (MI->csh->mode & CS_MODE_BOOKE && TH != 0 && TH != 16) {
if (TH > HEX_THRESHOLD)
SStream_concat(O, "0x%x, ", (unsigned int)TH);
else
SStream_concat(O, "%u, ", (unsigned int)TH);
if (MI->csh->detail) {
cs_ppc *ppc = &MI->flat_insn->detail->ppc;
ppc->operands[ppc->op_count].type = PPC_OP_IMM;
ppc->operands[ppc->op_count].imm = TH;
++ppc->op_count;
}
}
printOperand(MI, 1, O);
SStream_concat0(O, ", ");
printOperand(MI, 2, O);
if (!(MI->csh->mode & CS_MODE_BOOKE) && TH != 0 && TH != 16) {
if (TH > HEX_THRESHOLD)
SStream_concat(O, ", 0x%x", (unsigned int)TH);
else
SStream_concat(O, ", %u", (unsigned int)TH);
if (MI->csh->detail) {
cs_ppc *ppc = &MI->flat_insn->detail->ppc;
ppc->operands[ppc->op_count].type = PPC_OP_IMM;
ppc->operands[ppc->op_count].imm = TH;
++ppc->op_count;
}
}
return;
}
if (isBOCTRBranch(MCInst_getOpcode(MI))) {
if (MCOperand_isImm(MCInst_getOperand(MI,0)))
{
int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));
bd = SignExtend64(bd, 14);
MCOperand_setImm(MCInst_getOperand(MI, 0),bd);
if (opcode == PPC_DCBF) {
unsigned char L = (unsigned char)MCOperand_getImm(MCInst_getOperand(MI, 0));
if (!L || L == 1 || L == 3) {
SStream_concat0(O, "dcbf");
MCInst_setOpcodePub(MI, PPC_INS_DCBF);
if (L == 1 || L == 3) {
SStream_concat0(O, "l");
MCInst_setOpcodePub(MI, PPC_INS_DCBFL);
}
if (L == 3) {
SStream_concat0(O, "p");
MCInst_setOpcodePub(MI, PPC_INS_DCBFLP);
}
SStream_concat0(O, "\t");
printOperand(MI, 1, O);
SStream_concat0(O, ", ");
printOperand(MI, 2, O);
return;
}
}
if ((MCInst_getOpcode(MI) == PPC_B)||(MCInst_getOpcode(MI) == PPC_BA)||
(MCInst_getOpcode(MI) == PPC_BL)||(MCInst_getOpcode(MI) == PPC_BLA)) {
int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));
bd = SignExtend64(bd, 24);
MCOperand_setImm(MCInst_getOperand(MI, 0),bd);
}
// consider our own alias instructions first
mnem = printAliasInstrEx(MI, O, Info);
if (!mnem)
mnem = printAliasInstr(MI, O, Info);
mnem = printAliasInstr(MI, O, Info);
if (mnem != NULL) {
if (strlen(mnem) > 0) {
struct ppc_alias alias;
@ -204,19 +280,18 @@ void PPC_printInst(MCInst *MI, SStream *O, void *Info)
if (mnem[strlen(mnem) - 1] == '-' || mnem[strlen(mnem) - 1] == '+' || mnem[strlen(mnem) - 1] == '.')
mnem[strlen(mnem) - 1] = '\0';
if (PPC_alias_insn(mnem, &alias)) {
MCInst_setOpcodePub(MI, alias.id);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.bc = (ppc_bc)alias.cc;
}
}
MCInst_setOpcodePub(MI, PPC_map_insn(mnem));
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.bc = (ppc_bc)alias.cc;
}
}
cs_mem_free(mnem);
} else
printInstruction(MI, O, NULL);
printInstruction(MI, O);
}
// FIXME
enum ppc_bc_hint {
PPC_BC_LT_MINUS = (0 << 5) | 14,
PPC_BC_LE_MINUS = (1 << 5) | 6,
@ -236,6 +311,7 @@ enum ppc_bc_hint {
PPC_BC_NU_PLUS = (3 << 5) | 7,
};
// FIXME
// normalize CC to remove _MINUS & _PLUS
static int cc_normalize(int cc)
{
@ -365,15 +441,52 @@ static void printPredicateOperand(MCInst *MI, unsigned OpNo,
printOperand(MI, OpNo + 1, O);
}
static void printATBitsAsHint(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned Code = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
if (Code == 2) {
SStream_concat0(O, "-");
} else if (Code == 3) {
SStream_concat0(O, "+");
}
}
static void printU1ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
// assert(Value <= 1 && "Invalid u1imm argument!");
printUInt32(O, Value);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
MI->flat_insn->detail->ppc.op_count++;
}
}
static void printU2ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
//assert(Value <= 3 && "Invalid u2imm argument!");
if (Value > HEX_THRESHOLD)
SStream_concat(O, "0x%x", Value);
else
SStream_concat(O, "%u", Value);
printUInt32(O, Value);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
MI->flat_insn->detail->ppc.op_count++;
}
}
static void printU3ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
//assert(Value <= 8 && "Invalid u3imm argument!");
printUInt32(O, Value);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
@ -387,10 +500,7 @@ static void printU4ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
unsigned int Value = (int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
//assert(Value <= 15 && "Invalid u4imm argument!");
if (Value > HEX_THRESHOLD)
SStream_concat(O, "0x%x", Value);
else
SStream_concat(O, "%u", Value);
printUInt32(O, Value);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
@ -416,6 +526,7 @@ static void printS5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
static void printU5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
//assert(Value <= 31 && "Invalid u5imm argument!");
printUInt32(O, Value);
@ -429,6 +540,7 @@ static void printU5ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
static void printU6ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
//assert(Value <= 63 && "Invalid u6imm argument!");
printUInt32(O, Value);
@ -439,16 +551,57 @@ static void printU6ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
}
}
static void printU7ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
//assert(Value <= 127 && "Invalid u7imm argument!");
printUInt32(O, Value);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
MI->flat_insn->detail->ppc.op_count++;
}
}
// Operands of BUILD_VECTOR are signed and we use this to print operands
// of XXSPLTIB which are unsigned. So we simply truncate to 8 bits and
// print as unsigned.
static void printU8ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
printUInt32(O, Value);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
MI->flat_insn->detail->ppc.op_count++;
}
}
static void printU10ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned int Value = (unsigned int)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
//assert(Value <= 1023 && "Invalid u10imm argument!");
printUInt32(O, Value);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Value;
MI->flat_insn->detail->ppc.op_count++;
}
}
static void printU12ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned short Value = (unsigned short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
// assert(Value <= 4095 && "Invalid u12imm argument!");
if (Value > HEX_THRESHOLD)
SStream_concat(O, "0x%x", Value);
else
SStream_concat(O, "%u", Value);
printUInt32(O, Value);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
@ -458,48 +611,19 @@ static void printU12ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
}
static void printS16ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
unsigned short Imm = (unsigned short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
if (Imm > HEX_THRESHOLD)
SStream_concat(O, "0x%x", Imm);
else
SStream_concat(O, "%u", Imm);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;
MI->flat_insn->detail->ppc.op_count++;
}
} else
printOperand(MI, OpNo, O);
}
static void printS16ImmOperand_Mem(MCInst *MI, unsigned OpNo, SStream *O)
{
if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
short Imm = (short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
if (Imm >= 0) {
if (Imm > HEX_THRESHOLD)
SStream_concat(O, "0x%x", Imm);
else
SStream_concat(O, "%u", Imm);
} else {
if (Imm < -HEX_THRESHOLD)
SStream_concat(O, "-0x%x", -Imm);
else
SStream_concat(O, "-%u", -Imm);
}
printInt32(O, Imm);
if (MI->csh->detail) {
if (MI->csh->doing_mem) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = Imm;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.disp = Imm;
} else {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;
MI->flat_insn->detail->ppc.op_count++;
}
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].imm = Imm;
MI->flat_insn->detail->ppc.op_count++;
}
}
} else
printOperand(MI, OpNo, O);
@ -509,10 +633,7 @@ static void printU16ImmOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
if (MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
unsigned short Imm = (unsigned short)MCOperand_getImm(MCInst_getOperand(MI, OpNo));
if (Imm > HEX_THRESHOLD)
SStream_concat(O, "0x%x", Imm);
else
SStream_concat(O, "%u", Imm);
printUInt32(O, Imm);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
@ -527,11 +648,13 @@ static void printBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
if (!MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
printOperand(MI, OpNo, O);
return;
}
// Branches can take an immediate operand. This is used by the branch
// selection pass to print .+8, an eight byte displacement from the PC.
// O << ".+";
printAbsBranchOperand(MI, OpNo, O);
}
@ -541,6 +664,7 @@ static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
if (!MCOperand_isImm(MCInst_getOperand(MI, OpNo))) {
printOperand(MI, OpNo, O);
return;
}
@ -550,7 +674,7 @@ static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
imm = MI->address + imm;
}
SStream_concat(O, "0x%"PRIx64, imm);
printUInt64(O, imm);
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_IMM;
@ -565,7 +689,7 @@ static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
static void printcrbitm(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned RegNo, tmp;
unsigned RegNo;
unsigned CCReg = MCOperand_getReg(MCInst_getOperand(MI, OpNo));
switch (CCReg) {
@ -580,18 +704,14 @@ static void printcrbitm(MCInst *MI, unsigned OpNo, SStream *O)
case PPC_CR7: RegNo = 7; break;
}
tmp = 0x80 >> RegNo;
if (tmp > HEX_THRESHOLD)
SStream_concat(O, "0x%x", tmp);
else
SStream_concat(O, "%u", tmp);
printUInt32(O, 0x80 >> RegNo);
}
static void printMemRegImm(MCInst *MI, unsigned OpNo, SStream *O)
{
set_mem_access(MI, true);
printS16ImmOperand_Mem(MI, OpNo, O);
printS16ImmOperand(MI, OpNo, O);
SStream_concat0(O, "(");
@ -601,6 +721,7 @@ static void printMemRegImm(MCInst *MI, unsigned OpNo, SStream *O)
printOperand(MI, OpNo + 1, O);
SStream_concat0(O, ")");
set_mem_access(MI, false);
}
@ -629,6 +750,7 @@ static void printTLSCall(MCInst *MI, unsigned OpNo, SStream *O)
SStream_concat0(O, "(");
printOperand(MI, OpNo + 1, O);
SStream_concat0(O, ")");
set_mem_access(MI, false);
}
@ -661,10 +783,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
unsigned reg = MCOperand_getReg(Op);
#ifndef CAPSTONE_DIET
const char *RegName = getRegisterName(reg);
#endif
// map to public register
reg = PPC_map_register(reg);
#ifndef CAPSTONE_DIET
// The linux and AIX assembler does not take register prefixes.
if (MI->csh->syntax == CS_OPT_SYNTAX_NOREGNAME)
RegName = stripRegisterPrefix(RegName);
@ -673,6 +792,9 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
#endif
if (MI->csh->detail) {
// map this internal reg ID to public reg ID
reg = PPC_map_register(reg);
if (MI->csh->doing_mem) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].mem.base = reg;
} else {
@ -710,293 +832,8 @@ static void op_addImm(MCInst *MI, int v)
}
}
static void op_addReg(MCInst *MI, unsigned int reg)
{
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_REG;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].reg = reg;
MI->flat_insn->detail->ppc.op_count++;
}
}
static void op_addBC(MCInst *MI, unsigned int bc)
{
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.bc = (ppc_bc)bc;
}
}
#define CREQ (0)
#define CRGT (1)
#define CRLT (2)
#define CRUN (3)
static int getBICRCond(int bi)
{
return (bi-PPC_CR0EQ) >> 3;
}
static int getBICR(int bi)
{
return ((bi - PPC_CR0EQ) & 7) + PPC_CR0;
}
static char *printAliasInstrEx(MCInst *MI, SStream *OS, void *info)
{
#define GETREGCLASS_CONTAIN(_class, _reg) MCRegisterClass_contains(MCRegisterInfo_getRegClass(MRI, _class), MCOperand_getReg(MCInst_getOperand(MI, _reg)))
SStream ss;
const char *opCode;
char *tmp, *AsmMnem, *AsmOps, *c;
int OpIdx, PrintMethodIdx;
int decCtr = false, needComma = false;
MCRegisterInfo *MRI = (MCRegisterInfo *)info;
SStream_Init(&ss);
switch (MCInst_getOpcode(MI)) {
default: return NULL;
case PPC_gBC:
opCode = "b%s";
break;
case PPC_gBCA:
opCode = "b%sa";
break;
case PPC_gBCCTR:
opCode = "b%sctr";
break;
case PPC_gBCCTRL:
opCode = "b%sctrl";
break;
case PPC_gBCL:
opCode = "b%sl";
break;
case PPC_gBCLA:
opCode = "b%sla";
break;
case PPC_gBCLR:
opCode = "b%slr";
break;
case PPC_gBCLRL:
opCode = "b%slrl";
break;
}
if (MCInst_getNumOperands(MI) == 3 &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 0) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 1)) {
SStream_concat(&ss, opCode, "dnzf");
decCtr = true;
}
if (MCInst_getNumOperands(MI) == 3 &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 2) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 3)) {
SStream_concat(&ss, opCode, "dzf");
decCtr = true;
}
if (MCInst_getNumOperands(MI) == 3 &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 4) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 7) &&
MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
int cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
switch(cr) {
case CREQ:
SStream_concat(&ss, opCode, "ne");
break;
case CRGT:
SStream_concat(&ss, opCode, "le");
break;
case CRLT:
SStream_concat(&ss, opCode, "ge");
break;
case CRUN:
SStream_concat(&ss, opCode, "ns");
break;
}
if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 6)
SStream_concat0(&ss, "-");
if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 7)
SStream_concat0(&ss, "+");
decCtr = false;
}
if (MCInst_getNumOperands(MI) == 3 &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 8) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 9)) {
SStream_concat(&ss, opCode, "dnzt");
decCtr = true;
}
if (MCInst_getNumOperands(MI) == 3 &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 10) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 11)) {
SStream_concat(&ss, opCode, "dzt");
decCtr = true;
}
if (MCInst_getNumOperands(MI) == 3 &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) >= 12) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) <= 15) &&
MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1)) {
int cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
switch(cr) {
case CREQ:
SStream_concat(&ss, opCode, "eq");
break;
case CRGT:
SStream_concat(&ss, opCode, "gt");
break;
case CRLT:
SStream_concat(&ss, opCode, "lt");
break;
case CRUN:
SStream_concat(&ss, opCode, "so");
break;
}
if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 14)
SStream_concat0(&ss, "-");
if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 15)
SStream_concat0(&ss, "+");
decCtr = false;
}
if (MCInst_getNumOperands(MI) == 3 &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
((MCOperand_getImm(MCInst_getOperand(MI, 0)) & 0x12)== 16)) {
SStream_concat(&ss, opCode, "dnz");
if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 24)
SStream_concat0(&ss, "-");
if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 25)
SStream_concat0(&ss, "+");
needComma = false;
}
if (MCInst_getNumOperands(MI) == 3 &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
((MCOperand_getImm(MCInst_getOperand(MI, 0)) & 0x12)== 18)) {
SStream_concat(&ss, opCode, "dz");
if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 26)
SStream_concat0(&ss, "-");
if (MCOperand_getImm(MCInst_getOperand(MI, 0)) == 27)
SStream_concat0(&ss, "+");
needComma = false;
}
if (MCOperand_isReg(MCInst_getOperand(MI, 1)) &&
GETREGCLASS_CONTAIN(PPC_CRBITRCRegClassID, 1) &&
MCOperand_isImm(MCInst_getOperand(MI, 0)) &&
(MCOperand_getImm(MCInst_getOperand(MI, 0)) < 16)) {
int cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));
if (decCtr) {
needComma = true;
SStream_concat0(&ss, " ");
if (cr > PPC_CR0) {
SStream_concat(&ss, "4*cr%d+", cr - PPC_CR0);
}
cr = getBICRCond(MCOperand_getReg(MCInst_getOperand(MI, 1)));
switch(cr) {
case CREQ:
SStream_concat0(&ss, "eq");
op_addBC(MI, PPC_BC_EQ);
break;
case CRGT:
SStream_concat0(&ss, "gt");
op_addBC(MI, PPC_BC_GT);
break;
case CRLT:
SStream_concat0(&ss, "lt");
op_addBC(MI, PPC_BC_LT);
break;
case CRUN:
SStream_concat0(&ss, "so");
op_addBC(MI, PPC_BC_SO);
break;
}
cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));
if (cr > PPC_CR0) {
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].type = PPC_OP_CRX;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.scale = 4;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.reg = PPC_REG_CR0 + cr - PPC_CR0;
MI->flat_insn->detail->ppc.operands[MI->flat_insn->detail->ppc.op_count].crx.cond = MI->flat_insn->detail->ppc.bc;
MI->flat_insn->detail->ppc.op_count++;
}
}
} else {
if (cr > PPC_CR0) {
needComma = true;
SStream_concat(&ss, " cr%d", cr - PPC_CR0);
op_addReg(MI, PPC_REG_CR0 + cr - PPC_CR0);
}
}
}
if (MCOperand_isImm(MCInst_getOperand(MI, 2)) &&
MCOperand_getImm(MCInst_getOperand(MI, 2)) != 0) {
if (needComma)
SStream_concat0(&ss, ",");
SStream_concat0(&ss, " $\xFF\x03\x01");
}
tmp = cs_strdup(ss.buffer);
AsmMnem = tmp;
for(AsmOps = tmp; *AsmOps; AsmOps++) {
if (*AsmOps == ' ' || *AsmOps == '\t') {
*AsmOps = '\0';
AsmOps++;
break;
}
}
SStream_concat0(OS, AsmMnem);
if (*AsmOps) {
SStream_concat0(OS, "\t");
for (c = AsmOps; *c; c++) {
if (*c == '$') {
c += 1;
if (*c == (char)0xff) {
c += 1;
OpIdx = *c - 1;
c += 1;
PrintMethodIdx = *c - 1;
printCustomAliasOperand(MI, OpIdx, PrintMethodIdx, OS);
} else
printOperand(MI, *c - 1, OS);
} else {
SStream_concat(OS, "%c", *c);
}
}
}
return tmp;
}
#define PRINT_ALIAS_INSTR
#include "PPCGenRegisterName.inc"
#include "PPCGenAsmWriter.inc"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -24,11 +24,14 @@ struct ppc_alias {
const char *mnem;
};
// given alias mnemonic, return instruction ID & CC
bool PPC_alias_insn(const char *name, struct ppc_alias *alias);
// map instruction name to public instruction ID
ppc_insn PPC_map_insn(const char *name);
// check if this insn is relative branch
bool PPC_abs_branch(cs_struct *h, unsigned int id);
// map internal raw register to 'public' register
ppc_reg PPC_map_register(unsigned int r);
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,8 @@ static struct {
{ "x64att", CS_ARCH_X86, CS_MODE_64 }, // CS_MODE_64, CS_OPT_SYNTAX_ATT
{ "ppc64", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_LITTLE_ENDIAN },
{ "ppc64be", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN },
{ "ppc64qpx", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_QPX | CS_MODE_LITTLE_ENDIAN },
{ "ppc64beqpx", CS_ARCH_PPC, CS_MODE_64 | CS_MODE_QPX | CS_MODE_BIG_ENDIAN },
{ "sparc", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN },
{ "sparcv9", CS_ARCH_SPARC, CS_MODE_BIG_ENDIAN | CS_MODE_V9 },
{ "systemz", CS_ARCH_SYSZ, CS_MODE_BIG_ENDIAN },
@ -196,6 +198,8 @@ static void usage(char *prog)
if (cs_support(CS_ARCH_PPC)) {
printf(" ppc64 ppc64 + little endian\n");
printf(" ppc64be ppc64 + big endian\n");
printf(" ppc64qpx ppc64 + qpx + little endian\n");
printf(" ppc64beqpx ppc64 + qpx + big endian\n");
}
if (cs_support(CS_ARCH_SPARC)) {

View File

@ -118,6 +118,8 @@ typedef enum cs_mode {
CS_MODE_MIPS2 = 1 << 7, ///< Mips II ISA
CS_MODE_V9 = 1 << 4, ///< SparcV9 mode (Sparc)
CS_MODE_QPX = 1 << 4, ///< Quad Processing eXtensions mode (PPC)
CS_MODE_SPE = 1 << 5, ///< Signal Processing Engine mode (PPC)
CS_MODE_BOOKE = 1 << 6, ///< Book-E mode (PPC)
CS_MODE_M68K_000 = 1 << 1, ///< M68K 68000 mode
CS_MODE_M68K_010 = 1 << 2, ///< M68K 68010 mode
CS_MODE_M68K_020 = 1 << 3, ///< M68K 68020 mode

File diff suppressed because it is too large Load Diff

View File

@ -13,8 +13,7 @@
0x7c,0x02,0x18,0xac = dcbf 2, 3
0x7c,0x43,0x20,0x28 = lwarx 2, 3, 4
0x7c,0x43,0x20,0xa8 = ldarx 2, 3, 4
0x7c,0x00,0x04,0xac = sync 0
0x7c,0x00,0x04,0xac = sync 0
0x7c,0x00,0x04,0xac = sync
// 0x7c,0x20,0x04,0xac = sync 1
// 0x7c,0x40,0x04,0xac = sync 2
// 0x7c,0x00,0x00,0x7c = wait 0

View File

@ -5,12 +5,12 @@
0x7f,0xff,0xfa,0x14 = add 31, 31, 31
0x38,0x20,0x00,0x00 = li 1, 0
0x38,0x22,0x00,0x00 = addi 1, 2, 0
0x38,0x20,0x80,0x00 = li 1, 0x8000
0x38,0x20,0x80,0x00 = li 1, -0x8000
0x38,0x20,0x7f,0xff = li 1, 0x7fff
0x60,0x41,0x00,0x00 = ori 1, 2, 0
0x60,0x41,0xff,0xff = ori 1, 2, 65535
0x3c,0x20,0x00,0x00 = lis 1, 0
0x3c,0x20,0xff,0xff = lis 1, 0xffff
0x3c,0x20,0xff,0xff = lis 1, -1
0x80,0x20,0x00,0x00 = lwz 1, 0(0)
0x80,0x20,0x00,0x00 = lwz 1, 0(0)
0x80,0x3f,0x00,0x00 = lwz 1, 0(31)