Commit e7b489c8 by Roger Sayle Committed by Roger Sayle

builtins.def: Define new builtin functions exp...


	* 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).

From-SVN: r56010
parent de8920be
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> 2002-08-03 Jason Merrill <jason@redhat.com>
* explow.c (int_expr_size): New fn. * explow.c (int_expr_size): New fn.
......
...@@ -1525,7 +1525,15 @@ expand_builtin_mathfn (exp, target, subtarget) ...@@ -1525,7 +1525,15 @@ expand_builtin_mathfn (exp, target, subtarget)
case BUILT_IN_SQRTF: case BUILT_IN_SQRTF:
case BUILT_IN_SQRTL: case BUILT_IN_SQRTL:
builtin_optab = sqrt_optab; break; 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 (); abort ();
} }
...@@ -3689,11 +3697,18 @@ expand_builtin (exp, target, subtarget, mode, ignore) ...@@ -3689,11 +3697,18 @@ expand_builtin (exp, target, subtarget, mode, ignore)
if (!optimize && !CALLED_AS_BUILT_IN (fndecl)) if (!optimize && !CALLED_AS_BUILT_IN (fndecl))
switch (fcode) switch (fcode)
{ {
case BUILT_IN_SIN:
case BUILT_IN_COS:
case BUILT_IN_SQRT: case BUILT_IN_SQRT:
case BUILT_IN_SQRTF: case BUILT_IN_SQRTF:
case BUILT_IN_SQRTL: 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_MEMSET:
case BUILT_IN_MEMCPY: case BUILT_IN_MEMCPY:
case BUILT_IN_MEMCMP: case BUILT_IN_MEMCMP:
...@@ -3764,6 +3779,12 @@ expand_builtin (exp, target, subtarget, mode, ignore) ...@@ -3764,6 +3779,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_COS: case BUILT_IN_COS:
case BUILT_IN_COSF: case BUILT_IN_COSF:
case BUILT_IN_COSL: 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, /* Treat these like sqrt only if unsafe math optimizations are allowed,
because of possible accuracy problems. */ because of possible accuracy problems. */
if (! flag_unsafe_math_optimizations) if (! flag_unsafe_math_optimizations)
......
...@@ -324,6 +324,20 @@ DEF_LIB_BUILTIN(BUILT_IN_COS, ...@@ -324,6 +324,20 @@ DEF_LIB_BUILTIN(BUILT_IN_COS,
BT_FN_DOUBLE_DOUBLE, BT_FN_DOUBLE_DOUBLE,
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
: ATTR_PURE_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, DEF_LIB_BUILTIN(BUILT_IN_SQRTF,
"__builtin_sqrtf", "__builtin_sqrtf",
BT_FN_FLOAT_FLOAT, BT_FN_FLOAT_FLOAT,
...@@ -341,6 +355,20 @@ DEF_LIB_BUILTIN(BUILT_IN_COSF, ...@@ -341,6 +355,20 @@ DEF_LIB_BUILTIN(BUILT_IN_COSF,
BT_FN_FLOAT_FLOAT, BT_FN_FLOAT_FLOAT,
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
: ATTR_PURE_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, DEF_LIB_BUILTIN(BUILT_IN_SQRTL,
"__builtin_sqrtl", "__builtin_sqrtl",
BT_FN_LONG_DOUBLE_LONG_DOUBLE, BT_FN_LONG_DOUBLE_LONG_DOUBLE,
...@@ -358,6 +386,20 @@ DEF_LIB_BUILTIN(BUILT_IN_COSL, ...@@ -358,6 +386,20 @@ DEF_LIB_BUILTIN(BUILT_IN_COSL,
BT_FN_LONG_DOUBLE_LONG_DOUBLE, BT_FN_LONG_DOUBLE_LONG_DOUBLE,
flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST flag_unsafe_math_optimizations ? ATTR_CONST_NOTHROW_LIST
: ATTR_PURE_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_GETEXP)
DEF_UNUSED_BUILTIN(BUILT_IN_GETMAN) DEF_UNUSED_BUILTIN(BUILT_IN_GETMAN)
......
...@@ -4500,6 +4500,9 @@ v4si f (v4si a, v4si b, v4si c) ...@@ -4500,6 +4500,9 @@ v4si f (v4si a, v4si b, v4si c)
@findex exit @findex exit
@findex _exit @findex _exit
@findex _Exit @findex _Exit
@findex exp
@findex expf
@findex expl
@findex fabs @findex fabs
@findex fabsf @findex fabsf
@findex fabsl @findex fabsl
...@@ -4512,6 +4515,9 @@ v4si f (v4si a, v4si b, v4si c) ...@@ -4512,6 +4515,9 @@ v4si f (v4si a, v4si b, v4si c)
@findex index @findex index
@findex labs @findex labs
@findex llabs @findex llabs
@findex log
@findex logf
@findex logl
@findex memcmp @findex memcmp
@findex memcpy @findex memcpy
@findex memset @findex memset
...@@ -4577,13 +4583,15 @@ The ISO C99 functions @code{conj}, @code{conjf}, @code{conjl}, ...@@ -4577,13 +4583,15 @@ The ISO C99 functions @code{conj}, @code{conjf}, @code{conjl},
@code{cimagl}, @code{llabs} and @code{imaxabs} are handled as built-in @code{cimagl}, @code{llabs} and @code{imaxabs} are handled as built-in
functions except in strict ISO C90 mode. There are also built-in functions except in strict ISO C90 mode. There are also built-in
versions of the ISO C99 functions @code{cosf}, @code{cosl}, 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 @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 these names for the purpose to which ISO C99 puts them. All these
functions have corresponding versions prefixed with @code{__builtin_}. functions have corresponding versions prefixed with @code{__builtin_}.
The ISO C90 functions @code{abs}, @code{cos}, @code{fabs}, The ISO C90 functions @code{abs}, @code{cos}, @code{exp}, @code{fabs},
@code{fprintf}, @code{fputs}, @code{labs}, @code{memcmp}, @code{memcpy}, @code{fprintf}, @code{fputs}, @code{labs}, @code{log},
@code{memcmp}, @code{memcpy},
@code{memset}, @code{printf}, @code{sin}, @code{sqrt}, @code{strcat}, @code{memset}, @code{printf}, @code{sin}, @code{sqrt}, @code{strcat},
@code{strchr}, @code{strcmp}, @code{strcpy}, @code{strcspn}, @code{strchr}, @code{strcmp}, @code{strcpy}, @code{strcspn},
@code{strlen}, @code{strncat}, @code{strncmp}, @code{strncpy}, @code{strlen}, @code{strncat}, @code{strncmp}, @code{strncpy},
......
...@@ -2523,7 +2523,45 @@ Store the absolute value of operand 1 into operand 0. ...@@ -2523,7 +2523,45 @@ Store the absolute value of operand 1 into operand 0.
Store the square root of operand 1 into operand 0. Store the square root of operand 1 into operand 0.
The @code{sqrt} built-in function of C always uses the mode which 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 @cindex @code{ffs@var{m}2} instruction pattern
@item @samp{ffs@var{m}2} @item @samp{ffs@var{m}2}
......
...@@ -114,6 +114,8 @@ static const char * const optabs[] = ...@@ -114,6 +114,8 @@ static const char * const optabs[] =
"sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)", "sqrt_optab->handlers[$A].insn_code = CODE_FOR_$(sqrt$a2$)",
"sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)", "sin_optab->handlers[$A].insn_code = CODE_FOR_$(sin$a2$)",
"cos_optab->handlers[$A].insn_code = CODE_FOR_$(cos$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$)", "strlen_optab->handlers[$A].insn_code = CODE_FOR_$(strlen$a$)",
"one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)", "one_cmpl_optab->handlers[$A].insn_code = CODE_FOR_$(one_cmpl$a2$)",
"ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)", "ffs_optab->handlers[$A].insn_code = CODE_FOR_$(ffs$a2$)",
......
...@@ -5193,6 +5193,8 @@ init_optabs () ...@@ -5193,6 +5193,8 @@ init_optabs ()
sqrt_optab = init_optab (SQRT); sqrt_optab = init_optab (SQRT);
sin_optab = init_optab (UNKNOWN); sin_optab = init_optab (UNKNOWN);
cos_optab = init_optab (UNKNOWN); cos_optab = init_optab (UNKNOWN);
exp_optab = init_optab (UNKNOWN);
log_optab = init_optab (UNKNOWN);
strlen_optab = init_optab (UNKNOWN); strlen_optab = init_optab (UNKNOWN);
cbranch_optab = init_optab (UNKNOWN); cbranch_optab = init_optab (UNKNOWN);
cmov_optab = init_optab (UNKNOWN); cmov_optab = init_optab (UNKNOWN);
......
...@@ -131,6 +131,10 @@ enum optab_index ...@@ -131,6 +131,10 @@ enum optab_index
OTI_sin, OTI_sin,
/* Cosine */ /* Cosine */
OTI_cos, OTI_cos,
/* Exponential */
OTI_exp,
/* Natural Logarithm */
OTI_log,
/* Compare insn; two operands. */ /* Compare insn; two operands. */
OTI_cmp, OTI_cmp,
...@@ -198,6 +202,8 @@ extern GTY(()) optab optab_table[OTI_MAX]; ...@@ -198,6 +202,8 @@ extern GTY(()) optab optab_table[OTI_MAX];
#define sqrt_optab (optab_table[OTI_sqrt]) #define sqrt_optab (optab_table[OTI_sqrt])
#define sin_optab (optab_table[OTI_sin]) #define sin_optab (optab_table[OTI_sin])
#define cos_optab (optab_table[OTI_cos]) #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 cmp_optab (optab_table[OTI_cmp])
#define ucmp_optab (optab_table[OTI_ucmp]) #define ucmp_optab (optab_table[OTI_ucmp])
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment