aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <uros@kss-loka.si>2004-05-07 07:38:21 +0200
committerUros Bizjak <uros@gcc.gnu.org>2004-05-07 07:38:21 +0200
commitc2fcfa4ff8921c33ee899529ac170da8a1628c7c (patch)
tree471a2c68d2c2564dfb50adb742590b68eb2cd647 /gcc
parent61af3d861bbc083c5eede0039a1a2d780b7a3124 (diff)
downloadgcc-c2fcfa4ff8921c33ee899529ac170da8a1628c7c.zip
gcc-c2fcfa4ff8921c33ee899529ac170da8a1628c7c.tar.gz
gcc-c2fcfa4ff8921c33ee899529ac170da8a1628c7c.tar.bz2
optabs.h (enum optab_index): Add new OTI_log1p.
* optabs.h (enum optab_index): Add new OTI_log1p. (log1p_optab): Define corresponding macro. * optabs.c (init_optabs): Initialize log1p_optab. * genopinit.c (optabs): Implement log1p_optab using log1p?f2 patterns. * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOG1P{,F,L} using log1p_optab. (expand_builtin): Expand BUILT_IN_LOG1P{,F,L} using expand_builtin_mathfn if flag_unsafe_math_optimizations is set. * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FYL2XP1. * config/i386/i386.c (ix86_emit_i387_log1p): New function. * config/i386/i386-protos.h (ix86_emit_i387_log1p): Prototype here. * config/i386/i386.md (UNSPEC_FYL2XP1): New unspec to represent x87's fyl2xp1 instruction. (*fyl2x_xf3): Rename insn definition to fyl2x_xf3. (fyl2xp1_xf3): New pattern to implement fyl2xp1 x87 instruction. (log1psf2, log1pdf2, log1pxf2): New expanders to implement log1pf, log1p and log1pl built-ins as inline x87 intrinsics. * testsuite/gcc.dg/builtins-33.c: Also check log1p*. From-SVN: r81606
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog24
-rw-r--r--gcc/builtins.c7
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c30
-rw-r--r--gcc/config/i386/i386.md55
-rw-r--r--gcc/genopinit.c1
-rw-r--r--gcc/optabs.c1
-rw-r--r--gcc/optabs.h3
-rw-r--r--gcc/reg-stack.c1
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/builtins-33.c17
11 files changed, 144 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 329108b..fd79491 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,27 @@
+2004-05-07 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_log1p.
+ (log1p_optab): Define corresponding macro.
+ * optabs.c (init_optabs): Initialize log1p_optab.
+ * genopinit.c (optabs): Implement log1p_optab using log1p?f2
+ patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_LOG1P{,F,L}
+ using log1p_optab.
+ (expand_builtin): Expand BUILT_IN_LOG1P{,F,L} using
+ expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * reg-stack.c (subst_stack_regs_pat): Handle UNSPEC_FYL2XP1.
+
+ * config/i386/i386.c (ix86_emit_i387_log1p): New function.
+ * config/i386/i386-protos.h (ix86_emit_i387_log1p):
+ Prototype here.
+ * config/i386/i386.md (UNSPEC_FYL2XP1): New unspec to represent
+ x87's fyl2xp1 instruction.
+ (*fyl2x_xf3): Rename insn definition to fyl2x_xf3.
+ (fyl2xp1_xf3): New pattern to implement fyl2xp1 x87 instruction.
+ (log1psf2, log1pdf2, log1pxf2): New expanders to implement log1pf,
+ log1p and log1pl built-ins as inline x87 intrinsics.
+
2004-05-07 Loren James Rittle <ljrittle@acm.org>
* config/alpha/freebsd.h (SUBTARGET_EXTRA_SPECS): Pass -Werror.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 6126842..33fca2a 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1624,6 +1624,10 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
case BUILT_IN_LOG2F:
case BUILT_IN_LOG2L:
errno_set = true; builtin_optab = log2_optab; break;
+ case BUILT_IN_LOG1P:
+ case BUILT_IN_LOG1PF:
+ case BUILT_IN_LOG1PL:
+ errno_set = true; builtin_optab = log1p_optab; break;
case BUILT_IN_ASIN:
case BUILT_IN_ASINF:
case BUILT_IN_ASINL:
@@ -5322,6 +5326,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
case BUILT_IN_LOG2:
case BUILT_IN_LOG2F:
case BUILT_IN_LOG2L:
+ case BUILT_IN_LOG1P:
+ case BUILT_IN_LOG1PF:
+ case BUILT_IN_LOG1PL:
case BUILT_IN_TAN:
case BUILT_IN_TANF:
case BUILT_IN_TANL:
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 636d50b..42771f9 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -184,6 +184,8 @@ extern void x86_function_profiler (FILE *, int);
extern void x86_emit_floatuns (rtx [2]);
extern void ix86_emit_fp_unordered_jump (rtx);
+extern void ix86_emit_i387_log1p (rtx, rtx);
+
extern enum rtx_code ix86_reverse_condition (enum rtx_code, enum machine_mode);
#ifdef TREE_CODE
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a561d4f..0a45e3e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -15949,4 +15949,34 @@ ix86_emit_fp_unordered_jump (rtx label)
emit_jump_insn (temp);
}
+/* Output code to perform a log1p XFmode calculation. */
+
+void ix86_emit_i387_log1p (rtx op0, rtx op1)
+{
+ rtx label1 = gen_label_rtx ();
+ rtx label2 = gen_label_rtx ();
+
+ rtx tmp = gen_reg_rtx (XFmode);
+ rtx tmp2 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_absxf2 (tmp, op1));
+ emit_insn (gen_cmpxf (tmp,
+ CONST_DOUBLE_FROM_REAL_VALUE (
+ REAL_VALUE_ATOF ("0.29289321881345247561810596348408353", XFmode),
+ XFmode)));
+ emit_jump_insn (gen_bge (label1));
+
+ emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
+ emit_insn (gen_fyl2xp1_xf3 (op0, tmp2, op1));
+ emit_jump (label2);
+
+ emit_label (label1);
+ emit_move_insn (tmp, CONST1_RTX (XFmode));
+ emit_insn (gen_addxf3 (tmp, op1, tmp));
+ emit_move_insn (tmp2, standard_80387_constant_rtx (4)); /* fldln2 */
+ emit_insn (gen_fyl2x_xf3 (op0, tmp2, tmp));
+
+ emit_label (label2);
+}
+
#include "gt-i386.h"
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index ea61cc7..b136679 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -117,6 +117,7 @@
; x87 Floating point
(UNSPEC_FPATAN 65)
(UNSPEC_FYL2X 66)
+ (UNSPEC_FYL2XP1 67)
(UNSPEC_FRNDINT 68)
(UNSPEC_F2XM1 69)
@@ -15628,7 +15629,7 @@
emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
})
-(define_insn "*fyl2x_xf3"
+(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")]
@@ -15808,6 +15809,58 @@
emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
})
+(define_insn "fyl2xp1_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_FYL2XP1))
+ (clobber (match_scratch:XF 3 "=1"))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+ "fyl2xp1"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
+(define_expand "log1psf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx op0 = gen_reg_rtx (XFmode);
+ rtx op1 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extendsfxf2 (op1, operands[1]));
+ ix86_emit_i387_log1p (op0, op1);
+ emit_insn (gen_truncxfsf2_noop (operands[0], op0));
+ DONE;
+})
+
+(define_expand "log1pdf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx op0 = gen_reg_rtx (XFmode);
+ rtx op1 = gen_reg_rtx (XFmode);
+
+ emit_insn (gen_extenddfxf2 (op1, operands[1]));
+ ix86_emit_i387_log1p (op0, op1);
+ emit_insn (gen_truncxfdf2_noop (operands[0], op0));
+ DONE;
+})
+
+(define_expand "log1pxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ ix86_emit_i387_log1p (operands[0], operands[1]);
+ DONE;
+})
+
(define_insn "*fxtractxf3"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 2 "register_operand" "0")]
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 307849a..a7c9f7e 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -138,6 +138,7 @@ static const char * const optabs[] =
"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$)",
+ "log1p_optab->handlers[$A].insn_code = CODE_FOR_$(log1p$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 719fbb4..f89e053 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5394,6 +5394,7 @@ init_optabs (void)
log_optab = init_optab (UNKNOWN);
log10_optab = init_optab (UNKNOWN);
log2_optab = init_optab (UNKNOWN);
+ log1p_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 84d8957..6fc6c17 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -178,6 +178,8 @@ enum optab_index
OTI_log10,
/* Base-2 Logarithm */
OTI_log2,
+ /* logarithm of 1 plus argument */
+ OTI_log1p,
/* Rounding functions */
OTI_floor,
OTI_ceil,
@@ -294,6 +296,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define log_optab (optab_table[OTI_log])
#define log10_optab (optab_table[OTI_log10])
#define log2_optab (optab_table[OTI_log2])
+#define log1p_optab (optab_table[OTI_log1p])
#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/reg-stack.c b/gcc/reg-stack.c
index bab401f..8314b21 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -1747,6 +1747,7 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
case UNSPEC_FPATAN:
case UNSPEC_FYL2X:
+ case UNSPEC_FYL2XP1:
/* These insns operate on the top two stack slots. */
src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f36b682..c94bb54 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-05-07 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-33.c: Also check log1p*.
+
2004-05-07 Hans-Peter Nilsson <hp@axis.com>
PR optimization/15296
diff --git a/gcc/testsuite/gcc.dg/builtins-33.c b/gcc/testsuite/gcc.dg/builtins-33.c
index 758978f..11393e3 100644
--- a/gcc/testsuite/gcc.dg/builtins-33.c
+++ b/gcc/testsuite/gcc.dg/builtins-33.c
@@ -10,10 +10,13 @@
extern double log10(double);
extern double log2(double);
+extern double log1p(double);
extern float log10f(float);
extern float log2f(float);
+extern float log1pf(float);
extern long double log10l(long double);
extern long double log2l(long double);
+extern long double log1pl(long double);
double test1(double x)
@@ -26,6 +29,11 @@ double test2(double x)
return log2(x);
}
+double test3(double x)
+{
+ return log1p(x);
+}
+
float test1f(float x)
{
return log10f(x);
@@ -36,6 +44,11 @@ float test2f(float x)
return log2f(x);
}
+float test3f(float x)
+{
+ return log1pf(x);
+}
+
long double test1l(long double x)
{
return log10l(x);
@@ -46,3 +59,7 @@ long double test2l(long double x)
return log2l(x);
}
+long double test3l(long double x)
+{
+ return log1pl(x);
+}