|| (when1) == RELOAD_FOR_OPERAND_ADDRESS \
|| (when1) == RELOAD_FOR_OTHER_ADDRESS))
+ /* If we are going to reload an address, compute the reload type to
+ use. */
+#define ADDR_TYPE(type) \
+ ((type) == RELOAD_FOR_INPUT_ADDRESS \
+ ? RELOAD_FOR_INPADDR_ADDRESS \
+ : ((type) == RELOAD_FOR_OUTPUT_ADDRESS \
+ ? RELOAD_FOR_OUTADDR_ADDRESS \
+ : (type)))
+
static int push_secondary_reload PROTO((int, rtx, int, int, enum reg_class,
enum machine_mode, enum reload_type,
enum insn_code *));
int i;
int s_reload, t_reload = -1;
- if (type == RELOAD_FOR_INPUT_ADDRESS || type == RELOAD_FOR_OUTPUT_ADDRESS)
+ if (type == RELOAD_FOR_INPUT_ADDRESS
+ || type == RELOAD_FOR_OUTPUT_ADDRESS
+ || type == RELOAD_FOR_INPADDR_ADDRESS
+ || type == RELOAD_FOR_OUTADDR_ADDRESS)
secondary_type = type;
else
secondary_type = in_p ? RELOAD_FOR_INPUT_ADDRESS : RELOAD_FOR_OUTPUT_ADDRESS;
if (reload_in[i] && ! reload_optional[i] && ! reload_nocombine[i]
/* Life span of this reload must not extend past main insn. */
&& reload_when_needed[i] != RELOAD_FOR_OUTPUT_ADDRESS
+ && reload_when_needed[i] != RELOAD_FOR_OUTADDR_ADDRESS
&& reload_when_needed[i] != RELOAD_OTHER
&& (CLASS_MAX_NREGS (reload_reg_class[i], reload_inmode[i])
== CLASS_MAX_NREGS (reload_reg_class[output_reload],
we must change these to RELOAD_FOR_INPUT_ADDRESS. */
if (modified[i] == RELOAD_WRITE)
- for (j = 0; j < n_reloads; j++)
- if (reload_opnum[j] == i
- && reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS)
- reload_when_needed[j] = RELOAD_FOR_INPUT_ADDRESS;
+ {
+ for (j = 0; j < n_reloads; j++)
+ {
+ if (reload_opnum[j] == i)
+ {
+ if (reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS)
+ reload_when_needed[j] = RELOAD_FOR_INPUT_ADDRESS;
+ else if (reload_when_needed[j]
+ == RELOAD_FOR_OUTADDR_ADDRESS)
+ reload_when_needed[j] = RELOAD_FOR_INPADDR_ADDRESS;
+ }
+ }
+ }
}
else if (goal_alternative_matched[i] == -1)
operand_reloadnum[i] =
for (j = i + 1; j < n_reloads; j++)
if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
- || reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS)
+ || reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
&& (reload_when_needed[j] == RELOAD_FOR_INPUT_ADDRESS
- || reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS)
+ || reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS
+ || reload_when_needed[j] == RELOAD_FOR_INPADDR_ADDRESS
+ || reload_when_needed[j] == RELOAD_FOR_OUTADDR_ADDRESS)
&& rtx_equal_p (reload_in[i], reload_in[j])
&& (operand_reloadnum[reload_opnum[i]] < 0
|| reload_optional[operand_reloadnum[reload_opnum[i]]])
if (replacements[k].what == j)
replacements[k].what = i;
- reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
+ if (reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
+ reload_when_needed[i] = RELOAD_FOR_OPADDR_ADDR;
+ else
+ reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
reload_in[j] = 0;
}
}
reload_when_needed[i] = address_type[reload_opnum[i]];
if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
- || reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS)
+ || reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
&& (operand_reloadnum[reload_opnum[i]] < 0
|| reload_optional[operand_reloadnum[reload_opnum[i]]]))
{
/* If we have a secondary reload to go along with this reload,
change its type to RELOAD_FOR_OPADDR_ADDR. */
- if (reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
+ if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
&& reload_secondary_in_reload[i] != -1)
{
int secondary_in_reload = reload_secondary_in_reload[i];
= RELOAD_FOR_OPADDR_ADDR;
}
- if (reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
+ if ((reload_when_needed[i] == RELOAD_FOR_OUTPUT_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
&& reload_secondary_out_reload[i] != -1)
{
int secondary_out_reload = reload_secondary_out_reload[i];
reload_when_needed[reload_secondary_out_reload[secondary_out_reload]]
= RELOAD_FOR_OPADDR_ADDR;
}
- reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
+ if (reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_OUTADDR_ADDRESS)
+ reload_when_needed[i] = RELOAD_FOR_OPADDR_ADDR;
+ else
+ reload_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
}
- if (reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
+ if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
&& operand_reloadnum[reload_opnum[i]] >= 0
&& (reload_when_needed[operand_reloadnum[reload_opnum[i]]]
== RELOAD_OTHER))
for (i = 0; i < n_reloads; i++)
if (reload_in[i] != 0 && reload_out[i] == 0
&& (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_OPADDR_ADDR
|| reload_when_needed[i] == RELOAD_FOR_OTHER_ADDRESS))
for (j = 0; j < n_reloads; j++)
if (i != j && reload_in[j] != 0 && reload_out[j] == 0
{
tem = make_memloc (ad, regno);
find_reloads_address (GET_MODE (tem), NULL_PTR, XEXP (tem, 0),
- &XEXP (tem, 0), opnum, type, ind_levels);
+ &XEXP (tem, 0), opnum, ADDR_TYPE (type),
+ ind_levels);
push_reload (tem, NULL_RTX, loc, NULL_PTR,
reload_address_base_reg_class,
GET_MODE (ad), VOIDmode, 0, 0,
indirect addresses are valid, reload the MEM into a register. */
tem = ad;
find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0),
- opnum, type, ind_levels == 0 ? 0 : ind_levels - 1);
+ opnum, ADDR_TYPE (type),
+ ind_levels == 0 ? 0 : ind_levels - 1);
/* If tem was changed, then we must create a new memory reference to
hold it and store it back into memrefloc. */
rtx tem = make_memloc (XEXP (x, 0), regno);
/* First reload the memory location's address. */
find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0),
- &XEXP (tem, 0), opnum, type, ind_levels);
+ &XEXP (tem, 0), opnum, ADDR_TYPE (type),
+ ind_levels);
/* Put this inside a new increment-expression. */
x = gen_rtx (GET_CODE (x), GET_MODE (x), tem);
/* Proceed to reload that, as if it contained a register. */
reload1.c here. */
find_reloads_address (GET_MODE (x), &XEXP (x, 0),
XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 0),
- opnum, type, ind_levels);
+ opnum, ADDR_TYPE (type), ind_levels);
reloadnum = push_reload (x, NULL_RTX, loc, NULL_PTR,
(context
reload1.c here. */
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0),
- opnum, type, ind_levels);
+ opnum, ADDR_TYPE (type), ind_levels);
push_reload (*loc, NULL_RTX, loc, NULL_PTR,
(context ? reload_address_index_reg_class
: reload_address_base_reg_class),
{
x = make_memloc (x, regno);
find_reloads_address (GET_MODE (x), 0, XEXP (x, 0), &XEXP (x, 0),
- opnum, type, ind_levels);
+ opnum, ADDR_TYPE (type), ind_levels);
}
if (reg_renumber[regno] >= 0)
"RELOAD_FOR_INPUT",
"RELOAD_FOR_OUTPUT",
"RELOAD_FOR_INSN",
- "RELOAD_FOR_INPUT_ADDRESS",
+ "RELOAD_FOR_INPUT_ADDRESS",
+ "RELOAD_FOR_INPADDR_ADDRESS",
"RELOAD_FOR_OUTPUT_ADDRESS",
+ "RELOAD_FOR_OUTADDR_ADDRESS",
"RELOAD_FOR_OPERAND_ADDRESS",
"RELOAD_FOR_OPADDR_ADDR",
"RELOAD_OTHER",
struct needs op_addr;
struct needs op_addr_reload;
struct needs in_addr[MAX_RECOG_OPERANDS];
+ struct needs in_addr_addr[MAX_RECOG_OPERANDS];
struct needs out_addr[MAX_RECOG_OPERANDS];
+ struct needs out_addr_addr[MAX_RECOG_OPERANDS];
} insn_needs;
/* If needed, eliminate any eliminable registers. */
case RELOAD_FOR_INPUT_ADDRESS:
this_needs = &insn_needs.in_addr[reload_opnum[i]];
break;
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ this_needs = &insn_needs.in_addr_addr[reload_opnum[i]];
+ break;
case RELOAD_FOR_OUTPUT_ADDRESS:
this_needs = &insn_needs.out_addr[reload_opnum[i]];
break;
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ this_needs = &insn_needs.out_addr_addr[reload_opnum[i]];
+ break;
case RELOAD_FOR_OPERAND_ADDRESS:
this_needs = &insn_needs.op_addr;
break;
{
in_max
= MAX (in_max, insn_needs.in_addr[k].regs[j][i]);
+ in_max
+ = MAX (in_max,
+ insn_needs.in_addr_addr[k].regs[j][i]);
out_max
= MAX (out_max, insn_needs.out_addr[k].regs[j][i]);
+ out_max
+ = MAX (out_max,
+ insn_needs.out_addr_addr[k].regs[j][i]);
}
/* RELOAD_FOR_INSN reloads conflict with inputs, outputs,
j < reload_n_operands; j++)
{
in_max = MAX (in_max, insn_needs.in_addr[j].groups[i]);
+ in_max = MAX (in_max,
+ insn_needs.in_addr_addr[j].groups[i]);
out_max
= MAX (out_max, insn_needs.out_addr[j].groups[i]);
+ out_max
+ = MAX (out_max, insn_needs.out_addr_addr[j].groups[i]);
}
in_max = MAX (MAX (insn_needs.op_addr.groups[i],
static HARD_REG_SET reload_reg_used;
/* If reg is in use for a RELOAD_FOR_INPUT_ADDRESS reload for operand I. */
static HARD_REG_SET reload_reg_used_in_input_addr[MAX_RECOG_OPERANDS];
+/* If reg is in use for a RELOAD_FOR_INPADDR_ADDRESS reload for operand I. */
+static HARD_REG_SET reload_reg_used_in_inpaddr_addr[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_OUTPUT_ADDRESS reload for operand I. */
static HARD_REG_SET reload_reg_used_in_output_addr[MAX_RECOG_OPERANDS];
+/* If reg is in use for a RELOAD_FOR_OUTADDR_ADDRESS reload for operand I. */
+static HARD_REG_SET reload_reg_used_in_outaddr_addr[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_INPUT reload for operand I. */
static HARD_REG_SET reload_reg_used_in_input[MAX_RECOG_OPERANDS];
/* If reg is in use for a RELOAD_FOR_OUTPUT reload for operand I. */
SET_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i);
break;
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ SET_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], i);
+ break;
+
case RELOAD_FOR_OUTPUT_ADDRESS:
SET_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i);
break;
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ SET_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], i);
+ break;
+
case RELOAD_FOR_OPERAND_ADDRESS:
SET_HARD_REG_BIT (reload_reg_used_in_op_addr, i);
break;
CLEAR_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i);
break;
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ CLEAR_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], i);
+ break;
+
case RELOAD_FOR_OUTPUT_ADDRESS:
CLEAR_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i);
break;
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ CLEAR_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], i);
+ break;
+
case RELOAD_FOR_OPERAND_ADDRESS:
CLEAR_HARD_REG_BIT (reload_reg_used_in_op_addr, i);
break;
for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0;
/* If it is used in a later operand's address, can't use it. */
for (i = opnum + 1; i < reload_n_operands; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
return 0;
return 1;
case RELOAD_FOR_INPUT_ADDRESS:
/* Can't use a register if it is used for an input address for this
operand or used as an input in an earlier one. */
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno))
+ return 0;
+
+ for (i = 0; i < opnum; i++)
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
+ return 0;
+
+ return 1;
+
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ /* Can't use a register if it is used for an input address
+ address for this operand or used as an input in an earlier
+ one. */
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno))
return 0;
for (i = 0; i < opnum; i++)
return 1;
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ /* Can't use a register if it is used for an output address
+ address for this operand or used as an output in this or a
+ later operand. */
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno))
+ return 0;
+
+ for (i = opnum; i < reload_n_operands; i++)
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
+ return 0;
+
+ return 1;
+
case RELOAD_FOR_OPERAND_ADDRESS:
for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
return 0;
for (i = 0; i <= opnum; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
return 0;
return 1;
the first place, since we know that it was allocated. */
case RELOAD_FOR_OUTPUT_ADDRESS:
+ case RELOAD_FOR_OUTADDR_ADDRESS:
/* Earlier reloads are for earlier outputs or their addresses,
any RELOAD_FOR_INSN reloads, any inputs or their addresses, or any
RELOAD_FOR_OTHER_ADDRESS reloads (we know it can't conflict with
RELOAD_OTHER).. */
for (i = 0; i < opnum; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0;
for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
return 0;
anything that can't be used for it, except that we've already
tested for RELOAD_FOR_INSN objects. */
- if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno))
return 0;
for (i = 0; i < opnum; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0;
for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno))
return 0;
test is input addresses and the addresses of OTHER items. */
for (i = 0; i < reload_n_operands; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
return 0;
return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
with), and addresses of RELOAD_OTHER objects. */
for (i = 0; i <= opnum; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
return 0;
return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
case RELOAD_FOR_INPUT_ADDRESS:
+ case RELOAD_FOR_INPADDR_ADDRESS:
/* Similarly, all we have to check is for use in earlier inputs'
addresses. */
for (i = 0; i < opnum; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
return 0;
return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
return 0;
&& ! TEST_HARD_REG_BIT (reload_reg_used, regno));
case RELOAD_FOR_INPUT_ADDRESS:
+ case RELOAD_FOR_INPADDR_ADDRESS:
/* Similar, except that we check only for this and subsequent inputs
and the address of only subsequent inputs and we do not need
to check for RELOAD_OTHER objects since they are known not to
return 0;
for (i = opnum + 1; i < reload_n_operands; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
return 0;
for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0;
for (i = opnum + 1; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
return 0;
for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0;
case RELOAD_FOR_OPADDR_ADDR:
for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0;
case RELOAD_FOR_OUTPUT:
case RELOAD_FOR_OUTPUT_ADDRESS:
+ case RELOAD_FOR_OUTADDR_ADDRESS:
/* We already know these can't conflict with a later output. So the
only thing to check are later output addresses. */
for (i = opnum + 1; i < reload_n_operands; i++)
- if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno))
+ if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
+ || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
return 0;
return 1;
|| r2_type == RELOAD_FOR_OPERAND_ADDRESS
|| r2_type == RELOAD_FOR_OPADDR_ADDR
|| r2_type == RELOAD_FOR_INPUT
- || (r2_type == RELOAD_FOR_INPUT_ADDRESS && r2_opnum > r1_opnum));
+ || ((r2_type == RELOAD_FOR_INPUT_ADDRESS
+ || r2_type == RELOAD_FOR_INPADDR_ADDRESS)
+ && r2_opnum > r1_opnum));
case RELOAD_FOR_INPUT_ADDRESS:
return ((r2_type == RELOAD_FOR_INPUT_ADDRESS && r1_opnum == r2_opnum)
|| (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum));
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ return ((r2_type == RELOAD_FOR_INPADDR_ADDRESS && r1_opnum == r2_opnum)
+ || (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum));
+
case RELOAD_FOR_OUTPUT_ADDRESS:
return ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS && r2_opnum == r1_opnum)
|| (r2_type == RELOAD_FOR_OUTPUT && r2_opnum >= r1_opnum));
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ return ((r2_type == RELOAD_FOR_OUTADDR_ADDRESS && r2_opnum == r1_opnum)
+ || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum >= r1_opnum));
+
case RELOAD_FOR_OPERAND_ADDRESS:
return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN
|| r2_type == RELOAD_FOR_OPERAND_ADDRESS);
case RELOAD_FOR_OUTPUT:
return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT
- || (r2_type == RELOAD_FOR_OUTPUT_ADDRESS
+ || ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS
+ || r2_type == RELOAD_FOR_OUTADDR_ADDRESS)
&& r2_opnum >= r1_opnum));
case RELOAD_FOR_INSN:
int save_reload_spill_index[MAX_RELOADS];
HARD_REG_SET save_reload_reg_used;
HARD_REG_SET save_reload_reg_used_in_input_addr[MAX_RECOG_OPERANDS];
+ HARD_REG_SET save_reload_reg_used_in_inpaddr_addr[MAX_RECOG_OPERANDS];
HARD_REG_SET save_reload_reg_used_in_output_addr[MAX_RECOG_OPERANDS];
+ HARD_REG_SET save_reload_reg_used_in_outaddr_addr[MAX_RECOG_OPERANDS];
HARD_REG_SET save_reload_reg_used_in_input[MAX_RECOG_OPERANDS];
HARD_REG_SET save_reload_reg_used_in_output[MAX_RECOG_OPERANDS];
HARD_REG_SET save_reload_reg_used_in_op_addr;
CLEAR_HARD_REG_SET (reload_reg_used_in_output[i]);
CLEAR_HARD_REG_SET (reload_reg_used_in_input[i]);
CLEAR_HARD_REG_SET (reload_reg_used_in_input_addr[i]);
+ CLEAR_HARD_REG_SET (reload_reg_used_in_inpaddr_addr[i]);
CLEAR_HARD_REG_SET (reload_reg_used_in_output_addr[i]);
+ CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
}
#ifdef SMALL_REGISTER_CLASSES
reload_reg_used_in_input[i]);
COPY_HARD_REG_SET (save_reload_reg_used_in_input_addr[i],
reload_reg_used_in_input_addr[i]);
+ COPY_HARD_REG_SET (save_reload_reg_used_in_inpaddr_addr[i],
+ reload_reg_used_in_inpaddr_addr[i]);
COPY_HARD_REG_SET (save_reload_reg_used_in_output_addr[i],
reload_reg_used_in_output_addr[i]);
+ COPY_HARD_REG_SET (save_reload_reg_used_in_outaddr_addr[i],
+ reload_reg_used_in_outaddr_addr[i]);
}
/* If -O, try first with inheritance, then turning it off.
save_reload_reg_used_in_output[i]);
COPY_HARD_REG_SET (reload_reg_used_in_input_addr[i],
save_reload_reg_used_in_input_addr[i]);
+ COPY_HARD_REG_SET (reload_reg_used_in_inpaddr_addr[i],
+ save_reload_reg_used_in_inpaddr_addr[i]);
COPY_HARD_REG_SET (reload_reg_used_in_output_addr[i],
save_reload_reg_used_in_output_addr[i]);
+ COPY_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i],
+ save_reload_reg_used_in_outaddr_addr[i]);
}
}
&& reg_overlap_mentioned_for_reload_p (reload_in[j],
reload_in[i]))
reload_when_needed[j]
- = reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
- ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER;
+ = ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
+ || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
+ ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER);
}
}
}
rtx other_input_address_reload_insns = 0;
rtx other_input_reload_insns = 0;
rtx input_address_reload_insns[MAX_RECOG_OPERANDS];
+ rtx inpaddr_address_reload_insns[MAX_RECOG_OPERANDS];
rtx output_reload_insns[MAX_RECOG_OPERANDS];
rtx output_address_reload_insns[MAX_RECOG_OPERANDS];
+ rtx outaddr_address_reload_insns[MAX_RECOG_OPERANDS];
rtx operand_reload_insns = 0;
rtx other_operand_reload_insns = 0;
rtx other_output_reload_insns[MAX_RECOG_OPERANDS];
for (j = 0; j < reload_n_operands; j++)
input_reload_insns[j] = input_address_reload_insns[j]
+ = inpaddr_address_reload_insns[j]
= output_reload_insns[j] = output_address_reload_insns[j]
+ = outaddr_address_reload_insns[j]
= other_output_reload_insns[j] = 0;
/* Now output the instructions to copy the data into and out of the
case RELOAD_FOR_INPUT_ADDRESS:
where = &input_address_reload_insns[reload_opnum[j]];
break;
+ case RELOAD_FOR_INPADDR_ADDRESS:
+ where = &inpaddr_address_reload_insns[reload_opnum[j]];
+ break;
case RELOAD_FOR_OUTPUT_ADDRESS:
where = &output_address_reload_insns[reload_opnum[j]];
break;
+ case RELOAD_FOR_OUTADDR_ADDRESS:
+ where = &outaddr_address_reload_insns[reload_opnum[j]];
+ break;
case RELOAD_FOR_OPERAND_ADDRESS:
where = &operand_reload_insns;
break;
RELOAD_OTHER reloads.
- For each operand, any RELOAD_FOR_INPUT_ADDRESS reloads followed by
- the RELOAD_FOR_INPUT reload for the operand.
+ For each operand, any RELOAD_FOR_INPADDR_ADDRESS reloads followed
+ by any RELOAD_FOR_INPUT_ADDRESS reloads followed by the
+ RELOAD_FOR_INPUT reload for the operand.
RELOAD_FOR_OPADDR_ADDRS reloads.
After the insn being reloaded, we write the following:
- For each operand, any RELOAD_FOR_OUTPUT_ADDRESS reload followed by
- the RELOAD_FOR_OUTPUT reload, followed by any RELOAD_OTHER output
- reloads for the operand. The RELOAD_OTHER output reloads are output
- in descending order by reload number. */
+ For each operand, any RELOAD_FOR_OUTADDR_ADDRESS reloads followed
+ by any RELOAD_FOR_OUTPUT_ADDRESS reload followed by the
+ RELOAD_FOR_OUTPUT reload, followed by any RELOAD_OTHER output
+ reloads for the operand. The RELOAD_OTHER output reloads are
+ output in descending order by reload number. */
emit_insns_before (other_input_address_reload_insns, before_insn);
emit_insns_before (other_input_reload_insns, before_insn);
for (j = 0; j < reload_n_operands; j++)
{
+ emit_insns_before (inpaddr_address_reload_insns[j], before_insn);
emit_insns_before (input_address_reload_insns[j], before_insn);
emit_insns_before (input_reload_insns[j], before_insn);
}
for (j = 0; j < reload_n_operands; j++)
{
+ emit_insns_before (outaddr_address_reload_insns[j], following_insn);
emit_insns_before (output_address_reload_insns[j], following_insn);
emit_insns_before (output_reload_insns[j], following_insn);
emit_insns_before (other_output_reload_insns[j], following_insn);