re PR target/20421 (387 mode switching clobbers flags)
authorUros Bizjak <uros@kss-loka.si>
Tue, 5 Apr 2005 05:23:14 +0000 (07:23 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 5 Apr 2005 05:23:14 +0000 (07:23 +0200)
PR target/20421
* config/i386/i386.md (frndintxf2_floor, frndintxf2_ceil)
(frndintxf2_trunc, frndintxf2_mask_pm): Add FLAGS_REG clobber.
Allocate local stack slots here.  Set ix86_optimize_mode_switching.
flag here. Implement using define_insn_and_split.
(frndintxf2_floor_i387, frndintxf2_ceil_i387, frndintxf2_trunc_i387)
(frndintxf2_mask_pm_i387): New insn patterns.
(floorsf2, floordf2, floorxf2): Remove local stack slot allocations.
Do not set ix86_optimize_mode_switching flag.
(ceilsf2, ceildf2, ceilxf2): Same.
(btruncsf2, btruncdf2, btruncxf2): Same.
(nearbyintsf2, nearbyintdf2, nearbyintxf2): Same.

From-SVN: r97604

gcc/ChangeLog
gcc/config/i386/i386.md

index b29d81da1e5233d9bcf36cb61af9a1e538c5e96c..9f3a372f713331a073f0408e7d690573c2a542b3 100644 (file)
@@ -1,3 +1,18 @@
+2005-04-05 Uros Bizjak <uros@kss-loka.si>
+
+       PR target/20421
+       * config/i386/i386.md (frndintxf2_floor, frndintxf2_ceil)
+       (frndintxf2_trunc, frndintxf2_mask_pm): Add FLAGS_REG clobber.
+       Allocate local stack slots here.  Set ix86_optimize_mode_switching.
+       flag here. Implement using define_insn_and_split.  
+       (frndintxf2_floor_i387, frndintxf2_ceil_i387, frndintxf2_trunc_i387)
+       (frndintxf2_mask_pm_i387): New insn patterns.
+       (floorsf2, floordf2, floorxf2): Remove local stack slot allocations.
+       Do not set ix86_optimize_mode_switching flag.
+       (ceilsf2, ceildf2, ceilxf2): Same.
+       (btruncsf2, btruncdf2, btruncxf2): Same.
+       (nearbyintsf2, nearbyintdf2, nearbyintxf2): Same.
+
 2005-04-05  Ian Lance Taylor  <ian@airs.com>
 
        PR debug/9963
index f9df272e217632c544c9732b269896ebeba0ba5b..6c5962bdec4c45064055a2216379f46f913b8c63 100644 (file)
   DONE;
 })
 
-(define_insn "frndintxf2_floor"
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_floor"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+       (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+        UNSPEC_FRNDINT_FLOOR))
+   (clobber (reg:CC FLAGS_REG))]
+  "TARGET_USE_FANCY_MATH_387
+   && flag_unsafe_math_optimizations
+   && !(reload_completed || reload_in_progress)"
+  "#"
+  "&& 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);
+
+  emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
+                                       operands[2], operands[3]));
+  DONE;
+}
+  [(set_attr "type" "frndint")
+   (set_attr "i387_cw" "floor")
+   (set_attr "mode" "XF")])
+
+(define_insn "frndintxf2_floor_i387"
   [(set (match_operand:XF 0 "register_operand" "=f")
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
         UNSPEC_FRNDINT_FLOOR))
    (set_attr "i387_cw" "floor")
    (set_attr "mode" "XF")])
 
+(define_expand "floorxf2"
+  [(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_floor (operands[0], operands[1]));
+  DONE;
+})
+
 (define_expand "floordf2"
   [(use (match_operand:DF 0 "register_operand" ""))
    (use (match_operand:DF 1 "register_operand" ""))]
 {
   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));
+  emit_insn (gen_frndintxf2_floor (op0, op1));
 
   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
 {
   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_frndintxf2_floor (op0, op1));
 
   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "floorxf2"
