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]

[PATCH] SUBREG_BYTE fixes


Hi!

This fixes the genrecog crash when built with sparc64-* non
PROMOTE_FOR_CALL_ONLY compiler.  Basically, what used to be
gen_rtx_SUBREG (mode, reg, 0) with the meaning low part of a register
shall be rewritten in generic code as gen_rtx_SUBREG (mode, reg, -1)
and gen_rtx_SUBREG handles this special argument.  Only if we're sure it
will create a paradoxical subreg it can be left as *, 0).
There are still some places I need to study regarding to this and
tests for SUBREG_BYTE(x) == 0 which are meant as tests if it is a low part
of register.

1999-12-09  Jakub Jelinek  <jakub@redhat.com>

	* emit-rtl.c (gen_rtx_SUBREG): Allow a shorthand gen_rtx_SUBREG(.. -1)
	for low part SUBREG.  If the SUBREG to be created, offset will be
	always 0, otherwise it depends on machine endianess.
	* calls.c (precompute_arguments): Use it.
	* expr.c (store_expr, expand_expr): Likewise.
	* regmove.c (optimize_reg_copy_3): Likewise.
	* reload1.c (emit_reload_insns): Likewise.
	* stmt.c (expand_anon_union_decl): Likewise.

--- gcc/emit-rtl.c.jj	Wed Dec  8 10:54:45 1999
+++ gcc/emit-rtl.c	Thu Dec  9 17:08:16 1999
@@ -270,12 +270,34 @@ gen_rtx_MEM (mode, addr)
   return rt;
 }
 
+/* Passing OFFSET -1 will set offset so that the SUBREG will refer
+   to the low part of the register, unless it is a paradoxical SUBREG,
+   in which case it will use 0.  */
 rtx
 gen_rtx_SUBREG (mode, reg, offset)
      enum machine_mode mode;
      rtx reg;
      int offset;
 {
+  if (offset == -1)
+    {
+      enum machine_mode inmode;
+
+      inmode = GET_MODE (reg);
+      if (inmode == VOIDmode)
+	inmode = mode;
+      offset = 0;
+      if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (inmode)
+	  && (WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN))
+	{
+	  offset = GET_MODE_SIZE (inmode) - GET_MODE_SIZE (mode);
+	  if (! BYTES_BIG_ENDIAN)
+	    offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
+	  else if (! WORDS_BIG_ENDIAN)
+	    offset %= UNITS_PER_WORD;
+	}
+    }
+
   /* This is the most common failure type.
      Catch it early so we can see who does it.  */
   if ((offset % GET_MODE_SIZE (mode)) != 0)
--- gcc/calls.c.jj	Wed Dec  8 10:54:50 1999
+++ gcc/calls.c	Thu Dec  9 17:08:57 1999
@@ -1295,7 +1295,7 @@ precompute_arguments (is_const, must_pre
 	      {
 		args[i].initial_value
 		  = gen_rtx_SUBREG (TYPE_MODE (TREE_TYPE (args[i].tree_value)),
-				    args[i].value, 0);
+				    args[i].value, -1);
 		SUBREG_PROMOTED_VAR_P (args[i].initial_value) = 1;
 		SUBREG_PROMOTED_UNSIGNED_P (args[i].initial_value)
 		  = args[i].unsignedp;
--- gcc/expr.c.jj	Wed Dec  1 19:21:35 1999
+++ gcc/expr.c	Thu Dec  9 17:49:15 1999
@@ -3731,7 +3731,7 @@ store_expr (exp, target, want_value)
       if (want_value && GET_MODE (temp) != GET_MODE (target)
 	  && GET_MODE (temp) != VOIDmode)
 	{
-	  temp = gen_rtx_SUBREG (GET_MODE (target), temp, 0);
+	  temp = gen_rtx_SUBREG (GET_MODE (target), temp, -1);
 	  SUBREG_PROMOTED_VAR_P (temp) = 1;
 	  SUBREG_PROMOTED_UNSIGNED_P (temp)
 	    = SUBREG_PROMOTED_UNSIGNED_P (target);
@@ -5961,7 +5961,7 @@ expand_expr (exp, target, tmode, modifie
 	      != promote_mode (type, DECL_MODE (exp), &unsignedp, 0))
 	    abort ();
 
-	  temp = gen_rtx_SUBREG (mode, DECL_RTL (exp), 0);
+	  temp = gen_rtx_SUBREG (mode, DECL_RTL (exp), -1);
 	  SUBREG_PROMOTED_VAR_P (temp) = 1;
 	  SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
 	  return temp;
@@ -6079,7 +6079,7 @@ expand_expr (exp, target, tmode, modifie
 
 	  if (GET_CODE (temp) == REG && GET_MODE (temp) != mode)
 	    {
-	      temp = gen_rtx_SUBREG (mode, SAVE_EXPR_RTL (exp), 0);
+	      temp = gen_rtx_SUBREG (mode, SAVE_EXPR_RTL (exp), -1);
 	      SUBREG_PROMOTED_VAR_P (temp) = 1;
 	      SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
 	    }
@@ -6102,7 +6102,7 @@ expand_expr (exp, target, tmode, modifie
 	{
 	  /* Compute the signedness and make the proper SUBREG.  */
 	  promote_mode (type, mode, &unsignedp, 0);
-	  temp = gen_rtx_SUBREG (mode, SAVE_EXPR_RTL (exp), 0);
+	  temp = gen_rtx_SUBREG (mode, SAVE_EXPR_RTL (exp), -1);
 	  SUBREG_PROMOTED_VAR_P (temp) = 1;
 	  SUBREG_PROMOTED_UNSIGNED_P (temp) = unsignedp;
 	  return temp;
--- gcc/regmove.c.jj	Wed Dec  8 10:54:46 1999
+++ gcc/regmove.c	Thu Dec  9 17:56:47 1999
@@ -715,7 +715,7 @@ optimize_reg_copy_3 (insn, dest, src)
 
   /* Now walk forward making additional replacements.  We want to be able
      to undo all the changes if a later substitution fails.  */
-  subreg = gen_rtx_SUBREG (old_mode, src_reg, 0);
+  subreg = gen_rtx_SUBREG (old_mode, src_reg, -1);
   while (p = NEXT_INSN (p), p != insn)
     {
       if (GET_RTX_CLASS (GET_CODE (p)) != 'i')
--- gcc/reload1.c.jj	Wed Dec  8 10:54:49 1999
+++ gcc/reload1.c	Thu Dec  9 17:58:02 1999
@@ -6736,7 +6736,7 @@ emit_reload_insns (chain)
 	    oldequiv = SUBREG_REG (oldequiv);
 	  if (GET_MODE (oldequiv) != VOIDmode
 	      && mode != GET_MODE (oldequiv))
-	    oldequiv = gen_rtx_SUBREG (mode, oldequiv, 0);
+	    oldequiv = gen_rtx_SUBREG (mode, oldequiv, -1);
 
 	  /* Switch to the right place to emit the reload insns.  */
 	  switch (rld[j].when_needed)
--- gcc/stmt.c.jj	Tue Dec  7 08:27:41 1999
+++ gcc/stmt.c	Thu Dec  9 17:59:55 1999
@@ -4195,7 +4195,7 @@ expand_anon_union_decl (decl, cleanup, d
 	  if (mode == GET_MODE (x))
 	    DECL_RTL (decl_elt) = x;
 	  else
-	    DECL_RTL (decl_elt) = gen_rtx_SUBREG (mode, x, 0);
+	    DECL_RTL (decl_elt) = gen_rtx_SUBREG (mode, x, -1);
 	}
       else
 	abort ();

Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.18 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________


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