summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog91
-rw-r--r--gcc/config/alpha/alpha-protos.h1
-rw-r--r--gcc/config/alpha/alpha.c21
-rw-r--r--gcc/config/alpha/alpha.h14
-rw-r--r--gcc/config/arm/arm-protos.h2
-rw-r--r--gcc/config/arm/arm.c13
-rw-r--r--gcc/config/arm/arm.h30
-rw-r--r--gcc/config/avr/avr-protos.h1
-rw-r--r--gcc/config/avr/avr.c6
-rw-r--r--gcc/config/avr/avr.h7
-rw-r--r--gcc/config/bfin/bfin-protos.h1
-rw-r--r--gcc/config/bfin/bfin.c16
-rw-r--r--gcc/config/bfin/bfin.h19
-rw-r--r--gcc/config/cris/cris.h10
-rw-r--r--gcc/config/frv/frv-protos.h1
-rw-r--r--gcc/config/frv/frv.c6
-rw-r--r--gcc/config/frv/frv.h10
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c10
-rw-r--r--gcc/config/i386/i386.h28
-rw-r--r--gcc/config/iq2000/iq2000.c71
-rw-r--r--gcc/config/iq2000/iq2000.h66
-rw-r--r--gcc/config/m32c/m32c-protos.h1
-rw-r--r--gcc/config/m32c/m32c.c32
-rw-r--r--gcc/config/m32c/m32c.h4
-rw-r--r--gcc/config/m32r/m32r.c14
-rw-r--r--gcc/config/m32r/m32r.h23
-rw-r--r--gcc/config/m68hc11/m68hc11-protos.h2
-rw-r--r--gcc/config/m68hc11/m68hc11.c8
-rw-r--r--gcc/config/m68hc11/m68hc11.h22
-rw-r--r--gcc/config/m68k/m68k.c81
-rw-r--r--gcc/config/m68k/m68k.h49
-rw-r--r--gcc/config/mips/mips-protos.h1
-rw-r--r--gcc/config/mips/mips.c34
-rw-r--r--gcc/config/mips/mips.h7
-rw-r--r--gcc/config/mn10300/mn10300-protos.h1
-rw-r--r--gcc/config/mn10300/mn10300.c8
-rw-r--r--gcc/config/mn10300/mn10300.h18
-rw-r--r--gcc/config/pa/pa-protos.h2
-rw-r--r--gcc/config/pa/pa.c4
-rw-r--r--gcc/config/pa/pa.h20
-rw-r--r--gcc/config/picochip/picochip.h4
-rw-r--r--gcc/config/rs6000/rs6000-protos.h1
-rw-r--r--gcc/config/rs6000/rs6000.c8
-rw-r--r--gcc/config/rs6000/rs6000.h32
-rw-r--r--gcc/config/s390/s390-protos.h1
-rw-r--r--gcc/config/s390/s390.c9
-rw-r--r--gcc/config/s390/s390.h10
-rw-r--r--gcc/config/score/score-protos.h1
-rw-r--r--gcc/config/score/score.c16
-rw-r--r--gcc/config/score/score.h6
-rw-r--r--gcc/config/score/score3.c27
-rw-r--r--gcc/config/score/score3.h2
-rw-r--r--gcc/config/score/score7.c27
-rw-r--r--gcc/config/score/score7.h2
-rw-r--r--gcc/config/sh/sh.c58
-rw-r--r--gcc/config/sh/sh.h62
-rw-r--r--gcc/config/sparc/sparc-protos.h1
-rw-r--r--gcc/config/sparc/sparc.c11
-rw-r--r--gcc/config/sparc/sparc.h21
-rw-r--r--gcc/config/spu/spu-protos.h1
-rw-r--r--gcc/config/spu/spu.c10
-rw-r--r--gcc/config/spu/spu.h9
-rw-r--r--gcc/config/xtensa/xtensa-protos.h1
-rw-r--r--gcc/config/xtensa/xtensa.c6
-rw-r--r--gcc/config/xtensa/xtensa.h11
-rw-r--r--gcc/defaults.h4
-rw-r--r--gcc/doc/tm.texi30
-rw-r--r--gcc/explow.c7
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/target-def.h2
-rw-r--r--gcc/target.h4
-rw-r--r--gcc/targhooks.c7
-rw-r--r--gcc/targhooks.h1
74 files changed, 507 insertions, 643 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0897c6f637f..ad44ff2428b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,94 @@
+2009-05-04 Paolo Bonzini <bonzini@gnu.org>
+
+ * doc/tm.texi (LEGITIMIZE_ADDRESS): Revise documentation.
+ * gcc/defaults.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/explow.c (memory_address): Use target hook.
+ * gcc/targhooks.c (default_legitimize_address): New.
+ * gcc/targhooks.h (default_legitimize_address): New.
+ * gcc/target.h (legitimize_address): New.
+ * gcc/target-def.h (TARGET_LEGITIMIZE_ADDRESS): New.
+ (TARGET_INITIALIZER): Include it.
+ * gcc/system.h (LEGITIMIZE_ADDRESS): Poison.
+
+ * config/bfin/bfin-protos.h (legitimize_address): Remove.
+ * config/bfin/bfin.c (legitimize_address): Remove.
+ * config/bfin/bfin.h (LEGITIMIZE_ADDRESS): Remove.
+ * config/m68hc11/m68hc11-protos.h (m68hc11_legitimize_address): Remove.
+ * config/m68hc11/m68hc11.c (m68hc11_legitimize_address): Remove.
+ * config/m68hc11/m68hc11.h (LEGITIMIZE_ADDRESS): Remove.
+
+ * gcc/config/arm/arm.h (LEGITIMIZE_ADDRESS, ARM_LEGITIMIZE_ADDRESS,
+ THUMB_LEGITIMIZE_ADDRESS, THUMB2_LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/s390/s390.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/m32c/m32c.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/sparc/sparc.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/m32r/m32r.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/i386/i386.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/sh/sh.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/avr/avr.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/m68hc11/m68hc11.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/iq2000/iq2000.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/mn10300/mn10300.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/m68k/m68k.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/score/score.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/pa/pa.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/mips/mips.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/alpha/alpha.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/frv/frv.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/spu/spu.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/xtensa/xtensa.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/cris/cris.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/rs6000/rs6000.h (LEGITIMIZE_ADDRESS): Delete.
+ * gcc/config/picochip/picochip.h (LEGITIMIZE_ADDRESS): Delete.
+
+ * gcc/config/s390/s390-protos.h (legitimize_address): Delete.
+ * gcc/config/m32c/m32c-protos.h (m32c_legitimize_address): Delete.
+ * gcc/config/sparc/sparc-protos.h (legitimize_address): Delete.
+ * gcc/config/i386/i386-protos.h (legitimize_address): Delete.
+ * gcc/config/avr/avr-protos.h (legitimize_address): Delete.
+ * gcc/config/mn10300/mn10300-protos.h (legitimize_address): Delete.
+ * gcc/config/score/score-protos.h (score_legitimize_address): Delete.
+ * gcc/config/arm/arm-protos.h (arm_legitimize_address,
+ (thumb_legitimize_address): Delete.
+ * gcc/config/pa/pa-protos.h (hppa_legitimize_address): Delete.
+ * gcc/config/mips/mips-protos.h (mips_legitimize_address): Delete.
+ * gcc/config/alpha/alpha-protos.h (alpha_legitimize_address): Delete.
+ * gcc/config/frv/frv-protos.h (frv_legitimize_address): Delete.
+ * gcc/config/spu/spu-protos.h (spu_legitimize_address): Delete.
+ * gcc/config/xtensa/xtensa-protos.h (xtensa_legitimize_address): Delete.
+ * gcc/config/rs6000/rs6000-protos.h (rs6000_legitimize_address): Delete.
+
+ * config/arm/arm.c (arm_legitimize_address): Maybe call Thumb version.
+ * config/m32c/m32c.c (m32c_legitimize_address): Standardize.
+ * config/m32r/m32r.c (m32r_legitimize_address): New.
+ * config/m68k/m68k.c (m68k_legitimize_address): New.
+ * config/score/score.c (score_legitimize_address): Standardize.
+ * config/score/score3.c (score3_legitimize_address): Standardize.
+ * config/score/score3.h (score3_legitimize_address): Adjust.
+ * config/score/score7.c (score7_legitimize_address): Standardize.
+ * config/score/score7.h (score7_legitimize_address): Adjust.
+ * config/sh/sh.c (sh_legitimize_address): New.
+ * config/iq2000/iq2000.c (iq2000_legitimize_address): New.
+
+ * gcc/config/s390/s390.c (legitimize_address): Rename to...
+ (s390_legitimize_address): ... this.
+ * gcc/config/sparc/sparc.c (legitimize_address): Rename to...
+ (sparc_legitimize_address): ... this.
+ * gcc/config/i386/i386.c (legitimize_address): Rename to...
+ (ix86_legitimize_address): ... this.
+ * gcc/config/avr/avr.c (legitimize_address): Rename to...
+ (avr_legitimize_address): ... this.
+ * gcc/config/mn10300/mn10300.c (legitimize_address): Rename to...
+ (mn10300_legitimize_address): ... this.
+ * config/alpha/alpha.c (alpha_legitimize_address): Wrap...
+ (alpha_legitimize_address_1): ... the old alpha_legitimize_address.
+ (alpha_expand_mov): Adjust call.
+
+ * config/frv/frv.c (frv_legitimize_address): Return x on failure.
+ * config/spu/spu.c (spu_legitimize_address): Likewise.
+ * config/xtensa/xtensa.c (xtensa_legitimize_address): Likewise.
+ * config/rs6000/rs6000.c (rs6000_legitimize_address): Likewise.
+
2009-05-04 Joseph Myers <joseph@codesourcery.com>
* intl.c (locale_encoding, locale_utf8): New.
diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h
index bbbcd8f4f1a..66c68aebc91 100644
--- a/gcc/config/alpha/alpha-protos.h
+++ b/gcc/config/alpha/alpha-protos.h
@@ -39,7 +39,6 @@ extern rtx alpha_tablejump_best_label (rtx);
extern bool alpha_legitimate_constant_p (rtx);
extern bool alpha_legitimate_address_p (enum machine_mode, rtx, int);
-extern rtx alpha_legitimize_address (rtx, rtx, enum machine_mode);
extern rtx alpha_legitimize_reload_address (rtx, enum machine_mode,
int, int, int);
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 8a7c313d7b3..bb6542a37f9 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -917,8 +917,8 @@ get_tls_get_addr (void)
/* Try machine-dependent ways of modifying an illegitimate address
to be legitimate. If we find one, return the new, valid address. */
-rtx
-alpha_legitimize_address (rtx x, rtx scratch, enum machine_mode mode)
+static rtx
+alpha_legitimize_address_1 (rtx x, rtx scratch, enum machine_mode mode)
{
HOST_WIDE_INT addend;
@@ -1112,6 +1112,18 @@ alpha_legitimize_address (rtx x, rtx scratch, enum machine_mode mode)
}
}
+
+/* Try machine-dependent ways of modifying an illegitimate address
+ to be legitimate. Return X or the new, valid address. */
+
+static rtx
+alpha_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
+{
+ rtx new_x = alpha_legitimize_address_1 (x, NULL_RTX, mode);
+ return new_x ? new_x : x;
+}
+
/* Primarily this is required for TLS symbols, but given that our move
patterns *ought* to be able to handle any symbol at any time, we
should never be spilling symbolic operands to the constant pool, ever. */
@@ -2137,7 +2149,7 @@ alpha_expand_mov (enum machine_mode mode, rtx *operands)
/* Allow legitimize_address to perform some simplifications. */
if (mode == Pmode && symbolic_operand (operands[1], mode))
{
- tmp = alpha_legitimize_address (operands[1], operands[0], mode);
+ tmp = alpha_legitimize_address_1 (operands[1], operands[0], mode);
if (tmp)
{
if (tmp == operands[0])
@@ -10725,6 +10737,9 @@ alpha_init_libfuncs (void)
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS alpha_init_libfuncs
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS alpha_legitimize_address
+
#if TARGET_ABI_UNICOSMK
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START unicosmk_file_start
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 433823dbbd0..f33e8e63854 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -1009,20 +1009,6 @@ do { \
} while (0)
#endif
-/* 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. */
-
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-do { \
- rtx new_x = alpha_legitimize_address (X, NULL_RTX, MODE); \
- if (new_x) \
- { \
- X = new_x; \
- goto WIN; \
- } \
-} while (0)
-
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c. */
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 6019dc697df..34d266b139b 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -58,8 +58,6 @@ extern int arm_legitimate_address_p (enum machine_mode, rtx, RTX_CODE, int);
extern int thumb1_legitimate_address_p (enum machine_mode, rtx, int);
extern int thumb2_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);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index a7847f3235d..e6d2c5c67dc 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -73,6 +73,8 @@ static int arm_address_register_rtx_p (rtx, int);
static int arm_legitimate_index_p (enum machine_mode, rtx, RTX_CODE, int);
static int thumb2_legitimate_index_p (enum machine_mode, rtx, int);
static int thumb1_base_register_rtx_p (rtx, enum machine_mode, int);
+static rtx arm_legitimize_address (rtx, rtx, enum machine_mode);
+static rtx thumb_legitimize_address (rtx, rtx, enum machine_mode);
inline static int thumb1_index_register_rtx_p (rtx, int);
static int thumb_far_jump_used_p (void);
static bool thumb_force_lr_save (void);
@@ -205,6 +207,9 @@ static bool arm_allocate_stack_slots_for_args (void);
#define TARGET_MERGE_DECL_ATTRIBUTES merge_dllimport_decl_attributes
#endif
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS arm_legitimize_address
+
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
@@ -4590,6 +4595,14 @@ legitimize_tls_address (rtx x, rtx reg)
rtx
arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
{
+ if (!TARGET_ARM)
+ {
+ /* TODO: legitimize_address for Thumb2. */
+ if (TARGET_THUMB2)
+ return x;
+ return thumb_legitimize_address (x, orig_x, mode);
+ }
+
if (arm_tls_symbol_p (x))
return legitimize_tls_address (x, NULL_RTX);
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 8d97864861e..e7bc7a7a2d5 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -2204,36 +2204,6 @@ typedef struct
THUMB1_GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN)
-/* Try machine-dependent ways of modifying an illegitimate address
- 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); \
-} while (0)
-
-/* ??? Implement LEGITIMIZE_ADDRESS for thumb2. */
-#define THUMB2_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-do { \
-} while (0)
-
-#define THUMB1_LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-do { \
- X = thumb_legitimize_address (X, OLDX, MODE); \
-} while (0)
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-do { \
- if (TARGET_ARM) \
- ARM_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
- else if (TARGET_THUMB2) \
- THUMB2_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
- else \
- THUMB1_LEGITIMIZE_ADDRESS (X, OLDX, MODE, WIN); \
- \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-} while (0)
-
/* Define this for compatibility reasons. */
#define HANDLE_PRAGMA_PACK_PUSH_POP
diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h
index ef5286ee878..44246901b32 100644
--- a/gcc/config/avr/avr-protos.h
+++ b/gcc/config/avr/avr-protos.h
@@ -98,7 +98,6 @@ extern const char *avr_out_sbxx_branch (rtx insn, rtx operands[]);
extern enum reg_class preferred_reload_class (rtx x, enum reg_class rclass);
extern int extra_constraint_Q (rtx x);
-extern rtx legitimize_address (rtx x, rtx oldx, enum machine_mode mode);
extern int adjust_insn_length (rtx insn, int len);
extern rtx avr_libcall_value (enum machine_mode mode);
extern const char *output_reload_inhi (rtx insn, rtx *operands, int *len);
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 7683c380e74..449c0ee4f89 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -62,6 +62,7 @@ static const char *cond_string (enum rtx_code);
static int avr_num_arg_regs (enum machine_mode, tree);
static RTX_CODE compare_condition (rtx insn);
+static rtx avr_legitimize_address (rtx, rtx, enum machine_mode);
static int compare_sign_p (rtx insn);
static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
@@ -349,6 +350,9 @@ static const struct mcu_type_s avr_mcu_types[] = {
#undef TARGET_MACHINE_DEPENDENT_REORG
#define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS avr_legitimize_address
+
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY avr_return_in_memory
@@ -1164,7 +1168,7 @@ legitimate_address_p (enum machine_mode mode, rtx x, int strict)
memory address for an operand of mode MODE */
rtx
-legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
+avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
{
x = oldx;
if (TARGET_ALL_DEBUG)
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 45d02c4c414..79d81b94923 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -435,13 +435,6 @@ extern int avr_reg_order[];
#define REG_OK_FOR_INDEX_P(X) 0
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ \
- (X) = legitimize_address (X, OLDX, MODE); \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-}
-
#define XEXP_(X,Y) (X)
/* LEGITIMIZE_RELOAD_ADDRESS will allow register R26/27 to be used, where it
diff --git a/gcc/config/bfin/bfin-protos.h b/gcc/config/bfin/bfin-protos.h
index e92a7b6e48d..33de846da95 100644
--- a/gcc/config/bfin/bfin-protos.h
+++ b/gcc/config/bfin/bfin-protos.h
@@ -109,7 +109,6 @@ extern char *bfin_asm_long (void);
extern char *bfin_asm_short (void);
extern int log2constp (unsigned HOST_WIDE_INT);
-extern rtx legitimize_address (rtx, rtx, Mmode);
extern bool bfin_legitimate_constant_p (rtx);
extern int hard_regno_mode_ok (int, Mmode);
extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx);
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 63f60e1f60c..17201c652e1 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -1418,22 +1418,6 @@ bfin_return_addr_rtx (int count)
return get_hard_reg_initial_val (Pmode, REG_RETS);
}
-/* Try machine-dependent ways of modifying an illegitimate address X
- to be legitimate. If we find one, return the new, valid address,
- otherwise return NULL_RTX.
-
- 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 is the mode of the memory reference. */
-
-rtx
-legitimize_address (rtx x ATTRIBUTE_UNUSED, rtx oldx ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return NULL_RTX;
-}
-
static rtx
bfin_delegitimize_address (rtx orig_x)
{
diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h
index f7f2cd492eb..d97fe8faaf4 100644
--- a/gcc/config/bfin/bfin.h
+++ b/gcc/config/bfin/bfin.h
@@ -948,25 +948,6 @@ typedef struct {
} while (0);
#endif
-/* 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.
- */
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-do { \
- rtx _q = legitimize_address(X, OLDX, MODE); \
- if (_q) { X = _q; goto WIN; } \
-} while (0)
-
#define HAVE_POST_INCREMENT 1
#define HAVE_POST_DECREMENT 1
#define HAVE_PRE_DECREMENT 1
diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h
index 352be557818..47936d6e73e 100644
--- a/gcc/config/cris/cris.h
+++ b/gcc/config/cris/cris.h
@@ -1189,16 +1189,6 @@ struct cum_args {int regs;};
# define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
#endif
-/* For now, don't do anything. GCC does a good job most often.
-
- Maybe we could do something about gcc:s misbehavior when it
- recalculates frame offsets for local variables, from fp+offs to
- sp+offs. The resulting address expression gets screwed up
- sometimes, but I'm not sure that it may be fixed here, since it is
- already split up in several instructions (Is this still true?).
- FIXME: Check and adjust for gcc-2.9x. */
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) {}
-
/* Fix reloads known to cause suboptimal spilling. */
#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, INDL, WIN) \
do \
diff --git a/gcc/config/frv/frv-protos.h b/gcc/config/frv/frv-protos.h
index 911ed7c9170..c34d02cf96f 100644
--- a/gcc/config/frv/frv-protos.h
+++ b/gcc/config/frv/frv-protos.h
@@ -49,7 +49,6 @@ extern int frv_initial_elimination_offset (int, int);
#ifdef RTX_CODE
extern int frv_legitimate_address_p (enum machine_mode, rtx,
int, int, int);
-extern rtx frv_legitimize_address (rtx, rtx, enum machine_mode);
extern rtx frv_find_base_term (rtx);
#ifdef TREE_CODE
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index 56c99ae7c9f..4e8c1b24cf8 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -303,6 +303,7 @@ static int frv_check_constant_argument (enum insn_code, int, rtx);
static rtx frv_legitimize_target (enum insn_code, rtx);
static rtx frv_legitimize_argument (enum insn_code, int, rtx);
static rtx frv_legitimize_tls_address (rtx, enum tls_model);
+static rtx frv_legitimize_address (rtx, rtx, enum machine_mode);
static rtx frv_expand_set_builtin (enum insn_code, tree, rtx);
static rtx frv_expand_unop_builtin (enum insn_code, tree, rtx);
static rtx frv_expand_binop_builtin (enum insn_code, tree, rtx);
@@ -433,6 +434,9 @@ static bool frv_secondary_reload (bool, rtx, enum reg_class,
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE frv_issue_rate
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS frv_legitimize_address
+
#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL frv_function_ok_for_sibcall
#undef TARGET_CANNOT_FORCE_CONST_MEM
@@ -3661,7 +3665,7 @@ frv_legitimize_address (rtx x,
return frv_legitimize_tls_address (x, model);
}
- return NULL_RTX;
+ return x;
}
/* Test whether a local function descriptor is canonical, i.e.,
diff --git a/gcc/config/frv/frv.h b/gcc/config/frv/frv.h
index abe275f444b..b6fdca4aa0a 100644
--- a/gcc/config/frv/frv.h
+++ b/gcc/config/frv/frv.h
@@ -2120,16 +2120,6 @@ __asm__("\n" \
will reload one or both registers only if neither labeling works. */
#define REG_OK_FOR_INDEX_P(X) REG_OK_FOR_BASE_P (X)
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-do { \
- rtx new_x = frv_legitimize_address (X, OLDX, MODE); \
- if (new_x) \
- { \
- (X) = new_x; \
- goto WIN; \
- } \
-} while (0)
-
#define FIND_BASE_TERM frv_find_base_term
/* A C expression that is nonzero if X is a legitimate constant for an
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 5d92ec79f60..badea0d4335 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -57,7 +57,6 @@ extern bool constant_address_p (rtx);
extern bool legitimate_pic_operand_p (rtx);
extern int legitimate_pic_address_disp_p (rtx);
extern int legitimate_address_p (enum machine_mode, rtx, int);
-extern rtx legitimize_address (rtx, rtx, enum machine_mode);
extern void print_reg (rtx, int, FILE*);
extern void print_operand (FILE*, rtx, int);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5e7689b837d..b0974ff912f 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -9767,7 +9767,7 @@ get_thread_pointer (int to_reg)
return reg;
}
-/* A subroutine of legitimize_address and ix86_expand_move. FOR_MOV is
+/* A subroutine of ix86_legitimize_address and ix86_expand_move. FOR_MOV is
false if we expect this to be used for a memory address and true if
we expect to load the address into a register. */
@@ -10025,8 +10025,9 @@ legitimize_dllimport_symbol (rtx symbol, bool want_reg)
When -fpic is used, special handling is needed for symbolic references.
See comments by legitimize_pic_address in i386.c for details. */
-rtx
-legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
+static rtx
+ix86_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
{
int changed = 0;
unsigned log;
@@ -30044,6 +30045,9 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY ix86_return_in_memory
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS ix86_legitimize_address
+
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE ix86_attribute_table
#if TARGET_DLLIMPORT_DECL_ATTRIBUTES
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b3972a3f7c2..4aafd9c92fe 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1850,34 +1850,6 @@ do { \
#define FIND_BASE_TERM(X) ix86_find_base_term (X)
-/* 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.
-
- For the 80386, we handle X+REG by loading X into a register R and
- using R+REG. R will go in a general reg and indexing will be used.
- However, if REG is a broken-out memory address or multiplication,
- nothing needs to be done because REG can certainly go in a general reg.
-
- When -fpic is used, special handling is needed for symbolic references.
- See comments by legitimize_pic_address in i386.c for details. */
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-do { \
- (X) = legitimize_address ((X), (OLDX), (MODE)); \
- if (memory_address_p ((MODE), (X))) \
- goto WIN; \
-} while (0)
-
/* Nonzero if the constant value X is a legitimate general operand
when generating PIC code. It is given that flag_pic is on and
that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c
index d853b1fbfc6..3b9e1166b27 100644
--- a/gcc/config/iq2000/iq2000.c
+++ b/gcc/config/iq2000/iq2000.c
@@ -165,6 +165,7 @@ static void iq2000_setup_incoming_varargs (CUMULATIVE_ARGS *,
static bool iq2000_rtx_costs (rtx, int, int, int *, bool);
static int iq2000_address_cost (rtx, bool);
static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT);
+static rtx iq2000_legitimize_address (rtx, rtx, enum machine_mode);
static bool iq2000_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
static int iq2000_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
@@ -186,6 +187,9 @@ static void iq2000_va_start (tree, rtx);
#undef TARGET_ASM_SELECT_SECTION
#define TARGET_ASM_SELECT_SECTION iq2000_select_section
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS iq2000_legitimize_address
+
/* The assembler supports switchable .bss sections, but
iq2000_select_section doesn't yet make use of them. */
#undef TARGET_HAVE_SWITCHABLE_BSS_SECTIONS
@@ -3214,6 +3218,73 @@ print_operand (FILE *file, rtx op, int letter)
output_addr_const (file, op);
}
+
+/* For the IQ2000, transform:
+
+ memory(X + <large int>)
+ into:
+ Y = <large int> & ~0x7fff;
+ Z = X + Y
+ memory (Z + (<large int> & 0x7fff));
+*/
+
+rtx
+iq2000_legitimize_address (rtx xinsn, rtx old_x ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
+{
+ if (TARGET_DEBUG_B_MODE)
+ {
+ GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n");
+ GO_DEBUG_RTX (xinsn);
+ }
+
+ if (iq2000_check_split (xinsn, mode))
+ {
+ return gen_rtx_LO_SUM (Pmode,
+ copy_to_mode_reg (Pmode,
+ gen_rtx_HIGH (Pmode, xinsn)),
+ xinsn);
+ }
+
+ if (GET_CODE (xinsn) == PLUS)
+ {
+ rtx xplus0 = XEXP (xinsn, 0);
+ rtx xplus1 = XEXP (xinsn, 1);
+ enum rtx_code code0 = GET_CODE (xplus0);
+ enum rtx_code code1 = GET_CODE (xplus1);
+
+ if (code0 != REG && code1 == REG)
+ {
+ xplus0 = XEXP (xinsn, 1);
+ xplus1 = XEXP (xinsn, 0);
+ code0 = GET_CODE (xplus0);
+ code1 = GET_CODE (xplus1);
+ }
+
+ if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, mode)
+ && code1 == CONST_INT && !SMALL_INT (xplus1))
+ {
+ rtx int_reg = gen_reg_rtx (Pmode);
+ rtx ptr_reg = gen_reg_rtx (Pmode);
+
+ emit_move_insn (int_reg,
+ GEN_INT (INTVAL (xplus1) & ~ 0x7fff));
+
+ emit_insn (gen_rtx_SET (VOIDmode,
+ ptr_reg,
+ gen_rtx_PLUS (Pmode, xplus0, int_reg)));
+
+ return plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff);
+ }
+ }
+
+ if (TARGET_DEBUG_B_MODE)
+ GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n");
+
+ return xinsn;
+}
+
+
static bool
iq2000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int * total,
bool speed ATTRIBUTE_UNUSED)
diff --git a/gcc/config/iq2000/iq2000.h b/gcc/config/iq2000/iq2000.h
index acbe569503f..30642b2a13f 100644
--- a/gcc/config/iq2000/iq2000.h
+++ b/gcc/config/iq2000/iq2000.h
@@ -544,72 +544,6 @@ typedef struct iq2000_args
#define REG_OK_FOR_INDEX_P(X) 0
-
-/* For the IQ2000, transform:
-
- memory(X + <large int>)
- into:
- Y = <large int> & ~0x7fff;
- Z = X + Y
- memory (Z + (<large int> & 0x7fff));
-*/
-
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ \
- rtx xinsn = (X); \
- \
- if (TARGET_DEBUG_B_MODE) \
- { \
- GO_PRINTF ("\n========== LEGITIMIZE_ADDRESS\n"); \
- GO_DEBUG_RTX (xinsn); \
- } \
- \
- if (iq2000_check_split (X, MODE)) \
- { \
- X = gen_rtx_LO_SUM (Pmode, \
- copy_to_mode_reg (Pmode, \
- gen_rtx_HIGH (Pmode, X)), \
- X); \
- goto WIN; \
- } \
- \
- if (GET_CODE (xinsn) == PLUS) \
- { \
- rtx xplus0 = XEXP (xinsn, 0); \
- rtx xplus1 = XEXP (xinsn, 1); \
- enum rtx_code code0 = GET_CODE (xplus0); \
- enum rtx_code code1 = GET_CODE (xplus1); \
- \
- if (code0 != REG && code1 == REG) \
- { \
- xplus0 = XEXP (xinsn, 1); \
- xplus1 = XEXP (xinsn, 0); \
- code0 = GET_CODE (xplus0); \
- code1 = GET_CODE (xplus1); \
- } \
- \
- if (code0 == REG && REG_MODE_OK_FOR_BASE_P (xplus0, MODE) \
- && code1 == CONST_INT && !SMALL_INT (xplus1)) \
- { \
- rtx int_reg = gen_reg_rtx (Pmode); \
- rtx ptr_reg = gen_reg_rtx (Pmode); \
- \
- emit_move_insn (int_reg, \
- GEN_INT (INTVAL (xplus1) & ~ 0x7fff)); \
- \
- emit_insn (gen_rtx_SET (VOIDmode, \
- ptr_reg, \
- gen_rtx_PLUS (Pmode, xplus0, int_reg))); \
- \
- X = plus_constant (ptr_reg, INTVAL (xplus1) & 0x7fff); \
- goto WIN; \
- } \
- } \
- \
- if (TARGET_DEBUG_B_MODE) \
- GO_PRINTF ("LEGITIMIZE_ADDRESS could not fix.\n"); \
-}
-
#define LEGITIMATE_CONSTANT_P(X) (1)
diff --git a/gcc/config/m32c/m32c-protos.h b/gcc/config/m32c/m32c-protos.h
index ec98d81f93c..650c918b44a 100644
--- a/gcc/config/m32c/m32c-protos.h
+++ b/gcc/config/m32c/m32c-protos.h
@@ -79,7 +79,6 @@ rtx m32c_incoming_return_addr_rtx (void);
void m32c_initialize_trampoline (rtx, rtx, rtx);
int m32c_legitimate_address_p (MM, rtx, int);
int m32c_legitimate_constant_p (rtx);
-int m32c_legitimize_address (rtx *, rtx, MM);
int m32c_legitimize_reload_address (rtx *, MM, int, int, int);
rtx m32c_libcall_value (MM);
int m32c_limit_reload_class (MM, int);
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index bd33934dbed..6d386e3d8fd 100644
--- a/gcc/config/m32c/m32c.c
+++ b/gcc/config/m32c/m32c.c
@@ -1938,33 +1938,33 @@ m32c_reg_ok_for_base_p (rtx x, int strict)
displacement range. We deal with this by attempting to reload $fb
itself into an address register; that seems to result in the best
code. */
-int
-m32c_legitimize_address (rtx * x ATTRIBUTE_UNUSED,
- rtx oldx ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED)
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS m32c_legitimize_address
+static rtx
+m32c_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
{
#if DEBUG0
fprintf (stderr, "m32c_legitimize_address for mode %s\n", mode_name[mode]);
- debug_rtx (*x);
+ debug_rtx (x);
fprintf (stderr, "\n");
#endif
- if (GET_CODE (*x) == PLUS
- && GET_CODE (XEXP (*x, 0)) == REG
- && REGNO (XEXP (*x, 0)) == FB_REGNO
- && GET_CODE (XEXP (*x, 1)) == CONST_INT
- && (INTVAL (XEXP (*x, 1)) < -128
- || INTVAL (XEXP (*x, 1)) > (128 - GET_MODE_SIZE (mode))))
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 0)) == REG
+ && REGNO (XEXP (x, 0)) == FB_REGNO
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && (INTVAL (XEXP (x, 1)) < -128
+ || INTVAL (XEXP (x, 1)) > (128 - GET_MODE_SIZE (mode))))
{
/* reload FB to A_REGS */
rtx temp = gen_reg_rtx (Pmode);
- *x = copy_rtx (*x);
- emit_insn (gen_rtx_SET (VOIDmode, temp, XEXP (*x, 0)));
- XEXP (*x, 0) = temp;
- return 1;
+ x = copy_rtx (x);
+ emit_insn (gen_rtx_SET (VOIDmode, temp, XEXP (x, 0)));
+ XEXP (x, 0) = temp;
}
- return 0;
+ return x;
}
/* Implements LEGITIMIZE_RELOAD_ADDRESS. See comment above. */
diff --git a/gcc/config/m32c/m32c.h b/gcc/config/m32c/m32c.h
index 9e0c921f2ce..cb2b8bea1f0 100644
--- a/gcc/config/m32c/m32c.h
+++ b/gcc/config/m32c/m32c.h
@@ -587,10 +587,6 @@ typedef struct m32c_cumulative_args
/* #define FIND_BASE_TERM(X) when we do unspecs for symrefs */
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
- if (m32c_legitimize_address(&(X),OLDX,MODE)) \
- goto WIN;
-
#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN) \
if (m32c_legitimize_reload_address(&(X),MODE,OPNUM,TYPE,IND_LEVELS)) \
goto WIN;
diff --git a/gcc/config/m32r/m32r.c b/gcc/config/m32r/m32r.c
index ff537382789..656c0eae1be 100644
--- a/gcc/config/m32r/m32r.c
+++ b/gcc/config/m32r/m32r.c
@@ -70,6 +70,7 @@ static void init_reg_tables (void);
static void block_move_call (rtx, rtx, rtx);
static int m32r_is_insn (rtx);
const struct attribute_spec m32r_attribute_table[];
+static rtx m32r_legitimize_address (rtx, rtx, enum machine_mode);
static tree m32r_handle_model_attribute (tree *, tree, tree, int, bool *);
static void m32r_output_function_prologue (FILE *, HOST_WIDE_INT);
static void m32r_output_function_epilogue (FILE *, HOST_WIDE_INT);
@@ -95,6 +96,9 @@ static int m32r_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE m32r_attribute_table
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS m32r_legitimize_address
+
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
#undef TARGET_ASM_ALIGNED_SI_OP
@@ -1728,6 +1732,16 @@ m32r_legitimize_pic_address (rtx orig, rtx reg)
return orig;
}
+
+static rtx
+m32r_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ if (flag_pic)
+ return m32r_legitimize_pic_address (x, NULL_RTX);
+ else
+ return x;
+}
/* Nested function support. */
diff --git a/gcc/config/m32r/m32r.h b/gcc/config/m32r/m32r.h
index f2f7e891201..9bc0fa98a0a 100644
--- a/gcc/config/m32r/m32r.h
+++ b/gcc/config/m32r/m32r.h
@@ -1169,29 +1169,6 @@ L2: .word STATIC
} \
while (0)
-/* 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. */
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- do \
- { \
- if (flag_pic) \
- (X) = m32r_legitimize_pic_address (X, NULL_RTX); \
- if (memory_address_p (MODE, X)) \
- goto 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. */
#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
diff --git a/gcc/config/m68hc11/m68hc11-protos.h b/gcc/config/m68hc11/m68hc11-protos.h
index 1e9cf585904..5412e1d3eea 100644
--- a/gcc/config/m68hc11/m68hc11-protos.h
+++ b/gcc/config/m68hc11/m68hc11-protos.h
@@ -50,8 +50,6 @@ extern enum reg_class preferred_reload_class (rtx, enum reg_class);
extern int m68hc11_go_if_legitimate_address (rtx, enum machine_mode, int);
-extern int m68hc11_legitimize_address (rtx*, rtx, enum machine_mode);
-
extern void m68hc11_notice_update_cc (rtx, rtx);
extern void m68hc11_notice_keep_cc (rtx);
diff --git a/gcc/config/m68hc11/m68hc11.c b/gcc/config/m68hc11/m68hc11.c
index 4fba4a39a1c..5050fa46415 100644
--- a/gcc/config/m68hc11/m68hc11.c
+++ b/gcc/config/m68hc11/m68hc11.c
@@ -789,14 +789,6 @@ m68hc11_go_if_legitimate_address (rtx operand, enum machine_mode mode,
return result;
}
-int
-m68hc11_legitimize_address (rtx *operand ATTRIBUTE_UNUSED,
- rtx old_operand ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED)
-{
- return 0;
-}
-
int
m68hc11_reload_operands (rtx operands[])
diff --git a/gcc/config/m68hc11/m68hc11.h b/gcc/config/m68hc11/m68hc11.h
index 5496640b040..35176592601 100644
--- a/gcc/config/m68hc11/m68hc11.h
+++ b/gcc/config/m68hc11/m68hc11.h
@@ -1205,28 +1205,6 @@ extern unsigned char m68hc11_reg_valid_for_index[FIRST_PSEUDO_REGISTER];
#endif
-/* 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. */
-
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ rtx operand = (X); \
- if (m68hc11_legitimize_address (&operand, (OLDX), (MODE))) \
- { \
- (X) = operand; \
- GO_IF_LEGITIMATE_ADDRESS (MODE,X,WIN); \
- } \
-}
-
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index bccb8348a55..e4bb1e2b4a2 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -143,6 +143,7 @@ static tree m68k_handle_fndecl_attribute (tree *node, tree name,
static void m68k_compute_frame_layout (void);
static bool m68k_save_reg (unsigned int regno, bool interrupt_handler);
static bool m68k_ok_for_sibcall_p (tree, tree);
+static rtx m68k_legitimize_address (rtx, rtx, enum machine_mode);
static bool m68k_rtx_costs (rtx, int, int, int *, bool);
#if M68K_HONOR_TARGET_STRICT_ALIGNMENT
static bool m68k_return_in_memory (const_tree, const_tree);
@@ -195,6 +196,9 @@ int m68k_last_compare_had_fp_operands;
#undef TARGET_ASM_FILE_START_APP_OFF
#define TARGET_ASM_FILE_START_APP_OFF true
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS m68k_legitimize_address
+
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST m68k_sched_adjust_cost
@@ -1422,6 +1426,83 @@ m68k_legitimize_sibcall_address (rtx x)
return replace_equiv_address (x, gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM));
}
+/* Convert X to a legitimate address and return it if successful. Otherwise
+ return X.
+
+ For the 68000, we handle X+REG by loading X into a register R and
+ using R+REG. R will go in an address reg and indexing will be used.
+ However, if REG is a broken-out memory address or multiplication,
+ nothing needs to be done because REG can certainly go in an address reg. */
+
+rtx
+m68k_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
+{
+ if (GET_CODE (x) == PLUS)
+ {
+ int ch = (x) != (oldx);
+ int copied = 0;
+
+#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
+
+ if (GET_CODE (XEXP (x, 0)) == MULT)
+ {
+ COPY_ONCE (x);
+ XEXP (x, 0) = force_operand (XEXP (x, 0), 0);
+ }
+ if (GET_CODE (XEXP (x, 1)) == MULT)
+ {
+ COPY_ONCE (x);
+ XEXP (x, 1) = force_operand (XEXP (x, 1), 0);
+ }
+ if (ch)
+ {
+ if (GET_CODE (XEXP (x, 1)) == REG
+ && GET_CODE (XEXP (x, 0)) == REG)
+ {
+ if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (mode) == MODE_FLOAT)
+ {
+ COPY_ONCE (x);
+ x = force_operand (x, 0);
+ }
+ return x;
+ }
+ if (memory_address_p (mode, x))
+ return x;
+ }
+ if (GET_CODE (XEXP (x, 0)) == REG
+ || (GET_CODE (XEXP (x, 0)) == SIGN_EXTEND
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
+ && GET_MODE (XEXP (XEXP (x, 0), 0)) == HImode))
+ {
+ rtx temp = gen_reg_rtx (Pmode);
+ rtx val = force_operand (XEXP (x, 1), 0);
+ emit_move_insn (temp, val);
+ COPY_ONCE (x);
+ XEXP (x, 1) = temp;
+ if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (mode) == MODE_FLOAT
+ && GET_CODE (XEXP (x, 0)) == REG)
+ x = force_operand (x, 0);
+ }
+ else if (GET_CODE (XEXP (x, 1)) == REG
+ || (GET_CODE (XEXP (x, 1)) == SIGN_EXTEND
+ && GET_CODE (XEXP (XEXP (x, 1), 0)) == REG
+ && GET_MODE (XEXP (XEXP (x, 1), 0)) == HImode))
+ {
+ rtx temp = gen_reg_rtx (Pmode);
+ rtx val = force_operand (XEXP (x, 0), 0);
+ emit_move_insn (temp, val);
+ COPY_ONCE (x);
+ XEXP (x, 0) = temp;
+ if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (mode) == MODE_FLOAT
+ && GET_CODE (XEXP (x, 1)) == REG)
+ x = force_operand (x, 0);
+ }
+ }
+
+ return x;
+}
+
+
/* Output a dbCC; jCC sequence. Note we do not handle the
floating point version of this sequence (Fdbcc). We also
do not handle alternative conditions when CC_NO_OVERFLOW is
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index 11477c61ba9..875667dc428 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -765,56 +765,9 @@ __transfer_from_trampoline () \
} \
while (0)
+
/* This address is OK as it stands. */
#define PIC_CASE_VECTOR_ADDRESS(index) index
-
-/* For the 68000, we handle X+REG by loading X into a register R and
- using R+REG. R will go in an address reg and indexing will be used.
- However, if REG is a broken-out memory address or multiplication,
- nothing needs to be done because REG can certainly go in an address reg. */
-#define COPY_ONCE(Y) if (!copied) { Y = copy_rtx (Y); copied = ch = 1; }
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ register int ch = (X) != (OLDX); \
- if (GET_CODE (X) == PLUS) \
- { int copied = 0; \
- if (GET_CODE (XEXP (X, 0)) == MULT) \
- { COPY_ONCE (X); XEXP (X, 0) = force_operand (XEXP (X, 0), 0);} \
- if (GET_CODE (XEXP (X, 1)) == MULT) \
- { COPY_ONCE (X); XEXP (X, 1) = force_operand (XEXP (X, 1), 0);} \
- if (ch && GET_CODE (XEXP (X, 1)) == REG \
- && GET_CODE (XEXP (X, 0)) == REG) \
- { if (TARGET_COLDFIRE_FPU \
- && GET_MODE_CLASS (MODE) == MODE_FLOAT) \
- { COPY_ONCE (X); X = force_operand (X, 0);} \
- goto WIN; } \
- if (ch) { GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN); } \
- if (GET_CODE (XEXP (X, 0)) == REG \
- || (GET_CODE (XEXP (X, 0)) == SIGN_EXTEND \
- && GET_CODE (XEXP (XEXP (X, 0), 0)) == REG \
- && GET_MODE (XEXP (XEXP (X, 0), 0)) == HImode)) \
- { register rtx temp = gen_reg_rtx (Pmode); \
- register rtx val = force_operand (XEXP (X, 1), 0); \
- emit_move_insn (temp, val); \
- COPY_ONCE (X); \
- XEXP (X, 1) = temp; \
- if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && GET_CODE (XEXP (X, 0)) == REG) \
- X = force_operand (X, 0); \
- goto WIN; } \
- else if (GET_CODE (XEXP (X, 1)) == REG \
- || (GET_CODE (XEXP (X, 1)) == SIGN_EXTEND \
- && GET_CODE (XEXP (XEXP (X, 1), 0)) == REG \
- && GET_MODE (XEXP (XEXP (X, 1), 0)) == HImode)) \
- { register rtx temp = gen_reg_rtx (Pmode); \
- register rtx val = force_operand (XEXP (X, 0), 0); \
- emit_move_insn (temp, val); \
- COPY_ONCE (X); \
- XEXP (X, 0) = temp; \
- if (TARGET_COLDFIRE_FPU && GET_MODE_CLASS (MODE) == MODE_FLOAT \
- && GET_CODE (XEXP (X, 1)) == REG) \
- X = force_operand (X, 0); \
- goto WIN; }}}
-
#define CASE_VECTOR_MODE HImode
#define CASE_VECTOR_PC_RELATIVE 1
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 1f8054ede9c..b95461a4c4f 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -196,7 +196,6 @@ extern rtx mips_pic_base_register (rtx);
extern rtx mips_got_load (rtx, rtx, enum mips_symbol_type);
extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *);
extern rtx mips_unspec_address (rtx, enum mips_symbol_type);
-extern bool mips_legitimize_address (rtx *, enum machine_mode);
extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT);
extern bool mips_legitimize_move (enum machine_mode, rtx, rtx);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index e03e6adb304..b40ba3ba5fe 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -2848,41 +2848,36 @@ mips_force_address (rtx x, enum machine_mode mode)
return x;
}
-/* This function is used to implement LEGITIMIZE_ADDRESS. If *XLOC can
+/* This function is used to implement LEGITIMIZE_ADDRESS. If X can
be legitimized in a way that the generic machinery might not expect,
- put the new address in *XLOC and return true. MODE is the mode of
+ return a new address, otherwise return NULL. MODE is the mode of
the memory being accessed. */
-bool
-mips_legitimize_address (rtx *xloc, enum machine_mode mode)
+static rtx
+mips_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
{
rtx base, addr;
HOST_WIDE_INT offset;
- if (mips_tls_symbol_p (*xloc))
- {
- *xloc = mips_legitimize_tls_address (*xloc);
- return true;
- }
+ if (mips_tls_symbol_p (x))
+ return mips_legitimize_tls_address (x);
/* See if the address can split into a high part and a LO_SUM. */
- if (mips_split_symbol (NULL, *xloc, mode, &addr))
- {
- *xloc = mips_force_address (addr, mode);
- return true;
- }
+ if (mips_split_symbol (NULL, x, mode, &addr))
+ return mips_force_address (addr, mode);
/* Handle BASE + OFFSET using mips_add_offset. */
- mips_split_plus (*xloc, &base, &offset);
+ mips_split_plus (x, &base, &offset);
if (offset != 0)
{
if (!mips_valid_base_register_p (base, mode, false))
base = copy_to_mode_reg (Pmode, base);
addr = mips_add_offset (NULL, base, offset);
- *xloc = mips_force_address (addr, mode);
- return true;
+ return mips_force_address (addr, mode);
}
- return false;
+
+ return x;
}
/* Load VALUE into DEST. TEMP is as for mips_force_temporary. */
@@ -14749,6 +14744,9 @@ mips_final_postscan_insn (FILE *file, rtx insn, rtx *opvec, int noperands)
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP "\t.dword\t"
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS mips_legitimize_address
+
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE mips_output_function_prologue
#undef TARGET_ASM_FUNCTION_EPILOGUE
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index e14073ab2be..5c68688ccce 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2526,13 +2526,6 @@ typedef struct mips_args {
#define LEGITIMATE_CONSTANT_P(X) (mips_const_insns (X) > 0)
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
- do { \
- if (mips_legitimize_address (&(X), MODE)) \
- goto WIN; \
- } while (0)
-
-
/* This handles the magic '..CURRENT_FUNCTION' symbol, which means
'the start of the function that this code is output in'. */
diff --git a/gcc/config/mn10300/mn10300-protos.h b/gcc/config/mn10300/mn10300-protos.h
index d8fe2bd50a1..935cb8f81f6 100644
--- a/gcc/config/mn10300/mn10300-protos.h
+++ b/gcc/config/mn10300/mn10300-protos.h
@@ -21,7 +21,6 @@ along with GCC; see the file COPYING3. If not see
#ifdef RTX_CODE
extern void mn10300_override_options (void);
-extern struct rtx_def *legitimize_address (rtx, rtx, enum machine_mode);
extern rtx legitimize_pic_address (rtx, rtx);
extern int legitimate_pic_operand_p (rtx);
extern bool legitimate_address_p (enum machine_mode, rtx, int);
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c
index 1eb80ec78bb..ceb77e862c2 100644
--- a/gcc/config/mn10300/mn10300.c
+++ b/gcc/config/mn10300/mn10300.c
@@ -76,6 +76,7 @@ static void mn10300_file_start (void);
static bool mn10300_return_in_memory (const_tree, const_tree);
static rtx mn10300_builtin_saveregs (void);
static void mn10300_va_start (tree, rtx);
+static rtx mn10300_legitimize_address (rtx, rtx, enum machine_mode);
static bool mn10300_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
const_tree, bool);
static int mn10300_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
@@ -86,6 +87,9 @@ static unsigned int mn10300_case_values_threshold (void);
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS mn10300_legitimize_address
+
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS mn10300_rtx_costs
#undef TARGET_ADDRESS_COST
@@ -1795,8 +1799,8 @@ symbolic_operand (register rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
But on a few ports with segmented architectures and indexed addressing
(mn10300, hppa) it is used to rewrite certain problematical addresses. */
rtx
-legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED)
+mn10300_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (flag_pic && ! legitimate_pic_operand_p (x))
x = legitimize_pic_address (oldx, NULL_RTX);
diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h
index 2737d15345c..b35894435a2 100644
--- a/gcc/config/mn10300/mn10300.h
+++ b/gcc/config/mn10300/mn10300.h
@@ -693,24 +693,6 @@ do \
while (0)
-/* 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. */
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ rtx orig_x = (X); \
- (X) = legitimize_address (X, OLDX, MODE); \
- if ((X) != orig_x && memory_address_p (MODE, X)) \
- goto WIN; }
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
diff --git a/gcc/config/pa/pa-protos.h b/gcc/config/pa/pa-protos.h
index 7fc9dcad40f..3cd1f8580bc 100644
--- a/gcc/config/pa/pa-protos.h
+++ b/gcc/config/pa/pa-protos.h
@@ -29,8 +29,6 @@ extern int following_call (rtx);
extern int function_label_operand (rtx, enum machine_mode);
extern int lhs_lshift_cint_operand (rtx, enum machine_mode);
-extern rtx hppa_legitimize_address (rtx, rtx, enum machine_mode);
-
/* Define functions in pa.c and used in insn-output.c. */
extern const char *output_and (rtx *);
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index 08c987fbedf..80f5fe90bc2 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -131,6 +131,7 @@ static bool pa_scalar_mode_supported_p (enum machine_mode);
static bool pa_commutative_p (const_rtx x, int outer_code);
static void copy_fp_args (rtx) ATTRIBUTE_UNUSED;
static int length_fp_args (rtx) ATTRIBUTE_UNUSED;
+static rtx hppa_legitimize_address (rtx, rtx, enum machine_mode);
static inline void pa_file_start_level (void) ATTRIBUTE_UNUSED;
static inline void pa_file_start_space (int) ATTRIBUTE_UNUSED;
static inline void pa_file_start_file (int) ATTRIBUTE_UNUSED;
@@ -228,6 +229,9 @@ static size_t n_deferred_plabels = 0;
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE pa_output_function_epilogue
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS hppa_legitimize_address
+
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST pa_adjust_cost
#undef TARGET_SCHED_ADJUST_PRIORITY
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index ee890935b30..303bdd341df 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1421,26 +1421,6 @@ do { \
} while (0)
-
-
-/* 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. */
-
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ rtx orig_x = (X); \
- (X) = hppa_legitimize_address (X, OLDX, MODE); \
- if ((X) != orig_x && memory_address_p (MODE, X)) \
- goto WIN; }
#define TARGET_ASM_SELECT_SECTION pa_select_section
diff --git a/gcc/config/picochip/picochip.h b/gcc/config/picochip/picochip.h
index 497c1307839..7c32ebeec42 100644
--- a/gcc/config/picochip/picochip.h
+++ b/gcc/config/picochip/picochip.h
@@ -504,10 +504,6 @@ extern const enum reg_class picochip_regno_reg_class[FIRST_PSEUDO_REGISTER];
#endif /* !REG_OK_STRICT */
-/* extern struct rtx_def *picochip_legitimize_address */
-/* PARAMS ((struct rtx_def *, struct rtx_def *, int)); */
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN);
-
/* Legitimize reload address tries machine dependent means of
reloading addresses. There seems to be a strange error in gcc,
which necessitates this macro. Consider:
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index c898d51e3a3..4b8f5220a51 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -107,7 +107,6 @@ extern rtx create_TOC_reference (rtx);
extern void rs6000_split_multireg_move (rtx, rtx);
extern void rs6000_emit_move (rtx, rtx, enum machine_mode);
extern rtx rs6000_secondary_memory_needed_rtx (enum machine_mode);
-extern rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
extern rtx rs6000_legitimize_reload_address (rtx, enum machine_mode,
int, int, int, int *);
extern int rs6000_legitimate_address (enum machine_mode, rtx, int);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 00cf3bdcd2f..b6bc88b0a69 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -917,6 +917,7 @@ static rtx generate_set_vrsave (rtx, rs6000_stack_t *, int);
int easy_vector_constant (rtx, enum machine_mode);
static rtx rs6000_dwarf_register_span (rtx);
static void rs6000_init_dwarf_reg_sizes_extra (tree);
+static rtx rs6000_legitimize_address (rtx, rtx, enum machine_mode);
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
static rtx rs6000_tls_get_addr (void);
@@ -1103,6 +1104,9 @@ static const char alt_reg_names[][8] =
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE rs6000_output_function_epilogue
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS rs6000_legitimize_address
+
#undef TARGET_SCHED_VARIABLE_ISSUE
#define TARGET_SCHED_VARIABLE_ISSUE rs6000_variable_issue
@@ -3873,7 +3877,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|| mode == DImode)))
{
if (mode == DImode)
- return NULL_RTX;
+ return x;
/* We accept [reg + reg] and [reg + OFFSET]. */
if (GET_CODE (x) == PLUS)
@@ -3945,7 +3949,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
return create_TOC_reference (x);
}
else
- return NULL_RTX;
+ return x;
}
/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 5feae4d0db9..f11ea1fe249 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1812,38 +1812,6 @@ typedef struct rs6000_args
goto ADDR; \
}
-/* 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 RS/6000, first check for the sum of a register with a constant
- integer that is out of range. If so, generate code to add the
- constant with the low-order 16 bits masked to the register and force
- this result into another register (this can be done with `cau').
- Then generate an address of REG+(CONST&0xffff), allowing for the
- possibility of bit 16 being a one.
-
- Then check for the sum of a register and something not constant, try to
- load the other things into a register and return the sum. */
-
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ rtx result = rs6000_legitimize_address (X, OLDX, MODE); \
- if (result != NULL_RTX) \
- { \
- (X) = result; \
- goto WIN; \
- } \
-}
-
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c.
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 76f73f9dd2c..3bde1c14b48 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -74,7 +74,6 @@ extern int legitimate_constant_p (rtx);
extern bool legitimate_reload_constant_p (rtx);
extern bool legitimate_address_p (enum machine_mode, rtx, int);
extern rtx legitimize_pic_address (rtx, rtx);
-extern rtx legitimize_address (rtx, rtx, enum machine_mode);
extern rtx legitimize_reload_address (rtx, enum machine_mode, int, int);
extern enum reg_class s390_preferred_reload_class (rtx, enum reg_class);
extern enum reg_class s390_secondary_input_reload_class (enum reg_class,
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 61471bb41ba..e2ed4a0d407 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -3734,9 +3734,9 @@ emit_symbolic_move (rtx *operands)
When -fpic is used, special handling is needed for symbolic references.
See comments by legitimize_pic_address for details. */
-rtx
-legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED)
+static rtx
+s390_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx constant_term = const0_rtx;
@@ -9909,6 +9909,9 @@ s390_reorg (void)
#undef TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS s390_delegitimize_address
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS s390_legitimize_address
+
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY s390_return_in_memory
diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h
index c62f6bfa621..2b4d7ce72ca 100644
--- a/gcc/config/s390/s390.h
+++ b/gcc/config/s390/s390.h
@@ -764,16 +764,6 @@ used in insn definitions or inline assemblies. */
}
#endif
-/* 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. */
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ \
- (X) = legitimize_address (X, OLDX, MODE); \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-}
-
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c. */
diff --git a/gcc/config/score/score-protos.h b/gcc/config/score/score-protos.h
index 56cdce7ae3e..d6739b8cf4c 100644
--- a/gcc/config/score/score-protos.h
+++ b/gcc/config/score/score-protos.h
@@ -72,7 +72,6 @@ extern enum reg_class score_preferred_reload_class (rtx x,
extern HOST_WIDE_INT score_initial_elimination_offset (int from, int to);
extern void score_print_operand (FILE *file, rtx op, int letter);
extern void score_print_operand_address (FILE *file, rtx addr);
-extern int score_legitimize_address (rtx *xloc);
extern int score_arg_partial_bytes (CUMULATIVE_ARGS *cum,
enum machine_mode mode,
tree type, bool named);
diff --git a/gcc/config/score/score.c b/gcc/config/score/score.c
index e0887647708..2ac3021bf5e 100644
--- a/gcc/config/score/score.c
+++ b/gcc/config/score/score.c
@@ -68,6 +68,9 @@
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION score_handle_option
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS score_legitimize_address
+
#undef TARGET_SCHED_ISSUE_RATE
#define TARGET_SCHED_ISSUE_RATE score_issue_rate
@@ -540,16 +543,17 @@ score_address_p (enum machine_mode mode, rtx x, int strict)
gcc_unreachable ();
}
-/* This function is used to implement LEGITIMIZE_ADDRESS. If *XLOC can
+/* This function is used to implement LEGITIMIZE_ADDRESS. If X can
be legitimized in a way that the generic machinery might not expect,
- put the new address in *XLOC and return true. */
-int
-score_legitimize_address (rtx *xloc)
+ return the new address, else return X. */
+static rtx
+score_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
if (TARGET_SCORE5 || TARGET_SCORE5U || TARGET_SCORE7 || TARGET_SCORE7D)
- return score7_legitimize_address (xloc);
+ return score7_legitimize_address (x);
else if (TARGET_SCORE3)
- return score3_legitimize_address (xloc);
+ return score3_legitimize_address (x);
gcc_unreachable ();
}
diff --git a/gcc/config/score/score.h b/gcc/config/score/score.h
index d2dd7405feb..d9fe8e65625 100644
--- a/gcc/config/score/score.h
+++ b/gcc/config/score/score.h
@@ -778,12 +778,6 @@ typedef struct score_args
#define REG_OK_FOR_INDEX_P(X) 0
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- do { \
- if (score_legitimize_address (&(X))) \
- goto WIN; \
- } while (0)
-
#define LEGITIMATE_CONSTANT_P(X) 1
/* Condition Code Status. */
diff --git a/gcc/config/score/score3.c b/gcc/config/score/score3.c
index 655ee4507a0..9e41452c03d 100644
--- a/gcc/config/score/score3.c
+++ b/gcc/config/score/score3.c
@@ -414,31 +414,28 @@ score3_split_symbol (rtx temp, rtx addr)
return gen_rtx_LO_SUM (Pmode, high, addr);
}
-/* This function is used to implement LEGITIMIZE_ADDRESS. If *XLOC can
+/* This function is used to implement LEGITIMIZE_ADDRESS. If X can
be legitimized in a way that the generic machinery might not expect,
- put the new address in *XLOC and return true. */
-int
-score3_legitimize_address (rtx *xloc)
+ return the new address. */
+rtx
+score3_legitimize_address (rtx x)
{
enum score_symbol_type symbol_type;
- if (score3_symbolic_constant_p (*xloc, &symbol_type)
+ if (score3_symbolic_constant_p (x, &symbol_type)
&& symbol_type == SYMBOL_GENERAL)
- {
- *xloc = score3_split_symbol (0, *xloc);
- return 1;
- }
+ return score3_split_symbol (0, x);
- if (GET_CODE (*xloc) == PLUS
- && GET_CODE (XEXP (*xloc, 1)) == CONST_INT)
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
{
- rtx reg = XEXP (*xloc, 0);
+ rtx reg = XEXP (x, 0);
if (!score3_valid_base_register_p (reg, 0))
reg = copy_to_mode_reg (Pmode, reg);
- *xloc = score3_add_offset (reg, INTVAL (XEXP (*xloc, 1)));
- return 1;
+ return score3_add_offset (reg, INTVAL (XEXP (x, 1)));
}
- return 0;
+
+ return x;
}
/* Fill INFO with information about a single argument. CUM is the
diff --git a/gcc/config/score/score3.h b/gcc/config/score/score3.h
index f3aa0606dd0..c46a8e694d9 100644
--- a/gcc/config/score/score3.h
+++ b/gcc/config/score/score3.h
@@ -78,7 +78,7 @@ extern void score3_output_mi_thunk (FILE *file,
HOST_WIDE_INT delta,
HOST_WIDE_INT vcall_offset,
tree function);
-extern int score3_legitimize_address (rtx *xloc);
+extern rtx score3_legitimize_address (rtx x);
extern void
score3_function_prologue (FILE *file,
HOST_WIDE_INT size ATTRIBUTE_UNUSED);
diff --git a/gcc/config/score/score7.c b/gcc/config/score/score7.c
index 64ab5aadc5f..dc532764edd 100644
--- a/gcc/config/score/score7.c
+++ b/gcc/config/score/score7.c
@@ -413,31 +413,28 @@ score7_split_symbol (rtx temp, rtx addr)
return gen_rtx_LO_SUM (Pmode, high, addr);
}
-/* This function is used to implement LEGITIMIZE_ADDRESS. If *XLOC can
+/* This function is used to implement LEGITIMIZE_ADDRESS. If X can
be legitimized in a way that the generic machinery might not expect,
- put the new address in *XLOC and return true. */
-int
-score7_legitimize_address (rtx *xloc)
+ return the new address. */
+rtx
+score7_legitimize_address (rtx x)
{
enum score_symbol_type symbol_type;
- if (score7_symbolic_constant_p (*xloc, &symbol_type)
+ if (score7_symbolic_constant_p (x, &symbol_type)
&& symbol_type == SYMBOL_GENERAL)
- {
- *xloc = score7_split_symbol (0, *xloc);
- return 1;
- }
+ return score7_split_symbol (0, x);
- if (GET_CODE (*xloc) == PLUS
- && GET_CODE (XEXP (*xloc, 1)) == CONST_INT)
+ if (GET_CODE (x) == PLUS
+ && GET_CODE (XEXP (x, 1)) == CONST_INT)
{
- rtx reg = XEXP (*xloc, 0);
+ rtx reg = XEXP (x, 0);
if (!score7_valid_base_register_p (reg, 0))
reg = copy_to_mode_reg (Pmode, reg);
- *xloc = score7_add_offset (reg, INTVAL (XEXP (*xloc, 1)));
- return 1;
+ return score7_add_offset (reg, INTVAL (XEXP (x, 1)));
}
- return 0;
+
+ return x;
}
/* Fill INFO with information about a single argument. CUM is the
diff --git a/gcc/config/score/score7.h b/gcc/config/score/score7.h
index 473cc12a9a5..e2033c74498 100644
--- a/gcc/config/score/score7.h
+++ b/gcc/config/score/score7.h
@@ -78,7 +78,7 @@ extern void score7_output_mi_thunk (FILE *file,
HOST_WIDE_INT delta,
HOST_WIDE_INT vcall_offset,
tree function);
-extern int score7_legitimize_address (rtx *xloc);
+extern rtx score7_legitimize_address (rtx x);
extern void
score7_function_prologue (FILE *file,
HOST_WIDE_INT size ATTRIBUTE_UNUSED);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index f8a046b81e5..9834d62d13b 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -245,6 +245,7 @@ static bool sh_rtx_costs (rtx, int, int, int *, bool);
static int sh_address_cost (rtx, bool);
static int sh_pr_n_sets (void);
static rtx sh_allocate_initial_value (rtx);
+static rtx sh_legitimize_address (rtx, rtx, enum machine_mode);
static int shmedia_target_regs_stack_space (HARD_REG_SET *);
static int shmedia_reserve_space_for_target_registers_p (int, HARD_REG_SET *);
static int shmedia_target_regs_stack_adjust (HARD_REG_SET *);
@@ -374,6 +375,9 @@ static int sh2a_function_vector_p (tree);
#undef TARGET_SCHED_INIT
#define TARGET_SCHED_INIT sh_md_init
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS sh_legitimize_address
+
#undef TARGET_CANNOT_MODIFY_JUMPS_P
#define TARGET_CANNOT_MODIFY_JUMPS_P sh_cannot_modify_jumps_p
#undef TARGET_BRANCH_TARGET_REGISTER_CLASS
@@ -8868,6 +8872,60 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
return orig;
}
+/* Try machine-dependent ways of modifying an illegitimate address
+ to be legitimate. If we find one, return the new, valid address.
+ Otherwise, return X.
+
+ For the SH, if X is almost suitable for indexing, but the offset is
+ out of range, convert it into a normal form so that CSE has a chance
+ of reducing the number of address registers used. */
+
+static rtx
+sh_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
+{
+ if (flag_pic)
+ x = legitimize_pic_address (oldx, mode, NULL_RTX);
+
+ if (GET_CODE (x) == PLUS
+ && (GET_MODE_SIZE (mode) == 4
+ || GET_MODE_SIZE (mode) == 8)
+ && GET_CODE (XEXP (x, 1)) == CONST_INT
+ && BASE_REGISTER_RTX_P (XEXP (x, 0))
+ && ! TARGET_SHMEDIA
+ && ! ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && mode == DFmode)
+ && ! (TARGET_SH2E && mode == SFmode))
+ {
+ rtx index_rtx = XEXP (x, 1);
+ HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
+ rtx sum;
+
+ /* On rare occasions, we might get an unaligned pointer
+ that is indexed in a way to give an aligned address.
+ Therefore, keep the lower two bits in offset_base. */
+ /* Instead of offset_base 128..131 use 124..127, so that
+ simple add suffices. */
+ if (offset > 127)
+ offset_base = ((offset + 4) & ~60) - 4;
+ else
+ offset_base = offset & ~60;
+
+ /* Sometimes the normal form does not suit DImode. We
+ could avoid that by using smaller ranges, but that
+ would give less optimized code when SImode is
+ prevalent. */
+ if (GET_MODE_SIZE (mode) + offset - offset_base <= 64)
+ {
+ sum = expand_binop (Pmode, add_optab, XEXP (x, 0),
+ GEN_INT (offset_base), NULL_RTX, 0,
+ OPTAB_LIB_WIDEN);
+
+ return gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
+ }
+ }
+
+ return x;
+}
+
/* Mark the use of a constant in the literal table. If the constant
has multiple labels, make it unique. */
static rtx
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 5f5006f7ff4..71e202a87dd 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -2444,68 +2444,6 @@ struct sh_args {
} \
}
-/* 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.
-
- For the SH, if X is almost suitable for indexing, but the offset is
- out of range, convert it into a normal form so that cse has a chance
- of reducing the number of address registers used. */
-
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ \
- if (flag_pic) \
- (X) = legitimize_pic_address (OLDX, MODE, NULL_RTX); \
- if (GET_CODE (X) == PLUS \
- && (GET_MODE_SIZE (MODE) == 4 \
- || GET_MODE_SIZE (MODE) == 8) \
- && GET_CODE (XEXP ((X), 1)) == CONST_INT \
- && BASE_REGISTER_RTX_P (XEXP ((X), 0)) \
- && ! TARGET_SHMEDIA \
- && ! ((TARGET_SH4 || TARGET_SH2A_DOUBLE) && (MODE) == DFmode) \
- && ! (TARGET_SH2E && (MODE) == SFmode)) \
- { \
- rtx index_rtx = XEXP ((X), 1); \
- HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base; \
- rtx sum; \
- \
- GO_IF_LEGITIMATE_INDEX ((MODE), index_rtx, WIN); \
- /* On rare occasions, we might get an unaligned pointer \
- that is indexed in a way to give an aligned address. \
- Therefore, keep the lower two bits in offset_base. */ \
- /* Instead of offset_base 128..131 use 124..127, so that \
- simple add suffices. */ \
- if (offset > 127) \
- { \
- offset_base = ((offset + 4) & ~60) - 4; \
- } \
- else \
- offset_base = offset & ~60; \
- /* Sometimes the normal form does not suit DImode. We \
- could avoid that by using smaller ranges, but that \
- would give less optimized code when SImode is \
- prevalent. */ \
- if (GET_MODE_SIZE (MODE) + offset - offset_base <= 64) \
- { \
- sum = expand_binop (Pmode, add_optab, XEXP ((X), 0), \
- GEN_INT (offset_base), NULL_RTX, 0, \
- OPTAB_LIB_WIDEN); \
- \
- (X) = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base)); \
- goto WIN; \
- } \
- } \
-}
-
/* A C compound statement that attempts to replace X, which is an address
that needs reloading, with a valid memory address for an operand of
mode MODE. WIN is a C statement label elsewhere in the code.
diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h
index 35ee06f43aa..40ac75e130c 100644
--- a/gcc/config/sparc/sparc-protos.h
+++ b/gcc/config/sparc/sparc-protos.h
@@ -72,7 +72,6 @@ extern bool legitimate_pic_operand_p (rtx);
extern int legitimate_address_p (enum machine_mode, rtx, int);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
extern rtx legitimize_tls_address (rtx);
-extern rtx legitimize_address (rtx, rtx, enum machine_mode);
extern void sparc_emit_call_insn (rtx, rtx);
extern void sparc_defer_case_vector (rtx, rtx, int);
extern bool sparc_expand_move (enum machine_mode, rtx *);
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 60067b5dfdd..ab2b57bbcd9 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -412,6 +412,7 @@ static bool sparc_strict_argument_naming (CUMULATIVE_ARGS *);
static void sparc_va_start (tree, rtx);
static tree sparc_gimplify_va_arg (tree, tree, gimple_seq *, gimple_seq *);
static bool sparc_vector_mode_supported_p (enum machine_mode);
+static rtx sparc_legitimize_address (rtx, rtx, enum machine_mode);
static bool sparc_pass_by_reference (CUMULATIVE_ARGS *,
enum machine_mode, const_tree, bool);
static int sparc_arg_partial_bytes (CUMULATIVE_ARGS *,
@@ -492,6 +493,9 @@ static bool fpu_option_set = false;
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS sparc_init_builtins
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS sparc_legitimize_address
+
#undef TARGET_EXPAND_BUILTIN
#define TARGET_EXPAND_BUILTIN sparc_expand_builtin
#undef TARGET_FOLD_BUILTIN
@@ -3370,10 +3374,13 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
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 is the mode of the operand pointed to by X. */
+ MODE is the mode of the operand pointed to by X.
+
+ On SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */
rtx
-legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, enum machine_mode mode)
+sparc_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
{
rtx orig_x = x;
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index c0667700cd4..d21900135e2 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -1923,27 +1923,6 @@ do { \
} \
}
-/* 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 SPARC, change REG+N into REG+REG, and REG+(X*Y) into REG+REG. */
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
-{ \
- (X) = legitimize_address (X, OLDX, MODE); \
- if (memory_address_p (MODE, X)) \
- goto WIN; \
-}
-
/* Try a machine-dependent way of reloading an illegitimate address
operand. If we find one, push the reload and jump to WIN. This
macro is used in only one place: `find_reloads_address' in reload.c.
diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h
index d8376d86d0f..06e02ba0b48 100644
--- a/gcc/config/spu/spu-protos.h
+++ b/gcc/config/spu/spu-protos.h
@@ -57,7 +57,6 @@ extern int spu_constant_address_p (rtx x);
extern int spu_legitimate_constant_p (rtx x);
extern int spu_legitimate_address (enum machine_mode mode, rtx x,
int reg_ok_strict);
-extern rtx spu_legitimize_address (rtx x, rtx oldx, enum machine_mode mode);
extern int spu_initial_elimination_offset (int from, int to);
extern rtx spu_function_value (const_tree type, const_tree func);
extern rtx spu_function_arg (int cum, enum machine_mode mode, tree type,
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index f5041658223..61113aa51da 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -201,6 +201,7 @@ static void spu_init_libfuncs (void);
static bool spu_return_in_memory (const_tree type, const_tree fntype);
static void fix_range (const char *);
static void spu_encode_section_info (tree, rtx, int);
+static rtx spu_legitimize_address (rtx, rtx, enum machine_mode);
static tree spu_builtin_mul_widen_even (tree);
static tree spu_builtin_mul_widen_odd (tree);
static tree spu_builtin_mask_for_load (void);
@@ -280,6 +281,9 @@ spu_libgcc_shift_count_mode (void);
#undef TARGET_UNWIND_WORD_MODE
#define TARGET_UNWIND_WORD_MODE spu_unwind_word_mode
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS spu_legitimize_address
+
/* The .8byte directive doesn't seem to work well for a 32 bit
architecture. */
#undef TARGET_ASM_UNALIGNED_DI_OP
@@ -3683,7 +3687,7 @@ spu_legitimate_address (enum machine_mode mode ATTRIBUTE_UNUSED,
register. */
rtx
spu_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
- enum machine_mode mode)
+ enum machine_mode mode ATTRIBUTE_UNUSED)
{
rtx op0, op1;
/* Make sure both operands are registers. */
@@ -3706,10 +3710,8 @@ spu_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
else if (GET_CODE (op1) != REG)
op1 = force_reg (Pmode, op1);
x = gen_rtx_PLUS (Pmode, op0, op1);
- if (spu_legitimate_address (mode, x, 0))
- return x;
}
- return NULL_RTX;
+ return x;
}
/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
diff --git a/gcc/config/spu/spu.h b/gcc/config/spu/spu.h
index f8375f18c82..ed92715cd01 100644
--- a/gcc/config/spu/spu.h
+++ b/gcc/config/spu/spu.h
@@ -427,15 +427,6 @@ targetm.resolve_overloaded_builtin = spu_resolve_overloaded_builtin; \
goto ADDR; \
}
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN) \
- { rtx result = spu_legitimize_address (X, OLDX, MODE); \
- if (result != NULL_RTX) \
- { \
- (X) = result; \
- goto WIN; \
- } \
- }
-
#define LEGITIMATE_CONSTANT_P(X) spu_legitimate_constant_p(X)
diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h
index 0447fae0a2e..5f8cd74fe36 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -55,7 +55,6 @@ extern char *xtensa_emit_bit_branch (bool, bool, rtx *);
extern char *xtensa_emit_movcc (bool, bool, bool, rtx *);
extern char *xtensa_emit_call (int, rtx *);
extern bool xtensa_legitimate_address_p (enum machine_mode, rtx, bool);
-extern rtx xtensa_legitimize_address (rtx, rtx, enum machine_mode);
extern bool xtensa_tls_referenced_p (rtx);
#ifdef TREE_CODE
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 14825c31de3..50467b4602c 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -132,6 +132,7 @@ static rtx gen_conditional_move (rtx);
static rtx fixup_subreg_mem (rtx);
static struct machine_function * xtensa_init_machine_status (void);
static rtx xtensa_legitimize_tls_address (rtx);
+static rtx xtensa_legitimize_address (rtx, rtx, enum machine_mode);
static bool xtensa_return_in_msb (const_tree);
static void printx (FILE *, signed int);
static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT);
@@ -175,6 +176,9 @@ static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
+
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS xtensa_rtx_costs
#undef TARGET_ADDRESS_COST
@@ -1873,7 +1877,7 @@ xtensa_legitimize_address (rtx x,
}
}
- return NULL_RTX;
+ return x;
}
diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
index 1427fd0e3da..73f68ef315f 100644
--- a/gcc/config/xtensa/xtensa.h
+++ b/gcc/config/xtensa/xtensa.h
@@ -810,17 +810,6 @@ typedef struct xtensa_args
&& GET_CODE (X) != LABEL_REF \
&& GET_CODE (X) != CONST)
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
- do { \
- rtx new_x = xtensa_legitimize_address (X, OLDX, MODE); \
- if (new_x) \
- { \
- X = new_x; \
- goto WIN; \
- } \
- } while (0)
-
-
/* Treat constant-pool references as "mode dependent" since they can
only be accessed with SImode loads. This works around a bug in the
combiner where a constant pool reference is temporarily converted
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 0be7057fd31..8ed40d93b54 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -878,10 +878,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define SHIFT_COUNT_TRUNCATED 0
#endif
-#ifndef LEGITIMIZE_ADDRESS
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)
-#endif
-
#ifndef LEGITIMATE_PIC_OPERAND_P
#define LEGITIMATE_PIC_OPERAND_P(X) 1
#endif
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 4765cf6401a..4c9b16279b5 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5443,32 +5443,26 @@ The typical use of this macro is to handle addresses containing
a label_ref or symbol_ref within an UNSPEC@.
@end defmac
-@defmac LEGITIMIZE_ADDRESS (@var{x}, @var{oldx}, @var{mode}, @var{win})
-A C compound statement that attempts to replace @var{x} with a valid
-memory address for an operand of mode @var{mode}. @var{win} will be a
-C statement label elsewhere in the code; the macro definition may use
-
-@smallexample
-GO_IF_LEGITIMATE_ADDRESS (@var{mode}, @var{x}, @var{win});
-@end smallexample
-
-@noindent
-to avoid further processing if the address has become legitimate.
+@deftypefn {Target Hook} rtx TARGET_LEGITIMIZE_ADDRESS (rtx @var{x}, rtx @var{oldx}, enum machine_mode @var{mode})
+This hook is given an invalid memory address @var{x} for an
+operand of mode @var{mode} and should try to return a valid memory
+address.
@findex break_out_memory_refs
@var{x} will always be the result of a call to @code{break_out_memory_refs},
and @var{oldx} will be the operand that was given to that function to produce
@var{x}.
-The code generated by this macro should not alter the substructure of
+The code of the hook should not alter the substructure of
@var{x}. If it transforms @var{x} into a more legitimate form, it
-should assign @var{x} (which will always be a C variable) a new value.
+should return the new @var{x}.
-It is not necessary for this macro to come up with a legitimate
-address. The compiler has standard ways of doing so in all cases. In
-fact, it is safe to omit this macro. But often a
-machine-dependent strategy can generate better code.
-@end defmac
+It is not necessary for this hook to come up with a legitimate address.
+The compiler has standard ways of doing so in all cases. In fact, it
+is safe to omit this hook or make it return @var{x} if it cannot find
+a valid way to legitimize the address. But often a machine-dependent
+strategy can generate better code.
+@end deftypefn
@defmac LEGITIMIZE_RELOAD_ADDRESS (@var{x}, @var{mode}, @var{opnum}, @var{type}, @var{ind_levels}, @var{win})
A C compound statement that attempts to replace @var{x}, which is an address
diff --git a/gcc/explow.c b/gcc/explow.c
index 11c2a477b84..2e8f6488501 100644
--- a/gcc/explow.c
+++ b/gcc/explow.c
@@ -446,7 +446,12 @@ memory_address (enum machine_mode mode, rtx x)
in certain cases. This is not necessary since the code
below can handle all possible cases, but machine-dependent
transformations can make better code. */
- LEGITIMIZE_ADDRESS (x, oldx, mode, done);
+ {
+ rtx orig_x = x;
+ x = targetm.legitimize_address (x, oldx, mode);
+ if (orig_x != x && memory_address_p (mode, x))
+ goto done;
+ }
/* PLUS and MULT can appear in special ways
as the result of attempts to make an address usable for indexing.
diff --git a/gcc/system.h b/gcc/system.h
index 80bfe619c3d..223a9dd01b4 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -681,7 +681,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
MUST_PASS_IN_STACK FUNCTION_ARG_PASS_BY_REFERENCE \
VECTOR_MODE_SUPPORTED_P TARGET_SUPPORTS_HIDDEN \
FUNCTION_ARG_PARTIAL_NREGS ASM_OUTPUT_DWARF_DTPREL \
- ALLOCATE_INITIAL_VALUE
+ ALLOCATE_INITIAL_VALUE LEGITIMIZE_ADDRESS
/* Other obsolete target macros, or macros that used to be in target
headers and were not used, and may be obsolete or may never have
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 30172d0e693..0039f9a438f 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -486,6 +486,7 @@
#define TARGET_CANNOT_FORCE_CONST_MEM hook_bool_rtx_false
#define TARGET_CANNOT_COPY_INSN_P NULL
#define TARGET_COMMUTATIVE_P hook_bool_const_rtx_commutative_p
+#define TARGET_LEGITIMIZE_ADDRESS default_legitimize_address
#define TARGET_DELEGITIMIZE_ADDRESS hook_rtx_rtx_identity
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_false
#define TARGET_MIN_ANCHOR_OFFSET 0
@@ -869,6 +870,7 @@
TARGET_CANNOT_FORCE_CONST_MEM, \
TARGET_CANNOT_COPY_INSN_P, \
TARGET_COMMUTATIVE_P, \
+ TARGET_LEGITIMIZE_ADDRESS, \
TARGET_DELEGITIMIZE_ADDRESS, \
TARGET_USE_BLOCKS_FOR_CONSTANT_P, \
TARGET_MIN_ANCHOR_OFFSET, \
diff --git a/gcc/target.h b/gcc/target.h
index d3a4af6c31f..63fab54c42e 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -603,6 +603,10 @@ struct gcc_target
/* True if X is considered to be commutative. */
bool (* commutative_p) (const_rtx, int);
+ /* Given an invalid address X for a given machine mode, try machine-specific
+ ways to make it legitimate. Return X or an invalid address on failure. */
+ rtx (* legitimize_address) (rtx, rtx, enum machine_mode);
+
/* Given an address RTX, undo the effects of LEGITIMIZE_ADDRESS. */
rtx (* delegitimize_address) (rtx);
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 7035c494331..1dd6c7c6de8 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -112,6 +112,13 @@ default_return_in_memory (const_tree type,
}
rtx
+default_legitimize_address (rtx x, rtx orig_x ATTRIBUTE_UNUSED,
+ enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+ return x;
+}
+
+rtx
default_expand_builtin_saveregs (void)
{
error ("__builtin_saveregs not supported by this target");
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index cbd6e9085dc..19b78cbca33 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
extern void default_external_libcall (rtx);
+extern rtx default_legitimize_address (rtx, rtx, enum machine_mode);
extern int default_unspec_may_trap_p (const_rtx, unsigned);