rs6000.c (rs6000_legitimate_address): Allow any stack offsets if not REG_OK_STRICT.
authorFranz Sirl <Franz.Sirl-kernel@lauterbach.com>
Wed, 2 May 2001 20:30:19 +0000 (20:30 +0000)
committerFranz Sirl <sirl@gcc.gnu.org>
Wed, 2 May 2001 20:30:19 +0000 (20:30 +0000)
        2000-05-01  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>

        * config/rs6000/rs6000.c (rs6000_legitimate_address): Allow any stack
        offsets if not REG_OK_STRICT.

        * config/rs6000/rs6000.h (REG_OK_STRICT_FLAG): New macro.
        (INT_REG_OK_FOR_INDEX_P): Likewise.
        (INT_REG_OK_FOR_BASE_P): Likewise.
        (REG_OK_FOR_INDEX_P): Use INT_REG_OK_FOR_INDEX_P.
        (REG_OK_FOR_BASE_P): Use INT_REG_OK_FOR_BASE_P.
        (LEGITIMATE_OFFSET_ADDRESS_P): Use INT_REG_OK_FOR_INDEX_P and
        INT_REG_OK_FOR_BASE_P instead of REG_OK_FOR_INDEX_P and
        REG_OK_FOR_BASE_P. Take an additional parameter.
        (LEGITIMATE_INDEXED_ADDRESS_P): Likeewise.
        (LEGITIMATE_INDIRECT_ADDRESS_P): Likewise.
        (LEGITIMATE_LO_SUM_ADDRESS_P): Likewise.
        (GO_IF_LEGITIMATE_ADDRESS): Move code into new function
        rs6000_legitimate_address() and use it.
        * config/rs6000/rs6000.c: Update all callers.
        (rs6000_legitimate_address): New function.

From-SVN: r41772

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h

index eded70f6b529fad2737b3f694addf5f9569370b1..83ca906c43d1820d94c8bf3f7f2a5108468c770e 100644 (file)
@@ -1,3 +1,24 @@
+2000-05-01  Franz Sirl  <Franz.Sirl-kernel@lauterbach.com>
+
+       * config/rs6000/rs6000.c (rs6000_legitimate_address): Allow any stack
+       offsets if not REG_OK_STRICT.
+
+       * config/rs6000/rs6000.h (REG_OK_STRICT_FLAG): New macro.
+       (INT_REG_OK_FOR_INDEX_P): Likewise.
+       (INT_REG_OK_FOR_BASE_P): Likewise.
+       (REG_OK_FOR_INDEX_P): Use INT_REG_OK_FOR_INDEX_P.
+       (REG_OK_FOR_BASE_P): Use INT_REG_OK_FOR_BASE_P.
+       (LEGITIMATE_OFFSET_ADDRESS_P): Use INT_REG_OK_FOR_INDEX_P and
+        INT_REG_OK_FOR_BASE_P instead of REG_OK_FOR_INDEX_P and
+       REG_OK_FOR_BASE_P. Take an additional parameter.
+       (LEGITIMATE_INDEXED_ADDRESS_P): Likeewise.
+       (LEGITIMATE_INDIRECT_ADDRESS_P): Likewise.
+       (LEGITIMATE_LO_SUM_ADDRESS_P): Likewise.
+       (GO_IF_LEGITIMATE_ADDRESS): Move code into new function
+       rs6000_legitimate_address() and use it.
+       * config/rs6000/rs6000.c: Update all callers.
+       (rs6000_legitimate_address): New function.
+
 2001-05-02  David Edelsohn  <edelsohn@gnu.org>
 
        * config/rs6000/rs6000.c (rs6000_emit_move): Merge
index 9f8f984c7b1fd1c0abd488857c0624be80ac04c8..7e95c0bd7b6a01cef765bc5eef0bb6f07bdbb0a7 100644 (file)
@@ -107,6 +107,7 @@ extern struct rtx_def *create_TOC_reference PARAMS ((rtx));
 extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
 extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
 extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
+extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
 extern void rs6000_select_rtx_section PARAMS ((enum machine_mode, rtx));
 
 extern rtx rs6000_return_addr PARAMS ((int, rtx));
index d89e6875cd47b82e6e85efb0e608de44d4aad76c..4a22802a593be0bacf50acd3fb06f68fdc676042 100644 (file)
@@ -1550,6 +1550,58 @@ rs6000_legitimize_address (x, oldx, mode)
   else
     return NULL_RTX;
 }
