aboutsummaryrefslogtreecommitdiff
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2003-01-24 23:07:01 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2003-01-24 22:07:01 +0000
commit272f51a36f0274920b806cca375dca00ce7c51c8 (patch)
tree897959d6b91a286bdf8aff97f680af56bc3b6e8e /gcc/builtins.c
parent0ced43354fe55cfeed8e70eefc1110209ffb8c5f (diff)
downloadgcc-272f51a36f0274920b806cca375dca00ce7c51c8.zip
gcc-272f51a36f0274920b806cca375dca00ce7c51c8.tar.gz
gcc-272f51a36f0274920b806cca375dca00ce7c51c8.tar.bz2
builtins.c (DEF_BUILTIN): Accept 10 arguments.
* builtins.c (DEF_BUILTIN): Accept 10 arguments. (implicit_built_in_decls): New global array. (mathfn_built_in): New global function. (fold_trunc_transparent_mathfn): New static function (expand_builtin_strstr, expand_bultin_strchr, expand_builtin_strpbrk, expand_builtin_strcpy, expand_builtin_strncpy, expand_bultin_strcmp, expand_bultin_strncat, expand_builtin_fputs): Use implicint_built_in_decls. (fold_builtin): Fold floor/trunc/round/ceil/nearbyint. * builtins.def: Fix comments. (DEF_GCC_BUILTIN, DEF_FALLBACK_BUILTIN, DEF_EXT_FALLBACK_BUILTIN, DEF_LIB_BUILTIN, DEF_LIB_ALWAYS_BUILTIN, DEF_EXT_LIB_BUILTIN, DEF_C99_BULTIN, DEF_FRONT_END_LIB_BUILTIN, DEF_EXT_FRONT_END_LIB_BUILTIN): Pass implicit as needed. (DEF_C99_C90RES_BULTIN): New. (*f, *l builtins): Update. * c-common.c (DEF_BUILTIN): Initialize implicit array. (c_expand_builtin_printf, c_expand_builtin_fprintf): Update. * convert.c (strip_float_extensions): New global function. * tree.h (DEF_BUILTIN): Accept 10 arguments. (implicit_built_in_decls, mathfn_built_in, strip_float_extension): Declare. * java/builtins.c (define_builtin): Handle implicit. (DEF_BUILTIN): Update. * tm.texi (TARGET_C99_FUNCTIONS): Document. * defaults.h (TARGET_C99_FUNCTIONS): Default to 0. * config/linux.h (TARGET_C99_FUNCTIONS): Default to 1 when using glibc2. From-SVN: r61738
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c197
1 files changed, 183 insertions, 14 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 5e72df6..bb1f023 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -64,7 +64,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
const char *const built_in_class_names[4]
= {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
-#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT) STRINGX(X),
+#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM) STRINGX(X),
const char *const built_in_names[(int) END_BUILTINS] =
{
#include "builtins.def"
@@ -74,6 +74,10 @@ const char *const built_in_names[(int) END_BUILTINS] =
/* Setup an array of _DECL trees, make sure each element is
initialized to NULL_TREE. */
tree built_in_decls[(int) END_BUILTINS];
+/* Declarations used when constructing the builtin implicitly in the compiler.
+ It may be NULL_TREE when this is invalid (for instance runtime is not
+ required to implement the function call in all cases. */
+tree implicit_built_in_decls[(int) END_BUILTINS];
static int get_pointer_alignment PARAMS ((tree, unsigned int));
static tree c_strlen PARAMS ((tree));
@@ -153,6 +157,7 @@ static tree fold_builtin_classify_type PARAMS ((tree));
static tree fold_builtin_inf PARAMS ((tree, int));
static tree fold_builtin_nan PARAMS ((tree, tree, int));
static int validate_arglist PARAMS ((tree, ...));
+static tree fold_trunc_transparent_mathfn PARAMS ((tree));
/* Return the alignment in bits of EXP, a pointer valued expression.
But don't return more than MAX_ALIGN no matter what.
@@ -1469,6 +1474,170 @@ expand_builtin_constant_p (exp)
return tmp;
}
+/* Return mathematic function equivalent to FN but operating directly on TYPE,
+ if available. */
+tree
+mathfn_built_in (type, fn)
+ tree type;
+ enum built_in_function fn;
+{
+ enum built_in_function fcode = NOT_BUILT_IN;
+ if (TYPE_MODE (type) == TYPE_MODE (double_type_node))
+ switch (fn)
+ {
+ case BUILT_IN_SQRT:
+ case BUILT_IN_SQRTF:
+ case BUILT_IN_SQRTL:
+ fcode = BUILT_IN_SQRT;
+ break;
+ case BUILT_IN_SIN:
+ case BUILT_IN_SINF:
+ case BUILT_IN_SINL:
+ fcode = BUILT_IN_SIN;
+ break;
+ case BUILT_IN_COS:
+ case BUILT_IN_COSF:
+ case BUILT_IN_COSL:
+ fcode = BUILT_IN_COS;
+ break;
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
+ fcode = BUILT_IN_EXP;
+ break;
+ case BUILT_IN_FLOOR:
+ case BUILT_IN_FLOORF:
+ case BUILT_IN_FLOORL:
+ fcode = BUILT_IN_FLOOR;
+ break;
+ case BUILT_IN_CEIL:
+ case BUILT_IN_CEILF:
+ case BUILT_IN_CEILL:
+ fcode = BUILT_IN_CEIL;
+ break;
+ case BUILT_IN_TRUNC:
+ case BUILT_IN_TRUNCF:
+ case BUILT_IN_TRUNCL:
+ fcode = BUILT_IN_TRUNC;
+ break;
+ case BUILT_IN_ROUND:
+ case BUILT_IN_ROUNDF:
+ case BUILT_IN_ROUNDL:
+ fcode = BUILT_IN_ROUND;
+ break;
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
+ fcode = BUILT_IN_NEARBYINT;
+ break;
+ default:
+ abort ();
+ }
+ else if (TYPE_MODE (type) == TYPE_MODE (float_type_node))
+ switch (fn)
+ {
+ case BUILT_IN_SQRT:
+ case BUILT_IN_SQRTF:
+ case BUILT_IN_SQRTL:
+ fcode = BUILT_IN_SQRTF;
+ break;
+ case BUILT_IN_SIN:
+ case BUILT_IN_SINF:
+ case BUILT_IN_SINL:
+ fcode = BUILT_IN_SINF;
+ break;
+ case BUILT_IN_COS:
+ case BUILT_IN_COSF:
+ case BUILT_IN_COSL:
+ fcode = BUILT_IN_COSF;
+ break;
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
+ fcode = BUILT_IN_EXPF;
+ break;
+ case BUILT_IN_FLOOR:
+ case BUILT_IN_FLOORF:
+ case BUILT_IN_FLOORL:
+ fcode = BUILT_IN_FLOORF;
+ break;
+ case BUILT_IN_CEIL:
+ case BUILT_IN_CEILF:
+ case BUILT_IN_CEILL:
+ fcode = BUILT_IN_CEILF;
+ break;
+ case BUILT_IN_TRUNC:
+ case BUILT_IN_TRUNCF:
+ case BUILT_IN_TRUNCL:
+ fcode = BUILT_IN_TRUNCF;
+ break;
+ case BUILT_IN_ROUND:
+ case BUILT_IN_ROUNDF:
+ case BUILT_IN_ROUNDL:
+ fcode = BUILT_IN_ROUNDF;
+ break;
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
+ fcode = BUILT_IN_NEARBYINTF;
+ break;
+ default:
+ abort ();
+ }
+ else if (TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
+ switch (fn)
+ {
+ case BUILT_IN_SQRT:
+ case BUILT_IN_SQRTF:
+ case BUILT_IN_SQRTL:
+ fcode = BUILT_IN_SQRTL;
+ break;
+ case BUILT_IN_SIN:
+ case BUILT_IN_SINF:
+ case BUILT_IN_SINL:
+ fcode = BUILT_IN_SINL;
+ break;
+ case BUILT_IN_COS:
+ case BUILT_IN_COSF:
+ case BUILT_IN_COSL:
+ fcode = BUILT_IN_COSL;
+ break;
+ case BUILT_IN_EXP:
+ case BUILT_IN_EXPF:
+ case BUILT_IN_EXPL:
+ fcode = BUILT_IN_EXPL;
+ break;
+ case BUILT_IN_FLOOR:
+ case BUILT_IN_FLOORF:
+ case BUILT_IN_FLOORL:
+ fcode = BUILT_IN_FLOORL;
+ break;
+ case BUILT_IN_CEIL:
+ case BUILT_IN_CEILF:
+ case BUILT_IN_CEILL:
+ fcode = BUILT_IN_CEILL;
+ break;
+ case BUILT_IN_TRUNC:
+ case BUILT_IN_TRUNCF:
+ case BUILT_IN_TRUNCL:
+ fcode = BUILT_IN_TRUNCL;
+ break;
+ case BUILT_IN_ROUND:
+ case BUILT_IN_ROUNDF:
+ case BUILT_IN_ROUNDL:
+ fcode = BUILT_IN_ROUNDL;
+ break;
+ case BUILT_IN_NEARBYINT:
+ case BUILT_IN_NEARBYINTF:
+ case BUILT_IN_NEARBYINTL:
+ fcode = BUILT_IN_NEARBYINTL;
+ break;
+ default:
+ abort ();
+ }
+ return implicit_built_in_decls[fcode];
+}
+
/* Expand a call to one of the builtin math functions (sin, cos, or sqrt).
Return 0 if a normal call should be emitted rather than expanding the
function in-line. EXP is the expression that is a call to the builtin
@@ -1756,7 +1925,7 @@ expand_builtin_strstr (arglist, target, mode)
if (p2[1] != '\0')
return 0;
- fn = built_in_decls[BUILT_IN_STRCHR];
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
if (!fn)
return 0;
@@ -1860,7 +2029,7 @@ expand_builtin_strrchr (arglist, target, mode)
if (! integer_zerop (s2))
return 0;
- fn = built_in_decls[BUILT_IN_STRCHR];
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
if (!fn)
return 0;
@@ -1918,7 +2087,7 @@ expand_builtin_strpbrk (arglist, target, mode)
if (p2[1] != '\0')
return 0; /* Really call strpbrk. */
- fn = built_in_decls[BUILT_IN_STRCHR];
+ fn = implicit_built_in_decls[BUILT_IN_STRCHR];
if (!fn)
return 0;
@@ -2057,7 +2226,7 @@ expand_builtin_strcpy (exp, target, mode)
if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE))
return 0;
- fn = built_in_decls[BUILT_IN_MEMCPY];
+ fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
@@ -2159,7 +2328,7 @@ expand_builtin_strncpy (arglist, target, mode)
}
/* OK transform into builtin memcpy. */
- fn = built_in_decls[BUILT_IN_MEMCPY];
+ fn = implicit_built_in_decls[BUILT_IN_MEMCPY];
if (!fn)
return 0;
return expand_expr (build_function_call_expr (fn, arglist),
@@ -2575,7 +2744,7 @@ expand_builtin_strcmp (exp, target, mode)
if (TREE_SIDE_EFFECTS (len))
return 0;
- fn = built_in_decls[BUILT_IN_MEMCMP];
+ fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
if (!fn)
return 0;
@@ -2669,7 +2838,7 @@ expand_builtin_strncmp (exp, target, mode)
if (!len)
return 0;
- fn = built_in_decls[BUILT_IN_MEMCMP];
+ fn = implicit_built_in_decls[BUILT_IN_MEMCMP];
if (!fn)
return 0;
@@ -2750,7 +2919,7 @@ expand_builtin_strncat (arglist, target, mode)
{
tree newarglist
= tree_cons (NULL_TREE, dst, build_tree_list (NULL_TREE, src));
- tree fn = built_in_decls[BUILT_IN_STRCAT];
+ tree fn = implicit_built_in_decls[BUILT_IN_STRCAT];
/* If the replacement _DECL isn't initialized, don't do the
transformation. */
@@ -2838,7 +3007,7 @@ expand_builtin_strcspn (arglist, target, mode)
if (p2 && *p2 == '\0')
{
tree newarglist = build_tree_list (NULL_TREE, s1),
- fn = built_in_decls[BUILT_IN_STRLEN];
+ fn = implicit_built_in_decls[BUILT_IN_STRLEN];
/* If the replacement _DECL isn't initialized, don't do the
transformation. */
@@ -3445,10 +3614,10 @@ expand_builtin_fputs (arglist, ignore, unlocked)
int unlocked;
{
tree len, fn;
- tree fn_fputc = unlocked ? built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
- : built_in_decls[BUILT_IN_FPUTC];
- tree fn_fwrite = unlocked ? built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
- : built_in_decls[BUILT_IN_FWRITE];
+ tree fn_fputc = unlocked ? implicit_built_in_decls[BUILT_IN_FPUTC_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FPUTC];
+ tree fn_fwrite = unlocked ? implicit_built_in_decls[BUILT_IN_FWRITE_UNLOCKED]
+ : implicit_built_in_decls[BUILT_IN_FWRITE];
/* If the return value is used, or the replacement _DECL isn't
initialized, don't do the transformation. */