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]

[RFC PATCH] tangent builtin implementation for i386


Hello!

Attached patch implements tangent builtin for i386. However, this is my first try to write RTL code, so I guess I didn't get all thigs right...
Patch passed following testcase, both with "-O2 -lm" and "-O2 -ffast-math".


--cut-here-
int main()
{
double i;
double x = 0.0;

for(i = -3.0; i < 2.001; i = i + 0.01)
    x += tan(i);

printf ("%f\n", x);
return 0;
}
--cut-here-
[uros@localhost test]$ gcc -O2 -lm tan.c;./a.out
85.648634
[uros@localhost test]$ gcc -O2 -ffast-math tan.c;./a.out
85.648634

An unfortunate "feature" of i386 fptan command is that it pushes 1.0 on top of i387 stack after calculated result. To compensate this feature, fstp %y0 was added into assembler, so result is now on top of stack. Tan insn now looks like sin and cos instruction and UNSPEC_TAN can be treated as UNSPEC_SIN and UNSPEC_COS in reg-stack.c.

I would like to somehow model the push of value 1.0 on stack, so for example code like 1.0/tan(x) could use value 1.0 which was pushed on stack, instead of blindly popping it and loading constant 1.0 again to perform calculations with constant 1.0. Unfortunatelly, I don't know where/how to model this effect...

Another type of optimizations with tangent builtin will be possible in fold-const.c. As it is now, the only trigonometric optimization is :
/* Optimize tan(x)*cos(x) as sin(x). */


With tan(), we could perform classical optimization of sin(x)/cos(x) as tan(x).

Uros.


? config.cache
? config.log
? maybedep.tmp
? serdep.tmp
Index: gcc/reg-stack.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/reg-stack.c,v
retrieving revision 1.144
diff -u -r1.144 reg-stack.c
--- gcc/reg-stack.c	3 Mar 2004 08:34:33 -0000	1.144
+++ gcc/reg-stack.c	12 Mar 2004 07:47:58 -0000
@@ -1669,6 +1669,7 @@
 	      {
 	      case UNSPEC_SIN:
 	      case UNSPEC_COS:
+	      case UNSPEC_TAN:
 	      case UNSPEC_FRNDINT:
 	      case UNSPEC_F2XM1:
 		/* These insns only operate on the top of the stack.  */
Index: gcc/config/i386/i386.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.519
diff -u -r1.519 i386.md
--- gcc/config/i386/i386.md	10 Mar 2004 22:36:13 -0000	1.519
+++ gcc/config/i386/i386.md	12 Mar 2004 07:48:02 -0000
@@ -77,6 +77,7 @@
    (UNSPEC_SCAS			20)
    (UNSPEC_SIN			21)
    (UNSPEC_COS			22)
+   (UNSPEC_TAN			23)
    (UNSPEC_FNSTSW		24)
    (UNSPEC_SAHF			25)
    (UNSPEC_FSTCW		26)
@@ -14941,6 +14942,51 @@
   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
    && flag_unsafe_math_optimizations"
   "fcos"
+  [(set_attr "type" "fpspc")
+   (set_attr "mode" "XF")])
+
+(define_insn "tandf2"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+	(unspec:DF [(match_operand:DF 1 "register_operand" "0")]
+		   UNSPEC_TAN))
+   (clobber (match_scratch:DF 2 "=u"))]
+  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
+   && flag_unsafe_math_optimizations"
+  "fptan\;fstp\t%y0"
+  [(set_attr "type" "fpspc")
+   (set_attr "mode" "DF")])
+
+(define_insn "tansf2"
+  [(set (match_operand:SF 0 "register_operand" "=f")
+	(unspec:SF [(match_operand:SF 1 "register_operand" "0")]
+	UNSPEC_TAN))
+   (clobber (match_scratch:SF 2 "=u"))]
+  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
+   && flag_unsafe_math_optimizations"
+  "fptan\;fstp\t%y0"
+  [(set_attr "type" "fpspc")
+   (set_attr "mode" "SF")])
+
+(define_insn "*tanextendsfdf2"
+  [(set (match_operand:DF 0 "register_operand" "=f")
+	(unspec:DF [(float_extend:DF
+		     (match_operand:SF 1 "register_operand" "0"))]
+		   UNSPEC_TAN))
+   (clobber (match_scratch:DF 2 "=u"))]
+  "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 
+   && flag_unsafe_math_optimizations"
+  "fptan\;fstp\t%y0"
+  [(set_attr "type" "fpspc")
+   (set_attr "mode" "DF")])
+
+(define_insn "tanxf2"
+  [(set (match_operand:XF 0 "register_operand" "=f")
+	(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+		   UNSPEC_TAN))
+   (clobber (match_scratch:XF 2 "=u"))]
+  "TARGET_80387 && !TARGET_NO_FANCY_MATH_387
+   && flag_unsafe_math_optimizations"
+  "fptan\;fstp\t%y0"
   [(set_attr "type" "fpspc")
    (set_attr "mode" "XF")])
 

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