* regrename.c (copy_value): Don't record high part copies.
authorJ"orn Rennecke <joern.rennecke@superh.com>
Tue, 16 Jul 2002 20:13:35 +0000 (20:13 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Tue, 16 Jul 2002 20:13:35 +0000 (21:13 +0100)
From-SVN: r55493

gcc/ChangeLog
gcc/regrename.c

index e36fdc3..eecf797 100644 (file)
@@ -1,3 +1,7 @@
+Tue Jul 16 19:32:58 2002  J"orn Rennecke <joern.rennecke@superh.com>
+
+       * regrename.c (copy_value): Don't record high part copies.
+
 2002-07-16  Steve Ellcey  <sje@cup.hp.com>
 
        * gcc/config/pa/long_double.h (FIXUNS_TRUNCTFDI2_LIBCALL): New define.
index 532d575..0ceab76 100644 (file)
@@ -1268,6 +1268,26 @@ copy_value (dest, src, vd)
   if (vd->e[sr].mode == VOIDmode)
     set_value_regno (sr, vd->e[dr].mode, vd);
 
+  /* If we are narrowing the the input to a smaller number of hard regs,
+     and it is in big endian, we are really extracting a high part.
+     Since we generally associate a low part of a value with the value itself,
+     we must not do the same for the high part.
+     Note we can still get low parts for the same mode combination through
+     a two-step copy involving differently sized hard regs.
+     Assume hard regs fr* are 32 bits bits each, while r* are 64 bits each:
+     (set (reg:DI r0) (reg:DI fr0))
+     (set (reg:SI fr2) (reg:SI r0))
+     loads the low part of (reg:DI fr0) - i.e. fr1 - into fr2, while:
+     (set (reg:SI fr2) (reg:SI fr0))
+     loads the high part of (reg:DI fr0) into fr2.
+
+     We can't properly represent the latter case in our tables, so don't
+     record anything then.  */
+  else if (sn < (unsigned int) HARD_REGNO_NREGS (sr, vd->e[sr].mode)
+          && (GET_MODE_SIZE (vd->e[sr].mode) > UNITS_PER_WORD
+              ? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
+    return;
+
   /* If SRC had been assigned a mode narrower than the copy, we can't
      link DEST into the chain, because not all of the pieces of the
      copy came from oldest_regno.  */