aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2005-08-19 09:20:31 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2005-08-19 09:20:31 +0000
commita132dad65cb865aba22f2fae83a357977a19452f (patch)
tree1deaece4e80d19b36f21964548d94d696f9f88c2
parent156afe1308665239eb583eb9d65a5eaad8c35d8b (diff)
downloadgcc-a132dad65cb865aba22f2fae83a357977a19452f.zip
gcc-a132dad65cb865aba22f2fae83a357977a19452f.tar.gz
gcc-a132dad65cb865aba22f2fae83a357977a19452f.tar.bz2
re PR target/23436 (Insn does not satisfy its constraints (reload_cse_simplify_operands))
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. From-SVN: r103273
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/arm/arm-protos.h2
-rw-r--r--gcc/config/arm/arm.c43
-rw-r--r--gcc/config/arm/arm.h26
4 files changed, 61 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c7e899c..991beee 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index b03f765..cb34f3b 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -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);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 76f9091..9534a91 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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;
+}
+
#define REG_OR_SUBREG_REG(X) \
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 1f906c8..a434d4f 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -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) \