+
+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
+   that is a valid memory address for an instruction.
+   The MODE argument is the machine mode for the MEM expression
+   that wants to use this address.
+
+   On the RS/6000, there are four valid address: a SYMBOL_REF that
+   refers to a constant pool entry of an address (or the sum of it
+   plus a constant), a short (16-bit signed) constant plus a register,
+   the sum of two registers, or a register indirect, possibly with an
+   auto-increment.  For DFmode and DImode with an constant plus register,
+   we must ensure that both words are addressable or PowerPC64 with offset
+   word aligned.
+
+   For modes spanning multiple registers (DFmode in 32-bit GPRs,
+   32-bit DImode, TImode), indexed addressing cannot be used because
+   adjacent memory cells are accessed by adding word-sized offsets
+   during assembly output.  */
+int
+rs6000_legitimate_address (mode, x, reg_ok_strict)
+    enum machine_mode mode;
+    rtx x;
+    int reg_ok_strict;
+{
+  if (LEGITIMATE_INDIRECT_ADDRESS_P (x, reg_ok_strict))
+    return 1;
+  if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == PRE_DEC)
+      && TARGET_UPDATE
+      && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (x, 0), reg_ok_strict))
+    return 1;
+  if (LEGITIMATE_SMALL_DATA_P (mode, x))
+    return 1;
+  if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
+    return 1;
+  /* If not REG_OK_STRICT (before reload) let pass any stack offset.  */
+  if (! reg_ok_strict
+      && GET_CODE (x) == PLUS
+      && GET_CODE (XEXP (x, 0)) == REG
+      && XEXP (x, 0) == virtual_stack_vars_rtx
+      && GET_CODE (XEXP (x, 1)) == CONST_INT)
+    return 1;
+  if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, reg_ok_strict))
+    return 1;
+  if (mode != TImode
+      && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || mode != DFmode)
+      && (TARGET_POWERPC64 || mode != DImode)
+      && LEGITIMATE_INDEXED_ADDRESS_P (x, reg_ok_strict))
+    return 1;
+  if (LEGITIMATE_LO_SUM_ADDRESS_P (mode, x, reg_ok_strict))
+    return 1;
+  return 0;
+}
 \f
 /* Emit a move from SOURCE to DEST in mode MODE.  */
 void
@@ -3098,14 +3150,14 @@ lmw_operation (op, mode)
       || count != 32 - (int) dest_regno)
     return 0;
 
-  if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr))
+  if (LEGITIMATE_INDIRECT_ADDRESS_P (src_addr, 0))
     {
       offset = 0;
       base_regno = REGNO (src_addr);
       if (base_regno == 0)
        return 0;
     }
-  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr))
+  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, src_addr, 0))
     {
       offset = INTVAL (XEXP (src_addr, 1));
       base_regno = REGNO (XEXP (src_addr, 0));
@@ -3128,12 +3180,12 @@ lmw_operation (op, mode)
          || GET_MODE (SET_SRC (elt)) != SImode)
        return 0;
       newaddr = XEXP (SET_SRC (elt), 0);
-      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr))
+      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
        {
          newoffset = 0;
          addr_reg = newaddr;
        }
-      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr))
+      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
        {
          addr_reg = XEXP (newaddr, 0);
          newoffset = INTVAL (XEXP (newaddr, 1));
@@ -3176,14 +3228,14 @@ stmw_operation (op, mode)
       || count != 32 - (int) src_regno)
     return 0;
 
-  if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr))
+  if (LEGITIMATE_INDIRECT_ADDRESS_P (dest_addr, 0))
     {
       offset = 0;
       base_regno = REGNO (dest_addr);
       if (base_regno == 0)
        return 0;
     }
-  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr))
+  else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, dest_addr, 0))
     {
       offset = INTVAL (XEXP (dest_addr, 1));
       base_regno = REGNO (XEXP (dest_addr, 0));
@@ -3206,12 +3258,12 @@ stmw_operation (op, mode)
          || GET_MODE (SET_DEST (elt)) != SImode)
        return 0;
       newaddr = XEXP (SET_DEST (elt), 0);
-      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr))
+      if (LEGITIMATE_INDIRECT_ADDRESS_P (newaddr, 0))
        {
          newoffset = 0;
          addr_reg = newaddr;
        }
