From 4737caf22cfca1f3d49eef7663b048393570e43e Mon Sep 17 00:00:00 2001 From: uros Date: Sat, 12 Feb 2005 11:34:24 +0000 Subject: [PATCH] * optabs.h (enum optab_index): Add new OTI_ldexp. (ldexp_optab): Define corresponding macro. * optabs.c (init_optabs): Initialize ldexp_optab. * genopinit.c (optabs): Implement ldexp_optab using ldexp?f3 patterns. * builtins.c (expand_builtin_mathfn_2): Handle BUILT_IN_LDEXP{,F,L} using ldexp_optab. (expand_builtin): Expand BUILT_IN_LDEXP{,F,L} using expand_builtin_mathfn_2 if flag_unsafe_math_optimizations is set. * config/i386/i386.md (ldexpsf3, ldexpdf3, ldexpxf3): New expanders to implement ldexpf, ldexp and ldexpl built-ins as inline x87 intrinsics. testsuite: * gcc.dg/builtins-34.c: Also check ldexp*. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94931 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 16 ++++++++++ gcc/builtins.c | 15 ++++++++- gcc/config/i386/i386.md | 65 ++++++++++++++++++++++++++++++++++++++ gcc/genopinit.c | 1 + gcc/optabs.c | 1 + gcc/optabs.h | 3 ++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/builtins-34.c | 17 ++++++++++ 8 files changed, 121 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e8e8a80..bfaa691 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2005-02-12 Uros Bizjak + + * optabs.h (enum optab_index): Add new OTI_ldexp. + (ldexp_optab): Define corresponding macro. + * optabs.c (init_optabs): Initialize ldexp_optab. + * genopinit.c (optabs): Implement ldexp_optab using ldexp?f3 + patterns. + * builtins.c (expand_builtin_mathfn_2): Handle BUILT_IN_LDEXP{,F,L} + using ldexp_optab. + (expand_builtin): Expand BUILT_IN_LDEXP{,F,L} using + expand_builtin_mathfn_2 if flag_unsafe_math_optimizations is set. + + * config/i386/i386.md (ldexpsf3, ldexpdf3, ldexpxf3): New expanders + to implement ldexpf, ldexp and ldexpl built-ins as inline x87 + intrinsics. + 2005-02-13 Ira Rosen * tree-vectorizer.h (struct _stmt_vec_info): Rename a field: base diff --git a/gcc/builtins.c b/gcc/builtins.c index 420e5de..afeb9bc 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -1862,6 +1862,7 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) { optab builtin_optab; rtx op0, op1, insns; + int op1_type = REAL_TYPE; tree fndecl = get_callee_fndecl (exp); tree arglist = TREE_OPERAND (exp, 1); tree arg0, arg1, temp, narg; @@ -1869,7 +1870,12 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) bool errno_set = true; bool stable = true; - if (!validate_arglist (arglist, REAL_TYPE, REAL_TYPE, VOID_TYPE)) + if ((DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXP) + || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPF) + || (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LDEXPL)) + op1_type = INTEGER_TYPE; + + if (!validate_arglist (arglist, REAL_TYPE, op1_type, VOID_TYPE)) return 0; arg0 = TREE_VALUE (arglist); @@ -1885,6 +1891,10 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) case BUILT_IN_ATAN2F: case BUILT_IN_ATAN2L: builtin_optab = atan2_optab; break; + case BUILT_IN_LDEXP: + case BUILT_IN_LDEXPF: + case BUILT_IN_LDEXPL: + builtin_optab = ldexp_optab; break; case BUILT_IN_FMOD: case BUILT_IN_FMODF: case BUILT_IN_FMODL: @@ -5259,6 +5269,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, case BUILT_IN_ATAN2: case BUILT_IN_ATAN2F: case BUILT_IN_ATAN2L: + case BUILT_IN_LDEXP: + case BUILT_IN_LDEXPF: + case BUILT_IN_LDEXPL: case BUILT_IN_FMOD: case BUILT_IN_FMODF: case BUILT_IN_FMODL: diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 3fdf441..d9a4ce5 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -16176,6 +16176,71 @@ emit_move_insn (operands[2], temp); emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */ }) + +(define_expand "ldexpdf3" + [(set (match_dup 3) + (float_extend:XF (match_operand:DF 1 "register_operand" ""))) + (set (match_dup 4) + (float:XF (match_operand:SI 2 "register_operand" ""))) + (parallel [(set (match_dup 5) + (unspec:XF [(match_dup 3) (match_dup 4)] + UNSPEC_FSCALE_FRACT)) + (set (match_dup 6) + (unspec:XF [(match_dup 3) (match_dup 4)] + UNSPEC_FSCALE_EXP))]) + (set (match_operand:DF 0 "register_operand" "") + (float_truncate:DF (match_dup 5)))] + "TARGET_USE_FANCY_MATH_387 + && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387) + && flag_unsafe_math_optimizations" +{ + int i; + + for (i=3; i<7; i++) + operands[i] = gen_reg_rtx (XFmode); +}) + +(define_expand "ldexpsf3" + [(set (match_dup 3) + (float_extend:XF (match_operand:SF 1 "register_operand" ""))) + (set (match_dup 4) + (float:XF (match_operand:SI 2 "register_operand" ""))) + (parallel [(set (match_dup 5) + (unspec:XF [(match_dup 3) (match_dup 4)] + UNSPEC_FSCALE_FRACT)) + (set (match_dup 6) + (unspec:XF [(match_dup 3) (match_dup 4)] + UNSPEC_FSCALE_EXP))]) + (set (match_operand:SF 0 "register_operand" "") + (float_truncate:SF (match_dup 5)))] + "TARGET_USE_FANCY_MATH_387 + && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387) + && flag_unsafe_math_optimizations" +{ + int i; + + for (i=3; i<7; i++) + operands[i] = gen_reg_rtx (XFmode); +}) + +(define_expand "ldexpxf3" + [(set (match_dup 3) + (float:XF (match_operand:SI 2 "register_operand" ""))) + (parallel [(set (match_operand:XF 0 " register_operand" "") + (unspec:XF [(match_operand:XF 1 "register_operand" "") + (match_dup 3)] + UNSPEC_FSCALE_FRACT)) + (set (match_dup 4) + (unspec:XF [(match_dup 1) (match_dup 3)] + UNSPEC_FSCALE_EXP))])] + "TARGET_USE_FANCY_MATH_387 + && flag_unsafe_math_optimizations" +{ + int i; + + for (i=3; i<5; i++) + operands[i] = gen_reg_rtx (XFmode); +}) (define_insn "frndintxf2" diff --git a/gcc/genopinit.c b/gcc/genopinit.c index f56f13c..e52ca06 100644 --- a/gcc/genopinit.c +++ b/gcc/genopinit.c @@ -133,6 +133,7 @@ static const char * const optabs[] = "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$)", + "ldexp_optab->handlers[$A].insn_code = CODE_FOR_$(ldexp$a3$)", "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 75c78cd..9525620 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -5027,6 +5027,7 @@ init_optabs (void) exp10_optab = init_optab (UNKNOWN); exp2_optab = init_optab (UNKNOWN); expm1_optab = init_optab (UNKNOWN); + ldexp_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 621136b..e0a7985 100644 --- a/gcc/optabs.h +++ b/gcc/optabs.h @@ -171,6 +171,8 @@ enum optab_index OTI_exp2, /* Exponential - 1*/ OTI_expm1, + /* Load exponent of a floating point number */ + OTI_ldexp, /* Radix-independent exponent */ OTI_logb, OTI_ilogb, @@ -302,6 +304,7 @@ extern GTY(()) optab optab_table[OTI_MAX]; #define exp10_optab (optab_table[OTI_exp10]) #define exp2_optab (optab_table[OTI_exp2]) #define expm1_optab (optab_table[OTI_expm1]) +#define ldexp_optab (optab_table[OTI_ldexp]) #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 02ac9f4..408e128 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2005-02-12 Uros Bizjak + + * gcc.dg/builtins-34.c: Also check ldexp*. + 2005-02-12 Hans-Peter Nilsson * gcc.dg/tree-ssa/20040703-1.c: Quote decimal dot. diff --git a/gcc/testsuite/gcc.dg/builtins-34.c b/gcc/testsuite/gcc.dg/builtins-34.c index 0055f32..f2625d5 100644 --- a/gcc/testsuite/gcc.dg/builtins-34.c +++ b/gcc/testsuite/gcc.dg/builtins-34.c @@ -12,14 +12,17 @@ extern double exp10(double); extern double exp2(double); extern double pow10(double); extern double expm1(double); +extern double ldexp(double, int); extern float exp10f(float); extern float exp2f(float); extern float pow10f(float); extern float expm1f(float); +extern float ldexpf(float, int); extern long double exp10l(long double); extern long double exp2l(long double); extern long double pow10l(long double); extern long double expm1l(long double); +extern long double ldexpl(long double, int); double test1(double x) @@ -42,6 +45,11 @@ double test4(double x) return expm1(x); } +double test5(double x, int exp) +{ + return ldexp(x, exp); +} + float test1f(float x) { return exp10f(x); @@ -62,6 +70,11 @@ float test4f(float x) return expm1f(x); } +float test5f(float x, int exp) +{ + return ldexpf(x, exp); +} + long double test1l(long double x) { return exp10l(x); @@ -82,3 +95,7 @@ long double test4l(long double x) return expm1l(x); } +long double test5l(long double x, int exp) +{ + return ldexpl(x, exp); +} -- 2.7.4