Commit e31603c4 by Jakub Jelinek Committed by Jakub Jelinek

builtins.def (BUILT_IN_BCOPY, [...]): New.

	* builtins.def (BUILT_IN_BCOPY, BUILT_IN_MEMMOVE): New.
	* builtin-types.def (BT_FN_VOID_CONST_PTR_PTR_SIZE): New.
	* builtins.c (expand_builtin_memmove, expand_builtin_bcopy): New
	functions.
	(expand_builtin): Handle BUILT_IN_BCOPY and BUILT_IN_MEMMOVE.

	* gcc.c-torture/execute/string-opt-19.c: New test.

From-SVN: r66169
parent dbe983a8
2003-04-28 Jakub Jelinek <jakub@redhat.com>
* builtins.def (BUILT_IN_BCOPY, BUILT_IN_MEMMOVE): New.
* builtin-types.def (BT_FN_VOID_CONST_PTR_PTR_SIZE): New.
* builtins.c (expand_builtin_memmove, expand_builtin_bcopy): New
functions.
(expand_builtin): Handle BUILT_IN_BCOPY and BUILT_IN_MEMMOVE.
2003-04-28 Nick Clifton <nickc@redhat.com> 2003-04-28 Nick Clifton <nickc@redhat.com>
* config/arm/elf.h (ASM_OUTPUT_ALIGNED_COMMON): Remove definition. * config/arm/elf.h (ASM_OUTPUT_ALIGNED_COMMON): Remove definition.
......
...@@ -174,6 +174,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_INT_SIZE, ...@@ -174,6 +174,8 @@ DEF_FUNCTION_TYPE_3 (BT_FN_PTR_PTR_INT_SIZE,
BT_PTR, BT_PTR, BT_INT, BT_SIZE) BT_PTR, BT_PTR, BT_INT, BT_SIZE)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_INT_INT, DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_INT_INT,
BT_VOID, BT_PTR, BT_INT, BT_INT) BT_VOID, BT_PTR, BT_INT, BT_INT)
DEF_FUNCTION_TYPE_3 (BT_FN_VOID_CONST_PTR_PTR_SIZE,
BT_VOID, BT_CONST_PTR, BT_PTR, BT_SIZE)
DEF_FUNCTION_TYPE_3 (BT_FN_INT_STRING_CONST_STRING_VALIST_ARG, DEF_FUNCTION_TYPE_3 (BT_FN_INT_STRING_CONST_STRING_VALIST_ARG,
BT_INT, BT_STRING, BT_CONST_STRING, BT_VALIST_ARG) BT_INT, BT_STRING, BT_CONST_STRING, BT_VALIST_ARG)
DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG, DEF_FUNCTION_TYPE_3 (BT_FN_INT_CONST_STRING_CONST_STRING_VALIST_ARG,
......
...@@ -126,6 +126,9 @@ static rtx expand_builtin_strcspn PARAMS ((tree, rtx, ...@@ -126,6 +126,9 @@ static rtx expand_builtin_strcspn PARAMS ((tree, rtx,
enum machine_mode)); enum machine_mode));
static rtx expand_builtin_memcpy PARAMS ((tree, rtx, static rtx expand_builtin_memcpy PARAMS ((tree, rtx,
enum machine_mode, int)); enum machine_mode, int));
static rtx expand_builtin_memmove PARAMS ((tree, rtx,
enum machine_mode));
static rtx expand_builtin_bcopy PARAMS ((tree));
static rtx expand_builtin_strcpy PARAMS ((tree, rtx, static rtx expand_builtin_strcpy PARAMS ((tree, rtx,
enum machine_mode)); enum machine_mode));
static rtx expand_builtin_stpcpy PARAMS ((tree, rtx, static rtx expand_builtin_stpcpy PARAMS ((tree, rtx,
...@@ -2364,6 +2367,84 @@ expand_builtin_memcpy (arglist, target, mode, endp) ...@@ -2364,6 +2367,84 @@ expand_builtin_memcpy (arglist, target, mode, endp)
} }
} }
/* Expand expression EXP, which is a call to the memmove builtin. Return 0
if we failed the caller should emit a normal call. */
static rtx
expand_builtin_memmove (arglist, target, mode)
tree arglist;
rtx target;
enum machine_mode mode;
{
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return 0;
else
{
tree dest = TREE_VALUE (arglist);
tree src = TREE_VALUE (TREE_CHAIN (arglist));
tree len = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
unsigned int src_align = get_pointer_alignment (src, BIGGEST_ALIGNMENT);
unsigned int dest_align
= get_pointer_alignment (dest, BIGGEST_ALIGNMENT);
/* If DEST is not a pointer type, call the normal function. */
if (dest_align == 0)
return 0;
/* If the LEN parameter is zero, return DEST. */
if (host_integerp (len, 1) && tree_low_cst (len, 1) == 0)
{
/* Evaluate and ignore SRC in case it has side-effects. */
expand_expr (src, const0_rtx, VOIDmode, EXPAND_NORMAL);
return expand_expr (dest, target, mode, EXPAND_NORMAL);
}
/* If either SRC is not a pointer type, don't do this
operation in-line. */
if (src_align == 0)
return 0;
/* If src is a string constant and strings are not writable,
we can use normal memcpy. */
if (!flag_writable_strings && c_getstr (src))
return expand_builtin_memcpy (arglist, target, mode, 0);
/* Otherwise, call the normal function. */
return 0;
}
}
/* Expand expression EXP, which is a call to the bcopy builtin. Return 0
if we failed the caller should emit a normal call. */
static rtx
expand_builtin_bcopy (arglist)
tree arglist;
{
tree src, dest, size, newarglist;
if (!validate_arglist (arglist,
POINTER_TYPE, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
return NULL_RTX;
src = TREE_VALUE (arglist);
dest = TREE_VALUE (TREE_CHAIN (arglist));
size = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
/* New argument list transforming bcopy(ptr x, ptr y, int z) to
memmove(ptr y, ptr x, size_t z). This is done this way
so that if it isn't expanded inline, we fallback to
calling bcopy instead of memmove. */
newarglist = build_tree_list (NULL_TREE, convert (sizetype, size));
newarglist = tree_cons (NULL_TREE, src, newarglist);
newarglist = tree_cons (NULL_TREE, dest, newarglist);
return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode);
}
/* Expand expression EXP, which is a call to the strcpy builtin. Return 0 /* Expand expression EXP, which is a call to the strcpy builtin. Return 0
if we failed the caller should emit a normal call, otherwise try to get if we failed the caller should emit a normal call, otherwise try to get
the result in TARGET, if convenient (and in mode MODE if that's the result in TARGET, if convenient (and in mode MODE if that's
...@@ -4177,8 +4258,10 @@ expand_builtin (exp, target, subtarget, mode, ignore) ...@@ -4177,8 +4258,10 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_MEMCPY: case BUILT_IN_MEMCPY:
case BUILT_IN_MEMCMP: case BUILT_IN_MEMCMP:
case BUILT_IN_MEMPCPY: case BUILT_IN_MEMPCPY:
case BUILT_IN_MEMMOVE:
case BUILT_IN_BCMP: case BUILT_IN_BCMP:
case BUILT_IN_BZERO: case BUILT_IN_BZERO:
case BUILT_IN_BCOPY:
case BUILT_IN_INDEX: case BUILT_IN_INDEX:
case BUILT_IN_RINDEX: case BUILT_IN_RINDEX:
case BUILT_IN_STPCPY: case BUILT_IN_STPCPY:
...@@ -4543,6 +4626,18 @@ expand_builtin (exp, target, subtarget, mode, ignore) ...@@ -4543,6 +4626,18 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return target; return target;
break; break;
case BUILT_IN_MEMMOVE:
target = expand_builtin_memmove (arglist, target, mode);
if (target)
return target;
break;
case BUILT_IN_BCOPY:
target = expand_builtin_bcopy (arglist);
if (target)
return target;
break;
case BUILT_IN_MEMSET: case BUILT_IN_MEMSET:
target = expand_builtin_memset (exp, target, mode); target = expand_builtin_memset (exp, target, mode);
if (target) if (target)
......
...@@ -286,9 +286,9 @@ DEF_C99_BUILTIN(BUILT_IN_CIMAGL, ...@@ -286,9 +286,9 @@ DEF_C99_BUILTIN(BUILT_IN_CIMAGL,
BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE, BT_FN_LONG_DOUBLE_COMPLEX_LONG_DOUBLE,
ATTR_CONST_NOTHROW_LIST) ATTR_CONST_NOTHROW_LIST)
/* The system prototypes for `bzero' and `bcmp' functions have many /* The system prototypes for `bzero', 'bcopy' and `bcmp' functions
variations, so don't specify parameters to avoid conflicts. The have many variations, so don't specify parameters to avoid conflicts.
expand_* functions check the argument types anyway. */ The expand_* functions check the argument types anyway. */
DEF_BUILTIN (BUILT_IN_BZERO, DEF_BUILTIN (BUILT_IN_BZERO,
"__builtin_bzero", "__builtin_bzero",
BUILT_IN_NORMAL, BUILT_IN_NORMAL,
...@@ -296,6 +296,13 @@ DEF_BUILTIN (BUILT_IN_BZERO, ...@@ -296,6 +296,13 @@ DEF_BUILTIN (BUILT_IN_BZERO,
BT_FN_VOID_VAR, BT_FN_VOID_VAR,
true, true, true, true, true, true,
ATTR_NOTHROW_LIST, false) ATTR_NOTHROW_LIST, false)
DEF_BUILTIN (BUILT_IN_BCOPY,
"__builtin_bcopy",
BUILT_IN_NORMAL,
BT_FN_VOID_CONST_PTR_PTR_SIZE,
BT_FN_VOID_VAR,
true, true, true,
ATTR_NOTHROW_LIST, false)
DEF_BUILTIN (BUILT_IN_BCMP, DEF_BUILTIN (BUILT_IN_BCMP,
"__builtin_bcmp", "__builtin_bcmp",
BUILT_IN_NORMAL, BUILT_IN_NORMAL,
...@@ -380,6 +387,10 @@ DEF_LIB_BUILTIN(BUILT_IN_MEMCPY, ...@@ -380,6 +387,10 @@ DEF_LIB_BUILTIN(BUILT_IN_MEMCPY,
"__builtin_memcpy", "__builtin_memcpy",
BT_FN_PTR_PTR_CONST_PTR_SIZE, BT_FN_PTR_PTR_CONST_PTR_SIZE,
ATTR_NOTHROW_LIST) ATTR_NOTHROW_LIST)
DEF_LIB_BUILTIN(BUILT_IN_MEMMOVE,
"__builtin_memmove",
BT_FN_PTR_PTR_CONST_PTR_SIZE,
ATTR_NOTHROW_LIST)
DEF_LIB_BUILTIN(BUILT_IN_MEMCMP, DEF_LIB_BUILTIN(BUILT_IN_MEMCMP,
"__builtin_memcmp", "__builtin_memcmp",
BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, BT_FN_INT_CONST_PTR_CONST_PTR_SIZE,
......
2003-04-28 Jakub Jelinek <jakub@redhat.com>
* gcc.c-torture/execute/string-opt-19.c: New test.
2003-04-27 Mark Mitchell <mark@codesourcery.com> 2003-04-27 Mark Mitchell <mark@codesourcery.com>
PR c++/10506 PR c++/10506
......
/* Copyright (C) 2003 Free Software Foundation.
Ensure builtin memmove and bcopy perform correctly.
Written by Jakub Jelinek, 4/26/2003. */
extern void abort (void);
typedef __SIZE_TYPE__ size_t;
extern void *memmove (void *, const void *, size_t);
extern void bcopy (const void *, void *, size_t);
extern int memcmp (const void *, const void *, size_t);
const char s1[] = "123";
char p[32] = "";
int main()
{
int i;
const char *s;
if (memmove (p, "abcde", 6) != p || memcmp (p, "abcde", 6))
abort ();
s = s1;
if (memmove (p + 2, ++s, 0) != p + 2 || memcmp (p, "abcde", 6) || s != s1 + 1)
abort ();
if (__builtin_memmove (p + 3, "", 1) != p + 3 || memcmp (p, "abc\0e", 6))
abort ();
bcopy ("fghijk", p + 2, 4);
if (memcmp (p, "abfghi", 7))
abort ();
s = s1 + 1;
bcopy (s++, p + 1, 0);
if (memcmp (p, "abfghi", 7) || s != s1 + 2)
abort ();
__builtin_bcopy ("ABCDE", p + 4, 1);
if (memcmp (p, "abfgAi", 7))
abort ();
return 0;
}
/* When optimizing, all the above cases should be transformed into
something else. So any remaining calls to the original function
should abort. When not optimizing, provide memmove/bcopy implementation
just in case target lacks these in its libc. */
__attribute__ ((noinline))
static void *
memmove (void *d, const void *s, size_t n)
{
#ifdef __OPTIMIZE__
abort ();
#else
char *dst = (char *) d;
const char *src = (const char *) s;
if (src < dst)
{
dst += n;
src += n;
while (n--)
*--dst = *--src;
}
else
while (n--)
*dst++ = *src++;
return (char *) d;
#endif
}
__attribute__ ((noinline))
static void
bcopy (const void *s, void *d, size_t n)
{
#ifdef __OPTIMIZE__
abort ();
#else
char *dst = (char *) d;
const char *src = (const char *) s;
if (src < dst)
{
dst += n;
src += n;
while (n--)
*--dst = *--src;
}
else
while (n--)
*dst++ = *src++;
#endif
}
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