summaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c108
1 files changed, 64 insertions, 44 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index 1435945d62c..3333697f2e0 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -268,7 +268,8 @@ static bool alternative_allows_const_pool_ref (rtx, const char *, int);
static rtx find_reloads_toplev (rtx, int, enum reload_type, int, int, rtx,
int *);
static rtx make_memloc (rtx, int);
-static int maybe_memory_address_p (enum machine_mode, rtx, rtx *);
+static int maybe_memory_address_addr_space_p (enum machine_mode, rtx,
+ addr_space_t, rtx *);
static int find_reloads_address (enum machine_mode, rtx *, rtx, rtx *,
int, enum reload_type, int, rtx);
static rtx subst_reg_equivs (rtx, rtx);
@@ -612,7 +613,8 @@ get_secondary_mem (rtx x ATTRIBUTE_UNUSED, enum machine_mode mode,
didn't give us a new MEM, make a new one if it isn't valid. */
loc = eliminate_regs (secondary_memlocs[(int) mode], VOIDmode, NULL_RTX);
- mem_valid = strict_memory_address_p (mode, XEXP (loc, 0));
+ mem_valid = strict_memory_address_addr_space_p (mode, XEXP (loc, 0),
+ MEM_ADDR_SPACE (loc));
if (! mem_valid && loc == secondary_memlocs[(int) mode])
loc = copy_rtx (loc);
@@ -2129,21 +2131,23 @@ hard_reg_set_here_p (unsigned int beg_regno, unsigned int end_regno, rtx x)
return 0;
}
-/* Return 1 if ADDR is a valid memory address for mode MODE,
- and check that each pseudo reg has the proper kind of
- hard reg. */
+/* Return 1 if ADDR is a valid memory address for mode MODE
+ in address space AS, and check that each pseudo reg has the
+ proper kind of hard reg. */
int
-strict_memory_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx addr)
+strict_memory_address_addr_space_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ rtx addr, addr_space_t as)
{
#ifdef GO_IF_LEGITIMATE_ADDRESS
+ gcc_assert (ADDR_SPACE_GENERIC_P (as));
GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
return 0;
win:
return 1;
#else
- return targetm.legitimate_address_p (mode, addr, 1);
+ return targetm.addr_space.legitimate_address_p (mode, addr, 1, as);
#endif
}
@@ -2247,6 +2251,10 @@ operands_match_p (rtx x, rtx y)
if (GET_MODE (x) != GET_MODE (y))
return 0;
+ /* MEMs refering to different address space are not equivalent. */
+ if (code == MEM && MEM_ADDR_SPACE (x) != MEM_ADDR_SPACE (y))
+ return 0;
+
switch (code)
{
case CONST_INT:
@@ -3979,12 +3987,15 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
&& MEM_P (recog_data.operand[i]))
{
/* If the address to be reloaded is a VOIDmode constant,
- use Pmode as mode of the reload register, as would have
- been done by find_reloads_address. */
+ use the default address mode as mode of the reload register,
+ as would have been done by find_reloads_address. */
enum machine_mode address_mode;
address_mode = GET_MODE (XEXP (recog_data.operand[i], 0));
if (address_mode == VOIDmode)
- address_mode = Pmode;
+ {
+ addr_space_t as = MEM_ADDR_SPACE (recog_data.operand[i]);
+ address_mode = targetm.addr_space.address_mode (as);
+ }
operand_reloadnum[i]
= push_reload (XEXP (recog_data.operand[i], 0), NULL_RTX,
@@ -4760,8 +4771,9 @@ find_reloads_toplev (rtx x, int opnum, enum reload_type type,
#endif
&& (reg_equiv_address[regno] != 0
|| (reg_equiv_mem[regno] != 0
- && (! strict_memory_address_p (GET_MODE (x),
- XEXP (reg_equiv_mem[regno], 0))
+ && (! strict_memory_address_addr_space_p
+ (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
+ MEM_ADDR_SPACE (reg_equiv_mem[regno]))
|| ! offsettable_memref_p (reg_equiv_mem[regno])
|| num_not_at_initial_offset))))
x = find_reloads_subreg_address (x, 1, opnum, type, ind_levels,
@@ -4819,18 +4831,19 @@ make_memloc (rtx ad, int regno)
}
/* Returns true if AD could be turned into a valid memory reference
- to mode MODE by reloading the part pointed to by PART into a
- register. */
+ to mode MODE in address space AS by reloading the part pointed to
+ by PART into a register. */
static int
-maybe_memory_address_p (enum machine_mode mode, rtx ad, rtx *part)
+maybe_memory_address_addr_space_p (enum machine_mode mode, rtx ad,
+ addr_space_t as, rtx *part)
{
int retv;
rtx tem = *part;
rtx reg = gen_rtx_REG (GET_MODE (tem), max_reg_num ());
*part = reg;
- retv = memory_address_p (mode, ad);
+ retv = memory_address_addr_space_p (mode, ad, as);
*part = tem;
return retv;
@@ -4866,6 +4879,8 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
rtx *loc, int opnum, enum reload_type type,
int ind_levels, rtx insn)
{
+ addr_space_t as = memrefloc? MEM_ADDR_SPACE (*memrefloc)
+ : ADDR_SPACE_GENERIC;
int regno;
int removed_and = 0;
int op_index;
@@ -4893,7 +4908,9 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
if (reg_equiv_address[regno] != 0 || num_not_at_initial_offset)
{
tem = make_memloc (ad, regno);
- if (! strict_memory_address_p (GET_MODE (tem), XEXP (tem, 0)))
+ if (! strict_memory_address_addr_space_p (GET_MODE (tem),
+ XEXP (tem, 0),
+ MEM_ADDR_SPACE (tem)))
{
rtx orig = tem;
@@ -4909,7 +4926,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
address: only reg or reg+constant. */
if (ind_levels > 0
- && strict_memory_address_p (mode, tem)
+ && strict_memory_address_addr_space_p (mode, tem, as)
&& (REG_P (XEXP (tem, 0))
|| (GET_CODE (XEXP (tem, 0)) == PLUS
&& REG_P (XEXP (XEXP (tem, 0), 0))
@@ -4953,7 +4970,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
return 1;
}
- if (strict_memory_address_p (mode, ad))
+ if (strict_memory_address_addr_space_p (mode, ad, as))
{
/* The address appears valid, so reloads are not needed.
But the address may contain an eliminable register.
@@ -4976,14 +4993,14 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
return 0;
/* Check result for validity after substitution. */
- if (strict_memory_address_p (mode, ad))
+ if (strict_memory_address_addr_space_p (mode, ad, as))
return 0;
}
#ifdef LEGITIMIZE_RELOAD_ADDRESS
do
{
- if (memrefloc)
+ if (memrefloc && ADDR_SPACE_GENERIC_P (as))
{
LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
ind_levels, win);
@@ -5099,7 +5116,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
That will at least work. */
find_reloads_address_part (ad, loc,
base_reg_class (mode, MEM, SCRATCH),
- Pmode, opnum, type, ind_levels);
+ GET_MODE (ad), opnum, type, ind_levels);
}
return ! removed_and;
}
@@ -5160,8 +5177,8 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|| operand == arg_pointer_rtx
#endif
|| operand == stack_pointer_rtx)
- && ! maybe_memory_address_p (mode, ad,
- &XEXP (XEXP (ad, 0), 1 - op_index)))
+ && ! maybe_memory_address_addr_space_p
+ (mode, ad, as, &XEXP (XEXP (ad, 0), 1 - op_index)))
{
rtx offset_reg;
enum reg_class cls;
@@ -5199,7 +5216,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
tem = ad;
if (GET_CODE (ad) == PLUS)
tem = subst_indexed_address (ad);
- if (tem != ad && strict_memory_address_p (mode, tem))
+ if (tem != ad && strict_memory_address_addr_space_p (mode, tem, as))
{
/* Ok, we win that way. Replace any additional eliminable
registers. */
@@ -5209,7 +5226,8 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
/* Make sure that didn't make the address invalid again. */
- if (! subst_reg_equivs_changed || strict_memory_address_p (mode, tem))
+ if (! subst_reg_equivs_changed
+ || strict_memory_address_addr_space_p (mode, tem, as))
{
*loc = tem;
return 0;
@@ -5218,8 +5236,12 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
/* If constants aren't valid addresses, reload the constant address
into a register. */
- if (CONSTANT_P (ad) && ! strict_memory_address_p (mode, ad))
+ if (CONSTANT_P (ad) && ! strict_memory_address_addr_space_p (mode, ad, as))
{
+ enum machine_mode address_mode = GET_MODE (ad);
+ if (ad == VOIDmode)
+ address_mode = targetm.addr_space.address_mode (as);
+
/* If AD is an address in the constant pool, the MEM rtx may be shared.
Unshare it so we can safely alter it. */
if (memrefloc && GET_CODE (ad) == SYMBOL_REF
@@ -5232,7 +5254,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
}
find_reloads_address_part (ad, loc, base_reg_class (mode, MEM, SCRATCH),
- Pmode, opnum, type, ind_levels);
+ address_mode, opnum, type, ind_levels);
return ! removed_and;
}
@@ -5319,16 +5341,12 @@ subst_reg_equivs (rtx ad, rtx insn)
This routine assumes both inputs are already in canonical form. */
rtx
-form_sum (rtx x, rtx y)
+form_sum (enum machine_mode mode, rtx x, rtx y)
{
rtx tem;
- enum machine_mode mode = GET_MODE (x);
-
- if (mode == VOIDmode)
- mode = GET_MODE (y);
- if (mode == VOIDmode)
- mode = Pmode;
+ gcc_assert (GET_MODE (x) == mode || GET_MODE (x) == VOIDmode);
+ gcc_assert (GET_MODE (y) == mode || GET_MODE (y) == VOIDmode);
if (CONST_INT_P (x))
return plus_constant (y, INTVAL (x));
@@ -5338,12 +5356,12 @@ form_sum (rtx x, rtx y)
tem = x, x = y, y = tem;
if (GET_CODE (x) == PLUS && CONSTANT_P (XEXP (x, 1)))
- return form_sum (XEXP (x, 0), form_sum (XEXP (x, 1), y));
+ return form_sum (mode, XEXP (x, 0), form_sum (mode, XEXP (x, 1), y));
/* Note that if the operands of Y are specified in the opposite
order in the recursive calls below, infinite recursion will occur. */
if (GET_CODE (y) == PLUS && CONSTANT_P (XEXP (y, 1)))
- return form_sum (form_sum (x, XEXP (y, 0)), XEXP (y, 1));
+ return form_sum (mode, form_sum (mode, x, XEXP (y, 0)), XEXP (y, 1));
/* If both constant, encapsulate sum. Otherwise, just form sum. A
constant will have been placed second. */
@@ -5410,9 +5428,9 @@ subst_indexed_address (rtx addr)
/* Compute the sum. */
if (op2 != 0)
- op1 = form_sum (op1, op2);
+ op1 = form_sum (GET_MODE (addr), op1, op2);
if (op1 != 0)
- op0 = form_sum (op0, op1);
+ op0 = form_sum (GET_MODE (addr), op0, op1);
return op0;
}
@@ -5812,7 +5830,8 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
rtx equiv = (MEM_P (XEXP (x, 0))
? XEXP (x, 0)
: reg_equiv_mem[regno]);
- int icode = (int) optab_handler (add_optab, Pmode)->insn_code;
+ int icode
+ = (int) optab_handler (add_optab, GET_MODE (x))->insn_code;
if (insn && NONJUMP_INSN_P (insn) && equiv
&& memory_operand (equiv, GET_MODE (equiv))
#ifdef HAVE_cc0
@@ -5820,9 +5839,9 @@ find_reloads_address_1 (enum machine_mode mode, rtx x, int context,
#endif
&& ! (icode != CODE_FOR_nothing
&& ((*insn_data[icode].operand[0].predicate)
- (equiv, Pmode))
+ (equiv, GET_MODE (x)))
&& ((*insn_data[icode].operand[1].predicate)
- (equiv, Pmode))))
+ (equiv, GET_MODE (x)))))
{
/* We use the original pseudo for loc, so that
emit_reload_insns() knows which pseudo this
@@ -6180,8 +6199,9 @@ find_reloads_subreg_address (rtx x, int force_replace, int opnum,
the address, there is nothing further to do. */
if (reloaded == 0
&& reg_equiv_mem[regno] != 0
- && !strict_memory_address_p (GET_MODE (x),
- XEXP (reg_equiv_mem[regno], 0)))
+ && !strict_memory_address_addr_space_p
+ (GET_MODE (x), XEXP (reg_equiv_mem[regno], 0),
+ 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),
GET_MODE (XEXP (tem, 0)), VOIDmode, 0, 0,