summaryrefslogtreecommitdiffstats
path: root/gcc/builtins.c
diff options
context:
space:
mode:
authorghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4>2000-11-01 03:22:21 +0000
committerghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4>2000-11-01 03:22:21 +0000
commit17f5ea874265fddbd7c9fcaf2ff8d5b2d5b813fb (patch)
treee4e757584dc941d8bee942e484a6fd8344b8fa09 /gcc/builtins.c
parentc0921e860cbea2ca7a38116365f9766c55abd710 (diff)
downloadppe42-gcc-17f5ea874265fddbd7c9fcaf2ff8d5b2d5b813fb.tar.gz
ppe42-gcc-17f5ea874265fddbd7c9fcaf2ff8d5b2d5b813fb.zip
* builtins.c (expand_builtin_strstr): New function.
(expand_builtin): Handle BUILT_IN_STRSTR and BUILT_IN_STRCHR. * builtins.def (BUILT_IN_STRSTR, BUILT_IN_STRCHR): New entries. * c-common.c (c_common_nodes_and_builtins): Declare builtin strstr and builtin strchr. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37181 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/builtins.c')
-rw-r--r--gcc/builtins.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3304b68a46a..abb67476cd6 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -108,6 +108,8 @@ static rtx expand_builtin_memset PARAMS ((tree));
static rtx expand_builtin_bzero PARAMS ((tree));
static rtx expand_builtin_strlen PARAMS ((tree, rtx,
enum machine_mode));
+static rtx expand_builtin_strstr PARAMS ((tree, rtx,
+ enum machine_mode));
static rtx expand_builtin_alloca PARAMS ((tree, rtx));
static rtx expand_builtin_ffs PARAMS ((tree, rtx, rtx));
static rtx expand_builtin_frame_address PARAMS ((tree));
@@ -1431,6 +1433,64 @@ expand_builtin_strlen (exp, target, mode)
}
}
+/* Expand a call to the strstr builtin. Return 0 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 convenient). */
+
+static rtx
+expand_builtin_strstr (arglist, target, mode)
+ tree arglist;
+ rtx target;
+ enum machine_mode mode;
+{
+ if (arglist == 0
+ || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE
+ || TREE_CHAIN (arglist) == 0
+ || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE)
+ return 0;
+ else
+ {
+ tree s1 = TREE_VALUE (arglist), s2 = TREE_VALUE (TREE_CHAIN (arglist));
+ tree len = c_strlen (s2);
+
+ if (!len)
+ return 0;
+
+ switch (compare_tree_int (len, 1))
+ {
+ case -1: /* length is 0, return s1. */
+ return expand_expr (s1, target, mode, EXPAND_NORMAL);
+ case 0: /* length is 1, return strchr(s1, s2[0]). */
+ {
+ tree call_expr, fn = built_in_decls[BUILT_IN_STRCHR];
+
+ if (!fn)
+ return 0;
+ STRIP_NOPS (s2);
+ if (s2 && TREE_CODE (s2) == ADDR_EXPR)
+ s2 = TREE_OPERAND (s2, 0);
+
+ /* New argument list transforming strstr(s1, s2) to
+ strchr(s1, s2[0]). */
+ arglist =
+ build_tree_list (NULL_TREE,
+ build_int_2 (TREE_STRING_POINTER (s2)[0], 0));
+ arglist = tree_cons (NULL_TREE, s1, arglist);
+ call_expr = build1 (ADDR_EXPR,
+ build_pointer_type (TREE_TYPE (fn)), fn);
+ call_expr = build (CALL_EXPR, TREE_TYPE (TREE_TYPE (fn)),
+ call_expr, arglist, NULL_TREE);
+ TREE_SIDE_EFFECTS (call_expr) = 1;
+ return expand_expr (call_expr, target, mode, EXPAND_NORMAL);
+ }
+ case 1: /* length is greater than 1, really call strstr. */
+ return 0;
+ default:
+ abort();
+ }
+ }
+}
+
/* Expand a call to the memcpy builtin, with arguments in ARGLIST. */
static rtx
expand_builtin_memcpy (arglist)
@@ -2475,6 +2535,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
|| fcode == BUILT_IN_MEMCPY || fcode == BUILT_IN_MEMCMP
|| fcode == BUILT_IN_BCMP || fcode == BUILT_IN_BZERO
|| fcode == BUILT_IN_STRLEN || fcode == BUILT_IN_STRCPY
+ || fcode == BUILT_IN_STRSTR
|| fcode == BUILT_IN_STRCMP || fcode == BUILT_IN_FFS
|| fcode == BUILT_IN_PUTCHAR || fcode == BUILT_IN_PUTS
|| fcode == BUILT_IN_PRINTF || fcode == BUILT_IN_FPUTC
@@ -2603,6 +2664,12 @@ expand_builtin (exp, target, subtarget, mode, ignore)
return target;
break;
+ case BUILT_IN_STRSTR:
+ target = expand_builtin_strstr (arglist, target, mode);
+ if (target)
+ return target;
+ break;
+
case BUILT_IN_MEMCPY:
target = expand_builtin_memcpy (arglist);
if (target)
@@ -2696,6 +2763,7 @@ expand_builtin (exp, target, subtarget, mode, ignore)
case BUILT_IN_PUTS:
case BUILT_IN_FPUTC:
case BUILT_IN_FWRITE:
+ case BUILT_IN_STRCHR:
break;
case BUILT_IN_FPUTS:
OpenPOWER on IntegriCloud