From 41e3a0c76c897f6759118ed14f729334cea6ecfe Mon Sep 17 00:00:00 2001 From: bonzini Date: Mon, 4 May 2009 12:52:41 +0000 Subject: [PATCH] 2009-05-04 Paolo Bonzini * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147098 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 91 +++++++++++++++++++++++++++++++++++++ gcc/config/alpha/alpha-protos.h | 1 - gcc/config/alpha/alpha.c | 21 +++++++-- gcc/config/alpha/alpha.h | 14 ------ gcc/config/arm/arm-protos.h | 2 - gcc/config/arm/arm.c | 13 ++++++ gcc/config/arm/arm.h | 30 ------------ gcc/config/avr/avr-protos.h | 1 - gcc/config/avr/avr.c | 6 ++- gcc/config/avr/avr.h | 7 --- gcc/config/bfin/bfin-protos.h | 1 - gcc/config/bfin/bfin.c | 16 ------- gcc/config/bfin/bfin.h | 19 -------- gcc/config/cris/cris.h | 10 ---- gcc/config/frv/frv-protos.h | 1 - gcc/config/frv/frv.c | 6 ++- gcc/config/frv/frv.h | 10 ---- gcc/config/i386/i386-protos.h | 1 - gcc/config/i386/i386.c | 10 ++-- gcc/config/i386/i386.h | 28 ------------ gcc/config/iq2000/iq2000.c | 71 +++++++++++++++++++++++++++++ gcc/config/iq2000/iq2000.h | 66 --------------------------- gcc/config/m32c/m32c-protos.h | 1 - gcc/config/m32c/m32c.c | 32 ++++++------- gcc/config/m32c/m32c.h | 4 -- gcc/config/m32r/m32r.c | 14 ++++++ gcc/config/m32r/m32r.h | 23 ---------- gcc/config/m68hc11/m68hc11-protos.h | 2 - gcc/config/m68hc11/m68hc11.c | 8 ---- gcc/config/m68hc11/m68hc11.h | 22 --------- gcc/config/m68k/m68k.c | 81 +++++++++++++++++++++++++++++++++ gcc/config/m68k/m68k.h | 49 +------------------- gcc/config/mips/mips-protos.h | 1 - gcc/config/mips/mips.c | 34 +++++++------- gcc/config/mips/mips.h | 7 --- gcc/config/mn10300/mn10300-protos.h | 1 - gcc/config/mn10300/mn10300.c | 8 +++- gcc/config/mn10300/mn10300.h | 18 -------- gcc/config/pa/pa-protos.h | 2 - gcc/config/pa/pa.c | 4 ++ gcc/config/pa/pa.h | 20 -------- gcc/config/picochip/picochip.h | 4 -- gcc/config/rs6000/rs6000-protos.h | 1 - gcc/config/rs6000/rs6000.c | 8 +++- gcc/config/rs6000/rs6000.h | 32 ------------- gcc/config/s390/s390-protos.h | 1 - gcc/config/s390/s390.c | 9 ++-- gcc/config/s390/s390.h | 10 ---- gcc/config/score/score-protos.h | 1 - gcc/config/score/score.c | 16 ++++--- gcc/config/score/score.h | 6 --- gcc/config/score/score3.c | 27 +++++------ gcc/config/score/score3.h | 2 +- gcc/config/score/score7.c | 27 +++++------ gcc/config/score/score7.h | 2 +- gcc/config/sh/sh.c | 58 +++++++++++++++++++++++ gcc/config/sh/sh.h | 62 ------------------------- gcc/config/sparc/sparc-protos.h | 1 - gcc/config/sparc/sparc.c | 11 ++++- gcc/config/sparc/sparc.h | 21 --------- gcc/config/spu/spu-protos.h | 1 - gcc/config/spu/spu.c | 10 ++-- gcc/config/spu/spu.h | 9 ---- gcc/config/xtensa/xtensa-protos.h | 1 - gcc/config/xtensa/xtensa.c | 6 ++- gcc/config/xtensa/xtensa.h | 11 ----- gcc/defaults.h | 4 -- gcc/doc/tm.texi | 30 +++++------- gcc/explow.c | 7 ++- gcc/system.h | 2 +- gcc/target-def.h | 2 + gcc/target.h | 4 ++ gcc/targhooks.c | 7 +++ gcc/targhooks.h | 1 + 74 files changed, 507 insertions(+), 643 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0897c6f..ad44ff2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,94 @@ +2009-05-04 Paolo Bonzini + + * 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 * intl.c (locale_encoding, locale_utf8): New. diff --git a/gcc/config/alpha/alpha-protos.h b/gcc/config/alpha/alpha-protos.h index bbbcd8f..66c68ae 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 8a7c313..bb6542a 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 433823d..f33e8e6 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 6019dc6..34d266b 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 a7847f3..e6d2c5c 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 8d97864..e7bc7a7 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 ef5286e..4424690 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 7683c38..449c0ee 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 45d02c4..79d81b9 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 e92a7b6..33de846 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 63f60e1..17201c6 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 f7f2cd4..d97fe8f 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 352be55..47936d6 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 911ed7c..c34d02c 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 56c99ae..4e8c1b2 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 abe275f..b6fdca4 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 5d92ec7..badea0d 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 5e7689b..b0974ff 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 b3972a3..4aafd9c 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 d853b1f..3b9e116 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 + ) + into: + Y = & ~0x7fff; + Z = X + Y + memory (Z + ( & 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 acbe569..30642b2 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 + ) - into: - Y = & ~0x7fff; - Z = X + Y - memory (Z + ( & 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 ec98d81..650c918 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 bd33934..6d386e3 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 9e0c921..cb2b8be 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 ff53738..656c0ea 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 f2f7e89..9bc0fa9 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 1e9cf58..5412e1d 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 4fba4a3..5050fa4 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 5496640..3517659 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 bccb834..e4bb1e2 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 11477c6..875667d 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 1f8054e..b95461a 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 e03e6ad..b40ba3b 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 e14073a..5c68688 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 d8fe2bd..935cb8f 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 1eb80ec..ceb77e8 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 2737d15..b358944 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 7fc9dca..3cd1f85 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 08c987f..80f5fe9 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 ee89093..303bdd3 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 497c130..7c32ebe 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 c898d51..4b8f522 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 00cf3bd..b6bc88b 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 5feae4d..f11ea1f 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 76f73f9..3bde1c1 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 61471bb..e2ed4a0 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 c62f6bf..2b4d7ce 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 56cdce7..d6739b8 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 e088764..2ac3021 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 d2dd740..d9fe8e6 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 655ee45..9e41452 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 f3aa060..c46a8e6 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 64ab5aa..dc53276 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 473cc12..e2033c7 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 f8a046b..9834d62 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 5f5006f..71e202a 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 35ee06f..40ac75e 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 60067b5..ab2b57b 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 c066770..d219001 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 d8376d8..06e02ba 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 f504165..61113aa 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 f8375f1..ed92715 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 0447fae..5f8cd74 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 14825c3..50467b4 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 1427fd0..73f68ef 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 0be7057..8ed40d9 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 4765cf6..4c9b162 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 11c2a47..2e8f648 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 80bfe61..223a9dd 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 30172d0..0039f9a 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 d3a4af6..63fab54 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 7035c49..1dd6c7c 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 cbd6e90..19b78cb 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -19,6 +19,7 @@ along with GCC; see the file COPYING3. If not see . */ 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); -- 2.7.4