aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2011-03-02 11:24:22 +1030
committerAlan Modra <amodra@gcc.gnu.org>2011-03-02 11:24:22 +1030
commitf60a97cfa05159a31608779b9ef75ac084070102 (patch)
tree6e8c0bb6613534723d1a1bd465dfe1f90af0ee7f
parent60b5f5add3a5de1ecf656046bb44d1f69deb9568 (diff)
downloadgcc-f60a97cfa05159a31608779b9ef75ac084070102.zip
gcc-f60a97cfa05159a31608779b9ef75ac084070102.tar.gz
gcc-f60a97cfa05159a31608779b9ef75ac084070102.tar.bz2
re PR target/47935 (PowerPC64 -mcmodel=medium invalid lwa offset)
PR target/47935 * config/rs6000/predicates.md (lwa_operand): Check cmodel medium toc relative addresses for valid offsets. From-SVN: r170606
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/predicates.md32
2 files changed, 28 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c64de9d..ba871c6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2011-03-02 Alan Modra <amodra@gmail.com>
+
+ PR target/47935
+ * config/rs6000/predicates.md (lwa_operand): Check cmodel medium
+ toc relative addresses for valid offsets.
+
2011-03-01 Richard Guenther <rguenther@suse.de>
PR tree-optimization/47890
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 1d06cae..3839643 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -734,20 +734,32 @@
(define_predicate "lwa_operand"
(match_code "reg,subreg,mem")
{
- rtx inner = op;
+ rtx inner, addr, offset;
+ inner = op;
if (reload_completed && GET_CODE (inner) == SUBREG)
inner = SUBREG_REG (inner);
- return gpc_reg_operand (inner, mode)
- || (memory_operand (inner, mode)
- && GET_CODE (XEXP (inner, 0)) != PRE_INC
- && GET_CODE (XEXP (inner, 0)) != PRE_DEC
- && (GET_CODE (XEXP (inner, 0)) != PRE_MODIFY
- || legitimate_indexed_address_p (XEXP (XEXP (inner, 0), 1), 0))
- && (GET_CODE (XEXP (inner, 0)) != PLUS
- || GET_CODE (XEXP (XEXP (inner, 0), 1)) != CONST_INT
- || INTVAL (XEXP (XEXP (inner, 0), 1)) % 4 == 0));
+ if (gpc_reg_operand (inner, mode))
+ return true;
+ if (!memory_operand (inner, mode))
+ return false;
+ addr = XEXP (inner, 0);
+ if (GET_CODE (addr) == PRE_INC
+ || GET_CODE (addr) == PRE_DEC
+ || (GET_CODE (addr) == PRE_MODIFY
+ && !legitimate_indexed_address_p (XEXP (addr, 1), 0)))
+ return false;
+ if (GET_CODE (addr) == LO_SUM
+ && GET_CODE (XEXP (addr, 0)) == REG
+ && GET_CODE (XEXP (addr, 1)) == CONST)
+ addr = XEXP (XEXP (addr, 1), 0);
+ if (GET_CODE (addr) != PLUS)
+ return true;
+ offset = XEXP (addr, 1);
+ if (GET_CODE (offset) != CONST_INT)
+ return true;
+ return INTVAL (offset) % 4 == 0;
})
;; Return 1 if the operand, used inside a MEM, is a SYMBOL_REF.