This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: add h8sx support to h8300


On Jul  7, 2004, Richard Henderson <rth@redhat.com> 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}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]