[PATCH, i386]: Introduce FIST_ROUNDING int iterator
Uros Bizjak
ubizjak@gmail.com
Tue Jun 19 19:00:00 GMT 2012
Hello!
2012-06-19 Uros Bizjak <ubizjak@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.
-------------- next part --------------
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
More information about the Gcc-patches
mailing list