This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[mainline PATCH, i386]: Fix PR target/20421


Hello!

This is more radical patch to fix PR target/20421 on mainline. It introduces some more changes in addition to http://gcc.gnu.org/ml/gcc-patches/2005-03/msg01523.html. It optimizes fix_trunc* patterns and introduces mode macros into rint, floor, ceil, btrunc and frndint patterns.

Patch is bootstrapped on i686-pc-linux-gnu, regtested for c, c++. OK for mainline?

2005-03-16 Uros Bizjak <uros@kss-loka.si>

   PR target/20421
   PR target/12308
   * config/i386/i386.c (emit_i387_cw_initialization): Simplify "if"
   clause.

   * config/i386/i386.md (X87MODEF12): New mode macro define.
   (fix_truncxfdi2, fix_trunc<mode>di2, fix_truncxfsi2,
   fix_trunc<mode>si2, fix_trunc<mode>hi2): Remove clobber from insn
   definition.  Emit fix_trunc?i_i387_clob pattern when 387 rounding
   mode control word generation clobbers flags.
   (fix_trunc<mode>_i387_clob): New pattern.
   (*fix_trunc<mode>_i387_1): Remove clobber from insns definition.
   Update insn constraint.

(rintxf2, rintdf2, rintsf2): Implement using mode macros. Rename
to "rint<mode>2".
(frndintxf2_floor_clob, frndintxf2_ceil_clob, frndintxf2_trunc_clob,
frndintxf2_mask_pm_clob): New insn patterns.
(floorsf2, floordf2, floorxf2): Use frndintxf2_floor_clob when
387 rounding mode control word initialization clobbers flags.
(floorsf2, floordf2): Implement using mode macros. Use floorxf2
pattern. Rename to "floor<mode>2".


(ceilsf2, ceildf2, ceilxf2): Use frndintxf2_ceil_clob when
387 rounding mode control word initialization clobbers flags.
(ceilsf2, ceildf2): Implement using mode macros. Use ceilxf2
pattern. Rename to "ceil<mode>2".
(btruncsf2, btruncdf2, btruncxf2): Use frndintxf2_trunc_clob when
387 rounding mode control word initialization clobbers flags.
(btruncsf2, btruncdf2): Implement using mode macros. Use btruncxf2
pattern. Rename to "btrunc<mode>2".


   (frndintxf2_mask_pm): Rename to "*frndintxf2_mask_pm".
   (nearbyintsf2, nearbyintdf2, nearbyintxf2): Use
   frndintxf2_mask_pm_clob.
   (nearbyintsf2, nearbyintdf2): Implement using mode macros.  Use
   nearbyintxf2 pattern.  Rename to "nearbyint<mode>2".

Uros.
? i387.md
Index: i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.798
diff -u -p -r1.798 i386.c
--- i386.c	15 Mar 2005 14:44:08 -0000	1.798
+++ i386.c	16 Mar 2005 11:10:09 -0000
@@ -7215,26 +7215,27 @@ emit_i387_cw_initialization (rtx current
   emit_insn (gen_x86_fnstcw_1 (current_mode));
   emit_move_insn (reg, current_mode);
 
-  if (!TARGET_PARTIAL_REG_STALL && !optimize_size
-      && !TARGET_64BIT)
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
     {
       switch (mode)
 	{
 	case I387_CW_FLOOR:
 	  /* round down toward -oo */
-	  emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0x4)));
+	  emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
+	  emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
 	  break;
 
 	case I387_CW_CEIL:
 	  /* round up toward +oo */
-	  emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0x8)));
+	  emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
+	  emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
 	  break;
 
 	case I387_CW_TRUNC:
 	  /* round toward zero (truncate) */
-	  emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0xc)));
+	  emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
 	  break;
- 
+
 	case I387_CW_MASK_PM:
 	  /* mask precision exception for nearbyint() */
 	  emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020)));
@@ -7250,21 +7251,19 @@ emit_i387_cw_initialization (rtx current
 	{
 	case I387_CW_FLOOR:
 	  /* round down toward -oo */
-	  emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
-	  emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0400)));
+	  emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0x4)));
 	  break;
 
 	case I387_CW_CEIL:
 	  /* round up toward +oo */
-	  emit_insn (gen_andhi3 (reg, reg, GEN_INT (~0x0c00)));
-	  emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0800)));
+	  emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0x8)));
 	  break;
 
 	case I387_CW_TRUNC:
 	  /* round toward zero (truncate) */
-	  emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0c00)));
+	  emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0xc)));
 	  break;