-      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr))
+      else if (LEGITIMATE_OFFSET_ADDRESS_P (SImode, newaddr, 0))
        {
          addr_reg = XEXP (newaddr, 0);
          newoffset = INTVAL (XEXP (newaddr, 1));
@@ -4270,7 +4322,7 @@ print_operand (file, x, code)
 
     case 'X':
       if (GET_CODE (x) == MEM
-         && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0)))
+         && LEGITIMATE_INDEXED_ADDRESS_P (XEXP (x, 0), 0))
        putc ('x', file);
       return;
 
index cf3f9474813a3f15294f4606c8bc62f23ffeec54..694bc039b9d424ea7cd2113b6088f3163f2f805f 100644 (file)
@@ -1789,26 +1789,28 @@ typedef struct rs6000_args
    After reload, it makes no difference, since pseudo regs have
    been eliminated by then.  */
 
-#ifndef REG_OK_STRICT
+#ifdef REG_OK_STRICT
+# define REG_OK_STRICT_FLAG 1
+#else
+# define REG_OK_STRICT_FLAG 0
+#endif
 
 /* Nonzero if X is a hard reg that can be used as an index
-   or if it is a pseudo reg.  */
-#define REG_OK_FOR_INDEX_P(X)                  \
-  (REGNO (X) <= 31 || REGNO (X) == 67 || REGNO (X) >= FIRST_PSEUDO_REGISTER)
+   or if it is a pseudo reg in the non-strict case.  */
+#define INT_REG_OK_FOR_INDEX_P(X, STRICT)                      \
+  ((! (STRICT)                                                 \
+    && (REGNO (X) <= 31                                                \
+       || REGNO (X) == ARG_POINTER_REGNUM                      \
+       || REGNO (X) >= FIRST_PSEUDO_REGISTER))                 \
+   || ((STRICT) && REGNO_OK_FOR_INDEX_P (REGNO (X))))
 
 /* Nonzero if X is a hard reg that can be used as a base reg
-   or if it is a pseudo reg.  */
-#define REG_OK_FOR_BASE_P(X)                                    \
-  (REGNO (X) > 0 && REG_OK_FOR_INDEX_P (X))
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as an index.  */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as a base reg.  */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
+   or if it is a pseudo reg in the non-strict case.  */
+#define INT_REG_OK_FOR_BASE_P(X, STRICT)                       \
+  (REGNO (X) > 0 && INT_REG_OK_FOR_INDEX_P (X, (STRICT)))
 
