aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <uros@kss-loka.si>2004-05-03 07:31:45 +0200
committerUros Bizjak <uros@gcc.gnu.org>2004-05-03 07:31:45 +0200
commit7a8e07c7d1bc8526e0d67cb7ae0dc51ba5b90f68 (patch)
treec1a89b48d29d70f789473f5c7def695357e909f9 /gcc
parent5f2b959917e0d13044851e6165e9c17d4f4b3a0f (diff)
downloadgcc-7a8e07c7d1bc8526e0d67cb7ae0dc51ba5b90f68.zip
gcc-7a8e07c7d1bc8526e0d67cb7ae0dc51ba5b90f68.tar.gz
gcc-7a8e07c7d1bc8526e0d67cb7ae0dc51ba5b90f68.tar.bz2
optabs.h (enum optab_index): Add new OTI_expm1.
2004-05-03 Uros Bizjak <uros@kss-loka.si> * optabs.h (enum optab_index): Add new OTI_expm1. (expm1_optab): Define corresponding macro. * optabs.c (init_optabs): Initialize expm1_optab. * genopinit.c (optabs): Implement expm1_optab using expm1?f2 patterns. * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXPM1{,F,L} using expm1_optab. (expand_builtin): Expand BUILT_IN_EXPM1{,F,L} using expand_builtin_mathfn if flag_unsafe_math_optimizations is set. * config/i386/i386.md (expm1df2, expm1sf2, expm1xf2): New expanders to implement expm1, expm1f and expm1l built-ins as inline x87 intrinsics. testsuite: * gcc.dg/builtins-34.c: Also check expm1*. From-SVN: r81425
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/builtins.c7
-rw-r--r--gcc/config/i386/i386.md106
-rw-r--r--gcc/genopinit.c1
-rw-r--r--gcc/optabs.c1
-rw-r--r--gcc/optabs.h3
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/builtins-34.c22
8 files changed, 158 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9a23747..e907ac3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2004-05-03 Uros Bizjak <uros@kss-loka.si>
+
+ * optabs.h (enum optab_index): Add new OTI_expm1.
+ (expm1_optab): Define corresponding macro.
+ * optabs.c (init_optabs): Initialize expm1_optab.
+ * genopinit.c (optabs): Implement expm1_optab using expm1?f2
+ patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXPM1{,F,L}
+ using expm1_optab.
+ (expand_builtin): Expand BUILT_IN_EXPM1{,F,L} using
+ expand_builtin_mathfn if flag_unsafe_math_optimizations is set.
+
+ * config/i386/i386.md (expm1df2, expm1sf2, expm1xf2): New expanders
+ to implement expm1, expm1f and expm1l built-ins as inline x87
+ intrinsics.
+
2004-05-02 Alexandre Oliva <aoliva@redhat.com>
2003-11-19 Richard Sandiford <rsandifo@redhat.com>
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 96d365a..c42a423 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -1600,6 +1600,10 @@ 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_EXPM1:
+ case BUILT_IN_EXPM1F:
+ case BUILT_IN_EXPM1L:
+ errno_set = true; builtin_optab = expm1_optab; break;
case BUILT_IN_LOGB:
case BUILT_IN_LOGBF:
case BUILT_IN_LOGBL:
@@ -5292,6 +5296,9 @@ 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_EXPM1:
+ case BUILT_IN_EXPM1F:
+ case BUILT_IN_EXPM1L:
case BUILT_IN_LOGB:
case BUILT_IN_LOGBF:
case BUILT_IN_LOGBL:
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index e258559..75d153d 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -15982,6 +15982,112 @@
operands[i] = gen_reg_rtx (XFmode);
emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
})
+
+(define_expand "expm1df2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:DF 1 "register_operand" "")))
+ (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
+ (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
+ (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
+ (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
+ (parallel [(set (match_dup 8)
+ (unspec:XF [(match_dup 7) (match_dup 5)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 9)
+ (unspec:XF [(match_dup 7) (match_dup 5)]
+ UNSPEC_FSCALE_EXP))])
+ (parallel [(set (match_dup 11)
+ (unspec:XF [(match_dup 10) (match_dup 9)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 12)
+ (unspec:XF [(match_dup 10) (match_dup 9)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
+ (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
+ (set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF (match_dup 14)))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+ int i;
+
+ for (i=2; i<15; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[3], temp);
+ emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "expm1sf2"
+ [(set (match_dup 2)
+ (float_extend:XF (match_operand:SF 1 "register_operand" "")))
+ (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
+ (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
+ (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
+ (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
+ (parallel [(set (match_dup 8)
+ (unspec:XF [(match_dup 7) (match_dup 5)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 9)
+ (unspec:XF [(match_dup 7) (match_dup 5)]
+ UNSPEC_FSCALE_EXP))])
+ (parallel [(set (match_dup 11)
+ (unspec:XF [(match_dup 10) (match_dup 9)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 12)
+ (unspec:XF [(match_dup 10) (match_dup 9)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
+ (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
+ (set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF (match_dup 14)))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+ int i;
+
+ for (i=2; i<15; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[3], temp);
+ emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
+})
+
+(define_expand "expm1xf2"
+ [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
+ (match_dup 2)))
+ (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
+ (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
+ (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
+ (parallel [(set (match_dup 7)
+ (unspec:XF [(match_dup 6) (match_dup 4)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 8)
+ (unspec:XF [(match_dup 6) (match_dup 4)]
+ UNSPEC_FSCALE_EXP))])
+ (parallel [(set (match_dup 10)
+ (unspec:XF [(match_dup 9) (match_dup 8)]
+ UNSPEC_FSCALE_FRACT))
+ (set (match_dup 11)
+ (unspec:XF [(match_dup 9) (match_dup 8)]
+ UNSPEC_FSCALE_EXP))])
+ (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
+ (set (match_operand:XF 0 "register_operand" "")
+ (plus:XF (match_dup 12) (match_dup 7)))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && flag_unsafe_math_optimizations"
+{
+ rtx temp;
+ int i;
+
+ for (i=2; i<13; i++)
+ operands[i] = gen_reg_rtx (XFmode);
+ temp = standard_80387_constant_rtx (5); /* fldl2e */
+ emit_move_insn (operands[2], temp);
+ emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
+})
;; Block operation instructions
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 95d5310..8793449 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -130,6 +130,7 @@ 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$)",
+ "expm1_optab->handlers[$A].insn_code = CODE_FOR_$(expm1$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$)",
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 8d2a232..1632ecf 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -5386,6 +5386,7 @@ init_optabs (void)
exp_optab = init_optab (UNKNOWN);
exp10_optab = init_optab (UNKNOWN);
exp2_optab = init_optab (UNKNOWN);
+ expm1_optab = init_optab (UNKNOWN);
logb_optab = init_optab (UNKNOWN);
ilogb_optab = init_optab (UNKNOWN);
log_optab = init_optab (UNKNOWN);
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 2e0a47a..a7aac19 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -164,6 +164,8 @@ enum optab_index
OTI_exp10,
/* Base-2 Exponential */
OTI_exp2,
+ /* Exponential - 1*/
+ OTI_expm1,
/* Radix-independent exponent */
OTI_logb,
OTI_ilogb,
@@ -281,6 +283,7 @@ 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 expm1_optab (optab_table[OTI_expm1])
#define logb_optab (optab_table[OTI_logb])
#define ilogb_optab (optab_table[OTI_ilogb])
#define log_optab (optab_table[OTI_log])
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 822cb30..5735a6c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-05-03 Uros Bizjak <uros@kss-loka.si>
+
+ * gcc.dg/builtins-34.c: Also check expm1*.
+
2004-05-01 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/torture/builtin-integral-1.c: Reorg and add more cases.
diff --git a/gcc/testsuite/gcc.dg/builtins-34.c b/gcc/testsuite/gcc.dg/builtins-34.c
index d2bf4d4..0055f32 100644
--- a/gcc/testsuite/gcc.dg/builtins-34.c
+++ b/gcc/testsuite/gcc.dg/builtins-34.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2004 Free Software Foundation.
- Check that exp10, exp10f, exp10l, exp2, exp2f, exp2l, pow10, pow10f
- and pow10l built-in functions compile.
+ Check that exp10, exp10f, exp10l, exp2, exp2f, exp2l, pow10, pow10f,
+ pow10l, expm1, expm1f and expm1l built-in functions compile.
Written by Uros Bizjak, 13th February 2004. */
@@ -11,12 +11,15 @@
extern double exp10(double);
extern double exp2(double);
extern double pow10(double);
+extern double expm1(double);
extern float exp10f(float);
extern float exp2f(float);
extern float pow10f(float);
+extern float expm1f(float);
extern long double exp10l(long double);
extern long double exp2l(long double);
extern long double pow10l(long double);
+extern long double expm1l(long double);
double test1(double x)
@@ -34,6 +37,11 @@ double test3(double x)
return pow10(x);
}
+double test4(double x)
+{
+ return expm1(x);
+}
+
float test1f(float x)
{
return exp10f(x);
@@ -49,6 +57,11 @@ float test3f(float x)
return pow10f(x);
}
+float test4f(float x)
+{
+ return expm1f(x);
+}
+
long double test1l(long double x)
{
return exp10l(x);
@@ -64,3 +77,8 @@ long double test3l(long double x)
return pow10l(x);
}
+long double test4l(long double x)
+{
+ return expm1l(x);
+}
+