OSDN Git Service

PR target/15286
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 28 Oct 2004 12:47:21 +0000 (12:47 +0000)
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 28 Oct 2004 12:47:21 +0000 (12:47 +0000)
* final.c (alter_subreg): Compute correct offset to use with
paradoxical SUBREGs of memory operands.
* recog.c (general_operand): Allow paradoxical SUBREGs of
memory operands after reload.
* simplify-rtx.c (simplify_gen_subreg): Fail if simplify_subreg
has failed when passed a hard register.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89752 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/final.c
gcc/recog.c
gcc/simplify-rtx.c

index 4eb71fb..e4de1de 100644 (file)
@@ -1,3 +1,13 @@
+2004-10-28  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       PR target/15286
+       * final.c (alter_subreg): Compute correct offset to use with
+       paradoxical SUBREGs of memory operands.
+       * recog.c (general_operand): Allow paradoxical SUBREGs of
+       memory operands after reload.
+       * simplify-rtx.c (simplify_gen_subreg): Fail if simplify_subreg
+       has failed when passed a hard register.
+
 2004-10-28  Aldy Hernandez  <aldyh@redhat.com>
 
        * function.c (assign_parm_setup_block): Handle parallels correctly.
index bf4f521..3952b9f 100644 (file)
@@ -2608,7 +2608,24 @@ alter_subreg (rtx *xp)
   /* simplify_subreg does not remove subreg from volatile references.
      We are required to.  */
   if (MEM_P (y))
-    *xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x));
+    {
+      int offset = SUBREG_BYTE (x);
+
+      /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
+        contains 0 instead of the proper offset.  See simplify_subreg.  */
+      if (offset == 0
+         && GET_MODE_SIZE (GET_MODE (y)) < GET_MODE_SIZE (GET_MODE (x)))
+        {
+          int difference = GET_MODE_SIZE (GET_MODE (y))
+                          - GET_MODE_SIZE (GET_MODE (x));
+          if (WORDS_BIG_ENDIAN)
+            offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
+          if (BYTES_BIG_ENDIAN)
+            offset += difference % UNITS_PER_WORD;
+        }
+
+      *xp = adjust_address (y, GET_MODE (x), offset);
+    }
   else
     {
       rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
index 61e1186..eeb37af 100644 (file)
@@ -936,8 +936,10 @@ general_operand (rtx op, enum machine_mode mode)
 
 #ifdef INSN_SCHEDULING
       /* On machines that have insn scheduling, we want all memory
-        reference to be explicit, so outlaw paradoxical SUBREGs.  */
-      if (MEM_P (sub)
+        reference to be explicit, so outlaw paradoxical SUBREGs.
+        However, we must allow them after reload so that they can
+        get cleaned up by cleanup_subreg_operands.  */
+      if (!reload_completed && MEM_P (sub)
          && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (sub)))
        return 0;
 #endif
index 4af468a..e463fef 100644 (file)
@@ -3789,7 +3789,8 @@ simplify_gen_subreg (enum machine_mode outermode, rtx op,
   if (newx)
     return newx;
 
-  if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode)
+  if (GET_CODE (op) == SUBREG || GET_MODE (op) == VOIDmode
+      || (REG_P (op) && REGNO (op) < FIRST_PSEUDO_REGISTER))
     return NULL_RTX;
 
   return gen_rtx_SUBREG (outermode, op, byte);