-#endif
+#define REG_OK_FOR_INDEX_P(X) INT_REG_OK_FOR_INDEX_P (X, REG_OK_STRICT_FLAG)
+#define REG_OK_FOR_BASE_P(X)  INT_REG_OK_FOR_BASE_P (X, REG_OK_STRICT_FLAG)
 \f
 /* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
    that is a valid memory address for an instruction.
@@ -1845,68 +1847,51 @@ typedef struct rs6000_args
    && (GET_CODE (X) == SYMBOL_REF || GET_CODE (X) == CONST)            \
    && small_data_operand (X, MODE))
 
-#define LEGITIMATE_ADDRESS_INTEGER_P(X,OFFSET)                         \
+#define LEGITIMATE_ADDRESS_INTEGER_P(X, OFFSET)                                \
  (GET_CODE (X) == CONST_INT                                            \
   && (unsigned HOST_WIDE_INT) (INTVAL (X) + (OFFSET) + 0x8000) < 0x10000)
 
-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE,X)            \
- (GET_CODE (X) == PLUS                                 \
-  && GET_CODE (XEXP (X, 0)) == REG                     \
-  && REG_OK_FOR_BASE_P (XEXP (X, 0))                   \
-  && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)     \
-  && (((MODE) != DFmode && (MODE) != DImode)           \
-      || (TARGET_32BIT                                 \
-         ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4) \
-         : ! (INTVAL (XEXP (X, 1)) & 3)))              \
-  && ((MODE) != TImode                                 \
-      || (TARGET_32BIT                                 \
-         ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12) \
-         : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8) \
+#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, STRICT)           \
+ (GET_CODE (X) == PLUS                                         \
+  && GET_CODE (XEXP (X, 0)) == REG                             \
+  && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))             \
+  && LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 0)             \
+  && (((MODE) != DFmode && (MODE) != DImode)                   \
+      || (TARGET_32BIT                                         \
+         ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 4)       \
+         : ! (INTVAL (XEXP (X, 1)) & 3)))                      \
+  && ((MODE) != TImode                                         \
+      || (TARGET_32BIT                                         \
+         ? LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 12)      \
+         : (LEGITIMATE_ADDRESS_INTEGER_P (XEXP (X, 1), 8)      \
             && ! (INTVAL (XEXP (X, 1)) & 3)))))
 
-#define LEGITIMATE_INDEXED_ADDRESS_P(X)                \
- (GET_CODE (X) == PLUS                         \
-  && GET_CODE (XEXP (X, 0)) == REG             \
-  && GET_CODE (XEXP (X, 1)) == REG             \
-  && ((REG_OK_FOR_BASE_P (XEXP (X, 0))         \
-       && REG_OK_FOR_INDEX_P (XEXP (X, 1)))    \
-      || (REG_OK_FOR_BASE_P (XEXP (X, 1))      \
-         && REG_OK_FOR_INDEX_P (XEXP (X, 0)))))
-
-#define LEGITIMATE_INDIRECT_ADDRESS_P(X)       \
-  (GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))
-
-#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X)           \
-  (TARGET_ELF                                          \
-   && ! flag_pic && ! TARGET_TOC                       \
-   && (MODE) != DImode                                 \
-   && (MODE) != TImode                                 \
-   && (TARGET_HARD_FLOAT || (MODE) != DFmode)          \
-   && GET_CODE (X) == LO_SUM                           \
-   && GET_CODE (XEXP (X, 0)) == REG                    \
-   && REG_OK_FOR_BASE_P (XEXP (X, 0))                  \
+#define LEGITIMATE_INDEXED_ADDRESS_P(X, STRICT)                        \
+ (GET_CODE (X) == PLUS                                         \
+  && GET_CODE (XEXP (X, 0)) == REG                             \
+  && GET_CODE (XEXP (X, 1)) == REG                             \
+  && ((INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))           \
+       && INT_REG_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT)))      \
+      || (INT_REG_OK_FOR_BASE_P (XEXP (X, 1), (STRICT))                \
+         && INT_REG_OK_FOR_INDEX_P (XEXP (X, 0), (STRICT)))))
+
+#define LEGITIMATE_INDIRECT_ADDRESS_P(X, STRICT)               \
+  (GET_CODE (X) == REG && INT_REG_OK_FOR_BASE_P (X, (STRICT)))
+
+#define LEGITIMATE_LO_SUM_ADDRESS_P(MODE, X, STRICT)           \
+  (TARGET_ELF                                                  \
+   && ! flag_pic && ! TARGET_TOC                               \
+   && (MODE) != DImode                                         \
+   && (MODE) != TImode                                         \
+   && (TARGET_HARD_FLOAT || (MODE) != DFmode)                  \
+   && GET_CODE (X) == LO_SUM                                   \
+   && GET_CODE (XEXP (X, 0)) == REG                            \
+   && INT_REG_OK_FOR_BASE_P (XEXP (X, 0), (STRICT))            \
    && CONSTANT_P (XEXP (X, 1)))
 
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                \
-{ if (LEGITIMATE_INDIRECT_ADDRESS_P (X))               \
-    goto ADDR;                                         \
-  if ((GET_CODE (X) == PRE_INC || GET_CODE (X) == PRE_DEC) \
-      && TARGET_UPDATE                                 \
-      && LEGITIMATE_INDIRECT_ADDRESS_P (XEXP (X, 0)))  \
-    goto ADDR;                                         \
-  if (LEGITIMATE_SMALL_DATA_P (MODE, X))               \
-    goto ADDR;                                         \
-  if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (X))          \
-    goto ADDR;                                         \
-  if (LEGITIMATE_OFFSET_ADDRESS_P (MODE, X))           \
-    goto ADDR;                                         \
-  if ((MODE) != TImode                                 \
-      && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
-      && (TARGET_POWERPC64 || (MODE) != DImode)                \
-      && LEGITIMATE_INDEXED_ADDRESS_P (X))             \
-    goto ADDR;                                         \
-  if (LEGITIMATE_LO_SUM_ADDRESS_P (MODE, X))           \
-    goto ADDR;                                         \
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR)                        \
+{ if (rs6000_legitimate_address (MODE, X, REG_OK_STRICT_FLAG)) \
+    goto ADDR;                                                 \
 }
 \f
 /* Try machine-dependent ways of modifying an illegitimate address