optabs.h (enum optab_index): Add new OTI_scalb.

* optabs.h (enum optab_index): Add new OTI_scalb.
	(scalb_optab): Define corresponding macro.
	* optabs.c (init_optabs): Initialize scalb_optab.
	* genopinit.c (optabs): Implement scalb_optab using scalb?f3
	patterns.
	* builtins.c (expand_builtin_mathfn_2, expand_builtin): Handle
	BUILT_IN_SCALB{,F,L}, BUILT_IN_SCALBN{,F,L} and BUILT_IN_SCALBLN{,F,L}.
	(expand_builtin): Expand BUILT_IN_SCALB{,F,L}, BUILT_IN_SCALBN{,F,L}
	and BUILT_IN_SCALBLN{,F,L} using expand_builtin_mathfn_2 if
	flag_unsafe_math_optimizations is set.

	* config/i386/i386.md (scalbxf3, scalb<mode>3): New expanders
	to implement scalbf, scalb and scalbl built-ins as inline x87
	intrinsics.

testsuite/ChangeLog

	* gcc.dg/builtins-34.c: Add scalb/scalbn/scalbln cases.

From-SVN: r122162
This commit is contained in:
Kaveh R. Ghazi 2007-02-20 14:33:51 +01:00 committed by Uros Bizjak
parent d9f646e4b9
commit 0c0d910d23
8 changed files with 140 additions and 8 deletions

View File

@ -1,3 +1,21 @@
2007-02-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
Uros Bizjak <ubizjak@gmail.com>
* optabs.h (enum optab_index): Add new OTI_scalb.
(scalb_optab): Define corresponding macro.
* optabs.c (init_optabs): Initialize scalb_optab.
* genopinit.c (optabs): Implement scalb_optab using scalb?f3
patterns.
* builtins.c (expand_builtin_mathfn_2, expand_builtin): Handle
BUILT_IN_SCALB{,F,L}, BUILT_IN_SCALBN{,F,L} and BUILT_IN_SCALBLN{,F,L}.
(expand_builtin): Expand BUILT_IN_SCALB{,F,L}, BUILT_IN_SCALBN{,F,L}
and BUILT_IN_SCALBLN{,F,L} using expand_builtin_mathfn_2 if
flag_unsafe_math_optimizations is set.
* config/i386/i386.md (scalbxf3, scalb<mode>3): New expanders
to implement scalbf, scalb and scalbl built-ins as inline x87
intrinsics.
2007-02-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
DJ Delorie <dj@redhat.com>

View File

@ -1973,10 +1973,15 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
bool errno_set = true;
bool stable = true;
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;
switch (DECL_FUNCTION_CODE (fndecl))
{
CASE_FLT_FN (BUILT_IN_SCALBN):
CASE_FLT_FN (BUILT_IN_SCALBLN):
CASE_FLT_FN (BUILT_IN_LDEXP):
op1_type = INTEGER_TYPE;
default:
break;
}
if (!validate_arglist (exp, REAL_TYPE, op1_type, VOID_TYPE))
return NULL_RTX;
@ -1990,6 +1995,15 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
builtin_optab = pow_optab; break;
CASE_FLT_FN (BUILT_IN_ATAN2):
builtin_optab = atan2_optab; break;
CASE_FLT_FN (BUILT_IN_SCALB):
if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
return 0;
builtin_optab = scalb_optab; break;
CASE_FLT_FN (BUILT_IN_SCALBN):
CASE_FLT_FN (BUILT_IN_SCALBLN):
if (REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (exp)))->b != 2)
return 0;
/* Fall through... */
CASE_FLT_FN (BUILT_IN_LDEXP):
builtin_optab = ldexp_optab; break;
CASE_FLT_FN (BUILT_IN_FMOD):
@ -5963,6 +5977,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
CASE_FLT_FN (BUILT_IN_ATAN2):
CASE_FLT_FN (BUILT_IN_LDEXP):
CASE_FLT_FN (BUILT_IN_SCALB):
CASE_FLT_FN (BUILT_IN_SCALBN):
CASE_FLT_FN (BUILT_IN_SCALBLN):
if (! flag_unsafe_math_optimizations)
break;

View File

