From 86fc3d06b086930c41fa9fa1be82a0fa92699a12 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 8 Nov 2011 17:36:45 +0000 Subject: [PATCH] tm.texi.in (MODE_CODE_BASE_REG_CLASS): Add address space argument. * doc/tm.texi.in (MODE_CODE_BASE_REG_CLASS): Add address space argument. (REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise. * doc/tm.texi: Regenerate. * config/cris/cris.h (MODE_CODE_BASE_REG_CLASS): Add address space argument. (REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise. * config/bfin/bfin.h (MODE_CODE_BASE_REG_CLASS): Likewise. (REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise. * config/avr/avr.h (MODE_CODE_BASE_REG_CLASS): Add address space argument. (REGNO_MODE_CODE_OK_FOR_BASE_P): Ditto. * config/avr/avr-protos.h (avr_mode_code_base_reg_class): Ditto. (avr_regno_mode_code_ok_for_base_p): Ditto. * config/avr/avr.c (avr_mode_code_base_reg_class): Ditto. (avr_regno_mode_code_ok_for_base_p): Ditto. (avr_reg_ok_for_addr_p): Pass AS down to avr_regno_mode_code_ok_for_base_p. * addresses.h (base_reg_class): Add address space argument. Pass to MODE_CODE_BASE_REG_CLASS. (ok_for_base_p_1): Add address space argument. Pass to REGNO_MODE_CODE_OK_FOR_BASE_P. (regno_ok_for_base_p): Add address space argument. Pass to ok_for_base_p_1. * regrename.c (scan_rtx_address): Add address space argument. Pass address space to regno_ok_for_base_p and base_reg_class. Update recursive calls. (scan_rtx): Pass address space to scan_rtx_address. (build_def_use): Likewise. * regcprop.c (replace_oldest_value_addr): Add address space argument. Pass to regno_ok_for_base_p and base_reg_class. Update recursive calls. (replace_oldest_value_mem): Pass address space to replace_oldest_value_addr. (copyprop_hardreg_forward_1): Likewise. * reload.c (find_reloads_address_1): Add address space argument. Pass address space to base_reg_class and regno_ok_for_base_p. Update recursive calls. (find_reloads_address): Pass address space to base_reg_class, regno_ok_for_base_p, and find_reloads_address_1. (find_reloads): Pass address space to base_reg_class. (find_reloads_subreg_address): Likewise. * ira-costs.c (record_reg_classes): Update calls to base_reg_class. (ok_for_base_p_nonstrict): Add address space argument. Pass to ok_for_base_p_1. (record_address_regs): Add address space argument. Pass to base_reg_class and ok_for_base_p_nonstrict. Update recursive calls. (record_operand_costs): Pass address space to record_address_regs. (scan_one_insn): Likewise. * caller-save.c (init_caller_save): Update call to base_reg_class. * ira-conflicts.c (ira_build_conflicts): Likewise. * reload1.c (maybe_fix_stack_asms): Likewise. Co-Authored-By: Georg-Johann Lay From-SVN: r181175 --- gcc/ChangeLog | 62 ++++++++++++++++++++++ gcc/addresses.h | 11 ++-- gcc/caller-save.c | 3 +- gcc/config/avr/avr-protos.h | 4 +- gcc/config/avr/avr.c | 8 +-- gcc/config/avr/avr.h | 8 +-- gcc/config/bfin/bfin.h | 6 +-- gcc/config/cris/cris.h | 4 +- gcc/doc/tm.texi | 18 ++++--- gcc/doc/tm.texi.in | 18 ++++--- gcc/ira-conflicts.c | 8 +-- gcc/ira-costs.c | 89 +++++++++++++++++-------------- gcc/recog.c | 7 +-- gcc/regcprop.c | 36 +++++++------ gcc/regrename.c | 35 ++++++------ gcc/reload.c | 126 +++++++++++++++++++++++--------------------- gcc/reload1.c | 6 ++- 17 files changed, 274 insertions(+), 175 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index abbc82c..bd056b6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,65 @@ +2011-11-08 Ulrich Weigand + Georg-Johann Lay + + * doc/tm.texi.in (MODE_CODE_BASE_REG_CLASS): Add address space + argument. + (REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise. + * doc/tm.texi: Regenerate. + + * config/cris/cris.h (MODE_CODE_BASE_REG_CLASS): Add address + space argument. + (REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise. + * config/bfin/bfin.h (MODE_CODE_BASE_REG_CLASS): Likewise. + (REGNO_MODE_CODE_OK_FOR_BASE_P): Likewise. + * config/avr/avr.h (MODE_CODE_BASE_REG_CLASS): Add address space + argument. + (REGNO_MODE_CODE_OK_FOR_BASE_P): Ditto. + * config/avr/avr-protos.h (avr_mode_code_base_reg_class): Ditto. + (avr_regno_mode_code_ok_for_base_p): Ditto. + * config/avr/avr.c (avr_mode_code_base_reg_class): Ditto. + (avr_regno_mode_code_ok_for_base_p): Ditto. + (avr_reg_ok_for_addr_p): Pass AS down to + avr_regno_mode_code_ok_for_base_p. + + * addresses.h (base_reg_class): Add address space argument. + Pass to MODE_CODE_BASE_REG_CLASS. + (ok_for_base_p_1): Add address space argument. Pass to + REGNO_MODE_CODE_OK_FOR_BASE_P. + (regno_ok_for_base_p): Add address space argument. Pass to + ok_for_base_p_1. + + * regrename.c (scan_rtx_address): Add address space argument. + Pass address space to regno_ok_for_base_p and base_reg_class. + Update recursive calls. + (scan_rtx): Pass address space to scan_rtx_address. + (build_def_use): Likewise. + * regcprop.c (replace_oldest_value_addr): Add address space + argument. Pass to regno_ok_for_base_p and base_reg_class. + Update recursive calls. + (replace_oldest_value_mem): Pass address space to + replace_oldest_value_addr. + (copyprop_hardreg_forward_1): Likewise. + + * reload.c (find_reloads_address_1): Add address space argument. + Pass address space to base_reg_class and regno_ok_for_base_p. + Update recursive calls. + (find_reloads_address): Pass address space to base_reg_class, + regno_ok_for_base_p, and find_reloads_address_1. + (find_reloads): Pass address space to base_reg_class. + (find_reloads_subreg_address): Likewise. + + * ira-costs.c (record_reg_classes): Update calls to base_reg_class. + (ok_for_base_p_nonstrict): Add address space argument. Pass to + ok_for_base_p_1. + (record_address_regs): Add address space argument. Pass to + base_reg_class and ok_for_base_p_nonstrict. Update recursive calls. + (record_operand_costs): Pass address space to record_address_regs. + (scan_one_insn): Likewise. + + * caller-save.c (init_caller_save): Update call to base_reg_class. + * ira-conflicts.c (ira_build_conflicts): Likewise. + * reload1.c (maybe_fix_stack_asms): Likewise. + 2011-11-08 Michael Matz * gengtype.c (write_field_root): Avoid out-of-scope access of newv. diff --git a/gcc/addresses.h b/gcc/addresses.h index b229f17..235b438 100644 --- a/gcc/addresses.h +++ b/gcc/addresses.h @@ -23,11 +23,12 @@ along with GCC; see the file COPYING3. If not see static inline enum reg_class base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED, + addr_space_t as ATTRIBUTE_UNUSED, enum rtx_code outer_code ATTRIBUTE_UNUSED, enum rtx_code index_code ATTRIBUTE_UNUSED) { #ifdef MODE_CODE_BASE_REG_CLASS - return MODE_CODE_BASE_REG_CLASS (mode, outer_code, index_code); + return MODE_CODE_BASE_REG_CLASS (mode, as, outer_code, index_code); #else #ifdef MODE_BASE_REG_REG_CLASS if (index_code == REG) @@ -49,11 +50,13 @@ base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED, static inline bool ok_for_base_p_1 (unsigned regno ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIBUTE_UNUSED, + addr_space_t as ATTRIBUTE_UNUSED, enum rtx_code outer_code ATTRIBUTE_UNUSED, enum rtx_code index_code ATTRIBUTE_UNUSED) { #ifdef REGNO_MODE_CODE_OK_FOR_BASE_P - return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, mode, outer_code, index_code); + return REGNO_MODE_CODE_OK_FOR_BASE_P (regno, mode, as, + outer_code, index_code); #else #ifdef REGNO_MODE_OK_FOR_REG_BASE_P if (index_code == REG) @@ -71,11 +74,11 @@ ok_for_base_p_1 (unsigned regno ATTRIBUTE_UNUSED, complete. Arguments as for the called function. */ static inline bool -regno_ok_for_base_p (unsigned regno, enum machine_mode mode, +regno_ok_for_base_p (unsigned regno, enum machine_mode mode, addr_space_t as, enum rtx_code outer_code, enum rtx_code index_code) { if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] >= 0) regno = reg_renumber[regno]; - return ok_for_base_p_1 (regno, mode, outer_code, index_code); + return ok_for_base_p_1 (regno, mode, as, outer_code, index_code); } diff --git a/gcc/caller-save.c b/gcc/caller-save.c index 369b55c..39bccc4 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -231,7 +231,8 @@ init_caller_save (void) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (TEST_HARD_REG_BIT (reg_class_contents - [(int) base_reg_class (regno_save_mode[i][1], PLUS, CONST_INT)], i)) + [(int) base_reg_class (regno_save_mode[i][1], ADDR_SPACE_GENERIC, + PLUS, CONST_INT)], i)) break; gcc_assert (i < FIRST_PSEUDO_REGISTER); diff --git a/gcc/config/avr/avr-protos.h b/gcc/config/avr/avr-protos.h index f72c5f8..d351833 100644 --- a/gcc/config/avr/avr-protos.h +++ b/gcc/config/avr/avr-protos.h @@ -117,8 +117,8 @@ extern int avr_simplify_comparison_p (enum machine_mode mode, extern RTX_CODE avr_normalize_condition (RTX_CODE condition); extern void out_shift_with_cnt (const char *templ, rtx insn, rtx operands[], int *len, int t_len); -extern reg_class_t avr_mode_code_base_reg_class (enum machine_mode, RTX_CODE, RTX_CODE); -extern bool avr_regno_mode_code_ok_for_base_p (int, enum machine_mode, RTX_CODE, RTX_CODE); +extern reg_class_t avr_mode_code_base_reg_class (enum machine_mode, addr_space_t, RTX_CODE, RTX_CODE); +extern bool avr_regno_mode_code_ok_for_base_p (int, enum machine_mode, addr_space_t, RTX_CODE, RTX_CODE); extern rtx avr_incoming_return_addr_rtx (void); extern rtx avr_legitimize_reload_address (rtx*, enum machine_mode, int, int, int, int, rtx (*)(rtx,int)); #endif /* RTX_CODE */ diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 630b7ef..65d43b8 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -1281,12 +1281,12 @@ avr_cannot_modify_jumps_p (void) /* Helper function for `avr_legitimate_address_p'. */ static inline bool -avr_reg_ok_for_addr_p (rtx reg, addr_space_t as ATTRIBUTE_UNUSED, +avr_reg_ok_for_addr_p (rtx reg, addr_space_t as, RTX_CODE outer_code, bool strict) { return (REG_P (reg) - && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), - QImode, outer_code, UNKNOWN) + && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode, + as, outer_code, UNKNOWN) || (!strict && REGNO (reg) >= FIRST_PSEUDO_REGISTER))); } @@ -8049,6 +8049,7 @@ avr_hard_regno_mode_ok (int regno, enum machine_mode mode) reg_class_t avr_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED, + addr_space_t as ATTRIBUTE_UNUSED, RTX_CODE outer_code, RTX_CODE index_code ATTRIBUTE_UNUSED) { @@ -8064,6 +8065,7 @@ avr_mode_code_base_reg_class (enum machine_mode mode ATTRIBUTE_UNUSED, bool avr_regno_mode_code_ok_for_base_p (int regno, enum machine_mode mode ATTRIBUTE_UNUSED, + addr_space_t as ATTRIBUTE_UNUSED, RTX_CODE outer_code, RTX_CODE index_code ATTRIBUTE_UNUSED) { diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 47ca8ff..7a3bc73 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -308,13 +308,13 @@ enum reg_class { #define REGNO_REG_CLASS(R) avr_regno_reg_class(R) -#define MODE_CODE_BASE_REG_CLASS(mode, outer_code, index_code) \ - avr_mode_code_base_reg_class (mode, outer_code, index_code) +#define MODE_CODE_BASE_REG_CLASS(mode, as, outer_code, index_code) \ + avr_mode_code_base_reg_class (mode, as, outer_code, index_code) #define INDEX_REG_CLASS NO_REGS -#define REGNO_MODE_CODE_OK_FOR_BASE_P(num, mode, outer_code, index_code) \ - avr_regno_mode_code_ok_for_base_p (num, mode, outer_code, index_code) +#define REGNO_MODE_CODE_OK_FOR_BASE_P(num, mode, as, outer_code, index_code) \ + avr_regno_mode_code_ok_for_base_p (num, mode, as, outer_code, index_code) #define REGNO_OK_FOR_INDEX_P(NUM) 0 diff --git a/gcc/config/bfin/bfin.h b/gcc/config/bfin/bfin.h index 635c61b..a16feca 100644 --- a/gcc/config/bfin/bfin.h +++ b/gcc/config/bfin/bfin.h @@ -612,7 +612,7 @@ enum reg_class || (OUTER) == POST_DEC || (OUTER) == PRE_DEC \ || (OUTER) == MEM || (OUTER) == ADDRESS) -#define MODE_CODE_BASE_REG_CLASS(MODE, OUTER, INDEX) \ +#define MODE_CODE_BASE_REG_CLASS(MODE, AS, OUTER, INDEX) \ ((MODE) == HImode && IREG_POSSIBLE_P (OUTER) ? IPREGS : PREGS) #define INDEX_REG_CLASS PREGS @@ -627,10 +627,10 @@ enum reg_class || REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX)) #ifdef REG_OK_STRICT -#define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, OUTER, INDEX) \ +#define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, AS, OUTER, INDEX) \ REGNO_OK_FOR_BASE_STRICT_P (X, MODE, OUTER, INDEX) #else -#define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, OUTER, INDEX) \ +#define REGNO_MODE_CODE_OK_FOR_BASE_P(X, MODE, AS, OUTER, INDEX) \ REGNO_OK_FOR_BASE_NONSTRICT_P (X, MODE, OUTER, INDEX) #endif diff --git a/gcc/config/cris/cris.h b/gcc/config/cris/cris.h index a9a68b8..5a6ebda 100644 --- a/gcc/config/cris/cris.h +++ b/gcc/config/cris/cris.h @@ -545,7 +545,7 @@ enum reg_class #define BASE_REG_CLASS GENERAL_REGS -#define MODE_CODE_BASE_REG_CLASS(MODE, OCODE, ICODE) \ +#define MODE_CODE_BASE_REG_CLASS(MODE, AS, OCODE, ICODE) \ ((OCODE) != POST_INC ? BASE_REG_CLASS : GENNONACR_REGS) #define INDEX_REG_CLASS GENERAL_REGS @@ -560,7 +560,7 @@ enum reg_class /* REGNO_OK_FOR_BASE_P seems to be obsolete wrt. this one, but not yet documented as such. */ -#define REGNO_MODE_CODE_OK_FOR_BASE_P(REGNO, MODE, OCODE, ICODE) \ +#define REGNO_MODE_CODE_OK_FOR_BASE_P(REGNO, MODE, AS, OCODE, ICODE) \ (REGNO_OK_FOR_BASE_P (REGNO) \ && ((OCODE) != POST_INC \ || !((REGNO) == CRIS_ACR_REGNUM \ diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index d96932b..10fd876 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -2435,12 +2435,13 @@ register address. You should define this macro if base plus index addresses have different requirements than other base register uses. @end defmac -@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{outer_code}, @var{index_code}) +@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, @var{outer_code}, @var{index_code}) A C expression whose value is the register class to which a valid -base register must belong. @var{outer_code} and @var{index_code} define the -context in which the base register occurs. @var{outer_code} is the code of -the immediately enclosing expression (@code{MEM} for the top level of an -address, @code{ADDRESS} for something that occurs in an +base register for a memory reference in mode @var{mode} to address +space @var{address_space} must belong. @var{outer_code} and @var{index_code} +define the context in which the base register occurs. @var{outer_code} is +the code of the immediately enclosing expression (@code{MEM} for the top level +of an address, @code{ADDRESS} for something that occurs in an @code{address_operand}). @var{index_code} is the code of the corresponding index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise. @end defmac @@ -2480,8 +2481,11 @@ Use of this macro is deprecated; please use the more general @code{REGNO_MODE_CODE_OK_FOR_BASE_P}. @end defmac -@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{outer_code}, @var{index_code}) -A C expression that is just like @code{REGNO_MODE_OK_FOR_BASE_P}, except +@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{address_space}, @var{outer_code}, @var{index_code}) +A C expression which is nonzero if register number @var{num} is +suitable for use as a base register in operand addresses, accessing +memory in mode @var{mode} in address space @var{address_space}. +This is similar to @code{REGNO_MODE_OK_FOR_BASE_P}, except that that expression may examine the context in which the register appears in the memory reference. @var{outer_code} is the code of the immediately enclosing expression (@code{MEM} if at the top level of the diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 146e38a..cebeb1f 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -2423,12 +2423,13 @@ register address. You should define this macro if base plus index addresses have different requirements than other base register uses. @end defmac -@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{outer_code}, @var{index_code}) +@defmac MODE_CODE_BASE_REG_CLASS (@var{mode}, @var{address_space}, @var{outer_code}, @var{index_code}) A C expression whose value is the register class to which a valid -base register must belong. @var{outer_code} and @var{index_code} define the -context in which the base register occurs. @var{outer_code} is the code of -the immediately enclosing expression (@code{MEM} for the top level of an -address, @code{ADDRESS} for something that occurs in an +base register for a memory reference in mode @var{mode} to address +space @var{address_space} must belong. @var{outer_code} and @var{index_code} +define the context in which the base register occurs. @var{outer_code} is +the code of the immediately enclosing expression (@code{MEM} for the top level +of an address, @code{ADDRESS} for something that occurs in an @code{address_operand}). @var{index_code} is the code of the corresponding index expression if @var{outer_code} is @code{PLUS}; @code{SCRATCH} otherwise. @end defmac @@ -2468,8 +2469,11 @@ Use of this macro is deprecated; please use the more general @code{REGNO_MODE_CODE_OK_FOR_BASE_P}. @end defmac -@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{outer_code}, @var{index_code}) -A C expression that is just like @code{REGNO_MODE_OK_FOR_BASE_P}, except +@defmac REGNO_MODE_CODE_OK_FOR_BASE_P (@var{num}, @var{mode}, @var{address_space}, @var{outer_code}, @var{index_code}) +A C expression which is nonzero if register number @var{num} is +suitable for use as a base register in operand addresses, accessing +memory in mode @var{mode} in address space @var{address_space}. +This is similar to @code{REGNO_MODE_OK_FOR_BASE_P}, except that that expression may examine the context in which the register appears in the memory reference. @var{outer_code} is the code of the immediately enclosing expression (@code{MEM} if at the top level of the diff --git a/gcc/ira-conflicts.c b/gcc/ira-conflicts.c index 3df6570..225a3ab 100644 --- a/gcc/ira-conflicts.c +++ b/gcc/ira-conflicts.c @@ -845,6 +845,7 @@ ira_debug_conflicts (bool reg_p) void ira_build_conflicts (void) { + enum reg_class base; ira_allocno_t a; ira_allocno_iterator ai; HARD_REG_SET temp_hard_reg_set; @@ -874,13 +875,12 @@ ira_build_conflicts (void) ira_free (conflicts); } } - if (! targetm.class_likely_spilled_p (base_reg_class (VOIDmode, ADDRESS, - SCRATCH))) + base = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH); + if (! targetm.class_likely_spilled_p (base)) CLEAR_HARD_REG_SET (temp_hard_reg_set); else { - COPY_HARD_REG_SET (temp_hard_reg_set, - reg_class_contents[base_reg_class (VOIDmode, ADDRESS, SCRATCH)]); + COPY_HARD_REG_SET (temp_hard_reg_set, reg_class_contents[base]); AND_COMPL_HARD_REG_SET (temp_hard_reg_set, ira_no_alloc_regs); AND_HARD_REG_SET (temp_hard_reg_set, call_used_reg_set); } diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index dc983fd..4fa12a2 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -637,7 +637,8 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, base of an address, i.e. BASE_REG_CLASS. */ classes[i] = ira_reg_class_subunion[classes[i]] - [base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; break; case 'm': case 'o': case 'V': @@ -752,7 +753,8 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, i.e. BASE_REG_CLASS. */ classes[i] = ira_reg_class_subunion[classes[i]] - [base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; } #endif break; @@ -996,14 +998,14 @@ ok_for_index_p_nonstrict (rtx reg) pseudo-registers should count as OK. Arguments as for regno_ok_for_base_p. */ static inline bool -ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, +ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, addr_space_t as, enum rtx_code outer_code, enum rtx_code index_code) { unsigned regno = REGNO (reg); if (regno >= FIRST_PSEUDO_REGISTER) return true; - return ok_for_base_p_1 (regno, mode, outer_code, index_code); + return ok_for_base_p_1 (regno, mode, as, outer_code, index_code); } /* Record the pseudo registers we must reload into hard registers in a @@ -1012,16 +1014,16 @@ ok_for_base_p_nonstrict (rtx reg, enum machine_mode mode, If CONTEXT is 0, we are looking at the base part of an address, otherwise we are looking at the index part. - MODE is the mode of the memory reference; OUTER_CODE and INDEX_CODE - give the context that the rtx appears in. These three arguments - are passed down to base_reg_class. + MODE and AS are the mode and address space of the memory reference; + OUTER_CODE and INDEX_CODE give the context that the rtx appears in. + These four arguments are passed down to base_reg_class. SCALE is twice the amount to multiply the cost by (it is twice so we can represent half-cost adjustments). */ static void -record_address_regs (enum machine_mode mode, rtx x, int context, - enum rtx_code outer_code, enum rtx_code index_code, - int scale) +record_address_regs (enum machine_mode mode, addr_space_t as, rtx x, + int context, enum rtx_code outer_code, + enum rtx_code index_code, int scale) { enum rtx_code code = GET_CODE (x); enum reg_class rclass; @@ -1029,7 +1031,7 @@ record_address_regs (enum machine_mode mode, rtx x, int context, if (context == 1) rclass = INDEX_REG_CLASS; else - rclass = base_reg_class (mode, outer_code, index_code); + rclass = base_reg_class (mode, as, outer_code, index_code); switch (code) { @@ -1068,67 +1070,68 @@ record_address_regs (enum machine_mode mode, rtx x, int context, /* If this machine only allows one register per address, it must be in the first operand. */ if (MAX_REGS_PER_ADDRESS == 1) - record_address_regs (mode, arg0, 0, PLUS, code1, scale); + record_address_regs (mode, as, arg0, 0, PLUS, code1, scale); /* If index and base registers are the same on this machine, just record registers in any non-constant operands. We assume here, as well as in the tests below, that all addresses are in canonical form. */ - else if (INDEX_REG_CLASS == base_reg_class (VOIDmode, PLUS, SCRATCH)) + else if (INDEX_REG_CLASS + == base_reg_class (VOIDmode, as, PLUS, SCRATCH)) { - record_address_regs (mode, arg0, context, PLUS, code1, scale); + record_address_regs (mode, as, arg0, context, PLUS, code1, scale); if (! CONSTANT_P (arg1)) - record_address_regs (mode, arg1, context, PLUS, code0, scale); + record_address_regs (mode, as, arg1, context, PLUS, code0, scale); } /* If the second operand is a constant integer, it doesn't change what class the first operand must be. */ else if (code1 == CONST_INT || code1 == CONST_DOUBLE) - record_address_regs (mode, arg0, context, PLUS, code1, scale); + record_address_regs (mode, as, arg0, context, PLUS, code1, scale); /* If the second operand is a symbolic constant, the first operand must be an index register. */ else if (code1 == SYMBOL_REF || code1 == CONST || code1 == LABEL_REF) - record_address_regs (mode, arg0, 1, PLUS, code1, scale); + record_address_regs (mode, as, arg0, 1, PLUS, code1, scale); /* If both operands are registers but one is already a hard register of index or reg-base class, give the other the class that the hard register is not. */ else if (code0 == REG && code1 == REG && REGNO (arg0) < FIRST_PSEUDO_REGISTER - && (ok_for_base_p_nonstrict (arg0, mode, PLUS, REG) + && (ok_for_base_p_nonstrict (arg0, mode, as, PLUS, REG) || ok_for_index_p_nonstrict (arg0))) - record_address_regs (mode, arg1, - ok_for_base_p_nonstrict (arg0, mode, PLUS, REG) - ? 1 : 0, + record_address_regs (mode, as, arg1, + ok_for_base_p_nonstrict (arg0, mode, as, + PLUS, REG) ? 1 : 0, PLUS, REG, scale); else if (code0 == REG && code1 == REG && REGNO (arg1) < FIRST_PSEUDO_REGISTER - && (ok_for_base_p_nonstrict (arg1, mode, PLUS, REG) + && (ok_for_base_p_nonstrict (arg1, mode, as, PLUS, REG) || ok_for_index_p_nonstrict (arg1))) - record_address_regs (mode, arg0, - ok_for_base_p_nonstrict (arg1, mode, PLUS, REG) - ? 1 : 0, + record_address_regs (mode, as, arg0, + ok_for_base_p_nonstrict (arg1, mode, as, + PLUS, REG) ? 1 : 0, PLUS, REG, scale); /* If one operand is known to be a pointer, it must be the base with the other operand the index. Likewise if the other operand is a MULT. */ else if ((code0 == REG && REG_POINTER (arg0)) || code1 == MULT) { - record_address_regs (mode, arg0, 0, PLUS, code1, scale); - record_address_regs (mode, arg1, 1, PLUS, code0, scale); + record_address_regs (mode, as, arg0, 0, PLUS, code1, scale); + record_address_regs (mode, as, arg1, 1, PLUS, code0, scale); } else if ((code1 == REG && REG_POINTER (arg1)) || code0 == MULT) { - record_address_regs (mode, arg0, 1, PLUS, code1, scale); - record_address_regs (mode, arg1, 0, PLUS, code0, scale); + record_address_regs (mode, as, arg0, 1, PLUS, code1, scale); + record_address_regs (mode, as, arg1, 0, PLUS, code0, scale); } /* Otherwise, count equal chances that each might be a base or index register. This case should be rare. */ else { - record_address_regs (mode, arg0, 0, PLUS, code1, scale / 2); - record_address_regs (mode, arg0, 1, PLUS, code1, scale / 2); - record_address_regs (mode, arg1, 0, PLUS, code0, scale / 2); - record_address_regs (mode, arg1, 1, PLUS, code0, scale / 2); + record_address_regs (mode, as, arg0, 0, PLUS, code1, scale / 2); + record_address_regs (mode, as, arg0, 1, PLUS, code1, scale / 2); + record_address_regs (mode, as, arg1, 0, PLUS, code0, scale / 2); + record_address_regs (mode, as, arg1, 1, PLUS, code0, scale / 2); } } break; @@ -1138,10 +1141,10 @@ record_address_regs (enum machine_mode mode, rtx x, int context, up in the wrong place. */ case POST_MODIFY: case PRE_MODIFY: - record_address_regs (mode, XEXP (x, 0), 0, code, + record_address_regs (mode, as, XEXP (x, 0), 0, code, GET_CODE (XEXP (XEXP (x, 1), 1)), 2 * scale); if (REG_P (XEXP (XEXP (x, 1), 1))) - record_address_regs (mode, XEXP (XEXP (x, 1), 1), 1, code, REG, + record_address_regs (mode, as, XEXP (XEXP (x, 1), 1), 1, code, REG, 2 * scale); break; @@ -1152,7 +1155,7 @@ record_address_regs (enum machine_mode mode, rtx x, int context, /* Double the importance of an allocno that is incremented or decremented, since it would take two extra insns if it ends up in the wrong place. */ - record_address_regs (mode, XEXP (x, 0), 0, code, SCRATCH, 2 * scale); + record_address_regs (mode, as, XEXP (x, 0), 0, code, SCRATCH, 2 * scale); break; case REG: @@ -1200,7 +1203,7 @@ record_address_regs (enum machine_mode mode, rtx x, int context, int i; for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) if (fmt[i] == 'e') - record_address_regs (mode, XEXP (x, i), context, code, SCRATCH, + record_address_regs (mode, as, XEXP (x, i), context, code, SCRATCH, scale); } } @@ -1236,13 +1239,15 @@ record_operand_costs (rtx insn, enum reg_class *pref) if (MEM_P (recog_data.operand[i])) record_address_regs (GET_MODE (recog_data.operand[i]), + MEM_ADDR_SPACE (recog_data.operand[i]), XEXP (recog_data.operand[i], 0), 0, MEM, SCRATCH, frequency * 2); else if (constraints[i][0] == 'p' || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i])) - record_address_regs (VOIDmode, recog_data.operand[i], 0, ADDRESS, - SCRATCH, frequency * 2); + record_address_regs (VOIDmode, ADDR_SPACE_GENERIC, + recog_data.operand[i], 0, ADDRESS, SCRATCH, + frequency * 2); } /* Check for commutative in a separate loop so everything will have @@ -1316,8 +1321,10 @@ scan_one_insn (rtx insn) COSTS (costs, num)->mem_cost -= ira_memory_move_cost[GET_MODE (reg)][cl][1] * frequency; - record_address_regs (GET_MODE (SET_SRC (set)), XEXP (SET_SRC (set), 0), - 0, MEM, SCRATCH, frequency * 2); + record_address_regs (GET_MODE (SET_SRC (set)), + MEM_ADDR_SPACE (SET_SRC (set)), + XEXP (SET_SRC (set), 0), 0, MEM, SCRATCH, + frequency * 2); counted_mem = true; } diff --git a/gcc/recog.c b/gcc/recog.c index ae05204..17cec75 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2281,7 +2281,8 @@ preprocess_constraints (void) case 'p': op_alt[j].is_address = 1; op_alt[j].cl = reg_class_subunion[(int) op_alt[j].cl] - [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; break; case 'g': @@ -2302,8 +2303,8 @@ preprocess_constraints (void) op_alt[j].cl = (reg_class_subunion [(int) op_alt[j].cl] - [(int) base_reg_class (VOIDmode, ADDRESS, - SCRATCH)]); + [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]); break; } diff --git a/gcc/regcprop.c b/gcc/regcprop.c index b0f0343..ceb4635 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -98,7 +98,7 @@ static rtx find_oldest_value_reg (enum reg_class, rtx, struct value_data *); static bool replace_oldest_value_reg (rtx *, enum reg_class, rtx, struct value_data *); static bool replace_oldest_value_addr (rtx *, enum reg_class, - enum machine_mode, rtx, + enum machine_mode, addr_space_t, rtx, struct value_data *); static bool replace_oldest_value_mem (rtx, rtx, struct value_data *); static bool copyprop_hardreg_forward_1 (basic_block, struct value_data *); @@ -515,8 +515,8 @@ replace_oldest_value_reg (rtx *loc, enum reg_class cl, rtx insn, static bool replace_oldest_value_addr (rtx *loc, enum reg_class cl, - enum machine_mode mode, rtx insn, - struct value_data *vd) + enum machine_mode mode, addr_space_t as, + rtx insn, struct value_data *vd) { rtx x = *loc; RTX_CODE code = GET_CODE (x); @@ -585,15 +585,15 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, unsigned regno0 = REGNO (op0), regno1 = REGNO (op1); if (REGNO_OK_FOR_INDEX_P (regno1) - && regno_ok_for_base_p (regno0, mode, PLUS, REG)) + && regno_ok_for_base_p (regno0, mode, as, PLUS, REG)) index_op = 1; else if (REGNO_OK_FOR_INDEX_P (regno0) - && regno_ok_for_base_p (regno1, mode, PLUS, REG)) + && regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; - else if (regno_ok_for_base_p (regno0, mode, PLUS, REG) + else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG) || REGNO_OK_FOR_INDEX_P (regno1)) index_op = 1; - else if (regno_ok_for_base_p (regno1, mode, PLUS, REG)) + else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; else index_op = 1; @@ -616,13 +616,13 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, } if (locI) - changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, mode, - insn, vd); + changed |= replace_oldest_value_addr (locI, INDEX_REG_CLASS, + mode, as, insn, vd); if (locB) changed |= replace_oldest_value_addr (locB, - base_reg_class (mode, PLUS, + base_reg_class (mode, as, PLUS, index_code), - mode, insn, vd); + mode, as, insn, vd); return changed; } @@ -648,12 +648,12 @@ replace_oldest_value_addr (rtx *loc, enum reg_class cl, for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode, + changed |= replace_oldest_value_addr (&XEXP (x, i), cl, mode, as, insn, vd); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) changed |= replace_oldest_value_addr (&XVECEXP (x, i, j), cl, - mode, insn, vd); + mode, as, insn, vd); } return changed; @@ -669,10 +669,11 @@ replace_oldest_value_mem (rtx x, rtx insn, struct value_data *vd) if (DEBUG_INSN_P (insn)) cl = ALL_REGS; else - cl = base_reg_class (GET_MODE (x), MEM, SCRATCH); + cl = base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), MEM, SCRATCH); return replace_oldest_value_addr (&XEXP (x, 0), cl, - GET_MODE (x), insn, vd); + GET_MODE (x), MEM_ADDR_SPACE (x), + insn, vd); } /* Apply all queued updates for DEBUG_INSNs that change some reg to @@ -751,7 +752,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) if (!VAR_LOC_UNKNOWN_P (loc)) replace_oldest_value_addr (&INSN_VAR_LOCATION_LOC (insn), ALL_REGS, GET_MODE (loc), - insn, vd); + ADDR_SPACE_GENERIC, insn, vd); } if (insn == BB_END (bb)) @@ -913,7 +914,8 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) replaced[i] = replace_oldest_value_addr (recog_data.operand_loc[i], recog_op_alt[i][alt].cl, - VOIDmode, insn, vd); + VOIDmode, ADDR_SPACE_GENERIC, + insn, vd); else if (REG_P (recog_data.operand[i])) replaced[i] = replace_oldest_value_reg (recog_data.operand_loc[i], diff --git a/gcc/regrename.c b/gcc/regrename.c index 1823558..de39e90 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -1182,7 +1182,8 @@ scan_rtx_reg (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action, static void scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, - enum scan_actions action, enum machine_mode mode) + enum scan_actions action, enum machine_mode mode, + addr_space_t as) { rtx x = *loc; RTX_CODE code = GET_CODE (x); @@ -1250,15 +1251,15 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, unsigned regno0 = REGNO (op0), regno1 = REGNO (op1); if (REGNO_OK_FOR_INDEX_P (regno1) - && regno_ok_for_base_p (regno0, mode, PLUS, REG)) + && regno_ok_for_base_p (regno0, mode, as, PLUS, REG)) index_op = 1; else if (REGNO_OK_FOR_INDEX_P (regno0) - && regno_ok_for_base_p (regno1, mode, PLUS, REG)) + && regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; - else if (regno_ok_for_base_p (regno0, mode, PLUS, REG) + else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG) || REGNO_OK_FOR_INDEX_P (regno1)) index_op = 1; - else if (regno_ok_for_base_p (regno1, mode, PLUS, REG)) + else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) index_op = 0; else index_op = 1; @@ -1281,10 +1282,11 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, } if (locI) - scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode); + scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode, as); if (locB) - scan_rtx_address (insn, locB, base_reg_class (mode, PLUS, index_code), - action, mode); + scan_rtx_address (insn, locB, + base_reg_class (mode, as, PLUS, index_code), + action, mode, as); return; } @@ -1304,8 +1306,9 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, case MEM: scan_rtx_address (insn, &XEXP (x, 0), - base_reg_class (GET_MODE (x), MEM, SCRATCH), action, - GET_MODE (x)); + base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), + MEM, SCRATCH), + action, GET_MODE (x), MEM_ADDR_SPACE (x)); return; case REG: @@ -1320,10 +1323,10 @@ scan_rtx_address (rtx insn, rtx *loc, enum reg_class cl, for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - scan_rtx_address (insn, &XEXP (x, i), cl, action, mode); + scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as); else if (fmt[i] == 'E') for (j = XVECLEN (x, i) - 1; j >= 0; j--) - scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode); + scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as); } } @@ -1356,8 +1359,9 @@ scan_rtx (rtx insn, rtx *loc, enum reg_class cl, enum scan_actions action, case MEM: scan_rtx_address (insn, &XEXP (x, 0), - base_reg_class (GET_MODE (x), MEM, SCRATCH), action, - GET_MODE (x)); + base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x), + MEM, SCRATCH), + action, GET_MODE (x), MEM_ADDR_SPACE (x)); return; case SET: @@ -1697,7 +1701,8 @@ build_def_use (basic_block bb) if (insn_info) cur_operand = i == opn ? insn_info->op_info + i : NULL; if (recog_op_alt[opn][alt].is_address) - scan_rtx_address (insn, loc, cl, mark_read, VOIDmode); + scan_rtx_address (insn, loc, cl, mark_read, + VOIDmode, ADDR_SPACE_GENERIC); else scan_rtx (insn, loc, cl, mark_read, type); } diff --git a/gcc/reload.c b/gcc/reload.c index 7dbc163..896e8de 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -277,7 +277,7 @@ static int find_reloads_address (enum machine_mode, rtx *, rtx, rtx *, static rtx subst_reg_equivs (rtx, rtx); static rtx subst_indexed_address (rtx); static void update_auto_inc_notes (rtx, int, int); -static int find_reloads_address_1 (enum machine_mode, rtx, int, +static int find_reloads_address_1 (enum machine_mode, addr_space_t, rtx, int, enum rtx_code, enum rtx_code, rtx *, int, enum reload_type,int, rtx); static void find_reloads_address_part (rtx, rtx *, enum reg_class, @@ -3239,8 +3239,9 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, case 'p': /* All necessary reloads for an address_operand were handled in find_reloads_address. */ - this_alternative[i] = base_reg_class (VOIDmode, ADDRESS, - SCRATCH); + this_alternative[i] + = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH); win = 1; badop = 0; break; @@ -3445,9 +3446,9 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, /* If we didn't already win, we can reload the address into a base register. */ - this_alternative[i] = base_reg_class (VOIDmode, - ADDRESS, - SCRATCH); + this_alternative[i] + = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH); badop = 0; break; } @@ -3977,18 +3978,16 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, /* If the address to be reloaded is a VOIDmode constant, use the default address mode as mode of the reload register, as would have been done by find_reloads_address. */ + addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]); enum machine_mode address_mode; address_mode = GET_MODE (XEXP (recog_data.operand[i], 0)); if (address_mode == VOIDmode) - { - addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]); - address_mode = targetm.addr_space.address_mode (as); - } + address_mode = targetm.addr_space.address_mode (as); operand_reloadnum[i] = push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX, &XEXP (recog_data.operand[i], 0), (rtx*) 0, - base_reg_class (VOIDmode, MEM, SCRATCH), + base_reg_class (VOIDmode, as, MEM, SCRATCH), address_mode, VOIDmode, 0, 0, i, RELOAD_FOR_INPUT); rld[operand_reloadnum[i]].inc @@ -4885,7 +4884,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, if (reg_equiv_constant (regno) != 0) { find_reloads_address_part (reg_equiv_constant (regno), loc, - base_reg_class (mode, MEM, SCRATCH), + base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (ad), opnum, type, ind_levels); return 1; } @@ -4948,12 +4947,13 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, subject of a CLOBBER in this insn. */ else if (regno < FIRST_PSEUDO_REGISTER - && regno_ok_for_base_p (regno, mode, MEM, SCRATCH) + && regno_ok_for_base_p (regno, mode, as, MEM, SCRATCH) && ! regno_clobbered_p (regno, this_insn, mode, 0)) return 0; /* If we do not have one of the cases above, we must do the reload. */ - push_reload (ad, NULL_RTX, loc, (rtx*) 0, base_reg_class (mode, MEM, SCRATCH), + push_reload (ad, NULL_RTX, loc, (rtx*) 0, + base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (ad), VOIDmode, 0, 0, opnum, type); return 1; } @@ -5054,7 +5054,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, /* Must use TEM here, not AD, since it is the one that will have any subexpressions reloaded, if needed. */ push_reload (tem, NULL_RTX, loc, (rtx*) 0, - base_reg_class (mode, MEM, SCRATCH), GET_MODE (tem), + base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (tem), VOIDmode, 0, 0, opnum, type); return ! removed_and; @@ -5072,7 +5072,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, && REG_P (XEXP (ad, 0)) && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER && CONST_INT_P (XEXP (ad, 1)) - && (regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, PLUS, + && (regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as, PLUS, CONST_INT) /* Similarly, if we were to reload the base register and the mem+offset address is still invalid, then we want to reload @@ -5091,7 +5091,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, } if (double_reg_address_ok - && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, + && regno_ok_for_base_p (REGNO (XEXP (ad, 0)), mode, as, PLUS, CONST_INT)) { /* Unshare the sum as well. */ @@ -5110,7 +5110,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, reload the sum into a base reg. That will at least work. */ find_reloads_address_part (ad, loc, - base_reg_class (mode, MEM, SCRATCH), + base_reg_class (mode, as, MEM, SCRATCH), GET_MODE (ad), opnum, type, ind_levels); } return ! removed_and; @@ -5162,7 +5162,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, addend = XEXP (XEXP (ad, 0), 1 - op_index); - if ((regno_ok_for_base_p (REGNO (operand), mode, inner_code, + if ((regno_ok_for_base_p (REGNO (operand), mode, as, inner_code, GET_CODE (addend)) || operand == frame_pointer_rtx #if !HARD_FRAME_POINTER_IS_FRAME_POINTER @@ -5191,11 +5191,11 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, op_index == 0 ? addend : offset_reg); *loc = ad; - cls = base_reg_class (mode, MEM, GET_CODE (addend)); + cls = base_reg_class (mode, as, MEM, GET_CODE (addend)); find_reloads_address_part (XEXP (ad, op_index), &XEXP (ad, op_index), cls, GET_MODE (ad), opnum, type, ind_levels); - find_reloads_address_1 (mode, + find_reloads_address_1 (mode, as, XEXP (ad, 1 - op_index), 1, GET_CODE (ad), GET_CODE (XEXP (ad, op_index)), &XEXP (ad, 1 - op_index), opnum, @@ -5248,13 +5248,14 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad, loc = &XEXP (*loc, 0); } - find_reloads_address_part (ad, loc, base_reg_class (mode, MEM, SCRATCH), + find_reloads_address_part (ad, loc, + base_reg_class (mode, as, MEM, SCRATCH), address_mode, opnum, type, ind_levels); return ! removed_and; } - return find_reloads_address_1 (mode, ad, 0, MEM, SCRATCH, loc, opnum, type, - ind_levels, insn); + return find_reloads_address_1 (mode, as, ad, 0, MEM, SCRATCH, loc, + opnum, type, ind_levels, insn); } /* Find all pseudo regs appearing in AD @@ -5487,14 +5488,15 @@ update_auto_inc_notes (rtx insn ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED, handles those cases gracefully. */ static int -find_reloads_address_1 (enum machine_mode mode, rtx x, int context, +find_reloads_address_1 (enum machine_mode mode, addr_space_t as, + rtx x, int context, enum rtx_code outer_code, enum rtx_code index_code, rtx *loc, int opnum, enum reload_type type, int ind_levels, rtx insn) { -#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, OUTER, INDEX) \ +#define REG_OK_FOR_CONTEXT(CONTEXT, REGNO, MODE, AS, OUTER, INDEX) \ ((CONTEXT) == 0 \ - ? regno_ok_for_base_p (REGNO, MODE, OUTER, INDEX) \ + ? regno_ok_for_base_p (REGNO, MODE, AS, OUTER, INDEX) \ : REGNO_OK_FOR_INDEX_P (REGNO)) enum reg_class context_reg_class; @@ -5503,7 +5505,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, if (context == 1) context_reg_class = INDEX_REG_CLASS; else - context_reg_class = base_reg_class (mode, outer_code, index_code); + context_reg_class = base_reg_class (mode, as, outer_code, index_code); switch (code) { @@ -5560,10 +5562,10 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE || code0 == ZERO_EXTEND || code1 == MEM) { - find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0, + find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0, &XEXP (x, 1), opnum, type, ind_levels, insn); } @@ -5571,56 +5573,56 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE || code1 == ZERO_EXTEND || code0 == MEM) { - find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1, &XEXP (x, 0), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); } else if (code0 == CONST_INT || code0 == CONST || code0 == SYMBOL_REF || code0 == LABEL_REF) - find_reloads_address_1 (mode, orig_op1, 0, PLUS, code0, + find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, code0, &XEXP (x, 1), opnum, type, ind_levels, insn); else if (code1 == CONST_INT || code1 == CONST || code1 == SYMBOL_REF || code1 == LABEL_REF) - find_reloads_address_1 (mode, orig_op0, 0, PLUS, code1, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, code1, &XEXP (x, 0), opnum, type, ind_levels, insn); else if (code0 == REG && code1 == REG) { if (REGNO_OK_FOR_INDEX_P (REGNO (op1)) - && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG)) + && regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG)) return 0; else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)) - && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG)) + && regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG)) return 0; - else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG)) - find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, + else if (regno_ok_for_base_p (REGNO (op0), mode, as, PLUS, REG)) + find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); else if (REGNO_OK_FOR_INDEX_P (REGNO (op1))) - find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG, &XEXP (x, 0), opnum, type, ind_levels, insn); - else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG)) - find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH, + else if (regno_ok_for_base_p (REGNO (op1), mode, as, PLUS, REG)) + find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); else if (REGNO_OK_FOR_INDEX_P (REGNO (op0))) - find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG, &XEXP (x, 1), opnum, type, ind_levels, insn); else { - find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG, &XEXP (x, 0), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); } @@ -5628,20 +5630,20 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, else if (code0 == REG) { - find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op0, 1, PLUS, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op1, 0, PLUS, REG, &XEXP (x, 1), opnum, type, ind_levels, insn); } else if (code1 == REG) { - find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH, + find_reloads_address_1 (mode, as, orig_op1, 1, PLUS, SCRATCH, &XEXP (x, 1), opnum, type, ind_levels, insn); - find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG, + find_reloads_address_1 (mode, as, orig_op0, 0, PLUS, REG, &XEXP (x, 0), opnum, type, ind_levels, insn); } @@ -5683,7 +5685,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, if ((REG_P (XEXP (op1, 1)) && !REGNO_OK_FOR_INDEX_P (REGNO (XEXP (op1, 1)))) || GET_CODE (XEXP (op1, 1)) == PLUS) - find_reloads_address_1 (mode, XEXP (op1, 1), 1, code, SCRATCH, + find_reloads_address_1 (mode, as, XEXP (op1, 1), 1, code, SCRATCH, &XEXP (op1, 1), opnum, RELOAD_OTHER, ind_levels, insn); @@ -5725,8 +5727,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, register. */ reloadnum = push_reload (tem, tem, &XEXP (x, 0), &XEXP (op1, 0), - base_reg_class (mode, code, - index_code), + base_reg_class (mode, as, + code, index_code), GET_MODE (x), GET_MODE (x), 0, 0, opnum, RELOAD_OTHER); @@ -5739,11 +5741,12 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, regno = reg_renumber[regno]; /* We require a base register here... */ - if (!regno_ok_for_base_p (regno, GET_MODE (x), code, index_code)) + if (!regno_ok_for_base_p (regno, GET_MODE (x), as, code, index_code)) { reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0), &XEXP (op1, 0), &XEXP (x, 0), - base_reg_class (mode, code, index_code), + base_reg_class (mode, as, + code, index_code), GET_MODE (x), GET_MODE (x), 0, 0, opnum, RELOAD_OTHER); @@ -5809,7 +5812,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, if (reg_renumber[regno] >= 0) regno = reg_renumber[regno]; if (regno >= FIRST_PSEUDO_REGISTER - || !REG_OK_FOR_CONTEXT (context, regno, mode, code, + || !REG_OK_FOR_CONTEXT (context, regno, mode, as, code, index_code)) { int reloadnum; @@ -5878,7 +5881,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, reloaded. Targets that are better off reloading just either part (or perhaps even a different part of an outer expression), should define LEGITIMIZE_RELOAD_ADDRESS. */ - find_reloads_address_1 (GET_MODE (XEXP (x, 0)), XEXP (x, 0), + find_reloads_address_1 (GET_MODE (XEXP (x, 0)), as, XEXP (x, 0), context, code, SCRATCH, &XEXP (x, 0), opnum, type, ind_levels, insn); push_reload (x, NULL_RTX, loc, (rtx*) 0, @@ -5949,7 +5952,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, regno = reg_renumber[regno]; if (regno >= FIRST_PSEUDO_REGISTER - || !REG_OK_FOR_CONTEXT (context, regno, mode, outer_code, + || !REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code, index_code)) { push_reload (x, NULL_RTX, loc, (rtx*) 0, @@ -5982,7 +5985,7 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, { int regno ATTRIBUTE_UNUSED = subreg_regno (x); - if (!REG_OK_FOR_CONTEXT (context, regno, mode, outer_code, + if (!REG_OK_FOR_CONTEXT (context, regno, mode, as, outer_code, index_code)) { push_reload (x, NULL_RTX, loc, (rtx*) 0, @@ -6023,8 +6026,9 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context, if (fmt[i] == 'e') /* Pass SCRATCH for INDEX_CODE, since CODE can never be a PLUS once we get here. */ - find_reloads_address_1 (mode, XEXP (x, i), context, code, SCRATCH, - &XEXP (x, i), opnum, type, ind_levels, insn); + find_reloads_address_1 (mode, as, XEXP (x, i), context, + code, SCRATCH, &XEXP (x, i), + opnum, type, ind_levels, insn); } } @@ -6201,7 +6205,9 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum, MEM_ADDR_SPACE (reg_equiv_mem (regno)))) { push_reload (XEXP (tem, 0), NULL_RTX, &XEXP (tem, 0), (rtx*) 0, - base_reg_class (GET_MODE (tem), MEM, SCRATCH), + base_reg_class (GET_MODE (tem), + MEM_ADDR_SPACE (tem), + MEM, SCRATCH), GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0, opnum, type); reloaded = 1; diff --git a/gcc/reload1.c b/gcc/reload1.c index c9fb57b..2f783a2 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1422,7 +1422,8 @@ maybe_fix_stack_asms (void) case 'p': cls = (int) reg_class_subunion[cls] - [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; break; case 'g': @@ -1433,7 +1434,8 @@ maybe_fix_stack_asms (void) default: if (EXTRA_ADDRESS_CONSTRAINT (c, p)) cls = (int) reg_class_subunion[cls] - [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH)]; else cls = (int) reg_class_subunion[cls] [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]; -- 2.7.4