Add '4*cri+cond' to operand list
diff --git a/arch/PowerPC/PPCInstPrinter.c b/arch/PowerPC/PPCInstPrinter.c
index bb2d5db..9e5cdd4 100644
--- a/arch/PowerPC/PPCInstPrinter.c
+++ b/arch/PowerPC/PPCInstPrinter.c
@@ -907,10 +907,6 @@
(MCOperand_getImm(MCInst_getOperand(MI, 0)) < 16)) {
int cr = getBICR(MCOperand_getReg(MCInst_getOperand(MI, 1)));
- if (cr != PPC_CR0) {
- op_addReg(MI, PPC_REG_CR0 + cr - PPC_CR0);
- }
-
if (decCtr) {
needComma = true;
SStream_concat0(&ss, " ");
@@ -938,10 +934,22 @@
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);
}
}
}
diff --git a/include/ppc.h b/include/ppc.h
index abaf088..3490b18 100644
--- a/include/ppc.h
+++ b/include/ppc.h
@@ -28,8 +28,8 @@
PPC_BC_NU = (3 << 5) | 4,
// extra conditions
- PPC_BC_SO = 4 << 5, // summary overflow
- PPC_BC_NS = 4 << 5, // not summary overflow
+ PPC_BC_SO = (4 << 5) | 12, // summary overflow
+ PPC_BC_NS = (4 << 5) | 4, // not summary overflow
} ppc_bc;
//> PPC branch hint for some branch instructions
@@ -45,6 +45,7 @@
PPC_OP_REG, // Register operand.
PPC_OP_IMM, // Immediate operand.
PPC_OP_MEM, // Memory operand
+ PPC_OP_CRX, // Condition Register field
} ppc_op_type;
// Instruction's operand referring to memory
@@ -54,6 +55,12 @@
int32_t disp; // displacement/offset value
} ppc_op_mem;
+typedef struct ppc_op_crx {
+ unsigned int scale;
+ unsigned int reg;
+ unsigned int cond;
+} ppc_op_crx;
+
// Instruction operand
typedef struct cs_ppc_op {
ppc_op_type type; // operand type
@@ -61,6 +68,7 @@
unsigned int reg; // register value for REG operand
int32_t imm; // immediate value for IMM operand
ppc_op_mem mem; // base/disp value for MEM operand
+ ppc_op_crx crx; //
};
} cs_ppc_op;
diff --git a/tests/test_ppc.c b/tests/test_ppc.c
index 10071e6..c6b5244 100644
--- a/tests/test_ppc.c
+++ b/tests/test_ppc.c
@@ -28,6 +28,35 @@
printf("\n");
}
+static const char* get_bc_name(int bc)
+{
+ switch(bc) {
+ default:
+ case PPC_BC_INVALID:
+ return ("invalid");
+ case PPC_BC_LT:
+ return ("lt");
+ case PPC_BC_LE:
+ return ("le");
+ case PPC_BC_EQ:
+ return ("eq");
+ case PPC_BC_GE:
+ return ("ge");
+ case PPC_BC_GT:
+ return ("gt");
+ case PPC_BC_NE:
+ return ("ne");
+ case PPC_BC_UN:
+ return ("un");
+ case PPC_BC_NU:
+ return ("nu");
+ case PPC_BC_SO:
+ return ("so");
+ case PPC_BC_NS:
+ return ("ns");
+ }
+}
+
static void print_insn_detail(cs_insn *ins)
{
cs_ppc *ppc;
@@ -61,6 +90,12 @@
printf("\t\t\toperands[%u].mem.disp: 0x%x\n", i, op->mem.disp);
break;
+ case PPC_OP_CRX:
+ printf("\t\toperands[%u].type: CRX\n", i);
+ printf("\t\t\toperands[%u].crx.scale: %d\n", i, op->crx.scale);
+ printf("\t\t\toperands[%u].crx.reg: %s\n", i, cs_reg_name(handle, op->crx.reg));
+ printf("\t\t\toperands[%u].crx.cond: %s\n", i, get_bc_name(op->crx.cond));
+ break;
}
}
@@ -78,7 +113,7 @@
static void test()
{
-#define PPC_CODE "\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21\x40\x82\x00\x14"
+#define PPC_CODE "\x43\x20\x0c\x07\x41\x56\xff\x17\x80\x20\x00\x00\x80\x3f\x00\x00\x10\x43\x23\x0e\xd0\x44\x00\x80\x4c\x43\x22\x02\x2d\x03\x00\x80\x7c\x43\x20\x14\x7c\x43\x20\x93\x4f\x20\x00\x21\x4c\xc8\x00\x21\x40\x82\x00\x14"
struct platform platforms[] = {
{