]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
predicates.md (gpc_reg_operand): Check invalid_e500_subreg.
authorJoseph Myers <joseph@codesourcery.com>
Wed, 29 Nov 2006 17:33:59 +0000 (17:33 +0000)
committerJoseph Myers <jsm28@gcc.gnu.org>
Wed, 29 Nov 2006 17:33:59 +0000 (17:33 +0000)
* config/rs6000/predicates.md (gpc_reg_operand): Check
invalid_e500_subreg.
* config/rs6000/rs6000.c (invalid_e500_subreg): Don't allow any
SImode subregs of SPE vectors.
* config/rs6000/rs6000.md (insv): Fail for invalid E500 subregs.
* jump.c (true_regnum): Require subregs to satisfy
subreg_offset_representable_p.

From-SVN: r119324

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/jump.c

index 081cc1503b6b114134a3efa2f63714297532bb21..9bef3c87451b9b3442ba436823688c1ff8857f4f 100644 (file)
@@ -1,3 +1,13 @@
+2006-11-29  Joseph Myers  <joseph@codesourcery.com>
+
+       * config/rs6000/predicates.md (gpc_reg_operand): Check
+       invalid_e500_subreg.
+       * config/rs6000/rs6000.c (invalid_e500_subreg): Don't allow any
+       SImode subregs of SPE vectors.
+       * config/rs6000/rs6000.md (insv): Fail for invalid E500 subregs.
+       * jump.c (true_regnum): Require subregs to satisfy
+       subreg_offset_representable_p.
+
 2006-11-29  Daniel Berlin  <dberlin@dberlin.org>
            Steven Bosscher <stevenb.gcc@gmail.com>
 
index 2ff0ba77b857d5d6c0c49c59e4eff2a6e850eae5..6aefe2dd0c989835466d6a58bc2e46a6ecf732ed 100644 (file)
 ;; Return 1 if op is a register that is not special.
 (define_predicate "gpc_reg_operand"
    (and (match_operand 0 "register_operand")
-       (match_test "GET_CODE (op) != REG
-                    || (REGNO (op) >= ARG_POINTER_REGNUM
-                        && !XER_REGNO_P (REGNO (op)))
-                    || REGNO (op) < MQ_REGNO")))
+       (match_test "(GET_CODE (op) != REG
+                     || (REGNO (op) >= ARG_POINTER_REGNUM
+                         && !XER_REGNO_P (REGNO (op)))
+                     || REGNO (op) < MQ_REGNO)
+                    && !((TARGET_E500_DOUBLE || TARGET_SPE)
+                         && invalid_e500_subreg (op, mode))")))
 
 ;; Return 1 if op is a register that is a condition register field.
 (define_predicate "cc_reg_operand"
index 675af68fe9a37f08e832d0d2eb4b8971fea1f80f..d607de26f840e000371c70971eb9e5e2f8806f05 100644 (file)
@@ -2737,8 +2737,7 @@ invalid_e500_subreg (rtx op, enum machine_mode mode)
       && GET_CODE (op) == SUBREG
       && mode == SImode
       && REG_P (SUBREG_REG (op))
-      && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op)))
-      && SUBREG_BYTE (op) != 4)
+      && SPE_VECTOR_MODE (GET_MODE (SUBREG_REG (op))))
     return true;
 
   return false;
index f40e78dfafa219dd88684a00268bc6dec6a4090c..7e1d0a193268f94c7355b171efafc846c5a07041 100644 (file)
 {
   /* Do not handle 16/8 bit structures that fit in HI/QI modes directly, since
      the (SUBREG:SI (REG:HI xxx)) that is otherwise generated can confuse the
-     compiler if the address of the structure is taken later.  */
+     compiler if the address of the structure is taken later.  Likewise, do
+     not handle invalid E500 subregs.  */
   if (GET_CODE (operands[0]) == SUBREG
-      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD))
+      && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (operands[0]))) < UNITS_PER_WORD
+         || ((TARGET_E500_DOUBLE || TARGET_SPE)
+             && invalid_e500_subreg (operands[0], GET_MODE (operands[0])))))
     FAIL;
 
   if (TARGET_POWERPC64 && GET_MODE (operands[0]) == DImode)
index 807f2c6f7d6f2865fa595488b1398379a819dd7e..567017004f5df8d6558aecef4a2ab4b476c5d4c2 100644 (file)
@@ -1951,7 +1951,11 @@ true_regnum (rtx x)
   if (GET_CODE (x) == SUBREG)
     {
       int base = true_regnum (SUBREG_REG (x));
-      if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
+      if (base >= 0
+         && base < FIRST_PSEUDO_REGISTER
+         && subreg_offset_representable_p (REGNO (SUBREG_REG (x)),
+                                           GET_MODE (SUBREG_REG (x)),
+                                           SUBREG_BYTE (x), GET_MODE (x)))
        return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
                                           GET_MODE (SUBREG_REG (x)),
                                           SUBREG_BYTE (x), GET_MODE (x));