OSDN Git Service

* mn10300.c (symbolic_operand, legitimize_address): New functions.
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Oct 1997 19:18:29 +0000 (19:18 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 24 Oct 1997 19:18:29 +0000 (19:18 +0000)
        * mn10300.h (LEGITIMIZE_ADDRESS): Call legitimize_address.
        (GO_IF_LEGITIMATE_ADDRESS): Don't allow base + symbolic.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@16158 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/mn10300/mn10300.c
gcc/config/mn10300/mn10300.h

index 272e137..f4b2875 100644 (file)
@@ -1,3 +1,9 @@
+Fri Oct 24 13:19:40 1997  Jeffrey A Law  (law@cygnus.com)
+
+       * mn10300.c (symbolic_operand, legitimize_address): New functions.
+       * mn10300.h (LEGITIMIZE_ADDRESS): Call legitimize_address.
+       (GO_IF_LEGITIMATE_ADDRESS): Don't allow base + symbolic.
+
 Thu Oct 23 09:35:12 1997  Jeffrey A Law  (law@cygnus.com)
 
        * version.c: Bump for snapshot.
index e555921..8bb5371 100644 (file)
@@ -989,3 +989,72 @@ impossible_plus_operand (op, mode)
 
   return 0;
 }
+
+/* Return 1 if X contains a symbolic expression.  We know these
+   expressions will have one of a few well defined forms, so
+   we need only check those forms.  */
+int
+symbolic_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  switch (GET_CODE (op))
+    {
+    case SYMBOL_REF:
+    case LABEL_REF:
+      return 1;
+    case CONST:
+      op = XEXP (op, 0);
+      return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
+               || GET_CODE (XEXP (op, 0)) == LABEL_REF)
+              && GET_CODE (XEXP (op, 1)) == CONST_INT);
+    default:
+      return 0;
+    }
+}
+
+/* Try machine dependent ways of modifying an illegitimate address
+   to be legitimate.  If we find one, return the new valid address.
+   This macro is used in only one place: `memory_address' in explow.c.
+
+   OLDX is the address as it was before break_out_memory_refs was called.
+   In some cases it is useful to look at this to decide what needs to be done.
+
+   MODE and WIN are passed so that this macro can use
+   GO_IF_LEGITIMATE_ADDRESS.
+
+   Normally it is always safe for this macro to do nothing.  It exists to
+   recognize opportunities to optimize the output.
+
+   But on a few ports with segmented architectures and indexed addressing
+   (mn10300, hppa) it is used to rewrite certain problematical addresses.  */
+rtx
+legitimize_address (x, oldx, mode)
+     rtx x;
+     rtx oldx;
+     enum machine_mode mode;
+{
+  /* Uh-oh.  We might have an address for x[n-100000].  This needs
+     special handling to avoid creating an indexed memory address
+     with x-100000 as the base.  */
+  if (GET_CODE (x) == PLUS
+      && symbolic_operand (XEXP (x, 1), VOIDmode))
+    {
+      /* Ugly.  We modify things here so that the address offset specified
+         by the index expression is computed first, then added to x to form
+         the entire address.  */
+
+      rtx regx1, regx2, regy1, regy2, y;
+
+      /* Strip off any CONST.  */
+      y = XEXP (x, 1);
+      if (GET_CODE (y) == CONST)
+        y = XEXP (y, 0);
+
+      regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
+      regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
+      regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
+      regx1 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
+      return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
+    }
+}
index 88065a2..3201606 100644 (file)
@@ -661,7 +661,7 @@ extern struct rtx_def *mn10300_builtin_saveregs ();
        base = XEXP (X, 1), index = XEXP (X, 0);        \
       if (base != 0 && index != 0)                     \
        {                                               \
-         if (CONSTANT_ADDRESS_P (index))               \
+         if (GET_CODE (index) == CONST_INT)            \
            goto ADDR;                                  \
          if (REG_P (index)                             \
              && REG_OK_FOR_INDEX_P (index)             \
@@ -685,7 +685,12 @@ extern struct rtx_def *mn10300_builtin_saveregs ();
    It is always safe for this macro to do nothing.  It exists to recognize
    opportunities to optimize the output.   */
 
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)  {}
+extern struct rtx_def *legitimize_address ();
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)  \
+{ rtx orig_x = (X);                            \
+  (X) = legitimize_address (X, OLDX, MODE);    \
+  if ((X) != orig_x && memory_address_p (MODE, X)) \
+    goto WIN; }
 
 /* Go to LABEL if ADDR (a legitimate address expression)
    has an effect that depends on the machine mode it is used for.  */
@@ -998,3 +1003,4 @@ extern int impossible_plus_operand ();
 extern enum reg_class secondary_reload_class ();
 extern int initial_offset ();
 extern char *output_tst ();
+int symbolic_operand ();