Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/insn-selector.brg |   27 +++++++++++++++++++++------
 1 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/arch/x86/insn-selector.brg b/arch/x86/insn-selector.brg
index 41ab693..297ef7f 100644
--- a/arch/x86/insn-selector.brg
+++ b/arch/x86/insn-selector.brg
@@ -50,9 +50,9 @@
 #define MONOBURG_LOG 1
 #define HAVE_ARRAY_ELEM_INIT 1
 
-/* GCC magic for long long to double conversion.  See below for more...  */
-static unsigned long long xmm_double_magic_0 = 0x41f0000000000000;
-static unsigned long long xmm_double_magic_1 = 0x41e0000000000000;
+/* Constants used in l2d and d2l conversions. */
+static double xmm_double_constant_0 = 0x100000000;
+static double xmm_double_constant_1 =  0x80000000;
 
 static void select_insn(struct basic_block *bb, struct tree_node *tree,
                        struct insn *instruction);
@@ -1514,13 +1514,28 @@ freg:   EXPR_CONVERSION_TO_DOUBLE(reg)
                ftmp = get_var(s->b_parent, J_DOUBLE);
                tmp  = get_var(s->b_parent, J_INT);
 
-               /* GCC produces this fragment, don't ask! */
                select_insn(s, tree, reg_reg_insn(INSN_MOV_REG_REG, 
state->left->reg1, tmp));
+
+               /*
+                * We need to subtract 0x80000000 from lower 32-bits
+                * because conversion works on signed integers and we
+                * don't want lower part to be converted as negative
+                * number.
+                */
                select_insn(s, tree, imm_reg_insn(INSN_SUB_IMM_REG, 0x80000000, 
tmp));
+
                select_insn(s, tree, reg_reg_insn(INSN_CONV_GPR_TO_FPU64, 
state->left->reg2, state->reg1));
                select_insn(s, tree, reg_reg_insn(INSN_CONV_GPR_TO_FPU64, tmp, 
ftmp));
-               select_insn(s, tree, memdisp_reg_insn(INSN_FMUL_64_MEMDISP_REG, 
(unsigned long) &xmm_double_magic_0, state->reg1));
-               select_insn(s, tree, memdisp_reg_insn(INSN_FADD_64_MEMDISP_REG, 
(unsigned long) &xmm_double_magic_1, ftmp));
+
+               /* Multiply higher word value by pow(2, 32) */
+               select_insn(s, tree, memdisp_reg_insn(INSN_FMUL_64_MEMDISP_REG, 
(unsigned long) &xmm_double_constant_0, state->reg1));
+
+               /*
+                * Add 0x80000000 to the lower word value to fix the
+                * correction introduced at the beggining.
+                */
+               select_insn(s, tree, memdisp_reg_insn(INSN_FADD_64_MEMDISP_REG, 
(unsigned long) &xmm_double_constant_1, ftmp));
+
                select_insn(s, tree, reg_reg_insn(INSN_FADD_64_REG_REG, ftmp, 
state->reg1));
        } else {
                die("EXPR_CONVERSION_TO_DOUBLE: no conversion from %d to %d", 
src->vm_type, expr->vm_type);
-- 
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