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 <avr@gjlay.de>

From-SVN: r181175
This commit is contained in:
Ulrich Weigand 2011-11-08 17:36:45 +00:00 committed by Ulrich Weigand
parent ca8dc27473
commit 86fc3d06b0
17 changed files with 274 additions and 175 deletions

View File

@ -1,3 +1,65 @@
2011-11-08 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
Georg-Johann Lay <avr@gjlay.de>
* 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 <matz@suse.de>
* gengtype.c (write_field_root): Avoid out-of-scope access of newv.

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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],

View File

@ -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);
}

View File

@ -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;

View File

@ -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)];