From 7a8e07c7d1bc8526e0d67cb7ae0dc51ba5b90f68 Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 3 May 2004 07:31:45 +0200 Subject: [PATCH] optabs.h (enum optab_index): Add new OTI_expm1. 2004-05-03 Uros Bizjak * 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 --- gcc/ChangeLog | 16 +++++ gcc/builtins.c | 7 ++ gcc/config/i386/i386.md | 106 +++++++++++++++++++++++++++++ gcc/genopinit.c | 1 + gcc/optabs.c | 1 + gcc/optabs.h | 3 + gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/builtins-34.c | 22 +++++- 8 files changed, 158 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a2374792e5..e907ac3a52d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2004-05-03 Uros Bizjak + + * 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 2003-11-19 Richard Sandiford diff --git a/gcc/builtins.c b/gcc/builtins.c index 96d365ababb..c42a42392df 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 e258559d188..75d153d6c59 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 95d53107ae2..87934496b76 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 8d2a232a469..1632ecfe8c9 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 2e0a47ab9e9..a7aac1934f3 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 822cb30f7c0..5735a6c5548 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-05-03 Uros Bizjak + + * gcc.dg/builtins-34.c: Also check expm1*. + 2004-05-01 Kaveh R. Ghazi * 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 d2bf4d41219..0055f329dd5 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); +} + -- 2.30.2