Merge branch 'next' of github.com:aquynh/capstone into next

This commit is contained in:
Nguyen Anh Quynh 2019-05-13 13:52:09 +08:00
commit 90c0e6206b
8 changed files with 437 additions and 105 deletions

View File

@ -37,6 +37,7 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O);
static void printInstruction(MCInst *MI, SStream *O);
static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O);
static char *printAliasInstr(MCInst *MI, SStream *OS, MCRegisterInfo *MRI);
static char *printAliasBcc(MCInst *MI, SStream *OS, void *info);
static void printCustomAliasOperand(MCInst *MI, unsigned OpIdx,
unsigned PrintMethodIdx, SStream *OS);
@ -89,6 +90,305 @@ void PPC_post_printer(csh ud, cs_insn *insn, char *insn_asm, MCInst *mci)
#define GET_INSTRINFO_ENUM
#include "PPCGenInstrInfo.inc"
#define GET_REGINFO_ENUM
#include "PPCGenRegisterInfo.inc"
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 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 char *printAliasBcc(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;
}
#if 0
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++;
}
}
#endif
} 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_concat1(OS, *c);
}
}
}
return tmp;
}
static bool isBOCTRBranch(unsigned int op)
{
return ((op >= PPC_BDNZ) && (op <= PPC_BDZp));
}
void PPC_printInst(MCInst *MI, SStream *O, void *Info)
{
char *mnem;
@ -272,24 +572,46 @@ void PPC_printInst(MCInst *MI, SStream *O, void *Info)
}
}
if ((MCInst_getOpcode(MI) == PPC_B)||(MCInst_getOpcode(MI) == PPC_BA)||
(MCInst_getOpcode(MI) == PPC_BL)||(MCInst_getOpcode(MI) == PPC_BLA)) {
if (opcode == PPC_B || opcode == PPC_BA || opcode == PPC_BL ||
opcode == PPC_BLA) {
int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 0));
bd = SignExtend64(bd, 24);
MCOperand_setImm(MCInst_getOperand(MI, 0), bd);
}
mnem = printAliasInstr(MI, O, Info);
if (opcode == PPC_gBC || opcode == PPC_gBCA || opcode == PPC_gBCL ||
opcode == PPC_gBCLA) {
int64_t bd = MCOperand_getImm(MCInst_getOperand(MI, 2));
bd = SignExtend64(bd, 14);
MCOperand_setImm(MCInst_getOperand(MI, 2), bd);
}
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);
}
}
mnem = printAliasBcc(MI, O, Info);
if (!mnem)
mnem = printAliasInstr(MI, O, Info);
if (mnem != NULL) {
if (strlen(mnem) > 0) {
struct ppc_alias alias;
// check to remove the last letter of ('.', '-', '+')
if (mnem[strlen(mnem) - 1] == '-' || mnem[strlen(mnem) - 1] == '+' || mnem[strlen(mnem) - 1] == '.')
mnem[strlen(mnem) - 1] = '\0';
MCInst_setOpcodePub(MI, PPC_map_insn(mnem));
if (MI->csh->detail) {
MI->flat_insn->detail->ppc.bc = (ppc_bc)alias.cc;
struct ppc_alias alias;
if (PPC_alias_insn(mnem, &alias)) {
MI->flat_insn->detail->ppc.bc = (ppc_bc)alias.cc;
}
}
}
@ -676,6 +998,7 @@ static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
}
imm = SignExtend32(MCOperand_getImm(MCInst_getOperand(MI, OpNo)) * 4, 32);
//imm = MCOperand_getImm(MCInst_getOperand(MI, OpNo)) * 4;
if (!PPC_abs_branch(MI->csh, MCInst_getOpcode(MI))) {
imm = MI->address + imm;
@ -690,10 +1013,6 @@ static void printAbsBranchOperand(MCInst *MI, unsigned OpNo, SStream *O)
}
}
#define GET_REGINFO_ENUM
#include "PPCGenRegisterInfo.inc"
static void printcrbitm(MCInst *MI, unsigned OpNo, SStream *O)
{
unsigned RegNo;
@ -761,10 +1080,9 @@ static void printTLSCall(MCInst *MI, unsigned OpNo, SStream *O)
set_mem_access(MI, false);
}
#ifndef CAPSTONE_DIET
/// stripRegisterPrefix - This method strips the character prefix from a
/// register name so that only the number is left. Used by for linux asm.
static const char *stripRegisterPrefix(const char *RegName)
static char *stripRegisterPrefix(const char *RegName)
{
switch (RegName[0]) {
case 'r':
@ -772,23 +1090,29 @@ static const char *stripRegisterPrefix(const char *RegName)
case 'q': // for QPX
case 'v':
if (RegName[1] == 's')
return RegName + 2;
return RegName + 1;
return cs_strdup(RegName + 2);
return cs_strdup(RegName + 1);
case 'c':
if (RegName[1] == 'r')
return RegName + 2;
if (RegName[1] == 'r') {
// skip the first 2 letters "cr"
char *name = cs_strdup(RegName + 2);
// also strip the last 2 letters
name[strlen(name) - 2] = '\0';
return name;
}
}
return RegName;
return cs_strdup(RegName);
}
#endif
static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
{
MCOperand *Op = MCInst_getOperand(MI, OpNo);
if (MCOperand_isReg(Op)) {
unsigned reg = MCOperand_getReg(Op);
#ifndef CAPSTONE_DIET
const char *RegName = getRegisterName(reg);
// printf("reg = %u (%s)\n", reg, RegName);
@ -797,11 +1121,12 @@ static void printOperand(MCInst *MI, unsigned OpNo, SStream *O)
reg = PPC_name_reg(RegName);
// The linux and AIX assembler does not take register prefixes.
if (MI->csh->syntax == CS_OPT_SYNTAX_NOREGNAME)
RegName = stripRegisterPrefix(RegName);
SStream_concat0(O, RegName);
#endif
if (MI->csh->syntax == CS_OPT_SYNTAX_NOREGNAME) {
char *name = stripRegisterPrefix(RegName);
SStream_concat0(O, name);
cs_mem_free(name);
} else
SStream_concat0(O, RegName);
if (MI->csh->detail) {
if (MI->csh->doing_mem) {

View File

@ -417,7 +417,6 @@ const char *PPC_group_name(csh handle, unsigned int id)
#endif
}
#if 0
static const struct ppc_alias alias_insn_name_maps[] = {
//{ PPC_INS_BTA, "bta" },
{ PPC_INS_B, PPC_BC_LT, "blt" },
@ -513,32 +512,20 @@ static const struct ppc_alias alias_insn_name_maps[] = {
bool PPC_alias_insn(const char *name, struct ppc_alias *alias)
{
size_t i;
#ifndef CAPSTONE_DIET
int x;
#endif
alias->cc = PPC_BC_INVALID;
for(i = 0; i < ARR_SIZE(alias_insn_name_maps); i++) {
if (!strcmp(name, alias_insn_name_maps[i].mnem)) {
alias->id = alias_insn_name_maps[i].id;
// alias->id = alias_insn_name_maps[i].id;
alias->cc = alias_insn_name_maps[i].cc;
return true;
}
}
#ifndef CAPSTONE_DIET
// not really an alias insn
x = name2id(&insn_name_maps[1], ARR_SIZE(insn_name_maps) - 1, name);
if (x != -1) {
alias->id = insn_name_maps[x].id;
alias->cc = PPC_BC_INVALID;
return true;
}
#endif
// not found
return false;
}
#endif
// check if this insn is relative branch
bool PPC_abs_branch(cs_struct *h, unsigned int id)

View File

@ -33,5 +33,8 @@ 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);
// given alias mnemonic, return instruction ID & CC
bool PPC_alias_insn(const char *name, struct ppc_alias *alias);
#endif

View File

@ -790,28 +790,28 @@
{
PPC_BCCCTRL, PPC_INS_BEQCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BCCCTRL8, PPC_INS_BCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 0, 0
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 1, 0
#endif
},
{
PPC_BCCL, PPC_INS_BEQL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BCCLA, PPC_INS_BEQLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
@ -825,7 +825,7 @@
{
PPC_BCCLRL, PPC_INS_BEQLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
@ -853,28 +853,28 @@
{
PPC_BCCTRL, PPC_INS_BCCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BCCTRL8, PPC_INS_BCCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 0, 0
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 1, 0
#endif
},
{
PPC_BCCTRL8n, PPC_INS_BCCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 0, 0
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 1, 0
#endif
},
{
PPC_BCCTRLn, PPC_INS_BCCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
@ -993,14 +993,14 @@
{
PPC_BCLRL, PPC_INS_BCLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BCLRLn, PPC_INS_BCLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
@ -1014,14 +1014,14 @@
{
PPC_BCLalways, PPC_INS_BCL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BCLn, PPC_INS_BCL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
@ -1042,21 +1042,21 @@
{
PPC_BCTRL, PPC_INS_BCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { PPC_GRP_MODE32, 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { PPC_GRP_MODE32, 0 }, 1, 0
#endif
},
{
PPC_BCTRL8, PPC_INS_BCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 0, 0
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 1, 0
#endif
},
{
PPC_BCTRL8_LDinto_toc, PPC_INS_BCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 0, 0
{ PPC_REG_CTR8, PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { PPC_GRP_MODE64, 0 }, 1, 0
#endif
},
@ -1105,28 +1105,28 @@
{
PPC_BDNZL, PPC_INS_BDNZL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDNZLA, PPC_INS_BDNZLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDNZLAm, PPC_INS_BDNZLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDNZLAp, PPC_INS_BDNZLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
@ -1147,21 +1147,21 @@
{
PPC_BDNZLRL, PPC_INS_BDNZLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDNZLRLm, PPC_INS_BDNZLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDNZLRLp, PPC_INS_BDNZLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
@ -1182,14 +1182,14 @@
{
PPC_BDNZLm, PPC_INS_BDNZL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDNZLp, PPC_INS_BDNZL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
@ -1245,28 +1245,28 @@
{
PPC_BDZL, PPC_INS_BDZL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDZLA, PPC_INS_BDZLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDZLAm, PPC_INS_BDZLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDZLAp, PPC_INS_BDZLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
@ -1287,21 +1287,21 @@
{
PPC_BDZLRL, PPC_INS_BDZLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDZLRLm, PPC_INS_BDZLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDZLRLp, PPC_INS_BDZLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
@ -1322,14 +1322,14 @@
{
PPC_BDZLm, PPC_INS_BDZL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BDZLp, PPC_INS_BDZL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
@ -1350,91 +1350,91 @@
{
PPC_BL, PPC_INS_BL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BL8, PPC_INS_BL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BL8_NOP, PPC_INS_BL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BL8_NOP_TLS, PPC_INS_BL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BL8_TLS, PPC_INS_BL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BL8_TLS_, PPC_INS_BL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BLA, PPC_INS_BLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BLA8, PPC_INS_BLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BLA8_NOP, PPC_INS_BLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR8, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BLR, PPC_INS_BLR,
#ifndef CAPSTONE_DIET
{ PPC_REG_LR, PPC_REG_RM, 0 }, { 0 }, { PPC_GRP_MODE32, 0 }, 0, 0
{ PPC_REG_LR, PPC_REG_RM, 0 }, { 0 }, { PPC_GRP_MODE32, 0 }, 1, 0
#endif
},
{
PPC_BLR8, PPC_INS_BLR,
#ifndef CAPSTONE_DIET
{ PPC_REG_LR8, PPC_REG_RM, 0 }, { 0 }, { PPC_GRP_MODE64, 0 }, 0, 0
{ PPC_REG_LR8, PPC_REG_RM, 0 }, { 0 }, { PPC_GRP_MODE64, 0 }, 1, 0
#endif
},
{
PPC_BLRL, PPC_INS_BLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_BL_TLS, PPC_INS_BL,
#ifndef CAPSTONE_DIET
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 0, 0
{ PPC_REG_RM, 0 }, { PPC_REG_LR, 0 }, { 0 }, 1, 0
#endif
},
@ -12697,83 +12697,83 @@
{
PPC_gBC, PPC_INS_BC,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCA, PPC_INS_BCA,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCAat, PPC_INS_BCA,
#ifndef CAPSTONE_DIET
{ 0 }, { 0 }, { 0 }, 0, 0
{ 0 }, { 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCCTR, PPC_INS_BCCTR,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCCTRL, PPC_INS_BCCTRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCL, PPC_INS_BCL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCLA, PPC_INS_BCLA,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_RM, 0 }, { PPC_REG_LR, PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCLAat, PPC_INS_BCLA,
#ifndef CAPSTONE_DIET
{ 0 }, { 0 }, { 0 }, 0, 0
{ 0 }, { 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCLR, PPC_INS_BCLR,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCLRL, PPC_INS_BCLRL,
#ifndef CAPSTONE_DIET
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, PPC_REG_CTR, 0 }, { 0 }, 0, 0
{ PPC_REG_CTR, PPC_REG_LR, PPC_REG_RM, 0 }, { PPC_REG_LR, PPC_REG_CTR, 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCLat, PPC_INS_BCL,
#ifndef CAPSTONE_DIET
{ 0 }, { 0 }, { 0 }, 0, 0
{ 0 }, { 0 }, { 0 }, 1, 0
#endif
},
{
PPC_gBCat, PPC_INS_BC,
#ifndef CAPSTONE_DIET
{ 0 }, { 0 }, { 0 }, 0, 0
{ 0 }, { 0 }, { 0 }, 1, 0
#endif
},

View File

@ -1,3 +1,15 @@
!# issue PPC JUMP group
!# CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN, CS_OPT_DETAIL
0x41,0x82,0x00,0x10 == beq 0x10 ; Groups: jump
!# issue 1468 PPC bdnz
!# CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN, None
0x101086c: 0x42,0x00,0xff,0xf8 == bdnz 0x1010864
!# issue PPC bdnzt
!# CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN, None
0x1000: 0x41,0x00,0xff,0xac == bdnzt lt, 0xfac
!# issue 1469 PPC CRx
!# CS_ARCH_PPC, CS_MODE_64 | CS_MODE_BIG_ENDIAN, CS_OPT_DETAIL
0x4c,0x02,0x39,0x82 == crxor cr0lt, cr0eq, cr1un ; operands[0].type: REG = cr0lt

View File

@ -1,10 +1,13 @@
all:
x86:
# compile disassembler2 with X86GenDisassemblerTables2.inc
$(CC) disassemblertables2.c -o disassemblertables2
# compile disassembler2 with X86GenDisassemblerTables_reduce2.inc
$(CC) -DCAPSTONE_X86_REDUCE disassemblertables2.c -o disassemblertables_reduce2
arm64:
$(CC) arm64_gen_vreg.c -o arm64_gen_vreg
clean:

View File

@ -19,9 +19,6 @@ echo "Generating ${ARCH}MappingInsnName.inc"
echo "Generating ${ARCH}MappingInsn.inc"
./mapping_insn-arch.py $1/${ARCH}GenAsmMatcher.inc $1/${ARCH}GenInstrInfo.inc $2/${ARCH}MappingInsn.inc > ${ARCH}MappingInsn.inc
echo "Generating ${ARCH}MappingInsnOp.inc"
./mapping_insn_op-arch.py $1/${ARCH}GenAsmMatcher.inc $1/${ARCH}GenInstrInfo.inc $2/${ARCH}MappingInsnOp.inc > ${ARCH}MappingInsnOp.inc
echo "Generating ${ARCH}GenInstrInfo.inc"
./instrinfo-arch.py $1/${ARCH}GenInstrInfo.inc ${ARCH} > ${ARCH}GenInstrInfo.inc
@ -34,8 +31,6 @@ echo "Generating ${ARCH}GenRegisterInfo.inc"
echo "Generating ${ARCH}GenSubtargetInfo.inc"
./subtargetinfo.py $1/${ARCH}GenSubtargetInfo.inc ${ARCH} > ${ARCH}GenSubtargetInfo.inc
make
case $3 in
ARM)
# for ARM only
@ -46,6 +41,10 @@ case $3 in
echo "Generating instruction enum in insn_list.txt (for include/capstone/<arch>.h)"
./insn.py $1/${ARCH}GenAsmMatcher.inc $1/${ARCH}GenInstrInfo.inc $2/${ARCH}MappingInsn.inc > insn_list.txt
# then copy these instructions to include/capstone/<arch>.h
echo "Generating ${ARCH}MappingInsnOp.inc"
./mapping_insn_op-arch.py $1/${ARCH}GenAsmMatcher.inc $1/${ARCH}GenInstrInfo.inc $2/${ARCH}MappingInsnOp.inc > ${ARCH}MappingInsnOp.inc
echo "Generating ${ARCH}GenSystemRegister.inc"
./systemregister.py $1/${ARCH}GenSystemRegister.inc > ${ARCH}GenSystemRegister.inc
;;
AArch64)
echo "Generating ${ARCH}GenSystemOperands.inc"
@ -54,6 +53,9 @@ case $3 in
./insn.py $1/${ARCH}GenAsmMatcher.inc $1/${ARCH}GenInstrInfo.inc $2/${ARCH}MappingInsn.inc > insn_list.txt
# then copy these instructions to include/capstone/<arch>.h
./arm64_gen_vreg > AArch64GenRegisterV.inc
echo "Generating ${ARCH}MappingInsnOp.inc"
./mapping_insn_op-arch.py $1/${ARCH}GenAsmMatcher.inc $1/${ARCH}GenInstrInfo.inc $2/${ARCH}MappingInsnOp.inc > ${ARCH}MappingInsnOp.inc
make arm64
;;
PowerPC)
# PowerPC
@ -61,8 +63,6 @@ case $3 in
# then copy these instructions to include/capstone/arch.h
;;
*)
echo "Generating ${ARCH}GenSystemRegister.inc"
./systemregister.py $1/${ARCH}GenSystemRegister.inc > ${ARCH}GenSystemRegister.inc
echo "Generating instruction enum in insn_list.txt (for include/capstone/<arch>.h)"
./insn.py $1/${ARCH}GenAsmMatcher.inc $1/${ARCH}GenInstrInfo.inc $2/${ARCH}MappingInsn.inc > insn_list.txt
;;

View File

@ -29,3 +29,5 @@ echo "Generating GenInstrInfo.inc"
echo "Generating GenDisassemblerTables.inc & X86GenDisassemblerTables2.inc"
./disassemblertables.py $1/X86GenDisassemblerTables.inc X86GenDisassemblerTables.inc X86GenDisassemblerTables2.inc
make x86