From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3743 invoked by alias); 8 Jul 2004 01:06:42 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 3731 invoked from network); 8 Jul 2004 01:06:41 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org with SMTP; 8 Jul 2004 01:06:41 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i6816fe1011825 for ; Wed, 7 Jul 2004 21:06:41 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [172.16.52.156]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i6816f017876; Wed, 7 Jul 2004 21:06:41 -0400 Received: from free.redhat.lsd.ic.unicamp.br (vpn50-51.rdu.redhat.com [172.16.50.51]) by pobox.corp.redhat.com (8.12.8/8.12.8) with ESMTP id i6816dn4019597; Wed, 7 Jul 2004 21:06:40 -0400 Received: from free.redhat.lsd.ic.unicamp.br (free.redhat.lsd.ic.unicamp.br [127.0.0.1]) by free.redhat.lsd.ic.unicamp.br (8.12.11/8.12.11) with ESMTP id i6816ckC029536; Wed, 7 Jul 2004 22:06:38 -0300 Received: (from aoliva@localhost) by free.redhat.lsd.ic.unicamp.br (8.12.11/8.12.11/Submit) id i6816cxS029518; Wed, 7 Jul 2004 22:06:38 -0300 To: Richard Henderson Cc: gcc-patches@gcc.gnu.org, rsandifo@redhat.com Subject: Re: add h8sx support to h8300 References: <20040707013159.GA31661@redhat.com> <20040707085035.GA5417@redhat.com> <20040708003018.GA15820@redhat.com> From: Alexandre Oliva Organization: Red Hat Global Engineering Services Compiler Team Date: Thu, 08 Jul 2004 01:26:00 -0000 In-Reply-To: <20040708003018.GA15820@redhat.com> Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-SW-Source: 2004-07/txt/msg00701.txt.bz2 --=-=-= Content-length: 5929 On Jul 7, 2004, Richard Henderson wrote: > On Wed, Jul 07, 2004 at 08:07:24PM -0300, Alexandre Oliva wrote: >> +#ifndef HAVE_movstr >> + return 0; >> +#else > One change; please do the macro frobbing to avoid the conditional > compilation. Doh, I hadn't found precedent for defaulting CODE_FOR_ before. How about this? I fixed a bug of uninitialized `end' and added more cases to expand_builtin_stpcpy() to get strcpy and stpcpy inlined in all cases for the attached testcase, compiled with -O3. How's this patchlet? Index: builtins.c =================================================================== RCS file: /cvs/uberbaum/gcc/builtins.c,v retrieving revision 1.347 diff -u -p -d -u -p -d -u -p -r1.347 builtins.c --- builtins.c 7 Jul 2004 19:23:54 -0000 1.347 +++ builtins.c 8 Jul 2004 01:05:29 -0000 @@ -2976,6 +2976,72 @@ expand_builtin_bcopy (tree arglist) return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode); } +#ifndef HAVE_movstr +# define HAVE_movstr 0 +# define CODE_FOR_movstr CODE_FOR_nothing +#endif + +/* Expand into a movstr instruction, if one is available. 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). If ENDP is 0 return the destination pointer, if ENDP + is 1 return the end pointer ala mempcpy, and if ENDP is 2 return + the end pointer minus one ala stpcpy. */ + +static rtx +expand_movstr (tree dest, tree src, rtx target, + enum machine_mode mode, int endp) +{ + rtx end; + rtx dest_mem; + rtx src_mem; + rtx insn; + const struct insn_data * data; + + if (!HAVE_movstr) + return 0; + + dest_mem = get_memory_rtx (dest); + src_mem = get_memory_rtx (src); + if (!endp) + { + XEXP (dest_mem, 0) = force_reg (Pmode, XEXP (dest_mem, 0)); + target = XEXP (dest_mem, 0); + end = gen_reg_rtx (Pmode); + } + else + { + if (target == 0 || target == const0_rtx) + { + end = gen_reg_rtx (Pmode); + if (target == 0) + target = end; + } + else + end = target; + } + + data = insn_data + CODE_FOR_movstr; + + if (data->operand[0].mode != VOIDmode) + end = gen_lowpart (data->operand[0].mode, end); + + insn = data->genfun (end, dest_mem, src_mem); + + if (insn == 0) + abort (); + + emit_insn (insn); + + /* movstr is supposed to set end to the address of the NUL + terminator. If the caller requested a mempcpy-like return value, + adjust it. */ + if (endp == 1 && target != const0_rtx) + emit_move_insn (end, plus_constant (end, 1)); + + return target; +} + /* 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 the result in TARGET, if convenient (and in mode MODE if that's @@ -2996,12 +3062,14 @@ expand_builtin_strcpy (tree arglist, rtx if (operand_equal_p (src, dst, 0)) return expand_expr (dst, target, mode, EXPAND_NORMAL); - fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; - if (!fn) - return 0; - len = c_strlen (src, 1); if (len == 0 || TREE_SIDE_EFFECTS (len)) + return expand_movstr (TREE_VALUE (arglist), + TREE_VALUE (TREE_CHAIN (arglist)), + target, mode, /*endp=*/0); + + fn = implicit_built_in_decls[BUILT_IN_MEMCPY]; + if (!fn) return 0; len = size_binop (PLUS_EXPR, len, ssize_int (1)); @@ -3020,22 +3088,17 @@ expand_builtin_strcpy (tree arglist, rtx static rtx expand_builtin_stpcpy (tree arglist, rtx target, enum machine_mode mode) { + /* If return value is ignored, transform stpcpy into strcpy. */ + if (target == const0_rtx) + return expand_builtin_strcpy (arglist, target, mode); + if (!validate_arglist (arglist, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) return 0; else { tree dst, src, len; - - /* If return value is ignored, transform stpcpy into strcpy. */ - if (target == const0_rtx) - { - tree fn = implicit_built_in_decls[BUILT_IN_STRCPY]; - if (!fn) - return 0; - - return expand_expr (build_function_call_expr (fn, arglist), - target, mode, EXPAND_NORMAL); - } + tree narglist; + rtx ret; /* Ensure we get an actual string whose length can be evaluated at compile-time, not an expression containing a string. This is @@ -3043,14 +3106,46 @@ expand_builtin_stpcpy (tree arglist, rtx when used to produce the return value. */ src = TREE_VALUE (TREE_CHAIN (arglist)); if (! c_getstr (src) || ! (len = c_strlen (src, 0))) - return 0; + return expand_movstr (TREE_VALUE (arglist), + TREE_VALUE (TREE_CHAIN (arglist)), + target, mode, /*endp=*/2); dst = TREE_VALUE (arglist); len = fold (size_binop (PLUS_EXPR, len, ssize_int (1))); - arglist = build_tree_list (NULL_TREE, len); - arglist = tree_cons (NULL_TREE, src, arglist); - arglist = tree_cons (NULL_TREE, dst, arglist); - return expand_builtin_mempcpy (arglist, target, mode, /*endp=*/2); + narglist = build_tree_list (NULL_TREE, len); + narglist = tree_cons (NULL_TREE, src, narglist); + narglist = tree_cons (NULL_TREE, dst, narglist); + ret = expand_builtin_mempcpy (narglist, target, mode, /*endp=*/2); + + if (ret) + return ret; + + if (TREE_CODE (len) == INTEGER_CST) + { + rtx len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); + + if (GET_CODE (len_rtx) == CONST_INT) + { + ret = expand_builtin_strcpy (arglist, target, mode); + + if (ret) + { + target = ret; + + ret = emit_move_insn (target, + plus_constant (target, + INTVAL (len_rtx))); + if (! ret) + abort (); + + return target; + } + } + } + + return expand_movstr (TREE_VALUE (arglist), + TREE_VALUE (TREE_CHAIN (arglist)), + target, mode, /*endp=*/2); } } --=-=-= Content-Type: text/x-c Content-Disposition: attachment; filename=t.c Content-length: 369 char *copy(char *dest, const char *src) { return strcpy(dest, src); } char *copy2(char *dest, const char *src) { return stpcpy(dest, src); } char *copy3(char *dest) { return copy(dest, "this is a test"); } char *copy4(char *dest) { return copy2(dest, "this is a test"); } void copy5(char *dest) { copy3(dest); } void copy6(char *dest) { copy4(dest); } --=-=-= Content-length: 188 -- Alexandre Oliva http://www.ic.unicamp.br/~oliva/ Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org} Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org} --=-=-=--