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