OSDN Git Service

PR target/23436
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Aug 2005 09:20:31 +0000 (09:20 +0000)
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 19 Aug 2005 09:20:31 +0000 (09:20 +0000)
* arm.c (thumb_legitimize_reload_address): New function.
* arm-protos.h (thumb_legitimize_reload_address): Add prototype.
* arm.h (THUMB_LEGITIMIZE_RELOAD_ADDRESS): Call it.

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

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

index c7e899c..991beee 100644 (file)
@@ -1,3 +1,10 @@
+2005-08-19  Richard Earnshaw  <richard.earnshaw@arm.com>
+
+       PR target/23436
+       * arm.c (thumb_legitimize_reload_address): New function.
+       * arm-protos.h (thumb_legitimize_reload_address): Add prototype.
+       * arm.h (THUMB_LEGITIMIZE_RELOAD_ADDRESS): Call it.
+
 2005-08-19  Paul Woegerer  <paul.woegerer@nsc.com>
 
        * config/crx/crx.c: Implement crx_decompose_address. Reject
index b03f765..cb34f3b 100644 (file)
@@ -61,6 +61,8 @@ extern int thumb_legitimate_address_p (enum machine_mode, rtx, int);
 extern int thumb_legitimate_offset_p (enum machine_mode, HOST_WIDE_INT);
 extern rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
 extern rtx thumb_legitimize_address (rtx, rtx, enum machine_mode);
+extern rtx thumb_legitimize_reload_address (rtx *, enum machine_mode, int, int,
+                                           int);
 extern int arm_const_double_rtx (rtx);
 extern int neg_const_double_rtx_ok_for_fpa (rtx);
 extern enum reg_class vfp_secondary_reload_class (enum machine_mode, rtx);
index 76f9091..9534a91 100644 (file)
@@ -3839,6 +3839,49 @@ thumb_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
   return x;
 }
 
+rtx
+thumb_legitimize_reload_address(rtx *x_p,
+                               enum machine_mode mode,
+                               int opnum, int type,
+                               int ind_levels ATTRIBUTE_UNUSED)
+{
+  rtx x = *x_p;
+  
+  if (GET_CODE (x) == PLUS
+      && GET_MODE_SIZE (mode) < 4
+      && REG_P (XEXP (x, 0))
+      && XEXP (x, 0) == stack_pointer_rtx
+      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && !thumb_legitimate_offset_p (mode, INTVAL (XEXP (x, 1))))
+    {
+      rtx orig_x = x;
+
+      x = copy_rtx (x);
+      push_reload (orig_x, NULL_RTX, x_p, NULL, MODE_BASE_REG_CLASS (mode),
+                  Pmode, VOIDmode, 0, 0, opnum, type);
+      return x;
+    }
+
+  /* If both registers are hi-regs, then it's better to reload the
+     entire expression rather than each register individually.  That
+     only requires one reload register rather than two.  */
+  if (GET_CODE (x) == PLUS
+      && REG_P (XEXP (x, 0))
+      && REG_P (XEXP (x, 1))
+      && !REG_MODE_OK_FOR_REG_BASE_P (XEXP (x, 0), mode)
+      && !REG_MODE_OK_FOR_REG_BASE_P (XEXP (x, 1), mode))
+    {
+      rtx orig_x = x;
+
+      x = copy_rtx (x);
+      push_reload (orig_x, NULL_RTX, x_p, NULL, MODE_BASE_REG_CLASS (mode),
+                  Pmode, VOIDmode, 0, 0, opnum, type);
+      return x;
+    }
+
+  return NULL;
+}
+
 \f
 
 #define REG_OR_SUBREG_REG(X)                                           \
index 1f906c8..a434d4f 100644 (file)
@@ -1282,23 +1282,15 @@ enum reg_class
 /* We could probably achieve better results by defining PROMOTE_MODE to help
    cope with the variances between the Thumb's signed and unsigned byte and
    halfword load instructions.  */
-#define THUMB_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN) \
-{                                                                      \
-  if (GET_CODE (X) == PLUS                                             \
-      && GET_MODE_SIZE (MODE) < 4                                      \
-      && GET_CODE (XEXP (X, 0)) == REG                                 \
-      && XEXP (X, 0) == stack_pointer_rtx                              \
-      && GET_CODE (XEXP (X, 1)) == CONST_INT                           \
-      && ! thumb_legitimate_offset_p (MODE, INTVAL (XEXP (X, 1))))     \
-    {                                                                  \
-      rtx orig_X = X;                                                  \
-      X = copy_rtx (X);                                                        \
-      push_reload (orig_X, NULL_RTX, &X, NULL,                         \
-                  MODE_BASE_REG_CLASS (MODE),                          \
-                  Pmode, VOIDmode, 0, 0, OPNUM, TYPE);                 \
-      goto WIN;                                                                \
-    }                                                                  \
-}
+#define THUMB_LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_L, WIN)     \
+do {                                                                         \
+  rtx new_x = thumb_legitimize_reload_address (&X, MODE, OPNUM, TYPE, IND_L); \
+  if (new_x)                                                                 \
+    {                                                                        \
+      X = new_x;                                                             \
+      goto WIN;                                                                      \
+    }                                                                        \
+} while (0)
 
 #define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_LEVELS, WIN)   \
   if (TARGET_ARM)                                                         \