* pa.h (LEGITIMIZE_RELOAD_ADDRESS): Define.
authorJeffrey A Law <law@cygnus.com>
Tue, 7 Apr 1998 20:51:37 +0000 (20:51 +0000)
committerJeff Law <law@gcc.gnu.org>
Tue, 7 Apr 1998 20:51:37 +0000 (14:51 -0600)
From-SVN: r19036

gcc/ChangeLog
gcc/config/pa/pa.h

index 7c9e20dfe10ff051443a2d95d09877741658c9a5..f2d6bf8e6853ff830c73b8577b7308989866167b 100644 (file)
@@ -1,3 +1,7 @@
+Tue Apr  7 21:48:52 1998  Jeffrey A Law  (law@cygnus.com)
+
+       * pa.h (LEGITIMIZE_RELOAD_ADDRESS): Define.
+
 1998-04-07  Ken Raeburn  <raeburn@cygnus.com>
 
        * config/mips/mips.c (siginfo): Deleted.
index db0f99e5f44ccec01598737d4c0040a9a05cd3c4..b944388d93a80cda4a690567befeb521d314b704 100644 (file)
@@ -1615,6 +1615,64 @@ extern struct rtx_def *hppa_builtin_saveregs ();
           && GET_CODE (XEXP (X, 1)) == UNSPEC)         \
     goto ADDR;                                         \
 }
+
+/* Look for machine dependent ways to make the invalid address AD a
+   valid address.
+
+   For the PA, transform:
+
+        memory(X + <large int>)
+
+   into:
+
+        if (<large int> & mask) >= 16
+          Y = (<large int> & ~mask) + mask + 1  Round up.
+        else
+          Y = (<large int> & ~mask)             Round down.
+        Z = X + Y
+        memory (Z + (<large int> - Y));
+
+   This makes reload inheritance and reload_cse work better since Z
+   can be reused.
+
+   There may be more opportunities to improve code with this hook.  */
+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN)     \
+do {                                                                   \
+  int offset, newoffset, mask;                                         \
+  mask = GET_MODE_CLASS (MODE) == MODE_FLOAT ? 0x1f : 0x3fff;          \
+                                                                       \
+  if (GET_CODE (AD) == PLUS                                            \
+      && GET_CODE (XEXP (AD, 0)) == REG                                        \
+      && GET_CODE (XEXP (AD, 1)) == CONST_INT)                         \
+    {                                                                  \
+      offset = INTVAL (XEXP ((AD), 1));                                        \
+                                                                       \
+      /* Choose rounding direction.  Round up if we are >= halfway.  */        \
+      if ((offset & mask) >= ((mask + 1) / 2))                         \
+       newoffset = (offset & ~mask) + mask + 1;                        \
+      else                                                             \
+       newoffset = offset & ~mask;                                     \
+                                                                       \
+      if (newoffset != 0                                               \
+         && VAL_14_BITS_P (newoffset))                                 \
+       {                                                               \
+         rtx temp;                                                     \
+                                                                       \
+         /* Unshare the sum as well.  */                               \
+         AD = copy_rtx (AD);                                           \
+         temp = gen_rtx_PLUS (Pmode, XEXP (AD, 0),                     \
+                              GEN_INT (newoffset));                    \
+         AD = gen_rtx_PLUS (Pmode, temp, GEN_INT (offset - newoffset));\
+         push_reload (XEXP (AD, 0), 0, &XEXP (AD, 0), 0,               \
+                            BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,     \
+                            (OPNUM), (TYPE));                          \
+         goto WIN;                                                     \
+       }                                                               \
+    }                                                                  \
+} while (0)
+
+
+
 \f
 /* Try machine-dependent ways of modifying an illegitimate address
    to be legitimate.  If we find one, return the new, valid address.