From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27863 invoked by alias); 7 Jul 2004 23:07:32 -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 27837 invoked from network); 7 Jul 2004 23:07:27 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org with SMTP; 7 Jul 2004 23:07:27 -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 i67N7Re1017199 for ; Wed, 7 Jul 2004 19:07:27 -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 i67N7R021658; Wed, 7 Jul 2004 19:07:27 -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 i67N7Pn4005984; Wed, 7 Jul 2004 19:07:26 -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 i67N7OGP002218; Wed, 7 Jul 2004 20:07:24 -0300 Received: (from aoliva@localhost) by free.redhat.lsd.ic.unicamp.br (8.12.11/8.12.11/Submit) id i67N7O9B002212; Wed, 7 Jul 2004 20:07:24 -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> From: Alexandre Oliva Organization: Red Hat Global Engineering Services Compiler Team Date: Thu, 08 Jul 2004 00:14:00 -0000 In-Reply-To: <20040707085035.GA5417@redhat.com> Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2004-07/txt/msg00691.txt.bz2 On Jul 7, 2004, Richard Henderson wrote: > On Wed, Jul 07, 2004 at 03:55:43AM -0300, Alexandre Oliva wrote: >> However, even if it's close to stpcpy(), some arches will have the >> final register point one-past the NUL terminator, whereas others might >> have it point to the NUL terminator itself. I suppose we should >> probably model movstr exactly after stpcpy(), even if that takes an >> additional increment/decrement instruction to get the right value. > Probably. With one output. Is this sort of what you were expecting? Ok to install along with the H8SX patch, if it passes a build&test cycle? 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 7 Jul 2004 23:05:47 -0000 @@ -2976,6 +2976,70 @@ expand_builtin_bcopy (tree arglist) return expand_builtin_memmove (newarglist, const0_rtx, VOIDmode); } +/* 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 ATTRIBUTE_UNUSED, + tree src ATTRIBUTE_UNUSED, + rtx target ATTRIBUTE_UNUSED, + enum machine_mode mode ATTRIBUTE_UNUSED, + int endp ATTRIBUTE_UNUSED) +{ +#ifndef HAVE_movstr + return 0; +#else + 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; + } + + 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; +#endif +} + /* 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 +3060,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,30 +3086,25 @@ 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); - } - /* Ensure we get an actual string whose length can be evaluated at compile-time, not an expression containing a string. This is because the latter will potentially produce pessimized code 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))); -- 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}