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] Implement log builtin as x87 intrinsic


The following patch implements the log, logf and logl mathematical
functions as inline intrinsics on x86.  My first attempt at this was
http://gcc.gnu.org/ml/gcc-patches/2002-08/msg00246.html, however
RTH suggested a "define_expand" implementation that exposed the
individual FP instructions at the RTL level would provide better
scheduling opportunities (not to mention the FP stack overflow
problems in my first attempt :).

Its been nine months, but I now think I understand enough of GCC's
machine descriptions to give it a second try.  RTH was of course
right, and with this patch GCC can often avoid the "xchg" instruction
that was always present with the original "macro" implementation
above.


The following patch has been tested on i686-pc-linux-gnu with a
full "make bootstrap", all languages except treelang (including
Ada!), and regression tested with a top-level "make -k check"
with no new regressions.  I've also confirmed by hand that it
produces the expected results with -ffast-math, i.e. that
log(10.0) ~= 2.30259.

Ok for mainline?


2003-05-11  Roger Sayle  <roger@eyesopen.com>

	* config/i386/i386.md (logsf2, logdf2, logxf2, logdf2): New patterns
	to implement log, logf and logl built-ins as inline x87 intrinsics.
	(UNSPEC_FYL2X): New unspec to represent x87's "fyl2x" instruction.
	(*fyl2x_sfxf3, *fyl2x_dfxf3, *fyl2x_xf3, *fyl2x_tfxf3): New insn
	patterns for x87's "fyl2x" instruction, used by log?f2 patterns.

	* reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FYL2X like
	UNSPEC_FPATAN, i.e. replaces two stack operands with single result.

	* gcc.dg/i386-387-1.c: Update to also test log.
	* gcc.dg/i386-387-2.c: Likewise.


Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.458
diff -c -3 -p -r1.458 i386.md
*** config/i386/i386.md	10 May 2003 22:59:00 -0000	1.458
--- config/i386/i386.md	11 May 2003 21:24:00 -0000
***************
*** 112,117 ****
--- 112,118 ----

     ; x87 Floating point
     (UNSPEC_FPATAN		65)
+    (UNSPEC_FYL2X		66)
    ])

  (define_constants
***************
*** 15522,15527 ****
--- 15523,15628 ----
    "fpatan"
    [(set_attr "type" "fpspc")
     (set_attr "mode" "XF")])
