diff options
author | Alan Modra <amodra@gmail.com> | 2011-03-02 11:24:22 +1030 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2011-03-02 11:24:22 +1030 |
commit | f60a97cfa05159a31608779b9ef75ac084070102 (patch) | |
tree | 6e8c0bb6613534723d1a1bd465dfe1f90af0ee7f | |
parent | 60b5f5add3a5de1ecf656046bb44d1f69deb9568 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 32 |
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. |