sh-protos.h (sh_legitimate_index_p): Declare.
authorKaz Kojima <kkojima@gcc.gnu.org>
Tue, 12 May 2009 22:41:54 +0000 (22:41 +0000)
committerKaz Kojima <kkojima@gcc.gnu.org>
Tue, 12 May 2009 22:41:54 +0000 (22:41 +0000)
* config/sh/sh-protos.h (sh_legitimate_index_p): Declare.
(sh_legitimate_address_p): Likewise.
* config/sh/sh.c (sh_legitimate_index_p): New.
(sh_legitimate_address_p): Likewise.
* config/sh/sh.h (REG_OK_FOR_BASE_P): Add STRICT parameter.
(REG_OK_FOR_INDEX_P, SUBREG_OK_FOR_INDEX_P): Likewise.
(MODE_DISP_OK_4, MODE_DISP_OK_8): Remove.
(MAYBE_BASE_REGISTER_RTX_P): New macro.
(MAYBE_INDEX_REGISTER_RTX_P): Likewise.
(BASE_REGISTER_RTX_P): Use MAYBE_BASE_REGISTER_RTX_P.
(INDEX_REGISTER_RTX_P): Use MAYBE_INDEX_REGISTER_RTX_P.
(GO_IF_LEGITIMATE_INDEX): Use sh_legitimate_index_p.
(GO_IF_LEGITIMATE_ADDRESS): Use sh_legitimate_address_p.

From-SVN: r147450

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

index 2a21734..cb8074f 100644 (file)
@@ -1,3 +1,19 @@
+2009-05-12  Kaz Kojima  <kkojima@gcc.gnu.org>
+
+       * config/sh/sh-protos.h (sh_legitimate_index_p): Declare.
+       (sh_legitimate_address_p): Likewise.
+       * config/sh/sh.c (sh_legitimate_index_p): New.
+       (sh_legitimate_address_p): Likewise.
+       * config/sh/sh.h (REG_OK_FOR_BASE_P): Add STRICT parameter.
+       (REG_OK_FOR_INDEX_P, SUBREG_OK_FOR_INDEX_P): Likewise.
+       (MODE_DISP_OK_4, MODE_DISP_OK_8): Remove.
+       (MAYBE_BASE_REGISTER_RTX_P): New macro.
+       (MAYBE_INDEX_REGISTER_RTX_P): Likewise.
+       (BASE_REGISTER_RTX_P): Use MAYBE_BASE_REGISTER_RTX_P.
+       (INDEX_REGISTER_RTX_P): Use MAYBE_INDEX_REGISTER_RTX_P.
+       (GO_IF_LEGITIMATE_INDEX): Use sh_legitimate_index_p.
+       (GO_IF_LEGITIMATE_ADDRESS): Use sh_legitimate_address_p.
+
 2009-05-12  Jan Hubicka  <jh@suse.cz>
 
        * tree-inline.c (estimate_operator_cost): Add operands;
index 0c89f17..fb89681 100644 (file)
@@ -58,6 +58,8 @@ extern int fp_zero_operand (rtx);
 extern int fp_one_operand (rtx);
 extern int fp_int_operand (rtx);
 extern rtx get_fpscr_rtx (void);
+extern bool sh_legitimate_index_p (enum machine_mode, rtx);
+extern bool sh_legitimate_address_p (enum machine_mode, rtx, bool);
 extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
 extern int nonpic_symbol_mentioned_p (rtx);
 extern void emit_sf_insn (rtx);
index e25cd42..79343bf 100644 (file)
@@ -8950,6 +8950,124 @@ sh_insn_length_adjustment (rtx insn)
   return 0;
 }
 \f