+
+ (define_insn "*fyl2x_sfxf3"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(unspec:SF [(match_operand:SF 2 "register_operand" "0")
+ 		    (match_operand:XF 1 "register_operand" "u")]
+ 	 UNSPEC_FYL2X))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fyl2x"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "SF")])
+
+ (define_insn "*fyl2x_dfxf3"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(unspec:DF [(match_operand:DF 2 "register_operand" "0")
+ 		    (match_operand:XF 1 "register_operand" "u")]
+ 	 UNSPEC_FYL2X))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fyl2x"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "DF")])
+
+ (define_insn "*fyl2x_xf3"
+   [(set (match_operand:XF 0 "register_operand" "=f")
+ 	(unspec:XF [(match_operand:XF 2 "register_operand" "0")
+ 		    (match_operand:XF 1 "register_operand" "u")]
+ 	 UNSPEC_FYL2X))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fyl2x"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "XF")])
+
+ (define_insn "*fyl2x_tfxf3"
+   [(set (match_operand:TF 0 "register_operand" "=f")
+ 	(unspec:TF [(match_operand:TF 2 "register_operand" "0")
+ 		    (match_operand:XF 1 "register_operand" "u")]
+ 	 UNSPEC_FYL2X))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fyl2x"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "XF")])
+
+ (define_expand "logsf2"
+   [(set (match_operand:SF 0 "register_operand" "")
+ 	(unspec:SF [(match_operand:SF 1 "register_operand" "")
+ 		    (match_dup 2)] UNSPEC_FYL2X))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+ {
+   rtx temp;
+
+   operands[2] = gen_reg_rtx (XFmode);
+   temp = standard_80387_constant_rtx (4); /* fldln2 */
+   emit_move_insn (operands[2], temp);
+ })
+
+ (define_expand "logdf2"
+   [(set (match_operand:DF 0 "register_operand" "")
+ 	(unspec:DF [(match_operand:DF 1 "register_operand" "")
+ 		    (match_dup 2)] UNSPEC_FYL2X))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+ {
+   rtx temp;
+
+   operands[2] = gen_reg_rtx (XFmode);
+   temp = standard_80387_constant_rtx (4); /* fldln2 */
+   emit_move_insn (operands[2], temp);
+ })
+
+ (define_expand "logxf2"
+   [(set (match_operand:XF 0 "register_operand" "")
+ 	(unspec:XF [(match_operand:XF 1 "register_operand" "")
+ 		    (match_dup 2)] UNSPEC_FYL2X))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+ {
+   rtx temp;
+
+   operands[2] = gen_reg_rtx (XFmode);
+   temp = standard_80387_constant_rtx (4); /* fldln2 */
+   emit_move_insn (operands[2], temp);
+ })
+
+ (define_expand "logtf2"
+   [(set (match_operand:TF 0 "register_operand" "")
+ 	(unspec:TF [(match_operand:TF 1 "register_operand" "")
+ 		    (match_dup 2)] UNSPEC_FYL2X))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+ {
+   rtx temp;
+
+   operands[2] = gen_reg_rtx (XFmode);
+   temp = standard_80387_constant_rtx (4); /* fldln2 */
+   emit_move_insn (operands[2], temp);
+ })

  ;; Block operation instructions

Index: reg-stack.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reg-stack.c,v
retrieving revision 1.125
diff -c -3 -p -r1.125 reg-stack.c
*** reg-stack.c	15 Mar 2003 13:43:30 -0000	1.125
--- reg-stack.c	11 May 2003 21:24:01 -0000
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1729,1734 ****
--- 1729,1735 ----
  		break;

  	      case UNSPEC_FPATAN:
+ 	      case UNSPEC_FYL2X:
  		/* These insns operate on the top two stack slots.  */

  		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
Index: testsuite/gcc.dg/i386-387-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/i386-387-1.c,v
retrieving revision 1.4
diff -c -3 -p -r1.4 i386-387-1.c
*** testsuite/gcc.dg/i386-387-1.c	13 Feb 2003 03:09:45 -0000	1.4
--- testsuite/gcc.dg/i386-387-1.c	11 May 2003 21:24:01 -0000
***************
*** 5,12 ****
--- 5,14 ----
  /* { dg-final { scan-assembler "call\t_?cos" } } */
  /* { dg-final { scan-assembler "call\t_?sqrt" } } */
  /* { dg-final { scan-assembler "call\t_?atan2" } } */
+ /* { dg-final { scan-assembler "call\t_?log" } } */

  double f1(double x) { return __builtin_sin(x); }
  double f2(double x) { return __builtin_cos(x); }
  double f3(double x) { return __builtin_sqrt(x); }
  double f4(double x, double y) { return __builtin_atan2(x,y); }
+ double f5(double x) { return __builtin_log(x); }
Index: testsuite/gcc.dg/i386-387-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/i386-387-2.c,v
retrieving revision 1.3
diff -c -3 -p -r1.3 i386-387-2.c
*** testsuite/gcc.dg/i386-387-2.c	13 Feb 2003 03:09:45 -0000	1.3
--- testsuite/gcc.dg/i386-387-2.c	11 May 2003 21:24:01 -0000
***************
*** 5,12 ****
--- 5,14 ----
  /* { dg-final { scan-assembler "fcos" } } */
  /* { dg-final { scan-assembler "fsqrt" } } */
  /* { dg-final { scan-assembler "fpatan" } } */
+ /* { dg-final { scan-assembler "fyl2x" } } */

  double f1(double x) { return __builtin_sin(x); }
  double f2(double x) { return __builtin_cos(x); }
  double f3(double x) { return __builtin_sqrt(x); }
  double f4(double x, double y) { return __builtin_atan2(x,y); }
+ double f5(double x) { return __builtin_log(x); }


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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