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 exp and log builtins as x86 intrinsics


The following patch adds support for GCC's new exp and log built-in
functions as 387 instrinsics in the x86 backend.  The patch adds
exp?f2 and log?f2 patterns to i386.md necessary to implement exp,
expf, expl, log, logf and logl as short inlined sequences (when
-ffast-math is specified).

Whilst adding the UNSPEC_EXP and UNSPEC_LOG constants required by
this patch, I decided to renumber the UNSPECV_* constants in i386.md.
I believe this is safe.  The current scheme has the indices specified
in two places non-sequentially.  This interleaving even results in
the same index being duplicated as UNSPEC_SSE_PROLOGUE_SAVE and
UNSPECV_EH_RETURN.  To prevent this happening in future its probably
best to keep the UNSPECVs numbered sequentially.

The patch below has been tested with a full "make bootstrap", all
languages except Ada and treelang, and "make -k check" with no new
regressions on i686-pc-linux-gnu.  I've also run some tests to convince
myself that the numbers using the intrinsics (-ffast-math) are the
expected values returned by the system library.

BUT!  Despite the testing, I'm not 100% certain the patch is correct
as currently written.  Unlike the sin?f2 and cos?f2 patterns, the
exp?f2 and log?f2 patterns require storing a temporary value on the
i387 stack.  Reading though the code of reg-stack.c, I couldn't
immediately see how this is specified and whether it would cause a
problem.  Alas the only backend that uses reg-stack.c is x86, and
none of the FP patterns currently in i386.md require "temporary"
register stack slots.

Hopefully the reviewer (or Jan) will explain why this patch is fine
as it is, or what needs to be changed to make it acceptable.  My
apologies in advance for abusing the review process to request help
in developing a patch.

Not OK for mainline?



2002-08-04  Roger Sayle  <roger@eyesopen.com>

	* reg-stack.c (subst_stack_regs_pat): Treat UNSPEC_EXP and
	UNSPEC_LOG like UNSPEC_SIN and UNSPEC_COS.

	* config/i386/i386.md:  Add patterns for exp?f2 and log?f2 where
	? is s, d, extendsfd, x or t.  Define new UNSPEC constants
	UNSPEC_EXP and UNSPEC_LOG.  Renumber UNSPECV constants to avoid
	potential conflicts.

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


Index: reg-stack.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reg-stack.c,v
retrieving revision 1.112
diff -c -3 -p -r1.112 reg-stack.c
*** reg-stack.c	23 Jun 2002 05:30:04 -0000	1.112
--- reg-stack.c	4 Aug 2002 02:24:03 -0000
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1703,1708 ****
--- 1703,1710 ----
  	      {
  	      case UNSPEC_SIN:
  	      case UNSPEC_COS:
+ 	      case UNSPEC_EXP:
+ 	      case UNSPEC_LOG:
  		/* These insns only operate on the top of the stack.  */

  		src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.379
diff -c -3 -p -r1.379 i386.md
*** config/i386/i386.md	31 Jul 2002 23:18:43 -0000	1.379
--- config/i386/i386.md	4 Aug 2002 02:24:07 -0000
***************
*** 83,91 ****
     (UNSPEC_FSTCW		26)
     (UNSPEC_ADD_CARRY		27)
     (UNSPEC_FLDCW		28)

     ; For SSE/MMX support:
!    (UNSPEC_FIX			30)
     (UNSPEC_MASKMOV		32)
     (UNSPEC_MOVMSK		33)
     (UNSPEC_MOVNT		34)
--- 83,93 ----
     (UNSPEC_FSTCW		26)
     (UNSPEC_ADD_CARRY		27)
     (UNSPEC_FLDCW		28)
+    (UNSPEC_EXP			29)
+    (UNSPEC_LOG			30)

     ; For SSE/MMX support:
!    (UNSPEC_FIX			31)
     (UNSPEC_MASKMOV		32)
     (UNSPEC_MOVMSK		33)
     (UNSPEC_MOVNT		34)
***************
*** 110,122 ****
    ])

  (define_constants
!   [(UNSPECV_BLOCKAGE		0)
!    (UNSPECV_EH_RETURN		13)
!    (UNSPECV_EMMS		31)
!    (UNSPECV_LDMXCSR		37)
!    (UNSPECV_STMXCSR		40)
!    (UNSPECV_FEMMS		46)
!    (UNSPECV_CLFLUSH		57)
    ])

  ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
--- 112,124 ----
    ])

  (define_constants
!   [(UNSPECV_BLOCKAGE		70)
!    (UNSPECV_EH_RETURN		71)
!    (UNSPECV_EMMS		72)
!    (UNSPECV_LDMXCSR		73)
!    (UNSPECV_STMXCSR		74)
!    (UNSPECV_FEMMS		75)
!    (UNSPECV_CLFLUSH		76)
    ])

  ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
***************
*** 14765,14770 ****
--- 14767,14866 ----
    "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
     && flag_unsafe_math_optimizations"
    "fcos"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "XF")])
