+2002-08-03 Roger Sayle <roger@eyesopen.com>
+
+ * builtins.def: Define new builtin functions exp, expf, expl,
+ log, logf and logl (and their __builtin_* variants).
+ * optabs.h (enum optab_index): Add new OTI_exp and OTI_log.
+ Define exp_optab and log_optab.
+ * optabs.c (init_optans): Initialize exp_optab and log_optab.
+ * genopinit.c (optabs): Implement exp_optab and log_optab
+ using exp?f2 and log?f2 patterns.
+ * builtins.c (expand_builtin_mathfn): Handle BUILT_IN_EXP*
+ and BUILT_IN_LOG* using exp_optab and log_optab respectively.
+ (expand_builtin): Ignore the new builtins (and all cos and
+ sin variants) when not optimizing. Expand new builtins via
+ expand_builtin_mathfn when flag_unsafe_math_optimizations.
+
+ * doc/extend.texi: Document new exp and log builtins.
+ * doc/md.texi: Document new exp?f2 and log?f2 patterns
+ (and previously undocumented cos?f2 and sin?f2 patterns).
+
2002-08-03 Jason Merrill <jason@redhat.com>
* explow.c (int_expr_size): New fn.
case BUILT_IN_SQRTF:
case BUILT_IN_SQRTL:
builtin_optab = sqrt_optab; break;
- default:
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
+ builtin_optab = exp_optab; break;
+ case BUILT_IN_LOG:
+ case BUILT_IN_LOGF:
+ case BUILT_IN_LOGL:
+ builtin_optab = log_optab; break;
+ default:
abort ();
}
if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
switch (fcode)
{
- case BUILT_IN_SIN:
- case BUILT_IN_COS:
case BUILT_IN_SQRT:
case BUILT_IN_SQRTF:
case BUILT_IN_SQRTL:
+ case BUILT_IN_SIN:
+ case BUILT_IN_SINF:
+ case BUILT_IN_SINL:
+ case BUILT_IN_COS:
+ case BUILT_IN_COSF:
+ case BUILT_IN_COSL:
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
case BUILT_IN_MEMSET:
case BUILT_IN_MEMCPY:
case BUILT_IN_MEMCMP:
case BUILT_IN_COS:
case BUILT_IN_COSF:
case BUILT_IN_COSL:
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
+ case BUILT_IN_LOG:
+ case BUILT_IN_LOGF:
+ case BUILT_IN_LOGL:
/* Treat these like sqrt only if unsafe math optimizations are allowed,
because of possible accuracy problems. */
if (! flag_unsafe_math_optimizations)
BT_FN_DOUBLE_DOUBLE,
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
: ATTR_PURE_NOTHROW_LIST)
+DEF_LIB_BUILTIN(BUILT_IN_EXP,
+ "__builtin_exp",
+ BT_FN_DOUBLE_DOUBLE,
+ flag_errno_math ? ATTR_NOTHROW_LIST
+ : (flag_unsafe_math_optimizations
+ ? ATTR_CONST_NOTHROW_LIST
+ : ATTR_PURE_NOTHROW_LIST))
+DEF_LIB_BUILTIN(BUILT_IN_LOG,
+ "__builtin_log",
+ BT_FN_DOUBLE_DOUBLE,
+ flag_errno_math ? ATTR_NOTHROW_LIST
+ : (flag_unsafe_math_optimizations
+ ? ATTR_CONST_NOTHROW_LIST
+ : ATTR_PURE_NOTHROW_LIST))
DEF_LIB_BUILTIN(BUILT_IN_SQRTF,
"__builtin_sqrtf",
BT_FN_FLOAT_FLOAT,
BT_FN_FLOAT_FLOAT,
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
: ATTR_PURE_NOTHROW_LIST)
+DEF_LIB_BUILTIN(BUILT_IN_EXPF,
+ "__builtin_expf",
+ BT_FN_FLOAT_FLOAT,
+ flag_errno_math ? ATTR_NOTHROW_LIST
+ : (flag_unsafe_math_optimizations
+ ? ATTR_CONST_NOTHROW_LIST
+ : ATTR_PURE_NOTHROW_LIST))
+DEF_LIB_BUILTIN(BUILT_IN_LOGF,
+ "__builtin_logf",
+ BT_FN_FLOAT_FLOAT,
+ flag_errno_math ? ATTR_NOTHROW_LIST
+ : (flag_unsafe_math_optimizations
+ ? ATTR_CONST_NOTHROW_LIST
+ : ATTR_PURE_NOTHROW_LIST))
DEF_LIB_BUILTIN(BUILT_IN_SQRTL,
"__builtin_sqrtl",
BT_FN_LONG_DOUBLE_LONG_DOUBLE,
BT_FN_LONG_DOUBLE_LONG_DOUBLE,
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
: ATTR_PURE_NOTHROW_LIST)
+DEF_LIB_BUILTIN(BUILT_IN_EXPL,
+ "__builtin_expl",
+ BT_FN_LONG_DOUBLE_LONG_DOUBLE,
+ flag_errno_math ? ATTR_NOTHROW_LIST
+ : (flag_unsafe_math_optimizations
+ ? ATTR_CONST_NOTHROW_LIST
+ : ATTR_PURE_NOTHROW_LIST))
+DEF_LIB_BUILTIN(BUILT_IN_LOGL,
+ "__builtin_logl",
+ BT_FN_LONG_DOUBLE_LONG_DOUBLE,
+ flag_errno_math ? ATTR_NOTHROW_LIST
+ : (flag_unsafe_math_optimizations
+ ? ATTR_CONST_NOTHROW_LIST
+ : ATTR_PURE_NOTHROW_LIST))
DEF_UNUSED_BUILTIN(BUILT_IN_GETEXP)
DEF_UNUSED_BUILTIN(BUILT_IN_GETMAN)
@findex exit
@findex _exit
@findex _Exit
+@findex exp
+@findex expf
+@findex expl
@findex fabs
@findex fabsf
@findex fabsl
@findex index
@findex labs
@findex llabs
+@findex log
+@findex logf
+@findex logl
@findex memcmp
@findex memcpy
@findex memset
@code{cimagl}, @code{llabs} and @code{imaxabs} are handled as built-in
functions except in strict ISO C90 mode. There are also built-in
versions of the ISO C99 functions @code{cosf}, @code{cosl},
-@code{fabsf}, @code{fabsl}, @code{sinf}, @code{sinl}, @code{sqrtf}, and
+@code{expf}, @code{expl}, @code{fabsf}, @code{fabsl},
+@code{logf}, @code{logl}, @code{sinf}, @code{sinl}, @code{sqrtf}, and
@code{sqrtl}, that are recognized in any mode since ISO C90 reserves
these names for the purpose to which ISO C99 puts them. All these
functions have corresponding versions prefixed with @code{__builtin_}.
-The ISO C90 functions @code{abs}, @code{cos}, @code{fabs},
-@code{fprintf}, @code{fputs}, @code{labs}, @code{memcmp}, @code{memcpy},
+The ISO C90 functions @code{abs}, @code{cos}, @code{exp}, @code{fabs},
+@code{fprintf}, @code{fputs}, @code{labs}, @code{log},
+@code{memcmp}, @code{memcpy},
@code{memset}, @code{printf}, @code{sin}, @code{sqrt}, @code{strcat},
@code{strchr}, @code{strcmp}, @code{strcpy}, @code{strcspn},
@code{strlen}, @code{strncat}, @code{strncmp}, @code{strncpy},
Store the square root of operand 1 into operand 0.
The @code{sqrt} built-in function of C always uses the mode which
-corresponds to the C data type @code{double}.
+corresponds to the C data type @code{double} and the @code{sqrtf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{cos@var{m}2} instruction pattern
+@item @samp{cos@var{m}2}
+Store the cosine of operand 1 into operand 0.
+
+The @code{cos} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{cosf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{sin@var{m}2} instruction pattern
+@item @samp{sin@var{m}2}
+Store the sine of operand 1 into operand 0.
+
+The @code{sin} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{sinf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{exp@var{m}2} instruction pattern
+@item @samp{exp@var{m}2}
+Store the exponential of operand 1 into operand 0.
+
+The @code{exp} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{expf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
+
+@cindex @code{log@var{m}2} instruction pattern
+@item @samp{log@var{m}2}
+Store the natural logarithm of operand 1 into operand 0.
+
+The @code{log} built-in function of C always uses the mode which
+corresponds to the C data type @code{double} and the @code{logf}
+built-in function uses the mode which corresponds to the C data
+type @code{float}.
@cindex @code{ffs@var{m}2} instruction pattern
@item @samp{ffs@var{m}2}
"sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
"sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
"cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$a2$)",
+ "exp_optab->handlers[$A].insn_code = CODE_FOR_$(exp$a2$)",
+ "log_optab->handlers[$A].insn_code = CODE_FOR_$(log$a2$)",
"strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
"one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
"ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
sqrt_optab = init_optab (SQRT);
sin_optab = init_optab (UNKNOWN);
cos_optab = init_optab (UNKNOWN);
+ exp_optab = init_optab (UNKNOWN);
+ log_optab = init_optab (UNKNOWN);
strlen_optab = init_optab (UNKNOWN);
cbranch_optab = init_optab (UNKNOWN);
cmov_optab = init_optab (UNKNOWN);
OTI_sin,
/* Cosine */
OTI_cos,
+ /* Exponential */
+ OTI_exp,
+ /* Natural Logarithm */
+ OTI_log,
/* Compare insn; two operands. */
OTI_cmp,
#define sqrt_optab (optab_table[OTI_sqrt])
#define sin_optab (optab_table[OTI_sin])
#define cos_optab (optab_table[OTI_cos])
+#define exp_optab (optab_table[OTI_exp])
+#define log_optab (optab_table[OTI_log])
#define cmp_optab (optab_table[OTI_cmp])
#define ucmp_optab (optab_table[OTI_ucmp])