-
+ 
 	case I387_CW_MASK_PM:
 	  /* mask precision exception for nearbyint() */
 	  emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0x0020)));
Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.620
diff -u -p -r1.620 i386.md
--- i386.md	15 Mar 2005 14:44:09 -0000	1.620
+++ i386.md	16 Mar 2005 11:10:12 -0000
@@ -445,6 +445,9 @@
 ;; All x87 floating point modes
 (define_mode_macro X87MODEF [SF DF XF])
  
+;; x87 floating point modes without XFmode
+(define_mode_macro X87MODEF12 [SF DF])
+
 ;; All integer modes handled by x87 fisttp operator.
 (define_mode_macro X87MODEI [HI SI DI])
 
@@ -4014,9 +4017,8 @@
 ;; Signed conversion to DImode.
 
 (define_expand "fix_truncxfdi2"
-  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
-                   (fix:DI (match_operand:XF 1 "register_operand" "")))
-	      (clobber (reg:CC FLAGS_REG))])]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
+	(fix:DI (match_operand:XF 1 "register_operand" "")))]
   "TARGET_80387"
 {
   if (TARGET_FISTTP)
@@ -4024,12 +4026,16 @@
      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
      DONE;
    }
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+   {
+     emit_insn (gen_fix_truncdi_i387_clob (operands[0], operands[1]));
+     DONE;
+   }
 })
 
 (define_expand "fix_trunc<mode>di2"
-  [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
-                   (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
-              (clobber (reg:CC FLAGS_REG))])]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "")
+	(fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))]
   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
 {
   if (TARGET_FISTTP
@@ -4046,14 +4052,18 @@
 	emit_move_insn (operands[0], out);
      DONE;
    }
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+   {
+     emit_insn (gen_fix_truncdi_i387_clob (operands[0], operands[1]));
+     DONE;
+   }
 })
 
 ;; Signed conversion to SImode.
 
 (define_expand "fix_truncxfsi2"
-  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
-                   (fix:SI (match_operand:XF 1 "register_operand" "")))
-	      (clobber (reg:CC FLAGS_REG))])]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+	(fix:SI (match_operand:XF 1 "register_operand" "")))]
   "TARGET_80387"
 {
   if (TARGET_FISTTP)
@@ -4061,12 +4071,16 @@
      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
      DONE;
    }
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+   {
+     emit_insn (gen_fix_truncsi_i387_clob (operands[0], operands[1]));
+     DONE;
+   }
 })
 
 (define_expand "fix_trunc<mode>si2"
-  [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
-	           (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
-	      (clobber (reg:CC FLAGS_REG))])]
+  [(set (match_operand:SI 0 "nonimmediate_operand" "")
+	(fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))]
   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
 {
   if (TARGET_FISTTP
@@ -4083,14 +4097,18 @@
 	emit_move_insn (operands[0], out);
      DONE;
    }
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+   {
+     emit_insn (gen_fix_truncsi_i387_clob (operands[0], operands[1]));
+     DONE;
+   }
 })
 
 ;; Signed conversion to HImode.
 
 (define_expand "fix_trunc<mode>hi2"
-  [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
-	           (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
-              (clobber (reg:CC FLAGS_REG))])]
+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
+	(fix:HI (match_operand:X87MODEF 1 "register_operand" "")))]
   "TARGET_80387
    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
 {
@@ -4099,6 +4117,11 @@
      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
      DONE;
    }
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+   {
+     emit_insn (gen_fix_trunchi_i387_clob (operands[0], operands[1]));
+     DONE;
+   }
 })
 
 ;; When SSE is available, it is always faster to use it!
@@ -4237,7 +4260,7 @@
 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
 ;; function in i386.c.
-(define_insn_and_split "*fix_trunc<mode>_i387_1"
+(define_insn_and_split "fix_trunc<mode>_i387_clob"
   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
 	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
    (clobber (reg:CC FLAGS_REG))]
@@ -4245,7 +4268,40 @@
    && FLOAT_MODE_P (GET_MODE (operands[1]))
    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
 	 && (TARGET_64BIT || <MODE>mode != DImode))