+
+ (define_insn "expdf2"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_EXP))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fldl2e\;fmul\t%%st(1)\;fst\t%%st(1)\;frndint\;fxch\;fsub\t%%st(1)\;f2xm1\;fld1\;faddp\t%%st, %%st(1)\;fscale\;fstp\t%%st(1)"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "DF")])
+
+ (define_insn "expsf2"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_EXP))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fldl2e\;fmul\t%%st(1)\;fst\t%%st(1)\;frndint\;fxch\;fsub\t%%st(1)\;f2xm1\;fld1\;faddp\t%%st, %%st(1)\;fscale\;fstp\t%%st(1)"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "SF")])
+
+ (define_insn "*expextendsfdf2"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(unspec:DF [(float_extend:DF
+ 		     (match_operand:SF 1 "register_operand" "0"))]
+ 		   UNSPEC_EXP))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fldl2e\;fmul\t%%st(1)\;fst\t%%st(1)\;frndint\;fxch\;fsub\t%%st(1)\;f2xm1\;fld1\;faddp\t%%st, %%st(1)\;fscale\;fstp\t%%st(1)"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "DF")])
+
+ (define_insn "expxf2"
+   [(set (match_operand:XF 0 "register_operand" "=f")
+ 	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_EXP))]
+   "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
+    && flag_unsafe_math_optimizations"
+   "fldl2e\;fmul\t%%st(1)\;fst\t%%st(1)\;frndint\;fxch\;fsub\t%%st(1)\;f2xm1\;fld1\;faddp\t%%st, %%st(1)\;fscale\;fstp\t%%st(1)"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "XF")])
+
+ (define_insn "exptf2"
+   [(set (match_operand:TF 0 "register_operand" "=f")
+ 	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_EXP))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fldl2e\;fmul\t%%st(1)\;fst\t%%st(1)\;frndint\;fxch\;fsub\t%%st(1)\;f2xm1\;fld1\;faddp\t%%st, %%st(1)\;fscale\;fstp\t%%st(1)"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "XF")])
+
+ (define_insn "logdf2"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_LOG))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fldln2\;fxch\;fyl2x"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "DF")])
+
+ (define_insn "logsf2"
+   [(set (match_operand:SF 0 "register_operand" "=f")
+ 	(unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_LOG))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fldln2\;fxch\;fyl2x"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "SF")])
+
+ (define_insn "*logextendsfdf2"
+   [(set (match_operand:DF 0 "register_operand" "=f")
+ 	(unspec:DF [(float_extend:DF
+ 		     (match_operand:SF 1 "register_operand" "0"))]
+ 		   UNSPEC_LOG))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fldln2\;fxch\;fyl2x"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "DF")])
+
+ (define_insn "logxf2"
+   [(set (match_operand:XF 0 "register_operand" "=f")
+ 	(unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_LOG))]
+   "!TARGET_64BIT && TARGET_80387 && !TARGET_NO_FANCY_MATH_387
+    && flag_unsafe_math_optimizations"
+   "fldln2\;fxch\;fyl2x"
+   [(set_attr "type" "fpspc")
+    (set_attr "mode" "XF")])
+
+ (define_insn "logtf2"
+   [(set (match_operand:TF 0 "register_operand" "=f")
+ 	(unspec:TF [(match_operand:TF 1 "register_operand" "0")] UNSPEC_LOG))]
+   "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+    && flag_unsafe_math_optimizations"
+   "fldln2\;fxch\;fyl2x"
    [(set_attr "type" "fpspc")
     (set_attr "mode" "XF")])

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.3
diff -c -3 -p -r1.3 i386-387-1.c
*** testsuite/gcc.dg/i386-387-1.c	14 Apr 2002 11:52:25 -0000	1.3
--- testsuite/gcc.dg/i386-387-1.c	4 Aug 2002 16:10:22 -0000
***************
*** 4,10 ****
--- 4,14 ----
  /* { dg-final { scan-assembler "call\t_?sin" } } */
  /* { dg-final { scan-assembler "call\t_?cos" } } */
  /* { dg-final { scan-assembler "call\t_?sqrt" } } */
+ /* { dg-final { scan-assembler "call\t_?exp" } } */
+ /* { 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) { return __builtin_exp(x); }
+ 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.2
diff -c -3 -p -r1.2 i386-387-2.c
*** testsuite/gcc.dg/i386-387-2.c	29 Mar 2002 23:24:20 -0000	1.2
--- testsuite/gcc.dg/i386-387-2.c	4 Aug 2002 16:10:22 -0000
***************
*** 4,10 ****
--- 4,14 ----
  /* { dg-final { scan-assembler "fsin" } } */
  /* { dg-final { scan-assembler "fcos" } } */
  /* { dg-final { scan-assembler "fsqrt" } } */
+ /* { dg-final { scan-assembler "fldl2e" } } */
+ /* { dg-final { scan-assembler "fldln2" } } */

  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) { return __builtin_exp(x); }
+ 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]