Hello! 2012-06-20 Uros Bizjak <ubiz...@gmail.com>
* config/i386/i386.md (<rounding_insn><mode>2): Macroize expander from {floor,ceil,btrunc}<mode>2 using FIST_ROUNDING int iterator. (l<rounding_insn><MODEF:mode><SWI48:mode>2): Macroize expander from l{floor,ceil}<MODEF:mode><SWI48:mode>2 using FIST_ROUNDING int iterator. Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN. Uros.
Index: i386.md =================================================================== --- i386.md (revision 188837) +++ i386.md (working copy) @@ -15178,9 +15178,11 @@ && flag_unsafe_math_optimizations && !optimize_insn_for_size_p ()") -(define_expand "floor<mode>2" - [(use (match_operand:MODEF 0 "register_operand")) - (use (match_operand:MODEF 1 "register_operand"))] +(define_expand "<rounding_insn><mode>2" + [(parallel [(set (match_operand:MODEF 0 "register_operand") + (unspec:MODEF [(match_operand:MODEF 1 "register_operand")] + FRNDINT_ROUNDING)) + (clobber (reg:CC FLAGS_REG))])] "(TARGET_USE_FANCY_MATH_387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) @@ -15193,53 +15195,31 @@ { if (TARGET_ROUND) emit_insn (gen_sse4_1_round<mode>2 - (operands[0], operands[1], GEN_INT (ROUND_FLOOR))); + (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>))); else if (optimize_insn_for_size_p ()) - FAIL; - else if (TARGET_64BIT || (<MODE>mode != DFmode)) - ix86_expand_floorceil (operands[0], operands[1], true); - else - ix86_expand_floorceildf_32 (operands[0], operands[1], true); - } - else - { - rtx op0, op1; - - if (optimize_insn_for_size_p ()) FAIL; - - op0 = gen_reg_rtx (XFmode); - op1 = gen_reg_rtx (XFmode); - emit_insn (gen_extend<mode>xf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_floor (op0, op1)); - - emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); - } - DONE; -}) - -(define_expand "ceil<mode>2" - [(use (match_operand:MODEF 0 "register_operand")) - (use (match_operand:MODEF 1 "register_operand"))] - "(TARGET_USE_FANCY_MATH_387 - && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) - || TARGET_MIX_SSE_I387) - && flag_unsafe_math_optimizations) - || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH - && !flag_trapping_math)" -{ - if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH - && !flag_trapping_math) - { - if (TARGET_ROUND) - emit_insn (gen_sse4_1_round<mode>2 - (operands[0], operands[1], GEN_INT (ROUND_CEIL))); - else if (optimize_insn_for_size_p ()) - FAIL; else if (TARGET_64BIT || (<MODE>mode != DFmode)) - ix86_expand_floorceil (operands[0], operands[1], false); + { + if (ROUND_<ROUNDING> == ROUND_FLOOR) + ix86_expand_floorceil (operands[0], operands[1], true); + else if (ROUND_<ROUNDING> == ROUND_CEIL) + ix86_expand_floorceil (operands[0], operands[1], false); + else if (ROUND_<ROUNDING> == ROUND_TRUNC) + ix86_expand_trunc (operands[0], operands[1]); + else + gcc_unreachable (); + } else - ix86_expand_floorceildf_32 (operands[0], operands[1], false); + { + if (ROUND_<ROUNDING> == ROUND_FLOOR) + ix86_expand_floorceildf_32 (operands[0], operands[1], true); + else if (ROUND_<ROUNDING> == ROUND_CEIL) + ix86_expand_floorceildf_32 (operands[0], operands[1], false); + else if (ROUND_<ROUNDING> == ROUND_TRUNC) + ix86_expand_truncdf_32 (operands[0], operands[1]); + else + gcc_unreachable (); + } } else { @@ -15251,53 +15231,13 @@ op0 = gen_reg_rtx (XFmode); op1 = gen_reg_rtx (XFmode); emit_insn (gen_extend<mode>xf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_ceil (op0, op1)); + emit_insn (gen_frndintxf2_<rounding> (op0, op1)); emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); } DONE; }) -(define_expand "btrunc<mode>2" - [(use (match_operand:MODEF 0 "register_operand")) - (use (match_operand:MODEF 1 "register_operand"))] - "(TARGET_USE_FANCY_MATH_387 - && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH) - || TARGET_MIX_SSE_I387) - && flag_unsafe_math_optimizations) - || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH - && !flag_trapping_math)" -{ - if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH - && !flag_trapping_math) - { - if (TARGET_ROUND) - emit_insn (gen_sse4_1_round<mode>2 - (operands[0], operands[1], GEN_INT (ROUND_TRUNC))); - else if (optimize_insn_for_size_p ()) - FAIL; - else if (TARGET_64BIT || (<MODE>mode != DFmode)) - ix86_expand_trunc (operands[0], operands[1]); - else - ix86_expand_truncdf_32 (operands[0], operands[1]); - } - else - { - rtx op0, op1; - - if (optimize_insn_for_size_p ()) - FAIL; - - op0 = gen_reg_rtx (XFmode); - op1 = gen_reg_rtx (XFmode); - emit_insn (gen_extend<mode>xf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_trunc (op0, op1)); - - emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); - } - DONE; -}) - ;; Rounding mode control word calculation could clobber FLAGS_REG. (define_insn_and_split "frndintxf2_mask_pm" [(set (match_operand:XF 0 "register_operand") @@ -15519,25 +15459,24 @@ && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) && flag_unsafe_math_optimizations") -(define_expand "lfloor<MODEF:mode><SWI48:mode>2" - [(match_operand:SWI48 0 "nonimmediate_operand") - (match_operand:MODEF 1 "register_operand")] +(define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2" + [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand") + (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")] + FIST_ROUNDING)) + (clobber (reg:CC FLAGS_REG))])] "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH && !flag_trapping_math" { if (TARGET_64BIT && optimize_insn_for_size_p ()) FAIL; - ix86_expand_lfloorceil (operands[0], operands[1], true); - DONE; -}) -(define_expand "lceil<MODEF:mode><SWI48:mode>2" - [(match_operand:SWI48 0 "nonimmediate_operand") - (match_operand:MODEF 1 "register_operand")] - "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH - && !flag_trapping_math" -{ - ix86_expand_lfloorceil (operands[0], operands[1], false); + if (ROUND_<ROUNDING> == ROUND_FLOOR) + ix86_expand_lfloorceil (operands[0], operands[1], true); + else if (ROUND_<ROUNDING> == ROUND_CEIL) + ix86_expand_lfloorceil (operands[0], operands[1], false); + else + gcc_unreachable (); + DONE; })