+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
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);
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) \
/* 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) \