Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/emit-code.c                |   18 ++++++++++
 arch/x86/include/arch/instruction.h |    2 +
 arch/x86/insn-selector.brg          |   65 +++++++++++++++++++++++++++++++---
 arch/x86/lir-printer.c              |   14 +++++++
 arch/x86/use-def.c                  |    2 +
 include/jit/expression.h            |    9 +++++
 jit/expression.c                    |   49 ++++++++++++++++++++++++++
 jit/tree-printer.c                  |    4 ++
 jit/typeconv-bc.c                   |   14 ++++++-
 test/jit/typeconv-bc-test.c         |   12 +++---
 10 files changed, 175 insertions(+), 14 deletions(-)

diff --git a/arch/x86/emit-code.c b/arch/x86/emit-code.c
index e2fa035..a59523e 100644
--- a/arch/x86/emit-code.c
+++ b/arch/x86/emit-code.c
@@ -1466,6 +1466,22 @@ static void emit_exception_test(struct buffer *buf, enum 
machine_reg reg)
        __emit_test_membase_reg(buf, reg, 0, reg);
 }
 
+static void emit_conv_xmm_to_xmm64(struct buffer *buf, struct operand *src,
+                                  struct operand *dest)
+{
+       emit(buf, 0xf3);
+       emit(buf, 0x0f);
+       emit_reg_reg(buf, 0x5a, dest, src);
+}
+
+static void emit_conv_xmm64_to_xmm(struct buffer *buf, struct operand *src,
+                                  struct operand *dest)
+{
+       emit(buf, 0xf2);
+       emit(buf, 0x0f);
+       emit_reg_reg(buf, 0x5a, dest, src);
+}
+
 static void emit_conv_gpr_to_fpu(struct buffer *buf, struct operand *src,
                                struct operand *dest)
 {
@@ -1676,6 +1692,8 @@ struct emitter emitters[] = {
        DECL_EMITTER(INSN_CONV_GPR_TO_FPU64, emit_conv_gpr_to_fpu64, 
TWO_OPERANDS),
        DECL_EMITTER(INSN_CONV_FPU_TO_GPR, emit_conv_fpu_to_gpr, TWO_OPERANDS),
        DECL_EMITTER(INSN_CONV_FPU64_TO_GPR, emit_conv_fpu64_to_gpr, 
TWO_OPERANDS),
+       DECL_EMITTER(INSN_CONV_XMM_TO_XMM64, emit_conv_xmm_to_xmm64, 
TWO_OPERANDS),
+       DECL_EMITTER(INSN_CONV_XMM64_TO_XMM, emit_conv_xmm64_to_xmm, 
TWO_OPERANDS),
        DECL_EMITTER(INSN_JMP_MEMINDEX, emit_jmp_memindex, SINGLE_OPERAND),
        DECL_EMITTER(INSN_MOV_MEMBASE_XMM, emit_mov_membase_xmm, TWO_OPERANDS),
        DECL_EMITTER(INSN_MOV_64_MEMBASE_XMM, emit_mov_64_membase_xmm, 
TWO_OPERANDS),
diff --git a/arch/x86/include/arch/instruction.h 
b/arch/x86/include/arch/instruction.h
index cb65c1d..feb8dbe 100644
--- a/arch/x86/include/arch/instruction.h
+++ b/arch/x86/include/arch/instruction.h
@@ -90,6 +90,8 @@ enum insn_type {
        INSN_CONV_FPU64_TO_GPR,
        INSN_CONV_GPR_TO_FPU,
        INSN_CONV_GPR_TO_FPU64,
+       INSN_CONV_XMM_TO_XMM64,
+       INSN_CONV_XMM64_TO_XMM,
        INSN_JE_BRANCH,
        INSN_JGE_BRANCH,
        INSN_JG_BRANCH,
diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg
index db38e44..3860422 100644
--- a/arch/x86/insn-selector.brg
+++ b/arch/x86/insn-selector.brg
@@ -1438,6 +1438,28 @@ reg:     EXPR_CONVERSION(reg)
        }
 }
 
+freg:  EXPR_CONVERSION_FLOAT_TO_DOUBLE(freg)
+{
+       struct expression *expr, *src;
+
+       expr = to_expr(tree);
+       src = to_expr(expr->from_expression);
+
+       state->reg1 = get_var(s->b_parent, J_DOUBLE);
+       select_insn(s, tree, reg_reg_insn(INSN_CONV_XMM_TO_XMM64, 
state->left->reg1, state->reg1));
+}
+
+freg:  EXPR_CONVERSION_DOUBLE_TO_FLOAT(freg)
+{
+       struct expression *expr, *src;
+
+       expr = to_expr(tree);
+       src = to_expr(expr->from_expression);
+
+       state->reg1 = get_var(s->b_parent, J_FLOAT);
+       select_insn(s, tree, reg_reg_insn(INSN_CONV_XMM64_TO_XMM, 
state->left->reg1, state->reg1));
+}
+
 freg:  EXPR_CONVERSION_TO_FLOAT(reg)
 {
        struct expression *expr, *src;
@@ -1445,13 +1467,28 @@ freg:   EXPR_CONVERSION_TO_FLOAT(reg)
        expr = to_expr(tree);
        src = to_expr(expr->from_expression);
 
-       if (src->vm_type == J_INT && expr->vm_type == J_FLOAT) {
+       assert(expr->vm_type == J_FLOAT);
+
+       if (src->vm_type == J_INT) {
                state->reg1 = get_var(s->b_parent, J_FLOAT);
 
                select_insn(s, tree, reg_reg_insn(INSN_CONV_GPR_TO_FPU, 
state->left->reg1, state->reg1));
-       } else if (src->vm_type == J_INT && expr->vm_type == J_DOUBLE) {
-               state->reg1 = get_var(s->b_parent, J_DOUBLE);
+       } else {
+               die("EXPR_CONVERSION_TO_FLOAT: no conversion from %d to %d", 
src->vm_type, expr->vm_type);
+       }
+}
+
+freg:  EXPR_CONVERSION_TO_DOUBLE(reg)
+{
+       struct expression *expr, *src;
+
+       expr = to_expr(tree);
+       src = to_expr(expr->from_expression);
+
+       assert(expr->vm_type == J_DOUBLE);
 
+       if (src->vm_type == J_INT) {
+               state->reg1 = get_var(s->b_parent, J_DOUBLE);
                select_insn(s, tree, reg_reg_insn(INSN_CONV_GPR_TO_FPU64, 
state->left->reg1, state->reg1));
        } else {
                die("EXPR_CONVERSION_TO_FLOAT: no conversion from %d to %d", 
src->vm_type, expr->vm_type);
@@ -1465,16 +1502,32 @@ reg:    EXPR_CONVERSION_FROM_FLOAT(freg)
        expr = to_expr(tree);
        src = to_expr(expr->from_expression);
 
-       if (src->vm_type == J_FLOAT && expr->vm_type == J_INT) {
+       assert(src->vm_type == J_FLOAT);
+
+       if (expr->vm_type == J_INT) {
                state->reg1 = get_var(s->b_parent, J_INT);
 
                select_insn(s, tree, reg_reg_insn(INSN_CONV_FPU_TO_GPR, 
state->left->reg1, state->reg1));
-       } else if (src->vm_type == J_DOUBLE && expr->vm_type == J_INT) {
+       } else {
+               die("EXPR_CONVERSION_FROM_FLOAT: no conversion from %d to %d", 
src->vm_type, expr->vm_type);
+       }
+}
+
+reg:   EXPR_CONVERSION_FROM_DOUBLE(freg)
+{
+       struct expression *expr, *src;
+
+       expr = to_expr(tree);
+       src = to_expr(expr->from_expression);
+
+       assert(src->vm_type == J_DOUBLE);
+
+       if (expr->vm_type == J_INT) {
                state->reg1 = get_var(s->b_parent, J_INT);
 
                select_insn(s, tree, reg_reg_insn(INSN_CONV_FPU64_TO_GPR, 
state->left->reg1, state->reg1));
        } else {
-               die("EXPR_CONVERSION_FROM_FLOAT: no conversion from %d to %d", 
src->vm_type, expr->vm_type);
+               die("EXPR_CONVERSION_FROM_DOUBLE: no conversion from %d to %d", 
src->vm_type, expr->vm_type);
        }
 }
 
diff --git a/arch/x86/lir-printer.c b/arch/x86/lir-printer.c
index 27f67fa..c0a3600 100644
--- a/arch/x86/lir-printer.c
+++ b/arch/x86/lir-printer.c
@@ -432,6 +432,18 @@ static int print_conv_gpr_to_fpu64(struct string *str, 
struct insn *insn)
        return print_reg_reg(str, insn);
 }
 
+static int print_conv_xmm_to_xmm64(struct string *str, struct insn *insn)
+{
+       print_func_name(str);
+       return print_reg_reg(str, insn);
+}
+
+static int print_conv_xmm64_to_xmm(struct string *str, struct insn *insn)
+{
+       print_func_name(str);
+       return print_reg_reg(str, insn);
+}
+
 static int print_je_branch(struct string *str, struct insn *insn)
 {
        print_func_name(str);
@@ -887,6 +899,8 @@ static print_insn_fn insn_printers[] = {
        [INSN_CONV_FPU64_TO_GPR] = print_conv_fpu64_to_gpr,
        [INSN_CONV_GPR_TO_FPU] = print_conv_gpr_to_fpu,
        [INSN_CONV_GPR_TO_FPU64] = print_conv_gpr_to_fpu64,
+       [INSN_CONV_XMM_TO_XMM64] = print_conv_xmm_to_xmm64,
+       [INSN_CONV_XMM64_TO_XMM] = print_conv_xmm64_to_xmm,
        [INSN_JE_BRANCH] = print_je_branch,
        [INSN_JGE_BRANCH] = print_jge_branch,
        [INSN_JG_BRANCH] = print_jg_branch,
diff --git a/arch/x86/use-def.c b/arch/x86/use-def.c
index 65f6a7a..643b073 100644
--- a/arch/x86/use-def.c
+++ b/arch/x86/use-def.c
@@ -73,6 +73,8 @@ static struct insn_info insn_infos[] = {
        DECLARE_INFO(INSN_CONV_GPR_TO_FPU64, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_CONV_FPU_TO_GPR, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_CONV_FPU64_TO_GPR, USE_SRC | DEF_DST),
+       DECLARE_INFO(INSN_CONV_XMM_TO_XMM64, USE_SRC | DEF_DST),
+       DECLARE_INFO(INSN_CONV_XMM64_TO_XMM, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_MOV_MEMBASE_XMM, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_MOV_64_MEMBASE_XMM, USE_SRC | DEF_DST),
        DECLARE_INFO(INSN_MOV_XMM_MEMBASE, USE_SRC | USE_DST),
diff --git a/include/jit/expression.h b/include/jit/expression.h
index 70a459b..e97a7c8 100644
--- a/include/jit/expression.h
+++ b/include/jit/expression.h
@@ -27,8 +27,12 @@ enum expression_type {
        EXPR_BINOP,
        EXPR_UNARY_OP,
        EXPR_CONVERSION,
+       EXPR_CONVERSION_FLOAT_TO_DOUBLE,
+       EXPR_CONVERSION_DOUBLE_TO_FLOAT,
        EXPR_CONVERSION_FROM_FLOAT,
        EXPR_CONVERSION_TO_FLOAT,
+       EXPR_CONVERSION_FROM_DOUBLE,
+       EXPR_CONVERSION_TO_DOUBLE,
        EXPR_CLASS_FIELD,
        EXPR_INSTANCE_FIELD,
        EXPR_INVOKE,
@@ -323,8 +327,13 @@ struct expression *array_deref_expr(enum vm_type, struct 
expression *, struct ex
 struct expression *binop_expr(enum vm_type, enum binary_operator, struct 
expression *, struct expression *);
 struct expression *unary_op_expr(enum vm_type, enum unary_operator, struct 
expression *);
 struct expression *conversion_expr(enum vm_type, struct expression *);
+struct expression *conversion_double_to_float_expr(struct expression *);
+struct expression *conversion_float_to_double_expr(struct expression *);
 struct expression *conversion_from_float_expr(enum vm_type, struct expression 
*);
 struct expression *conversion_to_float_expr(enum vm_type, struct expression *);
+struct expression *conversion_from_double_expr(enum vm_type, struct expression 
*);
+struct expression *conversion_to_double_expr(enum vm_type, struct expression 
*);
+
 struct expression *class_field_expr(enum vm_type, struct vm_field *);
 struct expression *instance_field_expr(enum vm_type, struct vm_field *, struct 
expression *);
 struct expression *invoke_expr(struct vm_method *);
diff --git a/jit/expression.c b/jit/expression.c
index 302316f..a2ddd97 100644
--- a/jit/expression.c
+++ b/jit/expression.c
@@ -42,8 +42,12 @@ int expr_nr_kids(struct expression *expr)
                return 2;
        case EXPR_UNARY_OP:
        case EXPR_CONVERSION:
+       case EXPR_CONVERSION_FLOAT_TO_DOUBLE:
+       case EXPR_CONVERSION_DOUBLE_TO_FLOAT:
        case EXPR_CONVERSION_TO_FLOAT:
        case EXPR_CONVERSION_FROM_FLOAT:
+       case EXPR_CONVERSION_TO_DOUBLE:
+       case EXPR_CONVERSION_FROM_DOUBLE:
        case EXPR_INSTANCE_FIELD:
        case EXPR_FLOAT_INSTANCE_FIELD:
        case EXPR_INVOKE:
@@ -99,8 +103,12 @@ int expr_is_pure(struct expression *expr)
        case EXPR_ARGS_LIST:
        case EXPR_UNARY_OP:
        case EXPR_CONVERSION:
+       case EXPR_CONVERSION_FLOAT_TO_DOUBLE:
+       case EXPR_CONVERSION_DOUBLE_TO_FLOAT:
        case EXPR_CONVERSION_TO_FLOAT:
        case EXPR_CONVERSION_FROM_FLOAT:
+       case EXPR_CONVERSION_TO_DOUBLE:
+       case EXPR_CONVERSION_FROM_DOUBLE:
        case EXPR_ARG:
        case EXPR_ARG_THIS:
        case EXPR_ARRAYLENGTH:
@@ -310,6 +318,28 @@ struct expression *conversion_expr(enum vm_type vm_type,
        return expr;
 }
 
+struct expression *
+conversion_double_to_float_expr(struct expression *from_expression)
+{
+       struct expression *expr;
+
+       expr = alloc_expression(EXPR_CONVERSION_DOUBLE_TO_FLOAT, J_FLOAT);
+       if (expr)
+               expr->from_expression = &from_expression->node;
+       return expr;
+}
+
+struct expression *
+conversion_float_to_double_expr(struct expression *from_expression)
+{
+       struct expression *expr;
+
+       expr = alloc_expression(EXPR_CONVERSION_FLOAT_TO_DOUBLE, J_DOUBLE);
+       if (expr)
+               expr->from_expression = &from_expression->node;
+       return expr;
+}
+
 struct expression *conversion_to_float_expr(enum vm_type vm_type,
                                   struct expression *from_expression)
 {
@@ -328,6 +358,25 @@ struct expression *conversion_from_float_expr(enum vm_type 
vm_type,
        return expr;
 }
 
+struct expression *conversion_to_double_expr(enum vm_type vm_type,
+                                            struct expression *from_expression)
+{
+       struct expression *expr = alloc_expression(EXPR_CONVERSION_TO_DOUBLE, 
vm_type);
+       if (expr)
+               expr->from_expression = &from_expression->node;
+       return expr;
+}
+
+struct expression *conversion_from_double_expr(enum vm_type vm_type,
+                                       struct expression *from_expression)
+{
+       struct expression *expr = alloc_expression(EXPR_CONVERSION_FROM_DOUBLE,
+                                                  vm_type);
+       if (expr)
+               expr->from_expression = &from_expression->node;
+       return expr;
+}
+
 struct expression *class_field_expr(enum vm_type vm_type, struct vm_field 
*class_field)
 {
        struct expression *expr;
diff --git a/jit/tree-printer.c b/jit/tree-printer.c
index 8b1b0fe..e9ede43 100644
--- a/jit/tree-printer.c
+++ b/jit/tree-printer.c
@@ -1014,8 +1014,12 @@ static print_expr_fn expr_printers[] = {
        [EXPR_BINOP] = print_binop_expr,
        [EXPR_UNARY_OP] = print_unary_op_expr,
        [EXPR_CONVERSION] = print_conversion_expr,
+       [EXPR_CONVERSION_FLOAT_TO_DOUBLE] = print_conversion_expr,
+       [EXPR_CONVERSION_DOUBLE_TO_FLOAT] = print_conversion_expr,
        [EXPR_CONVERSION_FROM_FLOAT] = print_conversion_expr,
        [EXPR_CONVERSION_TO_FLOAT] = print_conversion_expr,
+       [EXPR_CONVERSION_FROM_DOUBLE] = print_conversion_expr,
+       [EXPR_CONVERSION_TO_DOUBLE] = print_conversion_expr,
        [EXPR_CLASS_FIELD] = print_class_field_expr,
        [EXPR_FLOAT_CLASS_FIELD] = print_float_class_field_expr,
        [EXPR_INSTANCE_FIELD] = print_instance_field_expr,
diff --git a/jit/typeconv-bc.c b/jit/typeconv-bc.c
index ca3300f..3a3b0e7 100644
--- a/jit/typeconv-bc.c
+++ b/jit/typeconv-bc.c
@@ -21,13 +21,23 @@
 static int convert_conversion(struct parse_context *ctx, enum vm_type to_type)
 {
        struct expression *from_expression, *conversion_expression;
+       enum vm_type from_type;
 
        from_expression = stack_pop(ctx->bb->mimic_stack);
+       from_type = from_expression->vm_type;
 
-       if (vm_type_is_float(to_type))
+       if (from_type == J_DOUBLE && to_type == J_FLOAT)
+               conversion_expression = 
conversion_double_to_float_expr(from_expression);
+       else if (from_type == J_FLOAT && to_type == J_DOUBLE)
+               conversion_expression = 
conversion_float_to_double_expr(from_expression);
+       else if (to_type == J_FLOAT)
                conversion_expression = conversion_to_float_expr(to_type, 
from_expression);
-       else if (vm_type_is_float(from_expression->vm_type))
+       else if (from_type == J_FLOAT)
                conversion_expression = conversion_from_float_expr(to_type, 
from_expression);
+       else if (to_type == J_DOUBLE)
+               conversion_expression = conversion_to_double_expr(to_type, 
from_expression);
+       else if (from_type == J_DOUBLE)
+               conversion_expression = conversion_from_double_expr(to_type, 
from_expression);
        else
                conversion_expression = conversion_expr(to_type, 
from_expression);
 
diff --git a/test/jit/typeconv-bc-test.c b/test/jit/typeconv-bc-test.c
index f409f4d..77bac3a 100644
--- a/test/jit/typeconv-bc-test.c
+++ b/test/jit/typeconv-bc-test.c
@@ -42,28 +42,28 @@ void test_convert_int_widening(void)
 {
        assert_conversion_mimic_stack(OPC_I2L, EXPR_CONVERSION, J_INT, J_LONG);
        assert_conversion_mimic_stack(OPC_I2F, EXPR_CONVERSION_TO_FLOAT, J_INT, 
J_FLOAT);
-       assert_conversion_mimic_stack(OPC_I2D, EXPR_CONVERSION, J_INT, 
J_DOUBLE);
+       assert_conversion_mimic_stack(OPC_I2D, EXPR_CONVERSION_TO_DOUBLE, 
J_INT, J_DOUBLE);
 }
 
 void test_convert_long_conversion(void)
 {
        assert_conversion_mimic_stack(OPC_L2I, EXPR_CONVERSION, J_LONG, J_INT);
        assert_conversion_mimic_stack(OPC_L2F, EXPR_CONVERSION_TO_FLOAT, 
J_LONG, J_FLOAT);
-       assert_conversion_mimic_stack(OPC_L2D, EXPR_CONVERSION, J_LONG, 
J_DOUBLE);
+       assert_conversion_mimic_stack(OPC_L2D, EXPR_CONVERSION_TO_DOUBLE, 
J_LONG, J_DOUBLE);
 }
 
 void test_convert_float_conversion(void)
 {
        assert_conversion_mimic_stack(OPC_F2I, EXPR_CONVERSION_FROM_FLOAT, 
J_FLOAT, J_INT);
        assert_conversion_mimic_stack(OPC_F2L, EXPR_CONVERSION_FROM_FLOAT, 
J_FLOAT, J_LONG);
-       assert_conversion_mimic_stack(OPC_F2D, EXPR_CONVERSION_FROM_FLOAT, 
J_FLOAT, J_DOUBLE);
+       assert_conversion_mimic_stack(OPC_F2D, EXPR_CONVERSION_FLOAT_TO_DOUBLE, 
J_FLOAT, J_DOUBLE);
 }
 
 void test_convert_double_conversion(void)
 {
-       assert_conversion_mimic_stack(OPC_D2I, EXPR_CONVERSION, J_DOUBLE, 
J_INT);
-       assert_conversion_mimic_stack(OPC_D2L, EXPR_CONVERSION, J_DOUBLE, 
J_LONG);
-       assert_conversion_mimic_stack(OPC_D2F, EXPR_CONVERSION_TO_FLOAT, 
J_DOUBLE, J_FLOAT);
+       assert_conversion_mimic_stack(OPC_D2I, EXPR_CONVERSION_FROM_DOUBLE, 
J_DOUBLE, J_INT);
+       assert_conversion_mimic_stack(OPC_D2L, EXPR_CONVERSION_FROM_DOUBLE, 
J_DOUBLE, J_LONG);
+       assert_conversion_mimic_stack(OPC_D2F, EXPR_CONVERSION_DOUBLE_TO_FLOAT, 
J_DOUBLE, J_FLOAT);
 }
 
 void test_convert_int_narrowing(void)
-- 
1.6.0.6


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to