From 88b28a31c004852530ec02c42a5893c3090a394c Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 15 Apr 2004 04:43:46 +0200 Subject: [PATCH] optabs.h (enum optab_index): Add new OTI_logb and OTI_ilogb. 2004-04-14 Uros Bizjak * 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. From-SVN: r80709 --- gcc/ChangeLog | 23 ++++++++ gcc/builtins.c | 14 +++++ gcc/config/i386/i386.md | 90 ++++++++++++++++++++++++++++++ gcc/genopinit.c | 2 + gcc/optabs.c | 2 + gcc/optabs.h | 5 ++ gcc/reg-stack.c | 2 + gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/builtins-38.c | 48 ++++++++++++++++ 9 files changed, 190 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/builtins-38.c 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 + + * 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 * 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 + + * gcc.dg/builtins-38.c: New test. + 2004-04-14 Eric Christopher * 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); +} +