@ -17228,6 +17228,40 @@
emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
DONE;
})
(define_expand "scalbxf3"
[(parallel [(set (match_operand:XF 0 " register_operand" "")
(unspec:XF [(match_operand:XF 1 "register_operand" "")
(match_operand:XF 2 "register_operand" "")]
UNSPEC_FSCALE_FRACT))
(set (match_dup 3)
(unspec:XF [(match_dup 1) (match_dup 2)]
UNSPEC_FSCALE_EXP))])]
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations && !optimize_size"
{
operands[3] = gen_reg_rtx (XFmode);
})
(define_expand "scalb<mode>3"
[(use (match_operand:X87MODEF12 0 "register_operand" ""))
(use (match_operand:X87MODEF12 1 "general_operand" ""))
(use (match_operand:X87MODEF12 2 "register_operand" ""))]
"TARGET_USE_FANCY_MATH_387
&& (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|| TARGET_MIX_SSE_I387)
&& flag_unsafe_math_optimizations && !optimize_size"
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
rtx op2 = gen_reg_rtx (XFmode);
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
emit_insn (gen_scalbxf3 (op0, op1, op2));
emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
DONE;
})
(define_insn "frndintxf2"

View File

@ -140,6 +140,7 @@ static const char * const optabs[] =
"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$)",
"scalb_optab->handlers[$A].insn_code = CODE_FOR_$(scalb$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$)",

View File

@ -5449,6 +5449,7 @@ init_optabs (void)
exp2_optab = init_optab (UNKNOWN);
expm1_optab = init_optab (UNKNOWN);
ldexp_optab = init_optab (UNKNOWN);
scalb_optab = init_optab (UNKNOWN);
logb_optab = init_optab (UNKNOWN);
ilogb_optab = init_optab (UNKNOWN);
log_optab = init_optab (UNKNOWN);

View File

@ -179,6 +179,8 @@ enum optab_index
OTI_expm1,
/* Load exponent of a floating point number */
OTI_ldexp,
/* Multiply floating-point number by integral power of radix */
OTI_scalb,
/* Radix-independent exponent */
OTI_logb,
OTI_ilogb,
@ -357,6 +359,7 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define exp2_optab (optab_table[OTI_exp2])
#define expm1_optab (optab_table[OTI_expm1])
#define ldexp_optab (optab_table[OTI_ldexp])
#define scalb_optab (optab_table[OTI_scalb])
#define logb_optab (optab_table[OTI_logb])
#define ilogb_optab (optab_table[OTI_ilogb])
#define log_optab (optab_table[OTI_log])

View File

@ -1,3 +1,7 @@
2007-02-20 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
* gcc.dg/builtins-34.c: Add scalb/scalbn/scalbln cases.
2007-02-20 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
DJ Delorie <dj@redhat.com>
@ -76,7 +80,7 @@
2007-02-18 Roger Sayle <roger@eyesopen.com>
* gfortran.dg/forall_10.f90: New test case.
* gfortran.dg/forall_10.f90: New test case.
2007-02-18 Eric Botcazou <ebotcazou@adacore.com>
@ -1199,9 +1203,9 @@
2007-01-06 Lee Millward <lee.millward@codesourcery.com>
PR c++/19439
* g++.dg/template/duplicate1.C: New test
* g++.dg/template/memfriend6.C: Adjust error markers.
PR c++/19439
* g++.dg/template/duplicate1.C: New test
* g++.dg/template/memfriend6.C: Adjust error markers.
2007-01-05 Andrew Pinski <Andrew_Pinski@playstation.sony.com>

View File

@ -13,16 +13,25 @@ extern double exp2(double);
extern double pow10(double);
extern double expm1(double);
extern double ldexp(double, int);
extern double scalb(double, double);
extern double scalbn(double, int);
extern double scalbln(double, long);
extern float exp10f(float);
extern float exp2f(float);
extern float pow10f(float);
extern float expm1f(float);
extern float ldexpf(float, int);
extern float scalbf(float, float);
extern float scalbnf(float, int);
extern float scalblnf(float, long);
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);
extern long double scalbl(long double, long double);
extern long double scalbnl(long double, int);
extern long double scalblnl(long double, long);
double test1(double x)
@ -50,6 +59,21 @@ double test5(double x, int exp)
return ldexp(x, exp);
}
double test6(double x, double exp)
{
return scalb(x, exp);
}
double test7(double x, int exp)
{
return scalbn(x, exp);
}
double test8(double x, long exp)
{
return scalbln(x, exp);
}
float test1f(float x)
{
return exp10f(x);
@ -75,6 +99,21 @@ float test5f(float x, int exp)
return ldexpf(x, exp);
}
float test6f(float x, float exp)
{
return scalbf(x, exp);
}
float test7f(float x, int exp)
{
return scalbnf(x, exp);
}
float test8f(float x, long exp)
{
return scalblnf(x, exp);
}
long double test1l(long double x)
{
return exp10l(x);
@ -99,3 +138,18 @@ long double test5l(long double x, int exp)
{
return ldexpl(x, exp);
}
long double test6l(long double x, long double exp)
{
return scalbl(x, exp);
}
long double test7l(long double x, int exp)
{
return scalbnl(x, exp);
}
long double test8l(long double x, long exp)
{
return scalblnl(x, exp);
}