-  [(use (match_operand:XF 0 "register_operand" ""))
-   (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_ceil"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+       (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+        UNSPEC_FRNDINT_CEIL))
+   (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
+   && flag_unsafe_math_optimizations
+   && !(reload_completed || reload_in_progress)"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
-  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));
+  operands[2] = assign_386_stack_local (HImode, 1);
+  operands[3] = assign_386_stack_local (HImode, 2);
+
+  emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
+                                      operands[2], operands[3]));
   DONE;
-})
+}
+  [(set_attr "type" "frndint")
+   (set_attr "i387_cw" "ceil")
+   (set_attr "mode" "XF")])
 
-(define_insn "frndintxf2_ceil"
+(define_insn "frndintxf2_ceil_i387"
   [(set (match_operand:XF 0 "register_operand" "=f")
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
         UNSPEC_FRNDINT_CEIL))
    (set_attr "i387_cw" "ceil")
    (set_attr "mode" "XF")])
 
+(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"
+{
+  emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
+  DONE;
+})
+
 (define_expand "ceildf2"
   [(use (match_operand:DF 0 "register_operand" ""))
    (use (match_operand:DF 1 "register_operand" ""))]
 {
   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));
+  emit_insn (gen_frndintxf2_ceil (op0, op1));
 
   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
 {
   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_frndintxf2_ceil (op0, op1));
 
   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "ceilxf2"
-  [(use (match_operand:XF 0 "register_operand" ""))
-   (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_trunc"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+       (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+        UNSPEC_FRNDINT_TRUNC))
+   (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
+   && flag_unsafe_math_optimizations
+   && !(reload_completed || reload_in_progress)"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
-  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));
+  operands[2] = assign_386_stack_local (HImode, 1);
+  operands[3] = assign_386_stack_local (HImode, 2);
+
+  emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
+                                       operands[2], operands[3]));
   DONE;
-})
+}
+  [(set_attr "type" "frndint")
+   (set_attr "i387_cw" "trunc")
+   (set_attr "mode" "XF")])
 
-(define_insn "frndintxf2_trunc"
+(define_insn "frndintxf2_trunc_i387"
   [(set (match_operand:XF 0 "register_operand" "=f")
        (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
         UNSPEC_FRNDINT_TRUNC))
    (set_attr "i387_cw" "trunc")
    (set_attr "mode" "XF")])
 
+(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"
+{
+  emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
+  DONE;
+})
+
 (define_expand "btruncdf2"
   [(use (match_operand:DF 0 "register_operand" ""))
    (use (match_operand:DF 1 "register_operand" ""))]
 {
   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));
+  emit_insn (gen_frndintxf2_trunc (op0, op1));
 
   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
 {
   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_frndintxf2_trunc (op0, op1));
 
   emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
   DONE;
 })
 
-(define_expand "btruncxf2"
-  [(use (match_operand:XF 0 "register_operand" ""))
-   (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_mask_pm"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+       (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+        UNSPEC_FRNDINT_MASK_PM))
+   (clobber (reg:CC FLAGS_REG))]
   "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
+   && flag_unsafe_math_optimizations
+   && !(reload_completed || reload_in_progress)"
+  "#"
+  "&& 1"
+  [(const_int 0)]
 {
-  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_trunc (operands[0], operands[1], op2, op3));
+  operands[2] = assign_386_stack_local (HImode, 1);
+  operands[3] = assign_386_stack_local (HImode, 2);
+
+  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"
+(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))
    (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 "nearbyintdf2"
   [(use (match_operand:DF 0 "register_operand" ""))
    (use (match_operand:DF 1 "register_operand" ""))]
 {
   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 (op0, op1));
 
   emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
   DONE;
 {
   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_frndintxf2_mask_pm (op0, op1));
 
   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_frndintxf2_mask_pm (operands[0], operands[1],
-                                    op2, op3));
-  DONE;
-})
-
 \f
 ;; Block operation instructions