aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Earnshaw <rearnsha@arm.com>2003-01-29 16:50:34 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2003-01-29 16:50:34 +0000
commitccf4d5128446c504efe2133f907f8b13181b0f3c (patch)
tree71fd9080e958d30ae437a22c2911f8676957654e /gcc
parent0680c8fb906deed9c3c90b25324c65056d826912 (diff)
downloadgcc-ccf4d5128446c504efe2133f907f8b13181b0f3c.zip
gcc-ccf4d5128446c504efe2133f907f8b13181b0f3c.tar.gz
gcc-ccf4d5128446c504efe2133f907f8b13181b0f3c.tar.bz2
arm.c (arm_legtimize_address): New function.
* arm.c (arm_legtimize_address): New function. * arm-protos.h (arm_legtimize_address): Add prototype. * arm.h (ARM_LEGITIMIZE_ADDRESS): Use arm_legitimize_address. (LEGITIMIZE_ADDRESS, THUMB_LEGITIMIZE_ADDRESS): Wrap with do ... while (0) From-SVN: r62091
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c85
-rw-r--r--gcc/config/arm/arm.h106
4 files changed, 115 insertions, 85 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 52d3f9e..744f126 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2003-01-29 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (arm_legtimize_address): New function.
+ * arm-protos.h (arm_legtimize_address): Add prototype.
+ * arm.h (ARM_LEGITIMIZE_ADDRESS): Use arm_legitimize_address.
+ (LEGITIMIZE_ADDRESS, THUMB_LEGITIMIZE_ADDRESS): Wrap with
+ do ... while (0)
+
2003-01-29 Joel Sherrill <joel@OARcorp.com>
* gthr-rtems.h: Define __GTHREAD_MUTEX_INIT. Apparently no code
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 1c3764d..6fce0ce 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -57,6 +57,7 @@ extern int thumb_legitimate_address_p PARAMS ((enum machine_mode, rtx,
int));
extern int thumb_legitimate_offset_p PARAMS ((enum machine_mode,
HOST_WIDE_INT));
+extern rtx arm_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
extern int const_double_rtx_ok_for_fpu PARAMS ((rtx));
extern int neg_const_double_rtx_ok_for_fpu PARAMS ((rtx));
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 427f68e..576d038 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -2905,6 +2905,91 @@ thumb_legitimate_offset_p (mode, val)
}
}
+/* Try machine-dependent ways of modifying an illegitimate address
+ to be legitimate. If we find one, return the new, valid address. */
+
+rtx
+arm_legitimize_address (x, orig_x, mode)
+ rtx x;
+ rtx orig_x;
+ enum machine_mode mode;
+{
+ if (GET_CODE (x) == PLUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ if (CONSTANT_P (xop0) && !symbol_mentioned_p (xop0))
+ xop0 = force_reg (SImode, xop0);
+
+ if (CONSTANT_P (xop1) && !symbol_mentioned_p (xop1))
+ xop1 = force_reg (SImode, xop1);
+
+ if (ARM_BASE_REGISTER_RTX_P (xop0)
+ && GET_CODE (xop1) == CONST_INT)
+ {
+ HOST_WIDE_INT n, low_n;
+ rtx base_reg, val;
+ n = INTVAL (xop1);
+
+ if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
+ {
+ low_n = n & 0x0f;
+ n &= ~0x0f;
+ if (low_n > 4)
+ {
+ n += 16;
+ low_n -= 16;
+ }
+ }
+ else
+ {
+ low_n = ((mode) == TImode ? 0
+ : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff));
+ n -= low_n;
+ }
+
+ base_reg = gen_reg_rtx (SImode);
+ val = force_operand (gen_rtx_PLUS (SImode, xop0,
+ GEN_INT (n)), NULL_RTX);
+ emit_move_insn (base_reg, val);
+ x = (low_n == 0 ? base_reg
+ : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n)));
+ }
+ else if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
+ x = gen_rtx_PLUS (SImode, xop0, xop1);
+ }
+
+ /* XXX We don't allow MINUS any more -- see comment in
+ arm_legitimate_address_p (). */
+ else if (GET_CODE (x) == MINUS)
+ {
+ rtx xop0 = XEXP (x, 0);
+ rtx xop1 = XEXP (x, 1);
+
+ if (CONSTANT_P (xop0))
+ xop0 = force_reg (SImode, xop0);
+
+ if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1))
+ xop1 = force_reg (SImode, xop1);
+
+ if (xop0 != XEXP (x, 0) || xop1 != XEXP (x, 1))
+ x = gen_rtx_MINUS (SImode, xop0, xop1);
+ }
+
+ if (flag_pic)
+ {
+ /* We need to find and carefully transform any SYMBOL and LABEL
+ references; so go back to the original address expression. */
+ rtx new_x = legitimize_pic_address (orig_x, mode, NULL_RTX);
+
+ if (new_x != orig_x)
+ x = new_x;
+ }
+
+ return x;
+}
+
#define REG_OR_SUBREG_REG(X) \
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index fb82ebc..9f3420b 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -1964,92 +1964,28 @@ typedef struct
/* 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.
-
- It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output.
-
- On the ARM, try to convert [REG, #BIGCONST]
- into ADD BASE, REG, #UPPERCONST and [BASE, #VALIDCONST],
- where VALIDCONST == 0 in case of TImode. */
-#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ \
- if (GET_CODE (X) == PLUS) \
- { \
- rtx xop0 = XEXP (X, 0); \
- rtx xop1 = XEXP (X, 1); \
- \
- if (CONSTANT_P (xop0) && ! symbol_mentioned_p (xop0)) \
- xop0 = force_reg (SImode, xop0); \
- if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
- xop1 = force_reg (SImode, xop1); \
- if (ARM_BASE_REGISTER_RTX_P (xop0) \
- && GET_CODE (xop1) == CONST_INT) \
- { \
- HOST_WIDE_INT n, low_n; \
- rtx base_reg, val; \
- n = INTVAL (xop1); \
- \
- if (MODE == DImode || (TARGET_SOFT_FLOAT && MODE == DFmode)) \
- { \
- low_n = n & 0x0f; \
- n &= ~0x0f; \
- if (low_n > 4) \
- { \
- n += 16; \
- low_n -= 16; \
- } \
- } \
- else \
- { \
- low_n = ((MODE) == TImode ? 0 \
- : n >= 0 ? (n & 0xfff) : -((-n) & 0xfff)); \
- n -= low_n; \
- } \
- base_reg = gen_reg_rtx (SImode); \
- val = force_operand (gen_rtx_PLUS (SImode, xop0, \
- GEN_INT (n)), NULL_RTX); \
- emit_move_insn (base_reg, val); \
- (X) = (low_n == 0 ? base_reg \
- : gen_rtx_PLUS (SImode, base_reg, GEN_INT (low_n))); \
- } \
- else if (xop0 != XEXP (X, 0) || xop1 != XEXP (x, 1)) \
- (X) = gen_rtx_PLUS (SImode, xop0, xop1); \
- } \
- else if (GET_CODE (X) == MINUS) \
- { \
- rtx xop0 = XEXP (X, 0); \
- rtx xop1 = XEXP (X, 1); \
- \
- if (CONSTANT_P (xop0)) \
- xop0 = force_reg (SImode, xop0); \
- if (CONSTANT_P (xop1) && ! symbol_mentioned_p (xop1)) \
- xop1 = force_reg (SImode, xop1); \
- if (xop0 != XEXP (X, 0) || xop1 != XEXP (X, 1)) \
- (X) = gen_rtx_MINUS (SImode, xop0, xop1); \
- } \
- if (flag_pic) \
- (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-}
+ to be legitimate. If we find one, return the new, valid address. */
+#define ARM_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ X = arm_legitimize_address (X, OLDX, MODE); \
+ \
+ if (memory_address_p (MODE, X)) \
+ goto WIN; \
+} while (0)
-#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- if (flag_pic) \
- (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX);
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- if (TARGET_ARM) \
- ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN) \
- else \
- THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN)
+#define THUMB_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ if (flag_pic) \
+ (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
+} while (0)
+
+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
+do { \
+ if (TARGET_ARM) \
+ ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
+ else \
+ THUMB_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
+} while (0)
/* Go to LABEL if ADDR (a legitimate address expression)
has an effect that depends on the machine mode it is used for. */