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]

[Patch, i386]: Rewrite and macroize sin, cos and sincos x87 patterns


Hello!

This patch rewrites and macroizes sin, cos and sincos x87 patterns. It rewrites these patterns the same way as fsqrt patterns have been rewritten (inherent float extensions of DFmode and SFmode operands to XFmode).

Patch was bootstrapped on i686-pc-linux-gnu, regression tested for c, c++ and fortran.

2006-11-25 Uros Bizjak <ubizjak@gmail.com>

       * config/i386/i386.md (*sinxf2): Rename to *sinxf2_i387.
       (*cosxf2): Rename to cosxf2_i387.

       (*sindf2, *sinsf2): Extend operand 1 to XFmode.  Macroize patterns
       using X87MODEF12 mode macro. Rename patterns to
       *sin_extend<mode>xf2_i387.  Use SSE_FLOAT_MODE_P to disable patterns
       for SSE math.
       (*cosdf2, *cossf2): Ditto.
       (sincosdf3, sincossf3): Ditto.  Fix corresponding splitters to match
       extended input operands.

(sincos<mode>3): New expander.

       (*sinextendsfdf2, *cosextendsfdf2, *sincosextendsfdf3): Remove
       insn patterns and corresponding splitters.

BTW: Patch also adds a couple of missing spaces in emit_insn() call, spotted by Vaclav Haisman - thanks.

OK for mainline?

Uros.
Index: i386.md
===================================================================
--- i386.md	(revision 119199)
+++ i386.md	(working copy)
@@ -15634,8 +15634,8 @@
   rtx op1 = gen_reg_rtx (XFmode);
   rtx op2 = gen_reg_rtx (XFmode);
 
-  emit_insn(gen_extend<mode>xf2 (op1, operands[1]));
-  emit_insn(gen_extend<mode>xf2 (op2, operands[2]));
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
+  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
 
   emit_label (label);
   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
@@ -15691,8 +15691,8 @@
   rtx op1 = gen_reg_rtx (XFmode);
   rtx op2 = gen_reg_rtx (XFmode);
 
-  emit_insn(gen_extend<mode>xf2 (op1, operands[1]));
-  emit_insn(gen_extend<mode>xf2 (op2, operands[2]));
+  emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
+  emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
 
   emit_label (label);
 
@@ -15703,86 +15703,48 @@
   DONE;
 })
 
