else if (regno < FIRST_PSEUDO_REGISTER
&& REGNO_MODE_OK_FOR_BASE_P (regno, mode)
- && ! regno_clobbered_p (regno, this_insn, mode))
+ && ! 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. */
if (REG_P (XEXP (op1, 0)))
{
- register int regno = REGNO (XEXP (op1, 0));
+ rtx link;
+ int regno = REGNO (XEXP (op1, 0));
+ int reloadnum;
/* A register that is incremented cannot be constant! */
if (regno >= FIRST_PSEUDO_REGISTER
write back the value after reading it, hence we actually
need two registers. */
find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
- &XEXP (tem, 0), opnum, type,
+ &XEXP (tem, 0), opnum,
+ RELOAD_OTHER,
ind_levels, insn);
/* Then reload the memory location into a base
register. */
- push_reload (tem, tem, &XEXP (x, 0), &XEXP (op1, 0),
- BASE_REG_CLASS, GET_MODE (x), GET_MODE (x),
- 0, 0, opnum, RELOAD_OTHER);
- break;
+ reloadnum = push_reload (tem, tem, &XEXP (x, 0),
+ &XEXP (op1, 0), BASE_REG_CLASS,
+ GET_MODE (x), GET_MODE (x), 0,
+ 0, opnum, RELOAD_OTHER);
+ goto reg_inc;
}
}
/* We require a base register here... */
if (!REGNO_MODE_OK_FOR_BASE_P (regno, GET_MODE (x)))
{
- push_reload (XEXP (op1, 0), XEXP (x, 0),
- &XEXP (op1, 0), &XEXP (x, 0),
- BASE_REG_CLASS,
- GET_MODE (x), GET_MODE (x), 0, 0,
- opnum, RELOAD_OTHER);
+ reloadnum = push_reload (XEXP (op1, 0), XEXP (x, 0),
+ &XEXP (op1, 0), &XEXP (x, 0),
+ BASE_REG_CLASS,
+ GET_MODE (x), GET_MODE (x), 0, 0,
+ opnum, RELOAD_OTHER);
}
+
+ /* Update the REG_INC notes. */
+ reg_inc:
+ for (link = REG_NOTES (this_insn); link; link = XEXP (link, 1))
+ if (REG_NOTE_KIND (link) == REG_INC
+ && REGNO (XEXP (link, 0)) == regno)
+ push_replacement (&XEXP (link, 0), reloadnum, VOIDmode);
}
else
abort ();
in this insn, reload it into some other register to be safe.
The CLOBBER is supposed to make the register unavailable
from before this insn to after it. */
- if (regno_clobbered_p (regno, this_insn, GET_MODE (x)))
+ if (regno_clobbered_p (regno, this_insn, GET_MODE (x), 0))
{
push_reload (x, NULL_RTX, loc, NULL_PTR,
(context ? INDEX_REG_CLASS : BASE_REG_CLASS),
return 0;
}
\f
-/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
+/* Return 1 if register REGNO is the subject of a clobber in insn INSN.
+ If SETS is nonzero, also consider SETs. */
int
-regno_clobbered_p (regno, insn, mode)
+regno_clobbered_p (regno, insn, mode, sets)
unsigned int regno;
rtx insn;
enum machine_mode mode;
+ int sets;
{
int nregs = HARD_REGNO_NREGS (regno, mode);
int endregno = regno + nregs;
- if (GET_CODE (PATTERN (insn)) == CLOBBER
+ if ((GET_CODE (PATTERN (insn)) == CLOBBER
+ || (sets && GET_CODE (PATTERN (insn)) == SET))
&& GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
{
int test = REGNO (XEXP (PATTERN (insn), 0));
for (; i >= 0; i--)
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
- if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG)
+ if ((GET_CODE (elt) == CLOBBER
+ || (sets && GET_CODE (PATTERN (insn)) == SET))
+ && GET_CODE (XEXP (elt, 0)) == REG)
{
int test = REGNO (XEXP (elt, 0));
In particular, we then can't use EQUIV for a
RELOAD_FOR_OUTPUT_ADDRESS reload. */
- if (equiv != 0 && regno_clobbered_p (regno, insn, rld[r].mode))
- {
- switch (rld[r].when_needed)
- {
- case RELOAD_FOR_OTHER_ADDRESS:
- case RELOAD_FOR_INPADDR_ADDRESS:
- case RELOAD_FOR_INPUT_ADDRESS:
- case RELOAD_FOR_OPADDR_ADDR:
- break;
- case RELOAD_OTHER:
- case RELOAD_FOR_INPUT:
- case RELOAD_FOR_OPERAND_ADDRESS:
- if (! rld[r].optional)
- reload_override_in[r] = equiv;
- /* Fall through. */
- default:
- equiv = 0;
- break;
- }
+ if (equiv != 0)
+ {
+ if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
+ switch (rld[r].when_needed)
+ {
+ case RELOAD_FOR_OTHER_ADDRESS:
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ case RELOAD_FOR_INPUT_ADDRESS:
+ case RELOAD_FOR_OPADDR_ADDR:
+ break;
+ case RELOAD_OTHER:
+ case RELOAD_FOR_INPUT:
+ case RELOAD_FOR_OPERAND_ADDRESS:
+ if (! rld[r].optional)
+ reload_override_in[r] = equiv;
+ /* Fall through. */
+ default:
+ equiv = 0;
+ break;
+ }
+ else if (regno_clobbered_p (regno, insn, rld[r].mode, 1))
+ switch (rld[r].when_needed)
+ {
+ case RELOAD_FOR_OTHER_ADDRESS:
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ case RELOAD_FOR_INPUT_ADDRESS:
+ case RELOAD_FOR_OPADDR_ADDR:
+ case RELOAD_FOR_OPERAND_ADDRESS:
+ case RELOAD_FOR_INPUT:
+ break;
+ case RELOAD_OTHER:
+ if (! rld[r].optional)
+ reload_override_in[r] = equiv;
+ /* Fall through. */
+ default:
+ equiv = 0;
+ break;
+ }
}
/* If we found an equivalent reg, say no code need be generated
|| !(set = single_set (insn))
|| rtx_equal_p (old, SET_DEST (set))
|| !reg_mentioned_p (old, SET_SRC (set))
- || !regno_clobbered_p (REGNO (old), insn, rl->mode))
+ || !regno_clobbered_p (REGNO (old), insn, rl->mode, 0))
gen_reload (old, reloadreg, rl->opnum,
rl->when_needed);
}