This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Implement log builtin as x87 intrinsic
- From: Roger Sayle <roger at www dot eyesopen dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 11 May 2003 19:58:20 -0600 (MDT)
- Subject: [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