summaryrefslogtreecommitdiff
path: root/gcc/reload.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/reload.c')
-rw-r--r--gcc/reload.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/gcc/reload.c b/gcc/reload.c
index 41d671d3146..67f411b9040 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -2641,7 +2641,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
if (*constraints[i] == 0)
/* Ignore things like match_operator operands. */
;
- else if (constraints[i][0] == 'p')
+ else if (constraints[i][0] == 'p'
+ || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
{
find_reloads_address (VOIDmode, (rtx*) 0,
recog_data.operand[i],
@@ -3222,6 +3223,49 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
{
#ifdef EXTRA_CONSTRAINT
+ if (EXTRA_MEMORY_CONSTRAINT (c))
+ {
+ if (force_reload)
+ break;
+ if (EXTRA_CONSTRAINT (operand, c))
+ win = 1;
+ /* If the address was already reloaded,
+ we win as well. */
+ if (GET_CODE (operand) == MEM && address_reloaded[i])
+ win = 1;
+ /* Likewise if the address will be reloaded because
+ reg_equiv_address is nonzero. For reg_equiv_mem
+ we have to check. */
+ if (GET_CODE (operand) == REG
+ && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+ && reg_renumber[REGNO (operand)] < 0
+ && ((reg_equiv_mem[REGNO (operand)] != 0
+ && EXTRA_CONSTRAINT (reg_equiv_mem[REGNO (operand)], c))
+ || (reg_equiv_address[REGNO (operand)] != 0)))
+ win = 1;
+
+ /* If we didn't already win, we can reload
+ constants via force_const_mem, and other
+ MEMs by reloading the address like for 'o'. */
+ if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
+ || GET_CODE (operand) == MEM)
+ badop = 0;
+ constmemok = 1;
+ offmemok = 1;
+ break;
+ }
+ if (EXTRA_ADDRESS_CONSTRAINT (c))
+ {
+ if (EXTRA_CONSTRAINT (operand, c))
+ win = 1;
+
+ /* If we didn't already win, we can reload
+ the address into a base register. */
+ this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
+ badop = 0;
+ break;
+ }
+
if (EXTRA_CONSTRAINT (operand, c))
win = 1;
#endif
@@ -4291,7 +4335,7 @@ alternative_allows_memconst (constraint, altnum)
/* Scan the requested alternative for 'm' or 'o'.
If one of them is present, this alternative accepts memory constants. */
while ((c = *constraint++) && c != ',' && c != '#')
- if (c == 'm' || c == 'o')
+ if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
return 1;
return 0;
}