This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH?] Implement exp and log builtins as x86 intrinsics
- From: Roger Sayle <roger at eyesopen dot com>
- To: <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 4 Aug 2002 10:33:57 -0600 (MDT)
- Subject: [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