- /* Store arg */
- frame = get_irg_frame(irg);
-
- /*
- Now we create a node to move the value from a XMM register into
- x87 FPU because it is unknown here, which FPU is used.
- This node is killed in transformation phase when not needed.
- Otherwise it is split up into a movsd + fld
- */
- a_f = new_rd_ia32_l_SSEtoX87(dbg, irg, block, frame, a_f, get_irg_no_mem(irg), mode_D);
- set_ia32_frame_ent(a_f, ent);
- set_ia32_use_frame(a_f);
- set_ia32_ls_mode(a_f, mode_D);
-
- /* store from FPU as Int */
- a_f = new_rd_ia32_l_vfist(dbg, irg, block, frame, a_f, get_irg_no_mem(irg));
- set_ia32_frame_ent(a_f, ent);
- set_ia32_use_frame(a_f);
- set_ia32_ls_mode(a_f, mode_Ls);
- mem = a_f;
-
- /* load low part of the result */
- l_res = new_rd_ia32_l_Load(dbg, irg, block, frame, mem);
- set_ia32_frame_ent(l_res, ent);
- set_ia32_use_frame(l_res);
- set_ia32_ls_mode(l_res, l_res_mode);
- l_res = new_r_Proj(irg, block, l_res, l_res_mode, pn_ia32_l_Load_res);
-
- /* load hight part of the result */
- h_res = new_rd_ia32_l_Load(dbg, irg, block, frame, mem);
- set_ia32_frame_ent(h_res, ent);
- add_ia32_am_offs_int(h_res, gp_bytes);
- set_ia32_use_frame(h_res);
- set_ia32_ls_mode(h_res, h_res_mode);
- h_res = new_r_Proj(irg, block, h_res, h_res_mode, pn_ia32_l_Load_res);
+ l_res = new_r_Proj(irg, block, float_to_ll, l_res_mode,
+ pn_ia32_l_FloattoLL_res_low);
+ h_res = new_r_Proj(irg, block, float_to_ll, h_res_mode,
+ pn_ia32_l_FloattoLL_res_high);
+ } else {
+ /* convert from float to signed 64bit */
+ ir_mode *flt_mode = get_irn_mode(a_f);
+ tarval *flt_tv = new_tarval_from_str("9223372036854775808", 19, flt_mode);
+ ir_node *flt_corr = new_Const(flt_mode, flt_tv);
+ ir_node *lower_blk = block;
+ ir_node *upper_blk;
+ ir_node *cmp, *proj, *cond, *blk, *int_phi, *flt_phi;
+ ir_node *in[2];
+
+ part_block(call);
+ upper_blk = get_nodes_block(call);
+
+ cmp = new_rd_Cmp(dbg, irg, upper_blk, a_f, flt_corr);
+ proj = new_r_Proj(irg, upper_blk, cmp, mode_b, pn_Cmp_Lt);
+ cond = new_rd_Cond(dbg, irg, upper_blk, proj);
+ in[0] = new_r_Proj(irg, upper_blk, cond, mode_X, pn_Cond_true);
+ in[1] = new_r_Proj(irg, upper_blk, cond, mode_X, pn_Cond_false);
+ blk = new_r_Block(irg, 1, &in[1]);
+ in[1] = new_r_Jmp(irg, blk);
+
+ set_irn_in(lower_blk, 2, in);
+
+ /* create to Phis */
+ in[0] = new_Const(h_res_mode, get_mode_null(h_res_mode));
+ in[1] = new_Const_long(h_res_mode, 0x80000000);
+
+ int_phi = new_r_Phi(irg, lower_blk, 2, in, h_res_mode);
+
+ in[0] = a_f;
+ in[1] = new_rd_Sub(dbg, irg, upper_blk, a_f, flt_corr, flt_mode);
+
+ flt_phi = new_r_Phi(irg, lower_blk, 2, in, flt_mode);
+
+ /* fix Phi links for next part_block() */
+ set_Block_phis(lower_blk, int_phi);
+ set_Phi_next(int_phi, flt_phi);
+ set_Phi_next(flt_phi, NULL);
+
+ float_to_ll = new_bd_ia32_l_FloattoLL(dbg, lower_blk, flt_phi);