-   && !(reload_completed || reload_in_progress)"
+   && !(reload_completed || reload_in_progress)
+   && (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)"
+  "#"
+  "&& 1"
+  [(const_int 0)]
+{
+  ix86_optimize_mode_switching = 1;
+  operands[2] = assign_386_stack_local (HImode, 1);
+  operands[3] = assign_386_stack_local (HImode, 2);
+  if (memory_operand (operands[0], VOIDmode))
+    emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
+					 operands[2], operands[3]));
+  else
+    {
+      operands[4] = assign_386_stack_local (<MODE>mode, 0);
+      emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
+						     operands[2], operands[3],
+						     operands[4]));
+    }
+  DONE;
+}
+  [(set_attr "type" "fistp")
+   (set_attr "i387_cw" "trunc")
+   (set_attr "mode" "<MODE>")])
+
+(define_insn_and_split "*fix_trunc<mode>_i387_1"
+  [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
+	(fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
+  "TARGET_80387 && !TARGET_FISTTP
+   && FLOAT_MODE_P (GET_MODE (operands[1]))
+   && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+	 && (TARGET_64BIT || <MODE>mode != DImode))
+   && !(reload_completed || reload_in_progress)
+   && !(TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)"
   "#"
   "&& 1"
   [(const_int 0)]
@@ -16200,49 +16256,60 @@
   [(set_attr "type" "fpspc")
    (set_attr "mode" "XF")])
 
-(define_expand "rintdf2"
-  [(use (match_operand:DF 0 "register_operand" ""))
-   (use (match_operand:DF 1 "register_operand" ""))]
+(define_expand "rintxf2"
+  [(use (match_operand:XF 0 "register_operand" ""))
+   (use (match_operand:XF 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && 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_extenddfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2 (op0, op1));
-
-  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
+  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
   DONE;
 })
 
-(define_expand "rintsf2"
-  [(use (match_operand:SF 0 "register_operand" ""))
-   (use (match_operand:SF 1 "register_operand" ""))]
+(define_expand "rint<mode>2"
+  [(use (match_operand:X87MODEF12 0 "register_operand" ""))
+   (use (match_operand:X87MODEF12 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
+   && (!(TARGET_SSE2 && 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_extendsfxf2 (op1, operands[1]));
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
   emit_insn (gen_frndintxf2 (op0, op1));
 
-  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "rintxf2"
-  [(use (match_operand:XF 0 "register_operand" ""))
-   (use (match_operand:XF 1 "register_operand" ""))]
+;; Following rounding expanders clobber FLAGS_REG, when logic instructions
+;; are emitted in emit_i387_cw_initialization () function.  The "if"
+;; condition in this function and the "if" condition in the body of round
+;; expanders should be kept in sync to select correct FLAGS_REG clobbering
+;; pattern.
+
+(define_insn_and_split "frndintxf2_floor_clob"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+	 UNSPEC_FRNDINT_FLOOR))
+   (use (match_operand:HI 2 "memory_operand" "m"))
+   (use (match_operand:HI 3 "memory_operand" "m"))
+   (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
-{
-  emit_insn (gen_frndintxf2 (operands[0], operands[1]));
-  DONE;
-})
+   && flag_unsafe_math_optimizations
+   && !(reload_completed || reload_in_progress)"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 0)
+	      (unspec:XF [(match_dup 1)]
+	       UNSPEC_FRNDINT_FLOOR))
+	      (use (match_dup 2))
+	      (use (match_dup 3))])]
+  ""
+  [(set_attr "type" "frndint")
+   (set_attr "i387_cw" "floor")
+   (set_attr "mode" "XF")])
 
 (define_insn "frndintxf2_floor"
   [(set (match_operand:XF 0 "register_operand" "=f")
@@ -16257,62 +16324,65 @@
    (set_attr "i387_cw" "floor")
    (set_attr "mode" "XF")])
 
-(define_expand "floordf2"
-  [(use (match_operand:DF 0 "register_operand" ""))
-   (use (match_operand:DF 1 "register_operand" ""))]
+(define_expand "floorxf2"
+  [(use (match_operand:XF 0 "register_operand" ""))
+   (use (match_operand:XF 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
 {
-  rtx op0 = gen_reg_rtx (XFmode);
-  rtx op1 = gen_reg_rtx (XFmode);
   rtx op2 = assign_386_stack_local (HImode, 1);
   rtx op3 = assign_386_stack_local (HImode, 2);
 	
   ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_extenddfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+    emit_insn (gen_frndintxf2_floor_clob (operands[0], operands[1],
+						       op2, op3));
+  else
+    emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
 
-  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "floorsf2"
-  [(use (match_operand:SF 0 "register_operand" ""))
-   (use (match_operand:SF 1 "register_operand" ""))]
+(define_expand "floor<mode>2"
+  [(use (match_operand:X87MODEF12 0 "register_operand" ""))
+   (use (match_operand:X87MODEF12 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
+   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
 {
   rtx op0 = gen_reg_rtx (XFmode);
   rtx op1 = gen_reg_rtx (XFmode);
-  rtx op2 = assign_386_stack_local (HImode, 1);
-  rtx op3 = assign_386_stack_local (HImode, 2);
-	
-  ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_extendsfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
 
-  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
+  emit_insn (gen_floorxf2 (op0, op1));
+
+  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "floorxf2"
-  [(use (match_operand:XF 0 "register_operand" ""))
-   (use (match_operand:XF 1 "register_operand" ""))]
+(define_insn_and_split "frndintxf2_ceil_clob"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+	 UNSPEC_FRNDINT_CEIL))
+   (use (match_operand:HI 2 "memory_operand" "m"))
+   (use (match_operand:HI 3 "memory_operand" "m"))
+   (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
-{
-  rtx op2 = assign_386_stack_local (HImode, 1);
-  rtx op3 = assign_386_stack_local (HImode, 2);
-	
-  ix86_optimize_mode_switching = 1;
-
-  emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
-  DONE;
-})
+   && flag_unsafe_math_optimizations
+   && !(reload_completed || reload_in_progress)"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 0)
+	      (unspec:XF [(match_dup 1)]
+	       UNSPEC_FRNDINT_CEIL))
+	      (use (match_dup 2))
+	      (use (match_dup 3))])]
+  ""
+  [(set_attr "type" "frndint")
+   (set_attr "i387_cw" "ceil")
+   (set_attr "mode" "XF")])
 
 (define_insn "frndintxf2_ceil"
   [(set (match_operand:XF 0 "register_operand" "=f")
@@ -16327,62 +16397,65 @@
    (set_attr "i387_cw" "ceil")
    (set_attr "mode" "XF")])
 
-(define_expand "ceildf2"
-  [(use (match_operand:DF 0 "register_operand" ""))
-   (use (match_operand:DF 1 "register_operand" ""))]
+(define_expand "ceilxf2"
+  [(use (match_operand:XF 0 "register_operand" ""))
+   (use (match_operand:XF 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
 {
-  rtx op0 = gen_reg_rtx (XFmode);
-  rtx op1 = gen_reg_rtx (XFmode);
   rtx op2 = assign_386_stack_local (HImode, 1);
   rtx op3 = assign_386_stack_local (HImode, 2);
 	
   ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_extenddfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+    emit_insn (gen_frndintxf2_ceil_clob (operands[0], operands[1],
+					 op2, op3));
+  else
+    emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
 
-  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "ceilsf2"
-  [(use (match_operand:SF 0 "register_operand" ""))
-   (use (match_operand:SF 1 "register_operand" ""))]
+(define_expand "ceil<mode>2"
+  [(use (match_operand:X87MODEF12 0 "register_operand" ""))
+   (use (match_operand:X87MODEF12 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
+   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
 {
   rtx op0 = gen_reg_rtx (XFmode);
   rtx op1 = gen_reg_rtx (XFmode);
-  rtx op2 = assign_386_stack_local (HImode, 1);
-  rtx op3 = assign_386_stack_local (HImode, 2);
-	
-  ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_extendsfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
 
-  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
+  emit_insn (gen_ceilxf2 (op0, op1));
+
+  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "ceilxf2"
-  [(use (match_operand:XF 0 "register_operand" ""))
-   (use (match_operand:XF 1 "register_operand" ""))]
+(define_insn_and_split "frndintxf2_trunc_clob"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+	 UNSPEC_FRNDINT_TRUNC))
+   (use (match_operand:HI 2 "memory_operand" "m"))
+   (use (match_operand:HI 3 "memory_operand" "m"))
+   (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
-{
-  rtx op2 = assign_386_stack_local (HImode, 1);
-  rtx op3 = assign_386_stack_local (HImode, 2);
-	
-  ix86_optimize_mode_switching = 1;
-
-  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
-  DONE;
-})
+   && flag_unsafe_math_optimizations
+   && !(reload_completed || reload_in_progress)"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 0)
+	      (unspec:XF [(match_dup 1)]
+	       UNSPEC_FRNDINT_TRUNC))
+	      (use (match_dup 2))
+	      (use (match_dup 3))])]
+  ""
+  [(set_attr "type" "frndint")
+   (set_attr "i387_cw" "trunc")
+   (set_attr "mode" "XF")])
 
 (define_insn "frndintxf2_trunc"
   [(set (match_operand:XF 0 "register_operand" "=f")
@@ -16397,64 +16470,69 @@
    (set_attr "i387_cw" "trunc")
    (set_attr "mode" "XF")])
 
-(define_expand "btruncdf2"
-  [(use (match_operand:DF 0 "register_operand" ""))
-   (use (match_operand:DF 1 "register_operand" ""))]
+(define_expand "btruncxf2"
+  [(use (match_operand:XF 0 "register_operand" ""))
+   (use (match_operand:XF 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
 {
-  rtx op0 = gen_reg_rtx (XFmode);
-  rtx op1 = gen_reg_rtx (XFmode);
   rtx op2 = assign_386_stack_local (HImode, 1);
   rtx op3 = assign_386_stack_local (HImode, 2);
 	
   ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_extenddfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+  if (TARGET_64BIT || TARGET_PARTIAL_REG_STALL || optimize_size)
+    emit_insn (gen_frndintxf2_trunc_clob (operands[0], operands[1],
+					  op2, op3));
+  else
+    emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
 
-  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "btruncsf2"
-  [(use (match_operand:SF 0 "register_operand" ""))
-   (use (match_operand:SF 1 "register_operand" ""))]
+(define_expand "btrunc<mode>2"
+  [(use (match_operand:X87MODEF12 0 "register_operand" ""))
+   (use (match_operand:X87MODEF12 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
+   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
 {
   rtx op0 = gen_reg_rtx (XFmode);
   rtx op1 = gen_reg_rtx (XFmode);
-  rtx op2 = assign_386_stack_local (HImode, 1);
-  rtx op3 = assign_386_stack_local (HImode, 2);
-	
-  ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_extendsfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
 
-  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
+  emit_insn (gen_btruncxf2 (op0, op1));
+
+  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
   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"
-{
-  rtx op2 = assign_386_stack_local (HImode, 1);
-  rtx op3 = assign_386_stack_local (HImode, 2);
-	
-  ix86_optimize_mode_switching = 1;
+;; PM bit setting is implemented using ior and always clobbers FP_REGS.
 
-  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
-  DONE;
-})
+(define_insn_and_split "frndintxf2_mask_pm_clob"
+  [(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"))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations
+   && !(reload_completed || reload_in_progress)"
+  "#"
+  "&& 1"
+  [(parallel [(set (match_dup 0)
+	      (unspec:XF [(match_dup 1)]
+	       UNSPEC_FRNDINT_MASK_PM))
+	      (use (match_dup 2))
+	      (use (match_dup 3))])]
+  ""
+  [(set_attr "type" "frndint")
+   (set_attr "i387_cw" "mask_pm")
+   (set_attr "mode" "XF")])
 
-(define_insn "frndintxf2_mask_pm"
+(define_insn "*frndintxf2_mask_pm"
   [(set (match_operand:XF 0 "register_operand" "=f")
 	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
 	 UNSPEC_FRNDINT_MASK_PM))
@@ -16467,61 +16545,38 @@
    (set_attr "i387_cw" "mask_pm")
    (set_attr "mode" "XF")])
 
-(define_expand "nearbyintdf2"
-  [(use (match_operand:DF 0 "register_operand" ""))
-   (use (match_operand:DF 1 "register_operand" ""))]
+(define_expand "nearbyintxf2"
+  [(use (match_operand:XF 0 "register_operand" ""))
+   (use (match_operand:XF 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
 {
-  rtx op0 = gen_reg_rtx (XFmode);
-  rtx op1 = gen_reg_rtx (XFmode);
   rtx op2 = assign_386_stack_local (HImode, 1);
   rtx op3 = assign_386_stack_local (HImode, 2);
 	
   ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_extenddfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
+  emit_insn (gen_frndintxf2_mask_pm_clob (operands[0], operands[1],
+					  op2, op3));
 
-  emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "nearbyintsf2"
-  [(use (match_operand:SF 0 "register_operand" ""))
-   (use (match_operand:SF 1 "register_operand" ""))]
+(define_expand "nearbyint<mode>2"
+  [(use (match_operand:X87MODEF12 0 "register_operand" ""))
+   (use (match_operand:X87MODEF12 1 "register_operand" ""))]
   "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
+   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
 {
   rtx op0 = gen_reg_rtx (XFmode);
   rtx op1 = gen_reg_rtx (XFmode);
-  rtx op2 = assign_386_stack_local (HImode, 1);
-  rtx op3 = assign_386_stack_local (HImode, 2);
-	
-  ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_extendsfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
 
-  emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
-  DONE;
-})
-
-(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"
-{
-  rtx op2 = assign_386_stack_local (HImode, 1);
-  rtx op3 = assign_386_stack_local (HImode, 2);
-	
-  ix86_optimize_mode_switching = 1;
+  emit_insn (gen_nearbyintxf2 (op0, op1));
 
-  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
-				     op2, op3));
+  emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
   DONE;
 })
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]