(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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122162
138bc75d-0d04-0410-961f-
82ee72b054a4
+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>
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;
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):
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;
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;
+})
\f
(define_insn "frndintxf2"
"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$)",
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);
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,
#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])
+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>
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>
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>
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)
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);
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);
{
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);
+}