#include "expr.h"
#include "optabs.h"
#include "regs.h"
+#include "addresses.h"
#include "basic-block.h"
#include "reload.h"
#include "recog.h"
/* We allocate reg_equiv_memory_loc inside a varray so that the garbage
collector can keep track of what is inside. */
-varray_type reg_equiv_memory_loc_varray;
+VEC(rtx,gc) *reg_equiv_memory_loc_vec;
/* Element N is the address of stack slot to which pseudo reg N is equivalent.
This is used when the address is not valid as a memory address
INIT_REG_SET (&spilled_pseudos);
INIT_REG_SET (&pseudos_counted);
- VARRAY_RTX_INIT (reg_equiv_memory_loc_varray, 0, "reg_equiv_memory_loc");
}
/* List of insn chains that are currently unused. */
free (reg_equiv_invariant);
reg_equiv_constant = 0;
reg_equiv_invariant = 0;
- VARRAY_GROW (reg_equiv_memory_loc_varray, 0);
+ VEC_free (rtx, gc, reg_equiv_memory_loc_vec);
reg_equiv_memory_loc = 0;
if (offsets_known_at)
case 'p':
cls = (int) reg_class_subunion[cls]
- [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
break;
case 'g':
default:
if (EXTRA_ADDRESS_CONSTRAINT (c, p))
cls = (int) reg_class_subunion[cls]
- [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+ [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
else
cls = (int) reg_class_subunion[cls]
[(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
new = eliminate_regs_1 (XEXP (x, i), mem_mode, insn, false);
if (new != XEXP (x, i) && ! copied)
{
- rtx new_x = rtx_alloc (code);
- memcpy (new_x, x, RTX_SIZE (code));
- x = new_x;
+ x = shallow_copy_rtx (x);
copied = 1;
}
XEXP (x, i) = new;
XVEC (x, i)->elem);
if (! copied)
{
- rtx new_x = rtx_alloc (code);
- memcpy (new_x, x, RTX_SIZE (code));
- x = new_x;
+ x = shallow_copy_rtx (x);
copied = 1;
}
XVEC (x, i) = new_v;
mode = GET_MODE (rld[r].in_reg);
}
#ifdef AUTO_INC_DEC
- else if ((GET_CODE (rld[r].in_reg) == PRE_INC
- || GET_CODE (rld[r].in_reg) == PRE_DEC
- || GET_CODE (rld[r].in_reg) == POST_INC
- || GET_CODE (rld[r].in_reg) == POST_DEC)
+ else if (GET_RTX_CLASS (GET_CODE (rld[r].in_reg)) == RTX_AUTOINC
&& REG_P (XEXP (rld[r].in_reg, 0)))
{
regno = REGNO (XEXP (rld[r].in_reg, 0));
if (equiv != 0)
{
- if (regno_clobbered_p (regno, insn, rld[r].mode, 0))
+ if (regno_clobbered_p (regno, insn, rld[r].mode, 2))
switch (rld[r].when_needed)
{
case RELOAD_FOR_OTHER_ADDRESS:
/* If a register gets output-reloaded from a non-spill register,
that invalidates any previous reloaded copy of it.
But forget_old_reloads_1 won't get to see it, because
- it thinks only about the original insn. So invalidate it here. */
- if (i < 0 && rld[r].out != 0
- && (REG_P (rld[r].out)
- || (MEM_P (rld[r].out)
+ it thinks only about the original insn. So invalidate it here.
+ Also do the same thing for RELOAD_OTHER constraints where the
+ output is discarded. */
+ if (i < 0
+ && ((rld[r].out != 0
+ && (REG_P (rld[r].out)
+ || (MEM_P (rld[r].out)
+ && REG_P (rld[r].out_reg))))
+ || (rld[r].out == 0 && rld[r].out_reg
&& REG_P (rld[r].out_reg))))
{
- rtx out = (REG_P (rld[r].out)
+ rtx out = ((rld[r].out && REG_P (rld[r].out))
? rld[r].out : rld[r].out_reg);
int nregno = REGNO (out);
if (nregno >= FIRST_PSEUDO_REGISTER)
}
else
{
- int num_regs = hard_regno_nregs[nregno][GET_MODE (rld[r].out)];
+ int num_regs = hard_regno_nregs[nregno][GET_MODE (out)];
while (num_regs-- > 0)
reg_last_reload_reg[nregno + num_regs] = 0;
rtx out_moded;
rtx set;
+ op1 = find_replacement (&XEXP (in, 0));
+ if (op1 != XEXP (in, 0))
+ in = gen_rtx_fmt_e (GET_CODE (in), GET_MODE (in), op1);
+
/* First, try a plain SET. */
set = emit_insn_if_valid_for_reload (gen_rtx_SET (VOIDmode, out, in));
if (set)
/* If that failed, move the inner operand to the reload
register, and try the same unop with the inner expression
replaced with the reload register. */
- op1 = XEXP (in, 0);
if (GET_MODE (op1) != GET_MODE (out))
out_moded = gen_rtx_REG (GET_MODE (op1), REGNO (out));
/* REG or MEM to be copied and incremented. */
rtx incloc = XEXP (value, 0);
/* Nonzero if increment after copying. */
- int post = (GET_CODE (value) == POST_DEC || GET_CODE (value) == POST_INC);
+ int post = (GET_CODE (value) == POST_DEC || GET_CODE (value) == POST_INC
+ || GET_CODE (value) == POST_MODIFY);
rtx last;
rtx inc;
rtx add_insn;
if (REG_P (incloc))
reg_last_reload_reg[REGNO (incloc)] = 0;
- if (GET_CODE (value) == PRE_DEC || GET_CODE (value) == POST_DEC)
- inc_amount = -inc_amount;
+ if (GET_CODE (value) == PRE_MODIFY || GET_CODE (value) == POST_MODIFY)
+ {
+ gcc_assert (GET_CODE (XEXP (value, 1)) == PLUS);
+ inc = XEXP (XEXP (value, 1), 1);
+ }
+ else
+ {
+ if (GET_CODE (value) == PRE_DEC || GET_CODE (value) == POST_DEC)
+ inc_amount = -inc_amount;
- inc = GEN_INT (inc_amount);
+ inc = GEN_INT (inc_amount);
+ }
/* If this is post-increment, first copy the location to the reload reg. */
if (post && real_in != reloadreg)
emit_insn (gen_add2_insn (reloadreg, inc));
store = emit_insn (gen_move_insn (incloc, reloadreg));
- emit_insn (gen_add2_insn (reloadreg, GEN_INT (-inc_amount)));
+ if (GET_CODE (inc) == CONST_INT)
+ emit_insn (gen_add2_insn (reloadreg, GEN_INT (-INTVAL(inc))));
+ else
+ emit_insn (gen_sub2_insn (reloadreg, inc));
}
return store;