diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2003-01-29 16:50:34 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2003-01-29 16:50:34 +0000 |
commit | ccf4d5128446c504efe2133f907f8b13181b0f3c (patch) | |
tree | 71fd9080e958d30ae437a22c2911f8676957654e /gcc | |
parent | 0680c8fb906deed9c3c90b25324c65056d826912 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 85 | ||||
-rw-r--r-- | gcc/config/arm/arm.h | 106 |
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. */ |