diff options
author | ghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-11-01 03:22:21 +0000 |
---|---|---|
committer | ghazi <ghazi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-11-01 03:22:21 +0000 |
commit | 17f5ea874265fddbd7c9fcaf2ff8d5b2d5b813fb (patch) | |
tree | e4e757584dc941d8bee942e484a6fd8344b8fa09 /gcc/builtins.c | |
parent | c0921e860cbea2ca7a38116365f9766c55abd710 (diff) | |
download | ppe42-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.c | 68 |
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: |