+/* Return TRUE for a valid displacement for the REG+disp addressing
+   with MODE.  */
+
+/* ??? The SH2e does not have the REG+disp addressing mode when loading values
+   into the FRx registers.  We implement this by setting the maximum offset
+   to zero when the value is SFmode.  This also restricts loading of SFmode
+   values into the integer registers, but that can't be helped.  */
+
+/* The SH allows a displacement in a QI or HI amode, but only when the
+   other operand is R0. GCC doesn't handle this very well, so we forgot
+   all of that.
+
+   A legitimate index for a QI or HI is 0, SI can be any number 0..63,
+   DI can be any number 0..60.  */
+
+bool
+sh_legitimate_index_p (enum machine_mode mode, rtx op)
+{
+  if (GET_CODE (op) == CONST_INT)
+    {
+      if (TARGET_SHMEDIA)
+       {
+         int size;
+
+         /* Check if this the address of an unaligned load / store.  */
+         if (mode == VOIDmode)
+           return CONST_OK_FOR_I06 (INTVAL (op));
+
+         size = GET_MODE_SIZE (mode);
+         return (!(INTVAL (op) & (size - 1))
+                 && INTVAL (op) >= -512 * size
+                 && INTVAL (op) < 512 * size);
+       }
+
+      if (TARGET_SH2A)
+       {
+         if (GET_MODE_SIZE (mode) == 1
+               && (unsigned) INTVAL (op) < 4096)
+           return true;
+       }
+
+      if ((GET_MODE_SIZE (mode) == 4
+          && (unsigned) INTVAL (op) < 64
+          && !(INTVAL (op) & 3)
+          && !(TARGET_SH2E && mode == SFmode))
+         || (GET_MODE_SIZE (mode) == 4
+             && (unsigned) INTVAL (op) < 16383
+             && !(INTVAL (op) & 3) && TARGET_SH2A))
+       return true;
+
+      if ((GET_MODE_SIZE (mode) == 8
+          && (unsigned) INTVAL (op) < 60
+          && !(INTVAL (op) & 3)
+          && !((TARGET_SH4 || TARGET_SH2A) && mode == DFmode))
+         || ((GET_MODE_SIZE (mode)==8)
+             && (unsigned) INTVAL (op) < 8192
+             && !(INTVAL (op) & (TARGET_SH2A_DOUBLE ? 7 : 3))
+             && (TARGET_SH2A && mode == DFmode)))
+       return true;
+    }
+
+  return false;
+}
+
+/* Recognize 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.
+   Allow  REG
+         REG+disp
+         REG+r0
+         REG++
+         --REG  */
+
+bool
+sh_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
+{
+  if (MAYBE_BASE_REGISTER_RTX_P (x, strict))
+    return true;
+  else if ((GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
+          && ! TARGET_SHMEDIA
+          && MAYBE_BASE_REGISTER_RTX_P (XEXP (x, 0), strict))
+    return true;
+  else if (GET_CODE (x) == PLUS
+          && (mode != PSImode || reload_completed))
+    {
+      rtx xop0 = XEXP (x, 0);
+      rtx xop1 = XEXP (x, 1);
+
+      if (GET_MODE_SIZE (mode) <= 8
+         && MAYBE_BASE_REGISTER_RTX_P (xop0, strict)
+         && sh_legitimate_index_p (mode, xop1))
+       return true;
+
+      if ((ALLOW_INDEXED_ADDRESS || GET_MODE (x) == DImode
+          || ((xop0 == stack_pointer_rtx
+               || xop0 == hard_frame_pointer_rtx)
+              && REG_P (xop1) && REGNO (xop1) == R0_REG)
+          || ((xop1 == stack_pointer_rtx
+               || xop1 == hard_frame_pointer_rtx)
+              && REG_P (xop0) && REGNO (xop0) == R0_REG))
+         && ((!TARGET_SHMEDIA && GET_MODE_SIZE (mode) <= 4)
+             || (TARGET_SHMEDIA && GET_MODE_SIZE (mode) <= 8)
+             || ((TARGET_SH4 || TARGET_SH2A_DOUBLE)
+                 && TARGET_FMOVD && mode == DFmode)))
+       {
+         if (MAYBE_BASE_REGISTER_RTX_P (xop1, strict)
+             && MAYBE_INDEX_REGISTER_RTX_P (xop0, strict))
+           return true;
+         if (MAYBE_INDEX_REGISTER_RTX_P (xop1, strict)
+             && MAYBE_BASE_REGISTER_RTX_P (xop0, strict))
+           return true;
+       }
+    }
+
+  return false;
+}
+\f
 /* Return TRUE if X references a SYMBOL_REF or LABEL_REF whose symbol
    isn't protected by a PIC unspec.  */
 int
index 71e202a..0b6294a 100644 (file)
@@ -2191,45 +2191,25 @@ struct sh_args {
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
-   We have two alternate definitions for each of them.
-   The usual definition accepts all pseudo regs; the other rejects
-   them unless they have been allocated suitable hard regs.
-   The symbol REG_OK_STRICT causes the latter definition to be used.  */
-
-#ifndef REG_OK_STRICT
-
-/* 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) \
-  (GENERAL_OR_AP_REGISTER_P (REGNO (X)) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-/* 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) \
-  ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
-    : REGNO (X) == R0_REG) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-/* Nonzero if X/OFFSET is a hard reg that can be used as an index
-   or if X is a pseudo reg.  */
-#define SUBREG_OK_FOR_INDEX_P(X, OFFSET) \
-  ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X)) \
-    : REGNO (X) == R0_REG && OFFSET == 0) || REGNO (X) >= FIRST_PSEUDO_REGISTER)
-
-#else
-
-/* 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))
-
-/* 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/OFFSET is a hard reg that can be used as an index.  */
-#define SUBREG_OK_FOR_INDEX_P(X, OFFSET) \
-  (REGNO_OK_FOR_INDEX_P (REGNO (X)) && (OFFSET) == 0)
-
-#endif
+   The suitable hard regs are always accepted and all pseudo regs
+   are also accepted if STRICT is not set.  */
+
+/* Nonzero if X is a reg that can be used as a base reg.  */
+#define REG_OK_FOR_BASE_P(X, STRICT)                   \
+  (GENERAL_OR_AP_REGISTER_P (REGNO (X))                        \
+   || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
+/* Nonzero if X is a reg that can be used as an index.  */
+#define REG_OK_FOR_INDEX_P(X, STRICT)                  \
+  ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X))    \
+    : REGNO (X) == R0_REG)                             \
+   || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
+
+/* Nonzero if X/OFFSET is a reg that can be used as an index.  */
+#define SUBREG_OK_FOR_INDEX_P(X, OFFSET, STRICT)       \
+  ((TARGET_SHMEDIA ? GENERAL_REGISTER_P (REGNO (X))    \
+    : REGNO (X) == R0_REG && OFFSET == 0)              \
+   || (!STRICT && REGNO (X) >= FIRST_PSEUDO_REGISTER))
 
 /* Macros for extra constraints.  */
 
