Signed-off-by: Tomek Grabiec <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel