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

Reply via email to