@@ -2305,144 +2285,55 @@ struct sh_args {
       || PCREL_SYMOFF_P (OP)) \
    : NON_PIC_REFERENCE_P (OP))
 \f
-/* 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.  */
-
-#define MODE_DISP_OK_4(X,MODE) \
-(GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64       \
- && ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode))
-
-#define MODE_DISP_OK_8(X,MODE) \
-((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60)  \
- && ! (INTVAL(X) & 3) && ! (TARGET_SH4 && (MODE) == DFmode))
-
-#undef MODE_DISP_OK_4
-#define MODE_DISP_OK_4(X,MODE) \
-((GET_MODE_SIZE (MODE) == 4 && (unsigned) INTVAL (X) < 64      \
-  && ! (INTVAL (X) & 3) && ! (TARGET_SH2E && (MODE) == SFmode)) \
-  || ((GET_MODE_SIZE(MODE)==4) && ((unsigned)INTVAL(X)<16383)  \
-  && ! (INTVAL(X) & 3) && TARGET_SH2A))
-
-#undef MODE_DISP_OK_8
-#define MODE_DISP_OK_8(X,MODE) \
-(((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<60) \
-  && ! (INTVAL(X) & 3) && ! ((TARGET_SH4 || TARGET_SH2A) && (MODE) == DFmode)) \
- || ((GET_MODE_SIZE(MODE)==8) && ((unsigned)INTVAL(X)<8192)    \
-  && ! (INTVAL(X) & (TARGET_SH2A_DOUBLE ? 7 : 3)) && (TARGET_SH2A && (MODE) == DFmode)))
-
-#define BASE_REGISTER_RTX_P(X)                         \
-  ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X))      \
-   || (GET_CODE (X) == SUBREG                          \
-       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
+#define MAYBE_BASE_REGISTER_RTX_P(X, STRICT)                   \
+  ((GET_CODE (X) == REG && REG_OK_FOR_BASE_P (X, STRICT))      \
+   || (GET_CODE (X) == SUBREG                                  \
+       && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))),    \
                                 GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
