aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <uros@kss-loka.si>2004-02-12 00:39:41 +0100
committerRoger Sayle <sayle@gcc.gnu.org>2004-02-11 23:39:41 +0000
commit3b8e0c9129b0ed3fe2e4aa5bc466df5348e2d5fd (patch)
tree159c66f75d67ab22ee9d79a474ed9f6f66eab4ba
parenta6abdce327180878f4753126647b351026b2dcd0 (diff)
downloadgcc-3b8e0c9129b0ed3fe2e4aa5bc466df5348e2d5fd.zip
gcc-3b8e0c9129b0ed3fe2e4aa5bc466df5348e2d5fd.tar.gz
gcc-3b8e0c9129b0ed3fe2e4aa5bc466df5348e2d5fd.tar.bz2
optabs.h (enum optab_index): Add new OTI_log10 and OTI_log2.
2004-02-11 Uros Bizjak <uros@kss-loka.si> * optabs.h (enum optab_index): Add new OTI_log10 and OTI_log2. (log10_optab, log2_optab): Define corresponding macros. * optabs.c (init_optabs): Initialize log10_optab and log2_optab. * genopinit.c (optabs): Implement log10_optab and log2_optab using log10?f2 and log2?f2 patterns. * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOG10{,F,L} using log10_optab, and BUILT_IN_LOG2{,F,L} using log2_optab. (expand_builtin): Expand BUILT_IN_LOG10{,F,L} and BUILT_IN_LOG2{,F,L} using expand_builtin_mathfn if flag_unsafe_math_optimizations is set. * config/i386/i386.md (log10sf2, log10df2, log10xf2, log2sf2, log2df2, log2xf2): New patterns to implement log10, log10f, log10l, log2, log2f and log2l built-ins as inline x87 intrinsics. * gcc.dg/builtins-33.c: New test. From-SVN: r77675
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/builtins.c14
-rw-r--r--gcc/config/i386/i386.md82
-rw-r--r--gcc/genopinit.c2
-rw-r--r--gcc/optabs.c2
-rw-r--r--gcc/optabs.h6
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/builtins-33.c48
8 files changed, 174 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9c73440..22d06d6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2004-02-11 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_log10 and OTI_log2.
+ (log10_optab, log2_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize log10_optab and log2_optab.
+ * genopinit.c (optabs): Implement log10_optab and log2_optab
+ using log10?f2 and log2?f2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOG10{,F,L}
+ using log10_optab, and BUILT_IN_LOG2{,F,L} using log2_optab.
+ (expand_builtin): Expand BUILT_IN_LOG10{,F,L} and BUILT_IN_LOG2{,F,L}
+ using expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * config/i386/i386.md (log10sf2, log10df2, log10xf2, log2sf2,
+ log2df2, log2xf2): New patterns to implement log10, log10f, log10l,
+ log2, log2f and log2l built-ins as inline x87 intrinsics.
+
2004-02-11 Richard Henderson <rth@redhat.com>
* flow.c (insn_dead_p): A clobber of a dead hard register is a
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 2fdc370..a5520a3 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1662,6 +1662,14 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
errno_set = true; builtin_optab = log_optab; break;
+ case BUILT_IN_LOG10:
+ case BUILT_IN_LOG10F:
+ case BUILT_IN_LOG10L:
+ errno_set = true; builtin_optab = log10_optab; break;
+ case BUILT_IN_LOG2:
+ case BUILT_IN_LOG2F:
+ case BUILT_IN_LOG2L:
+ errno_set = true; builtin_optab = log2_optab; break;
case BUILT_IN_TAN:
case BUILT_IN_TANF:
case BUILT_IN_TANL:
@@ -5130,6 +5138,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
case BUILT_IN_LOG:
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
+ case BUILT_IN_LOG10:
+ case BUILT_IN_LOG10F:
+ case BUILT_IN_LOG10L:
+ case BUILT_IN_LOG2:
+ case BUILT_IN_LOG2F:
+ case BUILT_IN_LOG2L:
case BUILT_IN_TAN:
case BUILT_IN_TANF:
case BUILT_IN_TANL:
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 2c7bbb4..70c21f8 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -15154,6 +15154,88 @@
emit_move_insn (operands[2], temp);
})
+(define_expand "log10sf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_operand:SF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:SF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (3); /* fldlg2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_expand "log10df2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_operand:DF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:DF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (3); /* fldlg2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_expand "log10xf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+
+ operands[2] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (3); /* fldlg2 */
+ emit_move_insn (operands[2], temp);
+})
+
+(define_expand "log2sf2"
+ [(parallel [(set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_operand:SF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:SF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+
+})
+
+(define_expand "log2df2"
+ [(parallel [(set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_operand:DF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:DF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "log2xf2"
+ [(parallel [(set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")
+ (match_dup 2)] UNSPEC_FYL2X))
+ (clobber (match_scratch:XF 3 ""))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
+})
+
(define_insn "*fscale_sfxf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(unspec:SF [(match_operand:XF 2 "register_operand" "0")
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 5e1599a..cbdc3dd 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -126,6 +126,8 @@ static const char * const optabs[] =
"cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
"exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
"log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
+ "log10_optab->handlers[$A].insn_code = CODE_FOR_$(log10$a2$)",
+ "log2_optab->handlers[$A].insn_code = CODE_FOR_$(log2$a2$)",
"tan_optab->handlers[$A].insn_code = CODE_FOR_$(tan$a2$)",
"atan_optab->handlers[$A].insn_code = CODE_FOR_$(atan$a2$)",
"strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
diff --git a/gcc/optabs.c b/gcc/optabs.c
index e748c15..7a47a6f 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5263,6 +5263,8 @@ init_optabs (void)
cos_optab = init_optab (UNKNOWN);
exp_optab = init_optab (UNKNOWN);
log_optab = init_optab (UNKNOWN);
+ log10_optab = init_optab (UNKNOWN);
+ log2_optab = init_optab (UNKNOWN);
tan_optab = init_optab (UNKNOWN);
atan_optab = init_optab (UNKNOWN);
strlen_optab = init_optab (UNKNOWN);
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 4f39e35..496ba1a 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -156,6 +156,10 @@ enum optab_index
OTI_exp,
/* Natural Logarithm */
OTI_log,
+ /* Base-10 Logarithm */
+ OTI_log10,
+ /* Base-2 Logarithm */
+ OTI_log2,
/* Rounding functions */
OTI_floor,
OTI_ceil,
@@ -260,6 +264,8 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define cos_optab (optab_table[OTI_cos])
#define exp_optab (optab_table[OTI_exp])
#define log_optab (optab_table[OTI_log])
+#define log10_optab (optab_table[OTI_log10])
+#define log2_optab (optab_table[OTI_log2])
#define floor_optab (optab_table[OTI_floor])
#define ceil_optab (optab_table[OTI_ceil])
#define btrunc_optab (optab_table[OTI_trunc])
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index be07e1f..7c1aa66 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-02-11 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-33.c: New test.
+
2004-02-11 Paolo Bonzini <bonzini@gnu.org>
* gcc.dg/pr14092-1.c: Use intptr_t for the cast.
diff --git a/gcc/testsuite/gcc.dg/builtins-33.c b/gcc/testsuite/gcc.dg/builtins-33.c
new file mode 100644
index 0000000..758978f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-33.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Check that log10, log10f, log10l, log2, log2f and log2l
+ built-in functions compile.
+
+ Written by Uros Bizjak, 11th February 2004. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern double log10(double);
+extern double log2(double);
+extern float log10f(float);
+extern float log2f(float);
+extern long double log10l(long double);
+extern long double log2l(long double);
+
+
+double test1(double x)
+{
+ return log10(x);
+}
+
+double test2(double x)
+{
+ return log2(x);
+}
+
+float test1f(float x)
+{
+ return log10f(x);
+}
+
+float test2f(float x)
+{
+ return log2f(x);
+}
+
+long double test1l(long double x)
+{
+ return log10l(x);
+}
+
+long double test2l(long double x)
+{
+ return log2l(x);
+}
+