Hello! 2012-06-19 Uros Bizjak <ubiz...@gmail.com>
* config/i386/i386.md (FIST_ROUNDING): New int iterator. (rounding): Handle UNSPEC_FIST_{FLOOR,CEIL}. (ROUNDING): Ditto. (*fist<mode>2_<rounding>_1): Macroize insn from *fist<mode>2_{floor,ceil}_1 using FIST_ROUNDING int iterator. (fistdi2_<rounding>): Macroize insn from fistdi2_{floor,ceil} using FIST_ROUNDING int iterator. (fistdi2_<rounding>_with_temp and splitters): Macroize insn and corresponding splitters from fistdi2_{floor,ceil} and corresponding splitters using FIST_ROUNDING int iterator. (fist<mode>2_<rounding>): Macroize insn from fist<mode>2_{floor,ceil} using FIST_ROUNDING int iterator. (fist<mode>2_<rounding>_with_temp and splitters): Macroize insn and corresponding splitters from fist<mode>2_{floor,ceil} and corresponding splitters using FIST_ROUNDING int iterator. (l<rounding>xf<mode>2): Macroize expander from l{floor,ceil}xf<mode>2 using FIST_ROUNDING int iterator. Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}, committed to mainline SVN. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 188783) +++ config/i386/i386.md (working copy) @@ -15104,15 +15104,23 @@ UNSPEC_FRNDINT_CEIL UNSPEC_FRNDINT_TRUNC]) +(define_int_iterator FIST_ROUNDING + [UNSPEC_FIST_FLOOR + UNSPEC_FIST_CEIL]) + (define_int_attr rounding [(UNSPEC_FRNDINT_FLOOR "floor") (UNSPEC_FRNDINT_CEIL "ceil") - (UNSPEC_FRNDINT_TRUNC "trunc")]) + (UNSPEC_FRNDINT_TRUNC "trunc") + (UNSPEC_FIST_FLOOR "floor") + (UNSPEC_FIST_CEIL "ceil")]) (define_int_attr ROUNDING [(UNSPEC_FRNDINT_FLOOR "FLOOR") (UNSPEC_FRNDINT_CEIL "CEIL") - (UNSPEC_FRNDINT_TRUNC "TRUNC")]) + (UNSPEC_FRNDINT_TRUNC "TRUNC") + (UNSPEC_FIST_FLOOR "FLOOR") + (UNSPEC_FIST_CEIL "CEIL")]) ;; Rounding mode control word calculation could clobber FLAGS_REG. (define_insn_and_split "frndintxf2_<rounding>" @@ -15205,174 +15213,59 @@ DONE; }) -(define_insn_and_split "*fist<mode>2_floor_1" - [(set (match_operand:SWI248x 0 "nonimmediate_operand") - (unspec:SWI248x [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_FLOOR)) - (clobber (reg:CC FLAGS_REG))] +(define_expand "ceilxf2" + [(use (match_operand:XF 0 "register_operand")) + (use (match_operand:XF 1 "register_operand"))] "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations - && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] + && flag_unsafe_math_optimizations" { - ix86_optimize_mode_switching[I387_FLOOR] = 1; + if (optimize_insn_for_size_p ()) + FAIL; + emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); + DONE; +}) - operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); - operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR); - if (memory_operand (operands[0], VOIDmode)) - emit_insn (gen_fist<mode>2_floor (operands[0], operands[1], - operands[2], operands[3])); +(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); + else + ix86_expand_floorceildf_32 (operands[0], operands[1], false); + } else { - operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); - emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1], - operands[2], operands[3], - operands[4])); - } - DONE; -} - [(set_attr "type" "fistp") - (set_attr "i387_cw" "floor") - (set_attr "mode" "<MODE>")]) + rtx op0, op1; -(define_insn "fistdi2_floor" - [(set (match_operand:DI 0 "memory_operand" "=m") - (unspec:DI [(match_operand:XF 1 "register_operand" "f")] - UNSPEC_FIST_FLOOR)) - (use (match_operand:HI 2 "memory_operand" "m")) - (use (match_operand:HI 3 "memory_operand" "m")) - (clobber (match_scratch:XF 4 "=&1f"))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" - "* return output_fix_trunc (insn, operands, false);" - [(set_attr "type" "fistp") - (set_attr "i387_cw" "floor") - (set_attr "mode" "DI")]) + if (optimize_insn_for_size_p ()) + FAIL; -(define_insn "fistdi2_floor_with_temp" - [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") - (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] - UNSPEC_FIST_FLOOR)) - (use (match_operand:HI 2 "memory_operand" "m,m")) - (use (match_operand:HI 3 "memory_operand" "m,m")) - (clobber (match_operand:DI 4 "memory_operand" "=X,m")) - (clobber (match_scratch:XF 5 "=&1f,&1f"))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" - "#" - [(set_attr "type" "fistp") - (set_attr "i387_cw" "floor") - (set_attr "mode" "DI")]) + 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)); -(define_split - [(set (match_operand:DI 0 "register_operand") - (unspec:DI [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_FLOOR)) - (use (match_operand:HI 2 "memory_operand")) - (use (match_operand:HI 3 "memory_operand")) - (clobber (match_operand:DI 4 "memory_operand")) - (clobber (match_scratch 5))] - "reload_completed" - [(parallel [(set (match_dup 4) - (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) - (use (match_dup 2)) - (use (match_dup 3)) - (clobber (match_dup 5))]) - (set (match_dup 0) (match_dup 4))]) - -(define_split - [(set (match_operand:DI 0 "memory_operand") - (unspec:DI [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_FLOOR)) - (use (match_operand:HI 2 "memory_operand")) - (use (match_operand:HI 3 "memory_operand")) - (clobber (match_operand:DI 4 "memory_operand")) - (clobber (match_scratch 5))] - "reload_completed" - [(parallel [(set (match_dup 0) - (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR)) - (use (match_dup 2)) - (use (match_dup 3)) - (clobber (match_dup 5))])]) - -(define_insn "fist<mode>2_floor" - [(set (match_operand:SWI24 0 "memory_operand" "=m") - (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] - UNSPEC_FIST_FLOOR)) - (use (match_operand:HI 2 "memory_operand" "m")) - (use (match_operand:HI 3 "memory_operand" "m"))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" - "* return output_fix_trunc (insn, operands, false);" - [(set_attr "type" "fistp") - (set_attr "i387_cw" "floor") - (set_attr "mode" "<MODE>")]) - -(define_insn "fist<mode>2_floor_with_temp" - [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") - (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] - UNSPEC_FIST_FLOOR)) - (use (match_operand:HI 2 "memory_operand" "m,m")) - (use (match_operand:HI 3 "memory_operand" "m,m")) - (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" - "#" - [(set_attr "type" "fistp") - (set_attr "i387_cw" "floor") - (set_attr "mode" "<MODE>")]) - -(define_split - [(set (match_operand:SWI24 0 "register_operand") - (unspec:SWI24 [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_FLOOR)) - (use (match_operand:HI 2 "memory_operand")) - (use (match_operand:HI 3 "memory_operand")) - (clobber (match_operand:SWI24 4 "memory_operand"))] - "reload_completed" - [(parallel [(set (match_dup 4) - (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR)) - (use (match_dup 2)) - (use (match_dup 3))]) - (set (match_dup 0) (match_dup 4))]) - -(define_split - [(set (match_operand:SWI24 0 "memory_operand") - (unspec:SWI24 [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_FLOOR)) - (use (match_operand:HI 2 "memory_operand")) - (use (match_operand:HI 3 "memory_operand")) - (clobber (match_operand:SWI24 4 "memory_operand"))] - "reload_completed" - [(parallel [(set (match_dup 0) - (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR)) - (use (match_dup 2)) - (use (match_dup 3))])]) - -(define_expand "lfloorxf<mode>2" - [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand") - (unspec:SWI248x [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_FLOOR)) - (clobber (reg:CC FLAGS_REG))])] - "TARGET_USE_FANCY_MATH_387 - && (!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")] - "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); + emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); + } DONE; }) -(define_expand "ceilxf2" +(define_expand "btruncxf2" [(use (match_operand:XF 0 "register_operand")) (use (match_operand:XF 1 "register_operand"))] "TARGET_USE_FANCY_MATH_387 @@ -15380,11 +15273,11 @@ { if (optimize_insn_for_size_p ()) FAIL; - emit_insn (gen_frndintxf2_ceil (operands[0], operands[1])); + emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); DONE; }) -(define_expand "ceil<mode>2" +(define_expand "btrunc<mode>2" [(use (match_operand:MODEF 0 "register_operand")) (use (match_operand:MODEF 1 "register_operand"))] "(TARGET_USE_FANCY_MATH_387 @@ -15399,13 +15292,13 @@ { if (TARGET_ROUND) emit_insn (gen_sse4_1_round<mode>2 - (operands[0], operands[1], GEN_INT (ROUND_CEIL))); + (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_floorceil (operands[0], operands[1], false); + ix86_expand_trunc (operands[0], operands[1]); else - ix86_expand_floorceildf_32 (operands[0], operands[1], false); + ix86_expand_truncdf_32 (operands[0], operands[1]); } else { @@ -15417,17 +15310,85 @@ 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_trunc (op0, op1)); emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); } DONE; }) -(define_insn_and_split "*fist<mode>2_ceil_1" +;; Rounding mode control word calculation could clobber FLAGS_REG. +(define_insn_and_split "frndintxf2_mask_pm" + [(set (match_operand:XF 0 "register_operand") + (unspec:XF [(match_operand:XF 1 "register_operand")] + UNSPEC_FRNDINT_MASK_PM)) + (clobber (reg:CC FLAGS_REG))] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations + && can_create_pseudo_p ()" + "#" + "&& 1" + [(const_int 0)] +{ + ix86_optimize_mode_switching[I387_MASK_PM] = 1; + + operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); + operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); + + emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], + operands[2], operands[3])); + DONE; +} + [(set_attr "type" "frndint") + (set_attr "i387_cw" "mask_pm") + (set_attr "mode" "XF")]) + +(define_insn "frndintxf2_mask_pm_i387" + [(set (match_operand:XF 0 "register_operand" "=f") + (unspec:XF [(match_operand:XF 1 "register_operand" "0")] + UNSPEC_FRNDINT_MASK_PM)) + (use (match_operand:HI 2 "memory_operand" "m")) + (use (match_operand:HI 3 "memory_operand" "m"))] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations" + "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" + [(set_attr "type" "frndint") + (set_attr "i387_cw" "mask_pm") + (set_attr "mode" "XF")]) + +(define_expand "nearbyintxf2" + [(use (match_operand:XF 0 "register_operand")) + (use (match_operand:XF 1 "register_operand"))] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations" +{ + emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); + DONE; +}) + +(define_expand "nearbyint<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" +{ + rtx op0 = gen_reg_rtx (XFmode); + rtx op1 = gen_reg_rtx (XFmode); + + emit_insn (gen_extend<mode>xf2 (op1, operands[1])); + emit_insn (gen_frndintxf2_mask_pm (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 "*fist<mode>2_<rounding>_1" [(set (match_operand:SWI248x 0 "nonimmediate_operand") (unspec:SWI248x [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (clobber (reg:CC FLAGS_REG))] "TARGET_USE_FANCY_MATH_387 && flag_unsafe_math_optimizations @@ -15436,30 +15397,30 @@ "&& 1" [(const_int 0)] { - ix86_optimize_mode_switching[I387_CEIL] = 1; + ix86_optimize_mode_switching[I387_<ROUNDING>] = 1; operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); - operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL); + operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>); if (memory_operand (operands[0], VOIDmode)) - emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1], - operands[2], operands[3])); + emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1], + operands[2], operands[3])); else { operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP); - emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1], - operands[2], operands[3], - operands[4])); + emit_insn (gen_fist<mode>2_<rounding>_with_temp + (operands[0], operands[1], operands[2], + operands[3], operands[4])); } DONE; } [(set_attr "type" "fistp") - (set_attr "i387_cw" "ceil") + (set_attr "i387_cw" "<rounding>") (set_attr "mode" "<MODE>")]) -(define_insn "fistdi2_ceil" +(define_insn "fistdi2_<rounding>" [(set (match_operand:DI 0 "memory_operand" "=m") (unspec:DI [(match_operand:XF 1 "register_operand" "f")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (use (match_operand:HI 2 "memory_operand" "m")) (use (match_operand:HI 3 "memory_operand" "m")) (clobber (match_scratch:XF 4 "=&1f"))] @@ -15467,13 +15428,13 @@ && flag_unsafe_math_optimizations" "* return output_fix_trunc (insn, operands, false);" [(set_attr "type" "fistp") - (set_attr "i387_cw" "ceil") + (set_attr "i387_cw" "<rounding>") (set_attr "mode" "DI")]) -(define_insn "fistdi2_ceil_with_temp" +(define_insn "fistdi2_<rounding>_with_temp" [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r") (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (use (match_operand:HI 2 "memory_operand" "m,m")) (use (match_operand:HI 3 "memory_operand" "m,m")) (clobber (match_operand:DI 4 "memory_operand" "=X,m")) @@ -15482,20 +15443,20 @@ && flag_unsafe_math_optimizations" "#" [(set_attr "type" "fistp") - (set_attr "i387_cw" "ceil") + (set_attr "i387_cw" "<rounding>") (set_attr "mode" "DI")]) (define_split [(set (match_operand:DI 0 "register_operand") (unspec:DI [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (use (match_operand:HI 2 "memory_operand")) (use (match_operand:HI 3 "memory_operand")) (clobber (match_operand:DI 4 "memory_operand")) (clobber (match_scratch 5))] "reload_completed" [(parallel [(set (match_dup 4) - (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) + (unspec:DI [(match_dup 1)] FIST_ROUNDING)) (use (match_dup 2)) (use (match_dup 3)) (clobber (match_dup 5))]) @@ -15504,35 +15465,35 @@ (define_split [(set (match_operand:DI 0 "memory_operand") (unspec:DI [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (use (match_operand:HI 2 "memory_operand")) (use (match_operand:HI 3 "memory_operand")) (clobber (match_operand:DI 4 "memory_operand")) (clobber (match_scratch 5))] "reload_completed" [(parallel [(set (match_dup 0) - (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL)) + (unspec:DI [(match_dup 1)] FIST_ROUNDING)) (use (match_dup 2)) (use (match_dup 3)) (clobber (match_dup 5))])]) -(define_insn "fist<mode>2_ceil" +(define_insn "fist<mode>2_<rounding>" [(set (match_operand:SWI24 0 "memory_operand" "=m") (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (use (match_operand:HI 2 "memory_operand" "m")) (use (match_operand:HI 3 "memory_operand" "m"))] "TARGET_USE_FANCY_MATH_387 && flag_unsafe_math_optimizations" "* return output_fix_trunc (insn, operands, false);" [(set_attr "type" "fistp") - (set_attr "i387_cw" "ceil") + (set_attr "i387_cw" "<rounding>") (set_attr "mode" "<MODE>")]) -(define_insn "fist<mode>2_ceil_with_temp" +(define_insn "fist<mode>2_<rounding>_with_temp" [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r") (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (use (match_operand:HI 2 "memory_operand" "m,m")) (use (match_operand:HI 3 "memory_operand" "m,m")) (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))] @@ -15540,19 +15501,19 @@ && flag_unsafe_math_optimizations" "#" [(set_attr "type" "fistp") - (set_attr "i387_cw" "ceil") + (set_attr "i387_cw" "<rounding>") (set_attr "mode" "<MODE>")]) (define_split [(set (match_operand:SWI24 0 "register_operand") (unspec:SWI24 [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (use (match_operand:HI 2 "memory_operand")) (use (match_operand:HI 3 "memory_operand")) (clobber (match_operand:SWI24 4 "memory_operand"))] "reload_completed" [(parallel [(set (match_dup 4) - (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL)) + (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) (use (match_dup 2)) (use (match_dup 3))]) (set (match_dup 0) (match_dup 4))]) @@ -15560,154 +15521,47 @@ (define_split [(set (match_operand:SWI24 0 "memory_operand") (unspec:SWI24 [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (use (match_operand:HI 2 "memory_operand")) (use (match_operand:HI 3 "memory_operand")) (clobber (match_operand:SWI24 4 "memory_operand"))] "reload_completed" [(parallel [(set (match_dup 0) - (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL)) + (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING)) (use (match_dup 2)) (use (match_dup 3))])]) -(define_expand "lceilxf<mode>2" +(define_expand "l<rounding>xf<mode>2" [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand") (unspec:SWI248x [(match_operand:XF 1 "register_operand")] - UNSPEC_FIST_CEIL)) + FIST_ROUNDING)) (clobber (reg:CC FLAGS_REG))])] "TARGET_USE_FANCY_MATH_387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) && flag_unsafe_math_optimizations") -(define_expand "lceil<MODEF:mode><SWI48:mode>2" +(define_expand "lfloor<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); - DONE; -}) - -(define_expand "btruncxf2" - [(use (match_operand:XF 0 "register_operand")) - (use (match_operand:XF 1 "register_operand"))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" -{ - if (optimize_insn_for_size_p ()) + if (TARGET_64BIT && optimize_insn_for_size_p ()) FAIL; - emit_insn (gen_frndintxf2_trunc (operands[0], operands[1])); + ix86_expand_lfloorceil (operands[0], operands[1], true); 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)" +(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" { - 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)); - } + ix86_expand_lfloorceil (operands[0], operands[1], false); DONE; }) -;; Rounding mode control word calculation could clobber FLAGS_REG. -(define_insn_and_split "frndintxf2_mask_pm" - [(set (match_operand:XF 0 "register_operand") - (unspec:XF [(match_operand:XF 1 "register_operand")] - UNSPEC_FRNDINT_MASK_PM)) - (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations - && can_create_pseudo_p ()" - "#" - "&& 1" - [(const_int 0)] -{ - ix86_optimize_mode_switching[I387_MASK_PM] = 1; - - operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED); - operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM); - - emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1], - operands[2], operands[3])); - DONE; -} - [(set_attr "type" "frndint") - (set_attr "i387_cw" "mask_pm") - (set_attr "mode" "XF")]) - -(define_insn "frndintxf2_mask_pm_i387" - [(set (match_operand:XF 0 "register_operand" "=f") - (unspec:XF [(match_operand:XF 1 "register_operand" "0")] - UNSPEC_FRNDINT_MASK_PM)) - (use (match_operand:HI 2 "memory_operand" "m")) - (use (match_operand:HI 3 "memory_operand" "m"))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" - "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2" - [(set_attr "type" "frndint") - (set_attr "i387_cw" "mask_pm") - (set_attr "mode" "XF")]) - -(define_expand "nearbyintxf2" - [(use (match_operand:XF 0 "register_operand")) - (use (match_operand:XF 1 "register_operand"))] - "TARGET_USE_FANCY_MATH_387 - && flag_unsafe_math_optimizations" -{ - emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1])); - DONE; -}) - -(define_expand "nearbyint<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" -{ - rtx op0 = gen_reg_rtx (XFmode); - rtx op1 = gen_reg_rtx (XFmode); - - emit_insn (gen_extend<mode>xf2 (op1, operands[1])); - emit_insn (gen_frndintxf2_mask_pm (op0, op1)); - - emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0)); - DONE; -}) - (define_insn "fxam<mode>2_i387" [(set (match_operand:HI 0 "register_operand" "=a") (unspec:HI