summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-04-15 02:43:46 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2004-04-15 02:43:46 +0000
commit4efbc64177acabe790e13e3c9a3b5b455104b5f9 (patch)
treea547f0ea372bc9cb69e8d7bac590390b63bae146
parentd42494d77af87c5b8f027475d8100238527d467e (diff)
downloadgcc-4efbc64177acabe790e13e3c9a3b5b455104b5f9.tar.gz
2004-04-14 Uros Bizjak <uros@kss-loka.si>
* optabs.h (enum optab_index): Add new OTI_logb and OTI_ilogb. (logb_optab, ilogb_optab): Define corresponding macros. * optabs.c (init_optabs): Initialize logb_optab and ilogb_optab. * genopinit.c (optabs): Implement logb_optab and ilogb_optab using logb?f2 and ilogb?i2 patterns. * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOGB{,F,L} using logb_optab, and BUILT_IN_ILOGB{,F,L} using ilogb_optab. (expand_builtin): Expand BUILT_IN_LOGB{,F,L} and BUILT_IN_ILOGB{,F,L} using expand_builtin_mathfn if flag_unsafe_math_optimizations is set. * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_XTRACT_FRACT and UNSPEC_XTRACT_EXP. * config/i386/i386.md (*fxtractdf3, *fxtractsf3, *fxtractxf3): New patterns to implement fxtract x87 instruction. (logbdf2, logbsf2, logbxf2, ilogbsi2): New expanders to implement logb, logbf, logbl, ilogb, ilogbf and ilogbl built-ins as inline x87 intrinsics. (UNSPEC_XTRACT_FRACT, UNSPEC_XTRACT_EXP): New unspecs to represent x87's fxtract insn. * gcc.dg/builtins-38.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80709 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/builtins.c14
-rw-r--r--gcc/config/i386/i386.md90
-rw-r--r--gcc/genopinit.c2
-rw-r--r--gcc/optabs.c2
-rw-r--r--gcc/optabs.h5
-rw-r--r--gcc/reg-stack.c2
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/builtins-38.c48
9 files changed, 190 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9cc50df18b9..428b3fb0c4b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,26 @@
+2004-04-14 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_logb and OTI_ilogb.
+ (logb_optab, ilogb_optab): Define corresponding macros.
+ * optabs.c (init_optabs): Initialize logb_optab and ilogb_optab.
+ * genopinit.c (optabs): Implement logb_optab and ilogb_optab
+ using logb?f2 and ilogb?i2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOGB{,F,L}
+ using logb_optab, and BUILT_IN_ILOGB{,F,L} using ilogb_optab.
+ (expand_builtin): Expand BUILT_IN_LOGB{,F,L} and BUILT_IN_ILOGB{,F,L}
+ using expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_XTRACT_FRACT
+ and UNSPEC_XTRACT_EXP.
+
+ * config/i386/i386.md (*fxtractdf3, *fxtractsf3, *fxtractxf3): New
+ patterns to implement fxtract x87 instruction.
+ (logbdf2, logbsf2, logbxf2, ilogbsi2): New expanders to implement
+ logb, logbf, logbl, ilogb, ilogbf and ilogbl built-ins as inline x87
+ intrinsics.
+ (UNSPEC_XTRACT_FRACT, UNSPEC_XTRACT_EXP): New unspecs to represent
+ x87's fxtract insn.
+
2004-04-14 Eric Christopher <echristo@redhat.com>
* config/mips/t-elf: Enable multilibs by default.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e1ba8586a1c..d653ec75f1a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1565,6 +1565,14 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
case BUILT_IN_EXP2F:
case BUILT_IN_EXP2L:
errno_set = true; builtin_optab = exp2_optab; break;
+ case BUILT_IN_LOGB:
+ case BUILT_IN_LOGBF:
+ case BUILT_IN_LOGBL:
+ errno_set = true; builtin_optab = logb_optab; break;
+ case BUILT_IN_ILOGB:
+ case BUILT_IN_ILOGBF:
+ case BUILT_IN_ILOGBL:
+ errno_set = true; builtin_optab = ilogb_optab; break;
case BUILT_IN_LOG:
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
@@ -5178,6 +5186,12 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
case BUILT_IN_EXP2:
case BUILT_IN_EXP2F:
case BUILT_IN_EXP2L:
+ case BUILT_IN_LOGB:
+ case BUILT_IN_LOGBF:
+ case BUILT_IN_LOGBL:
+ case BUILT_IN_ILOGB:
+ case BUILT_IN_ILOGBF:
+ case BUILT_IN_ILOGBL:
case BUILT_IN_LOG:
case BUILT_IN_LOGF:
case BUILT_IN_LOGL:
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index e4f2cce5fbe..2c498e0bf9f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -126,6 +126,8 @@
(UNSPEC_SINCOS_SIN 81)
(UNSPEC_TAN_ONE 82)
(UNSPEC_TAN_TAN 83)
+ (UNSPEC_XTRACT_FRACT 84)
+ (UNSPEC_XTRACT_EXP 85)
; REP instruction
(UNSPEC_REP 75)
@@ -15445,6 +15447,94 @@
emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
})
+(define_insn "*fxtractdf3"
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:DF 1 "register_operand" "=u")
+ (unspec:DF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fxtract"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "DF")])
+
+(define_expand "logbdf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:DF [(match_operand:DF 1 "register_operand" "")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:DF 0 "register_operand" "")
+ (unspec:DF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (DFmode);
+})
+
+(define_insn "*fxtractsf3"
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:SF 1 "register_operand" "=u")
+ (unspec:SF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fxtract"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "SF")])
+
+(define_expand "logbsf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:SF [(match_operand:SF 1 "register_operand" "")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:SF 0 "register_operand" "")
+ (unspec:SF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (SFmode);
+})
+
+(define_insn "*fxtractxf3"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:XF 1 "register_operand" "=u")
+ (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fxtract"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "logbxf2"
+ [(parallel [(set (match_dup 2)
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:XF 0 "register_operand" "")
+ (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+})
+
+(define_expand "ilogbsi2"
+ [(parallel [(set (match_dup 2)
+ (unspec:XF [(match_operand:XF 1 "register_operand" "")]
+ UNSPEC_XTRACT_FRACT))
+ (set (match_operand:XF 3 "register_operand" "")
+ (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
+ (parallel [(set (match_operand:SI 0 "register_operand" "")
+ (fix:SI (match_dup 3)))
+ (clobber (reg:CC 17))])]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ operands[2] = gen_reg_rtx (XFmode);
+ operands[3] = gen_reg_rtx (XFmode);
+})
+
(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 fad18793e50..f817969cf99 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -128,6 +128,8 @@ static const char * const optabs[] =
"exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
"exp10_optab->handlers[$A].insn_code = CODE_FOR_$(exp10$a2$)",
"exp2_optab->handlers[$A].insn_code = CODE_FOR_$(exp2$a2$)",
+ "logb_optab->handlers[$A].insn_code = CODE_FOR_$(logb$a2$)",
+ "ilogb_optab->handlers[$A].insn_code = CODE_FOR_$(ilogb$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$)",
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 51e1e707293..e8f4dc055da 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5384,6 +5384,8 @@ init_optabs (void)
exp_optab = init_optab (UNKNOWN);
exp10_optab = init_optab (UNKNOWN);
exp2_optab = init_optab (UNKNOWN);
+ logb_optab = init_optab (UNKNOWN);
+ ilogb_optab = init_optab (UNKNOWN);
log_optab = init_optab (UNKNOWN);
log10_optab = init_optab (UNKNOWN);
log2_optab = init_optab (UNKNOWN);
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 524cb678200..16caa1855d6 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -160,6 +160,9 @@ enum optab_index
OTI_exp10,
/* Base-2 Exponential */
OTI_exp2,
+ /* Radix-independent exponent */
+ OTI_logb,
+ OTI_ilogb,
/* Natural Logarithm */
OTI_log,
/* Base-10 Logarithm */
@@ -272,6 +275,8 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define exp_optab (optab_table[OTI_exp])
#define exp10_optab (optab_table[OTI_exp10])
#define exp2_optab (optab_table[OTI_exp2])
+#define logb_optab (optab_table[OTI_logb])
+#define ilogb_optab (optab_table[OTI_ilogb])
#define log_optab (optab_table[OTI_log])
#define log10_optab (optab_table[OTI_log10])
#define log2_optab (optab_table[OTI_log2])
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 5133f713f3f..c3279d0206f 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -1770,6 +1770,7 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
case UNSPEC_SINCOS_COS:
case UNSPEC_TAN_ONE:
+ case UNSPEC_XTRACT_FRACT:
/* These insns operate on the top two stack slots,
first part of one input, double output insn. */
@@ -1798,6 +1799,7 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
case UNSPEC_SINCOS_SIN:
case UNSPEC_TAN_TAN:
+ case UNSPEC_XTRACT_EXP:
/* These insns operate on the top two stack slots,
second part of one input, double output insn. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 89b2c707db0..b5be953740e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-04-14 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-38.c: New test.
+
2004-04-14 Eric Christopher <echristo@redhat.com>
* g++.dg/charset/charset.exp: Run .cc extension tests.
diff --git a/gcc/testsuite/gcc.dg/builtins-38.c b/gcc/testsuite/gcc.dg/builtins-38.c
new file mode 100644
index 00000000000..210516bb7dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-38.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 2004 Free Software Foundation.
+
+ Check that logb, logbf, logbl, ilogb, ilogbf and ilogbl
+ built-in functions compile.
+
+ Written by Uros Bizjak, 14th April 2004. */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern double logb(double);
+extern float logbf(float);
+extern long double logbl(long double);
+extern int ilogb(double);
+extern int ilogbf(float);
+extern int ilogbl(long double);
+
+
+double test1(double x)
+{
+ return logb(x);
+}
+
+float test1f(float x)
+{
+ return logbf(x);
+}
+
+long double test1l(long double x)
+{
+ return logbl(x);
+}
+
+int test2(double x)
+{
+ return ilogb(x);
+}
+
+int test2f(float x)
+{
+ return ilogbf(x);
+}
+
+int test2l(long double x)
+{
+ return ilogbl(x);
+}
+