re PR target/47935 (PowerPC64 -mcmodel=medium invalid lwa offset)
authorAlan Modra <amodra@gmail.com>
Wed, 2 Mar 2011 00:54:22 +0000 (11:24 +1030)
committerAlan Modra <amodra@gcc.gnu.org>
Wed, 2 Mar 2011 00:54:22 +0000 (11:24 +1030)
PR target/47935
* config/rs6000/predicates.md (lwa_operand): Check cmodel medium
toc relative addresses for valid offsets.

From-SVN: r170606

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

index c64de9d4f951546aeabef825b4ccd9c8ef11ebdb..ba871c6f12df962c592f608ee61b0f47e283a477 100644 (file)
@@ -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
index 1d06caeaef50888fc46d3318fc32cb4238d34d9e..3839643af4a6e39d608d35a21dcba94401dba27d 100644 (file)
 (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.