-(define_insn "*sindf2"
-  [(set (match_operand:DF 0 "register_operand" "=f")
-	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
+(define_insn "*sinxf2_i387"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
   "fsin"
   [(set_attr "type" "fpspc")
-   (set_attr "mode" "DF")])
+   (set_attr "mode" "XF")])
 
-(define_insn "*sinsf2"
-  [(set (match_operand:SF 0 "register_operand" "=f")
-	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
-  "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
-   && flag_unsafe_math_optimizations"
-  "fsin"
-  [(set_attr "type" "fpspc")
-   (set_attr "mode" "SF")])
-
-(define_insn "*sinextendsfdf2"
-  [(set (match_operand:DF 0 "register_operand" "=f")
-	(unspec:DF [(float_extend:DF
-		     (match_operand:SF 1 "register_operand" "0"))]
+(define_insn "*sin_extend<mode>xf2_i387"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+	(unspec:XF [(float_extend:XF
+		      (match_operand:X87MODEF12 1 "register_operand" "0"))]
 		   UNSPEC_SIN))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
+   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+       || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
   "fsin"
   [(set_attr "type" "fpspc")
-   (set_attr "mode" "DF")])
+   (set_attr "mode" "XF")])
 
-(define_insn "*sinxf2"
+(define_insn "*cosxf2_i387"
   [(set (match_operand:XF 0 "register_operand" "=f")
-	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
+	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
   "TARGET_USE_FANCY_MATH_387
    && flag_unsafe_math_optimizations"
-  "fsin"
+  "fcos"
   [(set_attr "type" "fpspc")
    (set_attr "mode" "XF")])
 
-(define_insn "*cosdf2"
-  [(set (match_operand:DF 0 "register_operand" "=f")
-	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
-  "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
-   && flag_unsafe_math_optimizations"
-  "fcos"
-  [(set_attr "type" "fpspc")
-   (set_attr "mode" "DF")])
-
-(define_insn "*cossf2"
-  [(set (match_operand:SF 0 "register_operand" "=f")
-	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
-  "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
-   && flag_unsafe_math_optimizations"
-  "fcos"
-  [(set_attr "type" "fpspc")
-   (set_attr "mode" "SF")])
-
-(define_insn "*cosextendsfdf2"
-  [(set (match_operand:DF 0 "register_operand" "=f")
-	(unspec:DF [(float_extend:DF
-		     (match_operand:SF 1 "register_operand" "0"))]
+(define_insn "*cos_extend<mode>xf2_i387"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+	(unspec:XF [(float_extend:XF
+		      (match_operand:X87MODEF12 1 "register_operand" "0"))]
 		   UNSPEC_COS))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
+   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+       || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
   "fcos"
   [(set_attr "type" "fpspc")
-   (set_attr "mode" "DF")])
-
-(define_insn "*cosxf2"
-  [(set (match_operand:XF 0 "register_operand" "=f")
-	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
-  "TARGET_USE_FANCY_MATH_387
-   && flag_unsafe_math_optimizations"
-  "fcos"
-  [(set_attr "type" "fpspc")
    (set_attr "mode" "XF")])
 
 ;; With sincos pattern defined, sin and cos builtin function will be
@@ -15791,126 +15753,50 @@
 ;; otherwise sincos pattern will be split back to sin or cos pattern,
 ;; depending on the unused output.
 
-(define_insn "sincosdf3"
-  [(set (match_operand:DF 0 "register_operand" "=f")
-	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]
+(define_insn "sincosxf3"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
 		   UNSPEC_SINCOS_COS))
-   (set (match_operand:DF 1 "register_operand" "=u")
-        (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
+   (set (match_operand:XF 1 "register_operand" "=u")
+        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
   "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
   "fsincos"
   [(set_attr "type" "fpspc")
-   (set_attr "mode" "DF")])
+   (set_attr "mode" "XF")])
 
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
+  [(set (match_operand:XF 0 "register_operand" "")
+	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
 		   UNSPEC_SINCOS_COS))
-   (set (match_operand:DF 1 "register_operand" "")
-	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
+   (set (match_operand:XF 1 "register_operand" "")
+	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
    && !reload_completed && !reload_in_progress"
-  [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
+  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
   "")
 
 (define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-	(unspec:DF [(match_operand:DF 2 "register_operand" "")]
+  [(set (match_operand:XF 0 "register_operand" "")
+	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
 		   UNSPEC_SINCOS_COS))
-   (set (match_operand:DF 1 "register_operand" "")
-	(unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
+   (set (match_operand:XF 1 "register_operand" "")
+	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
    && !reload_completed && !reload_in_progress"
-  [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
+  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
   "")
 
-(define_insn "sincossf3"
-  [(set (match_operand:SF 0 "register_operand" "=f")
-	(unspec:SF [(match_operand:SF 2 "register_operand" "0")]
-		   UNSPEC_SINCOS_COS))
-   (set (match_operand:SF 1 "register_operand" "=u")
-        (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
-  "TARGET_USE_FANCY_MATH_387
-   && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
-   && flag_unsafe_math_optimizations"
-  "fsincos"
-  [(set_attr "type" "fpspc")
-   (set_attr "mode" "SF")])
-
-(define_split
-  [(set (match_operand:SF 0 "register_operand" "")
-	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
-		   UNSPEC_SINCOS_COS))
-   (set (match_operand:SF 1 "register_operand" "")
-	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
-  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
-   && !reload_completed && !reload_in_progress"
-  [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
-  "")
-
-(define_split
-  [(set (match_operand:SF 0 "register_operand" "")
-	(unspec:SF [(match_operand:SF 2 "register_operand" "")]
-		   UNSPEC_SINCOS_COS))
-   (set (match_operand:SF 1 "register_operand" "")
-	(unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
-  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
-   && !reload_completed && !reload_in_progress"
-  [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
-  "")
-
-(define_insn "*sincosextendsfdf3"
-  [(set (match_operand:DF 0 "register_operand" "=f")
-	(unspec:DF [(float_extend:DF
-		     (match_operand:SF 2 "register_operand" "0"))]
-		   UNSPEC_SINCOS_COS))
-   (set (match_operand:DF 1 "register_operand" "=u")
-        (unspec:DF [(float_extend:DF
-		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
-  "TARGET_USE_FANCY_MATH_387
-   && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
-   && flag_unsafe_math_optimizations"
-  "fsincos"
-  [(set_attr "type" "fpspc")
-   (set_attr "mode" "DF")])
-
-(define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-	(unspec:DF [(float_extend:DF
-		     (match_operand:SF 2 "register_operand" ""))]
-		   UNSPEC_SINCOS_COS))
-   (set (match_operand:DF 1 "register_operand" "")
-        (unspec:DF [(float_extend:DF
-		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
-  "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
-   && !reload_completed && !reload_in_progress"
-  [(set (match_dup 1) (unspec:DF [(float_extend:DF
-				   (match_dup 2))] UNSPEC_SIN))]
-  "")
-
-(define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-	(unspec:DF [(float_extend:DF
-		     (match_operand:SF 2 "register_operand" ""))]
-		   UNSPEC_SINCOS_COS))
-   (set (match_operand:DF 1 "register_operand" "")
-        (unspec:DF [(float_extend:DF
-		     (match_dup 2))] UNSPEC_SINCOS_SIN))]
-  "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
-   && !reload_completed && !reload_in_progress"
-  [(set (match_dup 0) (unspec:DF [(float_extend:DF
-				   (match_dup 2))] UNSPEC_COS))]
-  "")
-
-(define_insn "sincosxf3"
+(define_insn "sincos_extend<mode>xf3_i387"
   [(set (match_operand:XF 0 "register_operand" "=f")
-	(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
+	(unspec:XF [(float_extend:XF
+		      (match_operand:X87MODEF12 2 "register_operand" "0"))]
 		   UNSPEC_SINCOS_COS))
    (set (match_operand:XF 1 "register_operand" "=u")
-        (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
+        (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
   "TARGET_USE_FANCY_MATH_387
+   && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
+       || TARGET_MIX_SSE_I387)
    && flag_unsafe_math_optimizations"
   "fsincos"
   [(set_attr "type" "fpspc")
@@ -15918,26 +15804,46 @@
 
 (define_split
   [(set (match_operand:XF 0 "register_operand" "")
-	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
+	(unspec:XF [(float_extend:XF
+		      (match_operand:X87MODEF12 2 "register_operand" ""))]
 		   UNSPEC_SINCOS_COS))
    (set (match_operand:XF 1 "register_operand" "")
-	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
+	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
    && !reload_completed && !reload_in_progress"
-  [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
+  [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
   "")
 
 (define_split
   [(set (match_operand:XF 0 "register_operand" "")
-	(unspec:XF [(match_operand:XF 2 "register_operand" "")]
+	(unspec:XF [(float_extend:XF
+		      (match_operand:X87MODEF12 2 "register_operand" ""))]
 		   UNSPEC_SINCOS_COS))
    (set (match_operand:XF 1 "register_operand" "")
-	(unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
+	(unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
    && !reload_completed && !reload_in_progress"
-  [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
+  [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
   "")
 
+(define_expand "sincos<mode>3"
+  [(use (match_operand:X87MODEF12 0 "register_operand" ""))
+   (use (match_operand:X87MODEF12 1 "register_operand" ""))
+   (use (match_operand:X87MODEF12 2 "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_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
+  emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
+  emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[1], op1));
+  DONE;
+})
+
 (define_insn "*tandf3_1"
   [(set (match_operand:DF 0 "register_operand" "=f")
 	(unspec:DF [(match_operand:DF 2 "register_operand" "0")]

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