aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2006-11-29 17:33:59 +0000
committerJoseph Myers <jsm28@gcc.gnu.org>2006-11-29 17:33:59 +0000
commit14502dad061deb34939adf92cb5ea35a06f1da34 (patch)
treee78160a35391b3a8c25d75660bc057354bc86734 /gcc
parentd315c4a9f8367f9452ff6afd3a49d9a3b6fa3105 (diff)
downloadgcc-14502dad061deb34939adf92cb5ea35a06f1da34.zip
gcc-14502dad061deb34939adf92cb5ea35a06f1da34.tar.gz
gcc-14502dad061deb34939adf92cb5ea35a06f1da34.tar.bz2
predicates.md (gpc_reg_operand): Check invalid_e500_subreg.
* 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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/rs6000/predicates.md10
-rw-r--r--gcc/config/rs6000/rs6000.c3
-rw-r--r--gcc/config/rs6000/rs6000.md7
-rw-r--r--gcc/jump.c6
5 files changed, 27 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 081cc15..9bef3c8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 2ff0ba7..6aefe2d 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -84,10 +84,12 @@
;; 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"
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 675af68..d607de2 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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;
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f40e78d..7e1d0a1 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -3419,9 +3419,12 @@
{
/* 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)
diff --git a/gcc/jump.c b/gcc/jump.c
index 807f2c6..5670170 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -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));