-       && GET_CODE (SUBREG_REG (X)) == REG             \
-       && REG_OK_FOR_BASE_P (SUBREG_REG (X))))
+       && GET_CODE (SUBREG_REG (X)) == REG                     \
+       && REG_OK_FOR_BASE_P (SUBREG_REG (X), STRICT)))
 
 /* Since this must be r0, which is a single register class, we must check
    SUBREGs more carefully, to be sure that we don't accept one that extends
    outside the class.  */
-#define INDEX_REGISTER_RTX_P(X)                                \
-  ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X))     \
-   || (GET_CODE (X) == SUBREG                          \
+#define MAYBE_INDEX_REGISTER_RTX_P(X, STRICT)                          \
+  ((GET_CODE (X) == REG && REG_OK_FOR_INDEX_P (X, STRICT))     \
+   || (GET_CODE (X) == SUBREG                                  \
        && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (GET_MODE ((X))), \
                                 GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (X)))) \
        && GET_CODE (SUBREG_REG (X)) == REG             \
-       && SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X))))
-
-/* Jump to LABEL if X is a valid address RTX.  This must also take
-   REG_OK_STRICT into account when deciding about valid registers, but it uses
-   the above macros so we are in luck.
+       && SUBREG_OK_FOR_INDEX_P (SUBREG_REG (X), SUBREG_BYTE (X), STRICT)))
 
-   Allow  REG
-         REG+disp
-         REG+r0
-         REG++
-         --REG  */
-
-/* ??? The SH2e does not have the REG+disp addressing mode when loading values
-   into the FRx registers.  We implement this by setting the maximum offset
-   to zero when the value is SFmode.  This also restricts loading of SFmode
-   values into the integer registers, but that can't be helped.  */
-
-/* The SH allows a displacement in a QI or HI amode, but only when the
-   other operand is R0. GCC doesn't handle this very well, so we forgo
-   all of that.
-
-   A legitimate index for a QI or HI is 0, SI can be any number 0..63,
-   DI can be any number 0..60.  */
-
-#define GO_IF_LEGITIMATE_INDEX(MODE, OP, LABEL)                        \
-  do {                                                                 \
-    if (GET_CODE (OP) == CONST_INT)                                    \
-      {                                                                        \
-       if (TARGET_SHMEDIA)                                             \
-         {                                                             \
-           int MODE_SIZE;                                              \
-           /* Check if this the address of an unaligned load / store.  */\
-           if ((MODE) == VOIDmode)                                     \
-             {                                                         \
-               if (CONST_OK_FOR_I06 (INTVAL (OP)))                     \
-                 goto LABEL;                                           \
-               break;                                                  \
-             }                                                         \
-           MODE_SIZE = GET_MODE_SIZE (MODE);                           \
-           if (! (INTVAL (OP) & (MODE_SIZE - 1))                       \
-               && INTVAL (OP) >= -512 * MODE_SIZE                      \
-               && INTVAL (OP) < 512 * MODE_SIZE)                       \
-             goto LABEL;                                               \
-           else                                                        \
-             break;                                                    \
-         }                                                             \
-       if (TARGET_SH2A)                                                \
-         {                                                             \
-           if (GET_MODE_SIZE (MODE) == 1                               \
-               && (unsigned) INTVAL (OP) < 4096)                       \
-           goto LABEL;                                                 \
-         }                                                             \
-       if (MODE_DISP_OK_4 ((OP), (MODE)))  goto LABEL;                 \
-       if (MODE_DISP_OK_8 ((OP), (MODE)))  goto LABEL;                 \
-      }                                                                        \
-  } while(0)
+#ifdef REG_OK_STRICT
+#define BASE_REGISTER_RTX_P(X) MAYBE_BASE_REGISTER_RTX_P(X, true)
+#define INDEX_REGISTER_RTX_P(X) MAYBE_INDEX_REGISTER_RTX_P(X, true)
+#else
+#define BASE_REGISTER_RTX_P(X) MAYBE_BASE_REGISTER_RTX_P(X, false)
+#define INDEX_REGISTER_RTX_P(X) MAYBE_INDEX_REGISTER_RTX_P(X, false)
+#endif
 
 #define ALLOW_INDEXED_ADDRESS \
   ((!TARGET_SHMEDIA32 && !TARGET_SHCOMPACT) || TARGET_ALLOW_INDEXED_ADDRESS)
 
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)                       \
-{                                                                      \
-  if (BASE_REGISTER_RTX_P (X))                                         \
-    goto LABEL;                                                                \
-  else if ((GET_CODE (X) == POST_INC || GET_CODE (X) == PRE_DEC)       \
-          && ! TARGET_SHMEDIA                                          \
-          && BASE_REGISTER_RTX_P (XEXP ((X), 0)))                      \
-    goto LABEL;                                                                \
-  else if (GET_CODE (X) == PLUS                                                \
-          && ((MODE) != PSImode || reload_completed))                  \
-    {                                                                  \
-      rtx xop0 = XEXP ((X), 0);                                                \
-      rtx xop1 = XEXP ((X), 1);                                                \
-      if (GET_MODE_SIZE (MODE) <= 8 && BASE_REGISTER_RTX_P (xop0))     \
-       GO_IF_LEGITIMATE_INDEX ((MODE), xop1, LABEL);                   \
-      if ((ALLOW_INDEXED_ADDRESS || GET_MODE (X) == DImode             \
-          || ((xop0 == stack_pointer_rtx                               \
-               || xop0 == hard_frame_pointer_rtx)                      \
-              && REG_P (xop1) && REGNO (xop1) == R0_REG)               \
-          || ((xop1 == stack_pointer_rtx                               \
-               || xop1 == hard_frame_pointer_rtx)                      \
-              && REG_P (xop0) && REGNO (xop0) == R0_REG))              \
-         && ((!TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 4)            \
-             || (TARGET_SHMEDIA && GET_MODE_SIZE (MODE) <= 8)          \
-             || ((TARGET_SH4 || TARGET_SH2A_DOUBLE)                    \
-                 && TARGET_FMOVD && MODE == DFmode)))                  \
-       {                                                               \
-         if (BASE_REGISTER_RTX_P (xop1) && INDEX_REGISTER_RTX_P (xop0))\
-           goto LABEL;                                                 \
-         if (INDEX_REGISTER_RTX_P (xop1) && BASE_REGISTER_RTX_P (xop0))\
-           goto LABEL;                                                 \
-       }                                                               \
-    }                                                                  \
-}
+#define GO_IF_LEGITIMATE_INDEX(MODE, OP, WIN)  \
+  do {                                         \
+    if (sh_legitimate_index_p ((MODE), (OP)))  \
+      goto WIN;                                        \
+  } while (0)
+
+#ifdef REG_OK_STRICT
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)       \
+  do {                                                 \
+    if (sh_legitimate_address_p ((MODE), (X), true))   \
+      goto LABEL;                                      \
+  } while (0)
+#else
+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)       \
+  do {                                                 \
+    if (sh_legitimate_address_p ((MODE), (X), false))  \
+      goto LABEL;                                      \
+  } while (0)
+#endif
 \f
 /* A C compound statement that attempts to replace X, which is an address
    that needs reloading, with a valid memory address for an operand of