ix86_expand_truncdf_32 (rtx operand0, rtx operand1)
{
machine_mode mode = GET_MODE (operand0);
- rtx xa, mask, TWO52, one, res, smask, tmp;
+ rtx xa, xa2, TWO52, tmp, one, res, mask;
rtx_code_label *label;
/* C code for SSE variant we expand below.
emit_move_insn (res, operand1);
/* xa = abs (operand1) */
- xa = ix86_expand_sse_fabs (res, &smask);
+ xa = ix86_expand_sse_fabs (res, &mask);
/* if (!isless (xa, TWO52)) goto label; */
label = ix86_expand_sse_compare_and_jump (UNLE, TWO52, xa, false);
- /* res = xa + TWO52 - TWO52; */
- tmp = expand_simple_binop (mode, PLUS, xa, TWO52, NULL_RTX, 0, OPTAB_DIRECT);
- tmp = expand_simple_binop (mode, MINUS, tmp, TWO52, tmp, 0, OPTAB_DIRECT);
- emit_move_insn (res, tmp);
+ /* xa2 = xa + TWO52 - TWO52; */
+ xa2 = expand_simple_binop (mode, PLUS, xa, TWO52, NULL_RTX, 0, OPTAB_DIRECT);
+ xa2 = expand_simple_binop (mode, MINUS, xa2, TWO52, xa2, 0, OPTAB_DIRECT);
/* generate 1.0 */
one = force_reg (mode, const_double_from_real_value (dconst1, mode));
- /* Compensate: res = xa2 - (res > xa ? 1 : 0) */
- mask = ix86_expand_sse_compare_mask (UNGT, res, xa, false);
- emit_insn (gen_rtx_SET (mask, gen_rtx_AND (mode, mask, one)));
+ /* Compensate: xa2 = xa2 - (xa2 > xa ? 1 : 0) */
+ tmp = ix86_expand_sse_compare_mask (UNGT, xa2, xa, false);
+ emit_insn (gen_rtx_SET (tmp, gen_rtx_AND (mode, one, tmp)));
tmp = expand_simple_binop (mode, MINUS,
- res, mask, NULL_RTX, 0, OPTAB_DIRECT);
- emit_move_insn (res, tmp);
+ xa2, tmp, NULL_RTX, 0, OPTAB_DIRECT);
+ /* Remove the sign with FE_DOWNWARD, where x - x = -0.0. */
+ if (flag_rounding_math)
+ tmp = ix86_expand_sse_fabs (tmp, NULL);
- /* res = copysign (res, operand1) */
- ix86_sse_copysign_to_positive (res, res, force_reg (mode, operand1), smask);
+ /* res = copysign (xa2, operand1) */
+ ix86_sse_copysign_to_positive (res, tmp, res, mask);
emit_label (label);
LABEL_NUSES (label) = 1;