From a81bf4247c0aa3c4ef66f96d9f0c5a44d1918663 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 7 Mar 2015 13:37:32 +0800 Subject: [PATCH] x86: add new field @xop_cc to struct @cs_x86 --- arch/X86/X86ATTInstPrinter.c | 16 ++++++++-------- arch/X86/X86IntelInstPrinter.c | 16 ++++++++-------- arch/X86/X86Mapping.c | 7 +++++++ arch/X86/X86Mapping.h | 1 + include/capstone/x86.h | 16 ++++++++++++++++ tests/test_x86.c | 7 ++++++- 6 files changed, 46 insertions(+), 17 deletions(-) diff --git a/arch/X86/X86ATTInstPrinter.c b/arch/X86/X86ATTInstPrinter.c index 9ebd158a..37b0f1c5 100644 --- a/arch/X86/X86ATTInstPrinter.c +++ b/arch/X86/X86ATTInstPrinter.c @@ -216,14 +216,14 @@ static void printXOPCC(MCInst *MI, unsigned Op, SStream *O) switch (Imm) { default: // llvm_unreachable("Invalid xopcc argument!"); - case 0: SStream_concat0(O, "lt"); break; // FIXME - case 1: SStream_concat0(O, "le"); break; - case 2: SStream_concat0(O, "gt"); break; - case 3: SStream_concat0(O, "ge"); break; - case 4: SStream_concat0(O, "eq"); break; - case 5: SStream_concat0(O, "neq"); break; - case 6: SStream_concat0(O, "false"); break; - case 7: SStream_concat0(O, "true"); break; + case 0: SStream_concat0(O, "lt"); op_addXopCC(MI, X86_XOP_CC_LT); break; + case 1: SStream_concat0(O, "le"); op_addXopCC(MI, X86_XOP_CC_LE); break; + case 2: SStream_concat0(O, "gt"); op_addXopCC(MI, X86_XOP_CC_GT); break; + case 3: SStream_concat0(O, "ge"); op_addXopCC(MI, X86_XOP_CC_GE); break; + case 4: SStream_concat0(O, "eq"); op_addXopCC(MI, X86_XOP_CC_EQ); break; + case 5: SStream_concat0(O, "neq"); op_addXopCC(MI, X86_XOP_CC_NEQ); break; + case 6: SStream_concat0(O, "false"); op_addXopCC(MI, X86_XOP_CC_FALSE); break; + case 7: SStream_concat0(O, "true"); op_addXopCC(MI, X86_XOP_CC_TRUE); break; } } diff --git a/arch/X86/X86IntelInstPrinter.c b/arch/X86/X86IntelInstPrinter.c index 313657f6..c6fd532e 100644 --- a/arch/X86/X86IntelInstPrinter.c +++ b/arch/X86/X86IntelInstPrinter.c @@ -230,14 +230,14 @@ static void printXOPCC(MCInst *MI, unsigned Op, SStream *O) switch (Imm) { default: // llvm_unreachable("Invalid xopcc argument!"); - case 0: SStream_concat0(O, "lt"); break; // FIXME - case 1: SStream_concat0(O, "le"); break; - case 2: SStream_concat0(O, "gt"); break; - case 3: SStream_concat0(O, "ge"); break; - case 4: SStream_concat0(O, "eq"); break; - case 5: SStream_concat0(O, "neq"); break; - case 6: SStream_concat0(O, "false"); break; - case 7: SStream_concat0(O, "true"); break; + case 0: SStream_concat0(O, "lt"); op_addXopCC(MI, X86_XOP_CC_LT); break; + case 1: SStream_concat0(O, "le"); op_addXopCC(MI, X86_XOP_CC_LE); break; + case 2: SStream_concat0(O, "gt"); op_addXopCC(MI, X86_XOP_CC_GT); break; + case 3: SStream_concat0(O, "ge"); op_addXopCC(MI, X86_XOP_CC_GE); break; + case 4: SStream_concat0(O, "eq"); op_addXopCC(MI, X86_XOP_CC_EQ); break; + case 5: SStream_concat0(O, "neq"); op_addXopCC(MI, X86_XOP_CC_NEQ); break; + case 6: SStream_concat0(O, "false"); op_addXopCC(MI, X86_XOP_CC_FALSE); break; + case 7: SStream_concat0(O, "true"); op_addXopCC(MI, X86_XOP_CC_TRUE); break; } } diff --git a/arch/X86/X86Mapping.c b/arch/X86/X86Mapping.c index 15e971b4..a42464ce 100644 --- a/arch/X86/X86Mapping.c +++ b/arch/X86/X86Mapping.c @@ -63165,6 +63165,13 @@ void op_addImm(MCInst *MI, int v) MI->op1_size = MI->imm_size; } +void op_addXopCC(MCInst *MI, int v) +{ + if (MI->csh->detail) { + MI->flat_insn->detail->x86.xop_cc = v; + } +} + void op_addSseCC(MCInst *MI, int v) { if (MI->csh->detail) { diff --git a/arch/X86/X86Mapping.h b/arch/X86/X86Mapping.h index 59cd4f0d..d8185488 100644 --- a/arch/X86/X86Mapping.h +++ b/arch/X86/X86Mapping.h @@ -51,6 +51,7 @@ void op_addImm(MCInst *MI, int v); void op_addAvxBroadcast(MCInst *MI, x86_avx_bcast v); +void op_addXopCC(MCInst *MI, int v); void op_addSseCC(MCInst *MI, int v); void op_addAvxCC(MCInst *MI, int v); diff --git a/include/capstone/x86.h b/include/capstone/x86.h index 0ac82f69..350a15b8 100644 --- a/include/capstone/x86.h +++ b/include/capstone/x86.h @@ -78,6 +78,19 @@ typedef enum x86_op_type { X86_OP_FP, // = CS_OP_FP (Floating-Point operand). } x86_op_type; +//> XOP Code Condition type +typedef enum x86_xop_cc { + X86_XOP_CC_INVALID = 0, // Uninitialized. + X86_XOP_CC_LT, + X86_XOP_CC_LE, + X86_XOP_CC_GT, + X86_XOP_CC_GE, + X86_XOP_CC_EQ, + X86_XOP_CC_NEQ, + X86_XOP_CC_FALSE, + X86_XOP_CC_TRUE, +} x86_xop_cc; + //> AVX broadcast type typedef enum x86_avx_bcast { X86_AVX_BCAST_INVALID = 0, // Uninitialized. @@ -233,6 +246,9 @@ typedef struct cs_x86 { // SIB base register, or X86_REG_INVALID when irrelevant. x86_reg sib_base; + // XOP Code Condition + x86_xop_cc xop_cc; + // SSE Code Condition x86_sse_cc sse_cc; diff --git a/tests/test_x86.c b/tests/test_x86.c index 24f80a79..8af4c39f 100644 --- a/tests/test_x86.c +++ b/tests/test_x86.c @@ -63,6 +63,11 @@ static void print_insn_detail(csh ud, cs_mode mode, cs_insn *ins) printf("\t\tsib_scale: %d\n", x86->sib_scale); } + // XOP code condition + if (x86->xop_cc != X86_XOP_CC_INVALID) { + printf("\txop_cc: %u\n", x86->xop_cc); + } + // SSE code condition if (x86->sse_cc != X86_SSE_CC_INVALID) { printf("\tsse_cc: %u\n", x86->sse_cc); @@ -148,7 +153,7 @@ static void test() //#define X86_CODE32 "\xa1\x13\x48\x6d\x3a\x8b\x81\x23\x01\x00\x00\x8b\x84\x39\x23\x01\x00\x00" //#define X86_CODE32 "\xb4\xc6" // mov ah, 0x6c //#define X86_CODE32 "\x77\x04" // ja +6 -#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00" +#define X86_CODE64 "\x55\x48\x8b\x05\xb8\x13\x00\x00\x8f\xe8\x60\xcd\xe2\x07" //#define X86_CODE64 "\xe9\x79\xff\xff\xff" // jmp 0xf7e #define X86_CODE16 "\x8d\x4c\x32\x08\x01\xd8\x81\xc6\x34\x12\x00\x00\x05\x23\x01\x00\x00\x36\x8b\x84\x91\x23\x01\x00\x00\x41\x8d\x84\x39\x89\x67\x00\x00\x8d\x87\x89\x67\x00\x00\xb4\xc6"