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]

add h8sx support to h8300


This patch introduces support for the H8SX processor to the h8300
port.  Unfortunately, h8300-elf wouldn't build out of mainline, so I
regression tested it with an older tree that built h8300-elf
successfully, without any regressions on h8300-elf (multilibs default,
-ms, -mh, and the latter two with -mint32).  The patch fixes whatever
problem it was that prevented building of h8300-elf in mainline; I
didn't try to track down what exact set of changes fixed it, and I
hope I don't have to.  Suffice it to say that the test results I got
in mainline after installing the patch were only slightly worse than
those in the older tree.  Since the patch was the same, I think it's
reasonably safe to assume that it doesn't introduce any regressions in
mainline, but since it was totally broken before installing the patch
(and has been for quite a while), it's hard to tell.  I hope this is
good enough.

There are very few changes to machine-independent code, that I enclose
as plain text below, even though they're also in the compressed patch,
such that global-write maintainers can more easily look at them and
hopefully approve them to go in along with the rest of the patch, that
should probably be reviewed by the H8 maintainers.

I'm Cc:ing Richard Sandiford, who wrote most of them, and most of the
port as well, in case clarifications on the need for the changes are
needed.

As for the change I recently wrote myself, to tree.c:get_narrower(),
the problem was that it would strip conversions from a 16-bit pointer
type to a 16-bit integer type, and then to 32 bits.
c-type.c:build_binary_op() `shorten && none_complex' code made a big
fuss about that when it passed the pointer type to int_fits_type_p(),
after c_common_signed_or_unsigned_type() returned it unchanged.  I
figured stopping the conversion-stripping while we still have an
integral type (as long as we started with one) would be best.

Bootstrapped on i686-pc-linux-gnu native, and cross-built and tested
for target h8300-elf.  Ok to install?

Index: gcc/builtins.c
===================================================================
RCS file: /cvs/uberbaum/gcc/builtins.c,v
retrieving revision 1.342
diff -u -p -r1.342 builtins.c
--- gcc/builtins.c 20 Jun 2004 17:03:02 -0000 1.342
+++ gcc/builtins.c 21 Jun 2004 10:57:01 -0000
@@ -3002,7 +3002,11 @@ expand_builtin_strcpy (tree arglist, rtx
 
   len = c_strlen (src, 1);
   if (len == 0 || TREE_SIDE_EFFECTS (len))
-    return 0;
+    /* Try using a stpcpy pattern.  If we don't need to use the
+       return value, it's better to treat this like strpcy().  */
+    return expand_strcpy (TREE_VALUE (arglist),
+			  TREE_VALUE (TREE_CHAIN (arglist)),
+			  target, target == const0_rtx);
 
   len = size_binop (PLUS_EXPR, len, ssize_int (1));
   arglist = build_tree_list (NULL_TREE, len);
@@ -3043,7 +3047,9 @@ 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_strcpy (TREE_VALUE (arglist),
+			      TREE_VALUE (TREE_CHAIN (arglist)),
+			      target, 1);
 
       dst = TREE_VALUE (arglist);
       len = fold (size_binop (PLUS_EXPR, len, ssize_int (1)));
Index: gcc/expr.c
===================================================================
RCS file: /cvs/uberbaum/gcc/expr.c,v
retrieving revision 1.654
diff -u -p -r1.654 expr.c
--- gcc/expr.c 19 Jun 2004 15:33:05 -0000 1.654
+++ gcc/expr.c 21 Jun 2004 10:57:08 -0000
@@ -10212,4 +10212,95 @@ const_vector_from_tree (tree exp)
 
   return gen_rtx_raw_CONST_VECTOR (mode, v);
 }
+
+
+#ifdef HAVE_stpcpy
+static rtx expand_strcpy_arg (tree);
+static void legitimize_strcpy_operand (const struct insn_operand_data *, rtx);
+
+/* Subroutine of expand_strcpy.  Return a BLKmode
+   reference to the string pointed to by ARG.  */
+
+static rtx
+expand_strcpy_arg (tree arg)
+{
+  rtx addr, mem;
+
+  addr = protect_from_queue (expand_expr (arg, 0, Pmode, 0), 0);
+  mem = gen_rtx_MEM (BLKmode, memory_address (BLKmode, addr));
+  set_mem_attributes (mem, TREE_TYPE (arg), 1);
+
+  return mem;
+}
+
+/* Subroutine of expand_strcpy.  If memory reference OPERAND
+   doesn't satisfy DATA, convert it into a (mem (reg)).  */
+
+static void
+legitimize_strcpy_operand (const struct insn_operand_data *  data,
+			   rtx                               operand)
+{
+  if (data->predicate != 0
+      && ! data->predicate (operand, data->mode))
+    XEXP (operand, 0) = copy_to_mode_reg (Pmode, operand);
+}
+#endif
+
+/* Try to copy a string from SRC to DEST, where both SRC and DEST
+   are pointers.  If ENDP, return a pointer to DEST's null terminator,
+   otherwise return a pointer to its first character.  Use TARGET as
+   the destination if convenient.
+
+   Return null if the machine has no special way of implementing
+   such moves.  */
+
+rtx
+expand_strcpy (tree  dest    ATTRIBUTE_UNUSED,
+	       tree  src     ATTRIBUTE_UNUSED,
+	       rtx   target  ATTRIBUTE_UNUSED,
+	       int   endp    ATTRIBUTE_UNUSED)
+{
+#ifndef HAVE_stpcpy
+  return 0;
+#else
+  rtx end;
+  rtx dest_mem;
+  rtx src_mem;
+  rtx insn;
+  const struct insn_data * data;
+
+  if (!HAVE_stpcpy)
+    return 0;
+
+  dest_mem = expand_strcpy_arg (dest);
+  src_mem = expand_strcpy_arg (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 = gen_reg_rtx (Pmode);
+      end = target;
+    }
+
+  data = insn_data + CODE_FOR_stpcpy;
+
+  if (data->operand[0].mode != VOIDmode)
+    end = gen_lowpart (data->operand[0].mode, end);
+  legitimize_strcpy_operand (data->operand + 1, dest_mem);
+  legitimize_strcpy_operand (data->operand + 2, src_mem);
+
+  insn = data->genfun (end, dest_mem, src_mem);
+  if (insn == 0)
+    abort ();
+
+  emit_insn (insn);
+  return target;
+#endif
+}
+
 #include "gt-expr.h"
Index: gcc/expr.h
===================================================================
RCS file: /cvs/uberbaum/gcc/expr.h,v
retrieving revision 1.158
diff -u -p -r1.158 expr.h
--- gcc/expr.h 2 Jun 2004 02:09:45 -0000 1.158
+++ gcc/expr.h 21 Jun 2004 10:57:08 -0000
@@ -501,6 +501,8 @@ extern rtx emit_move_insn_1 (rtx, rtx);
    and return an rtx to address the beginning of the block.  */
 extern rtx push_block (rtx, int, int);
 
+extern rtx expand_strcpy (tree, tree, rtx, int);
+
 /* Generate code to push something onto the stack, given its mode and type.  */
 extern void emit_push_insn (rtx, enum machine_mode, tree, rtx, unsigned int,
 			    int, rtx, int, rtx, rtx, int, rtx);
Index: gcc/final.c
===================================================================
RCS file: /cvs/uberbaum/gcc/final.c,v
retrieving revision 1.315
diff -u -p -r1.315 final.c
--- gcc/final.c 15 Jun 2004 18:02:19 -0000 1.315
+++ gcc/final.c 21 Jun 2004 10:57:10 -0000
@@ -2655,11 +2655,13 @@ walk_alter_subreg (rtx *xp)
     {
     case PLUS:
     case MULT:
+    case AND:
       XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
       XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1));
       break;
 
     case MEM:
+    case ZERO_EXTEND:
       XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0));
       break;
 
Index: gcc/genattrtab.c
===================================================================
RCS file: /cvs/uberbaum/gcc/genattrtab.c,v
retrieving revision 1.145
diff -u -p -r1.145 genattrtab.c
--- gcc/genattrtab.c 13 May 2004 06:39:42 -0000 1.145
+++ gcc/genattrtab.c 21 Jun 2004 10:57:14 -0000
@@ -5520,6 +5520,11 @@ write_eligible_delay (const char *kind)
   printf ("  if (slot >= %d)\n", max_slots);
   printf ("    abort ();\n");
   printf ("\n");
+  /* Allow dbr_schedule to pass labels, etc.  This can happen if try_split
+     converts a compound instruction into a loop.  */
+  printf ("  if (!INSN_P (candidate_insn))\n");
+  printf ("    return 0;\n");
+  printf ("\n");
 
   /* If more than one delay type, find out which type the delay insn is.  */
 
Index: gcc/tree.c
===================================================================
RCS file: /cvs/uberbaum/gcc/tree.c,v
retrieving revision 1.376
diff -u -p -r1.376 tree.c
--- gcc/tree.c 15 Jun 2004 18:37:32 -0000 1.376
+++ gcc/tree.c 21 Jun 2004 10:57:17 -0000
@@ -4471,6 +4471,7 @@ get_narrower (tree op, int *unsignedp_pt
   int uns = 0;
   int first = 1;
   tree win = op;
+  bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op));
 
   while (TREE_CODE (op) == NOP_EXPR)
     {
@@ -4507,6 +4508,10 @@ get_narrower (tree op, int *unsignedp_pt
 	    uns = TYPE_UNSIGNED (TREE_TYPE (op));
 	  first = 0;
 	  op = TREE_OPERAND (op, 0);
+	  /* Keep trying to narrow, but don't assign op to win if it
+	     would turn an integral type into something else.  */
+	  if (INTEGRAL_TYPE_P (TREE_TYPE (op)) != integral_p)
+	    continue;
 	}
 
       win = op;

Attachment: gcc-h8sx.patch.bz2
Description: BZip2 compressed data

-- 
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]