MUL_MEMBASE_REG and MUL_REG_REG have been renamed to MUL_*_EAX because of the implicit eax operand of the x86 "mul" instruction. MUL_REG_REG was introduced and emits the x86 "imul" instruction that does not have implicit operands.
Signed-off-by: Arthur HUILLET <arthur.huil...@free.fr> --- arch/x86/emit-code_32.c | 36 ++++++++++++++++++++++++++++---- arch/x86/include/arch/instruction.h | 4 ++- arch/x86/insn-selector_32.brg | 2 +- arch/x86/use-def.c | 4 ++- test/arch-x86/emit-code-test_32.c | 4 +- test/arch-x86/insn-selector-test_32.c | 2 +- test/arch-x86/use-def-test_32.c | 2 +- 7 files changed, 42 insertions(+), 12 deletions(-) diff --git a/arch/x86/emit-code_32.c b/arch/x86/emit-code_32.c index 3c9c528..83a3573 100644 --- a/arch/x86/emit-code_32.c +++ b/arch/x86/emit-code_32.c @@ -478,7 +478,7 @@ static void emit_sub_membase_reg(struct buffer *buf, emit_membase_reg(buf, 0x2b, src, dest); } -static void __emit_div_mul_membase_reg(struct buffer *buf, +static void __emit_div_mul_membase_eax(struct buffer *buf, struct operand *src, struct operand *dest, unsigned char opc_ext) @@ -500,10 +500,34 @@ static void __emit_div_mul_membase_reg(struct buffer *buf, emit_imm(buf, disp); } -static void emit_mul_membase_reg(struct buffer *buf, +static void __emit_div_mul_reg_eax(struct buffer *buf, + struct operand *src, + struct operand *dest, + unsigned char opc_ext) +{ + assert(mach_reg(&dest->reg) == REG_EAX); + + emit(buf, 0xf7); + emit(buf, encode_modrm(0x03, opc_ext, encode_reg(&src->base_reg))); +} + +static void emit_mul_membase_eax(struct buffer *buf, struct operand *src, struct operand *dest) { - __emit_div_mul_membase_reg(buf, src, dest, 0x04); + __emit_div_mul_membase_eax(buf, src, dest, 0x04); +} + +static void emit_mul_reg_eax(struct buffer *buf, + struct operand *src, struct operand *dest) +{ + __emit_div_mul_reg_eax(buf, src, dest, 0x04); +} + +static void emit_mul_reg_reg(struct buffer *buf, + struct operand *src, struct operand *dest) +{ + emit(buf, 0x0f); + __emit_reg_reg(buf, 0xaf, mach_reg(&dest->reg), mach_reg(&src->reg)); } static void emit_neg_reg(struct buffer *buf, struct operand *operand) @@ -523,7 +547,7 @@ static void emit_cltd_reg_reg(struct buffer *buf, struct operand *src, struct op static void emit_div_membase_reg(struct buffer *buf, struct operand *src, struct operand *dest) { - __emit_div_mul_membase_reg(buf, src, dest, 0x07); + __emit_div_mul_membase_eax(buf, src, dest, 0x07); } static void __emit_shift_reg_reg(struct buffer *buf, @@ -769,7 +793,9 @@ static struct emitter emitters[] = { DECL_EMITTER(INSN_MOV_REG_MEMINDEX, emit_mov_reg_memindex, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_REG_MEMLOCAL, emit_mov_reg_memlocal, TWO_OPERANDS), DECL_EMITTER(INSN_MOV_REG_REG, emit_mov_reg_reg, TWO_OPERANDS), - DECL_EMITTER(INSN_MUL_MEMBASE_REG, emit_mul_membase_reg, TWO_OPERANDS), + DECL_EMITTER(INSN_MUL_MEMBASE_EAX, emit_mul_membase_eax, TWO_OPERANDS), + DECL_EMITTER(INSN_MUL_REG_EAX, emit_mul_reg_eax, TWO_OPERANDS), + DECL_EMITTER(INSN_MUL_REG_REG, emit_mul_reg_reg, TWO_OPERANDS), DECL_EMITTER(INSN_NEG_REG, emit_neg_reg, SINGLE_OPERAND), DECL_EMITTER(INSN_OR_MEMBASE_REG, emit_or_membase_reg, TWO_OPERANDS), DECL_EMITTER(INSN_OR_REG_REG, emit_or_reg_reg, TWO_OPERANDS), diff --git a/arch/x86/include/arch/instruction.h b/arch/x86/include/arch/instruction.h index 5a09f19..b8ab850 100644 --- a/arch/x86/include/arch/instruction.h +++ b/arch/x86/include/arch/instruction.h @@ -84,7 +84,9 @@ enum insn_type { INSN_MOV_REG_MEMINDEX, INSN_MOV_REG_MEMLOCAL, INSN_MOV_REG_REG, - INSN_MUL_MEMBASE_REG, + INSN_MUL_MEMBASE_EAX, + INSN_MUL_REG_EAX, + INSN_MUL_REG_REG, INSN_NEG_REG, INSN_OR_MEMBASE_REG, INSN_OR_REG_REG, diff --git a/arch/x86/insn-selector_32.brg b/arch/x86/insn-selector_32.brg index 2950c52..fa375c2 100644 --- a/arch/x86/insn-selector_32.brg +++ b/arch/x86/insn-selector_32.brg @@ -238,7 +238,7 @@ reg: OP_MUL(reg, EXPR_LOCAL) 1 state->reg1 = eax; bb_add_insn(s, reg_reg_insn(INSN_MOV_REG_REG, state->left->reg1, eax)); - __binop_reg_local(state, s, tree, INSN_MUL_MEMBASE_REG, eax, 0); + __binop_reg_local(state, s, tree, INSN_MUL_MEMBASE_EAX, eax, 0); } reg: OP_DIV(reg, EXPR_LOCAL) 1 diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c index b1f3c43..d35b03d 100644 --- a/arch/x86/use-def.c +++ b/arch/x86/use-def.c @@ -55,7 +55,9 @@ static struct insn_info insn_infos[] = { DECLARE_INFO(INSN_MOV_REG_MEMINDEX, USE_SRC | USE_DST | USE_IDX_DST | DEF_NONE), DECLARE_INFO(INSN_MOV_REG_MEMLOCAL, USE_SRC), DECLARE_INFO(INSN_MOV_REG_REG, USE_SRC | DEF_DST), - DECLARE_INFO(INSN_MUL_MEMBASE_REG, USE_SRC | DEF_DST), + DECLARE_INFO(INSN_MUL_MEMBASE_EAX, USE_SRC | DEF_DST), + DECLARE_INFO(INSN_MUL_REG_EAX, USE_SRC | DEF_DST), + DECLARE_INFO(INSN_MUL_REG_REG, USE_SRC | DEF_DST), //FIXME: defines EDX as well. DECLARE_INFO(INSN_NEG_REG, USE_SRC | DEF_SRC), DECLARE_INFO(INSN_OR_MEMBASE_REG, USE_SRC | DEF_DST), DECLARE_INFO(INSN_OR_REG_REG, USE_SRC | DEF_DST), diff --git a/test/arch-x86/emit-code-test_32.c b/test/arch-x86/emit-code-test_32.c index d6adcf8..a793713 100644 --- a/test/arch-x86/emit-code-test_32.c +++ b/test/arch-x86/emit-code-test_32.c @@ -347,8 +347,8 @@ void test_emit_sbb_membase_reg(void) void test_emit_mul_membase_reg(void) { - assert_emit_insn_3(0xf7, 0x65, 0x0c, membase_reg_insn(INSN_MUL_MEMBASE_REG, &VAR_EBP, 0x0c, &VAR_EAX)); - assert_emit_insn_6(0xf7, 0xa5, 0xef, 0xbe, 0xad, 0xde, membase_reg_insn(INSN_MUL_MEMBASE_REG, &VAR_EBP, 0xdeadbeef, &VAR_EAX)); + assert_emit_insn_3(0xf7, 0x65, 0x0c, membase_reg_insn(INSN_MUL_MEMBASE_EAX, &VAR_EBP, 0x0c, &VAR_EAX)); + assert_emit_insn_6(0xf7, 0xa5, 0xef, 0xbe, 0xad, 0xde, membase_reg_insn(INSN_MUL_MEMBASE_EAX, &VAR_EBP, 0xdeadbeef, &VAR_EAX)); } void test_emit_cltd(void) diff --git a/test/arch-x86/insn-selector-test_32.c b/test/arch-x86/insn-selector-test_32.c index accb81f..b573ed4 100644 --- a/test/arch-x86/insn-selector-test_32.c +++ b/test/arch-x86/insn-selector-test_32.c @@ -292,7 +292,7 @@ void test_select_local_local_mul(void) assert_reg_reg_insn(INSN_MOV_REG_REG, dreg, REG_EAX, insn); insn = list_next_entry(&insn->insn_list_node, struct insn, insn_list_node); - assert_membase_reg_insn(INSN_MUL_MEMBASE_REG, REG_EBP, 24, REG_EAX, insn); + assert_membase_reg_insn(INSN_MUL_MEMBASE_EAX, REG_EBP, 24, REG_EAX, insn); free_compilation_unit(bb->b_parent); } diff --git a/test/arch-x86/use-def-test_32.c b/test/arch-x86/use-def-test_32.c index 98a8065..3bbc8b8 100644 --- a/test/arch-x86/use-def-test_32.c +++ b/test/arch-x86/use-def-test_32.c @@ -134,7 +134,7 @@ void test_membase_reg_uses_source_defines_target(void) assert_uses_r0_defines_r1(membase_reg_insn(INSN_CMP_MEMBASE_REG, &r0, 0, &r1)); assert_uses_r0_defines_r1(membase_reg_insn(INSN_DIV_MEMBASE_REG, &r0, 0, &r1)); assert_uses_r0_defines_r1(membase_reg_insn(INSN_MOV_MEMBASE_REG, &r0, 0, &r1)); - assert_uses_r0_defines_r1(membase_reg_insn(INSN_MUL_MEMBASE_REG, &r0, 0, &r1)); + assert_uses_r0_defines_r1(membase_reg_insn(INSN_MUL_MEMBASE_EAX, &r0, 0, &r1)); assert_uses_r0_defines_r1(membase_reg_insn(INSN_OR_MEMBASE_REG, &r0, 0, &r1)); assert_uses_r0_defines_r1(membase_reg_insn(INSN_SUB_MEMBASE_REG, &r0, 0, &r1)); assert_uses_r0_defines_r1(membase_reg_insn(INSN_SBB_MEMBASE_REG, &r0, 0, &r1)); -- 1.6.2.2 ------------------------------------------------------------------------------ This SF.net email is sponsored by: High Quality Requirements in a Collaborative Environment. Download a free trial of Rational Requirements Composer Now! http://p.sf.net/sfu/www-ibm-com _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel