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]

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


Hello!

This is the same problem as in PR target/12308. When 387 rounding mode control word calculation clobbers flags, patterns should be marked as FLAGS_REG clobbering. fistp* patterns were fixed in target/12308, but ceil/floor/... patterns should be fixed as well.

This is a 4.0 version of patch. Patch was bootstrapped on i686-pc-linux-gnu, regtested for c,c++. OK to install on 4.0 branch?

(The mainline patch will be implemented usign mode_macro macros).

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

   PR target/20421
   PR target/12308
   * config/i386/i386.md (frndintxf2_floor_1, frndintxf2_ceil_1,
   frndintxf2_trunc_1, frndintxf2_mask_pm_1): New insn patterns.
   (floorsf2, floordf2, floorxf2): Use frndintxf2_floor_1 when
   387 rounding mode control word initialization clobbers flags.
   (ceilsf2, ceildf2, ceilxf2): Use frndintxf2_ceil_1 when
   387 rounding mode control word initialization clobbers flags.
   (truncsf2, truncdf2, truncxf2): Use frndintxf2_trunc_1 when
   387 rounding mode control word initialization clobbers flags.
   (nearbyintsf2, nearbyintdf2, nearbyintxf2): Use frndintxf2_mask_pm_1.

Uros.
Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.618
diff -u -p -r1.618 i386.md
--- i386.md	12 Feb 2005 11:34:22 -0000	1.618
+++ i386.md	16 Mar 2005 06:58:14 -0000
@@ -16297,6 +16297,34 @@
   DONE;
 })
 
+;; 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_1"
+  [(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
+   && !(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")
 	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
@@ -16325,7 +16353,11 @@
   ix86_optimize_mode_switching = 1;
 
   emit_insn (gen_extenddfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+  else
+    emit_insn (gen_frndintxf2_floor_1 (op0, op1, op2, op3));
 
   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
@@ -16346,7 +16378,11 @@
   ix86_optimize_mode_switching = 1;
 
   emit_insn (gen_extendsfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+  else
+    emit_insn (gen_frndintxf2_floor_1 (op0, op1, op2, op3));
 
   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
   DONE;
@@ -16363,10 +16399,36 @@
 	
   ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
+  else
+    emit_insn (gen_frndintxf2_floor_1 (operands[0], operands[1], op2, op3));
+
   DONE;
 })
 
+(define_insn_and_split "frndintxf2_ceil_1"
+  [(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
+   && !(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")
 	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
@@ -16395,7 +16457,11 @@
   ix86_optimize_mode_switching = 1;
 
   emit_insn (gen_extenddfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+  else
+    emit_insn (gen_frndintxf2_ceil_1 (op0, op1, op2, op3));
 
   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
@@ -16416,7 +16482,11 @@
   ix86_optimize_mode_switching = 1;
 
   emit_insn (gen_extendsfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+  else
+    emit_insn (gen_frndintxf2_ceil_1 (op0, op1, op2, op3));
 
   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
   DONE;
@@ -16433,10 +16503,36 @@
 	
   ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
+  else
+    emit_insn (gen_frndintxf2_ceil_1 (operands[0], operands[1], op2, op3));
+
   DONE;
 })
 
+(define_insn_and_split "frndintxf2_trunc_1"
+  [(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
+   && !(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")
 	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
@@ -16465,7 +16561,11 @@
   ix86_optimize_mode_switching = 1;
 
   emit_insn (gen_extenddfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+  else
+    emit_insn (gen_frndintxf2_trunc_1 (op0, op1, op2, op3));
 
   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
@@ -16486,7 +16586,11 @@
   ix86_optimize_mode_switching = 1;
 
   emit_insn (gen_extendsfxf2 (op1, operands[1]));
-  emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+  else
+    emit_insn (gen_frndintxf2_trunc_1 (op0, op1, op2, op3));
 
   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
   DONE;
@@ -16503,10 +16607,38 @@
 	
   ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
+  if (!TARGET_PARTIAL_REG_STALL && !optimize_size && !TARGET_64BIT)
+    emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
+  else
+    emit_insn (gen_frndintxf2_trunc_1 (operands[0], operands[1], op2, op3));
+
   DONE;
 })
 
+;; PM bit setting is implemented using ior and always clobbers FP_REGS.
+
+(define_insn_and_split "frndintxf2_mask_pm_1"
+  [(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"
   [(set (match_operand:XF 0 "register_operand" "=f")
 	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
@@ -16515,7 +16647,7 @@
    (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"
+  "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
   [(set_attr "type" "frndint")
    (set_attr "i387_cw" "mask_pm")
    (set_attr "mode" "XF")])
@@ -16535,7 +16667,7 @@
   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_1 (op0, op1, op2, op3));
 
   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
@@ -16556,7 +16688,7 @@
   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_frndintxf2_mask_pm_1 (op0, op1, op2, op3));
 
   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
   DONE;
@@ -16573,8 +16705,8 @@
 	
   ix86_optimize_mode_switching = 1;
 
-  emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
-				     op2, op3));
+  emit_insn (gen_frndintxf2_mask_pm_1 (operands[0], operands[1], op2, op3));
+
   DONE;
 })
 

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