emit-rtl.c (operand_subword): Tighten checks for when it is safe to safe to extract...
authorJeffrey A Law <law@cygnus.com>
Thu, 17 Jun 1999 01:56:31 +0000 (01:56 +0000)
committerJeff Law <law@gcc.gnu.org>
Thu, 17 Jun 1999 01:56:31 +0000 (19:56 -0600)
        * emit-rtl.c (operand_subword): Tighten checks for when it is safe
        to safe to extract a subword out of a REG.

From-SVN: r27564

gcc/ChangeLog
gcc/emit-rtl.c

index 73fd4f90b820115d072b8e01f448bdd6e9c87ab6..f0608fcd84983cdb26b84f695aa5cdfb52a822b7 100644 (file)
@@ -1,3 +1,8 @@
+Thu Jun 17 02:54:30 1999  Jeffrey A Law  (law@cygnus.com)
+
+       * emit-rtl.c (operand_subword): Tighten checks for when it is safe
+       to safe to extract a subword out of a REG.
+
 Thu Jun 17 01:45:24 1999  J"orn Rennecke <amylaar@cygnus.co.uk>
 
        * sh.md (mulsi3): Don't add a no-op move at the end.
index 2aa51aca4da14ded0d31da3632e0b8e6058733ba..f1caea7d60d0bce2d1aae1c64c174d5fb5c493da 100644 (file)
@@ -1196,10 +1196,33 @@ operand_subword (op, i, validate_address, mode)
   /* If OP is a REG or SUBREG, we can handle it very simply.  */
   if (GET_CODE (op) == REG)
     {
-      /* If the register is not valid for MODE, return 0.  If we don't
-        do this, there is no way to fix up the resulting REG later.  */
+      /* ??? There is a potential problem with this code.  It does not
+        properly handle extractions of a subword from a hard register
+        that is larger than word_mode.  Presumably the check for
+        HARD_REGNO_MODE_OK catches these most of these cases.  */
+
+      /* If OP is a hard register, but OP + I is not a hard register,
+        then extracting a subword is impossible.
+
+        For example, consider if OP is the last hard register and it is
+        larger than word_mode.  If we wanted word N (for N > 0) because a
+        part of that hard register was known to contain a useful value,
+        then OP + I would refer to a pseudo, not the hard register we
+        actually wanted.  */
+      if (REGNO (op) < FIRST_PSEUDO_REGISTER
+         && REGNO (op) + i >= FIRST_PSEUDO_REGISTER)
+       return 0;
+
+      /* If the register is not valid for MODE, return 0.  Note we
+        have to check both OP and OP + I since they may refer to
+        different parts of the register file.
+
+        Consider if OP refers to the last 96bit FP register and we want
+        subword 3 because that subword is known to contain a value we
+        needed.  */
       if (REGNO (op) < FIRST_PSEUDO_REGISTER
-         && ! HARD_REGNO_MODE_OK (REGNO (op) + i, word_mode))
+         && (! HARD_REGNO_MODE_OK (REGNO (op), word_mode)
+             || ! HARD_REGNO_MODE_OK (REGNO (op) + i, word_mode)))
        return 0;
       else if (REGNO (op) >= FIRST_PSEUDO_REGISTER
               || (REG_FUNCTION_VALUE_P (op)