Commit 47c8cf91 by Ian Lance Taylor

Add INPADDR_ADDRESS and OUTADDR_ADDRESS reload types

From-SVN: r13600
parent 5ff0385c
...@@ -296,6 +296,15 @@ static int output_reloadnum; ...@@ -296,6 +296,15 @@ static int output_reloadnum;
|| (when1) == RELOAD_FOR_OPERAND_ADDRESS \ || (when1) == RELOAD_FOR_OPERAND_ADDRESS \
|| (when1) == RELOAD_FOR_OTHER_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, static int push_secondary_reload PROTO((int, rtx, int, int, enum reg_class,
enum machine_mode, enum reload_type, enum machine_mode, enum reload_type,
enum insn_code *)); enum insn_code *));
...@@ -359,7 +368,10 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode, ...@@ -359,7 +368,10 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode,
int i; int i;
int s_reload, t_reload = -1; 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; secondary_type = type;
else else
secondary_type = in_p ? RELOAD_FOR_INPUT_ADDRESS : RELOAD_FOR_OUTPUT_ADDRESS; secondary_type = in_p ? RELOAD_FOR_INPUT_ADDRESS : RELOAD_FOR_OUTPUT_ADDRESS;
...@@ -1528,6 +1540,7 @@ combine_reloads () ...@@ -1528,6 +1540,7 @@ combine_reloads ()
if (reload_in[i] && ! reload_optional[i] && ! reload_nocombine[i] if (reload_in[i] && ! reload_optional[i] && ! reload_nocombine[i]
/* Life span of this reload must not extend past main insn. */ /* 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_OUTPUT_ADDRESS
&& reload_when_needed[i] != RELOAD_FOR_OUTADDR_ADDRESS
&& reload_when_needed[i] != RELOAD_OTHER && reload_when_needed[i] != RELOAD_OTHER
&& (CLASS_MAX_NREGS (reload_reg_class[i], reload_inmode[i]) && (CLASS_MAX_NREGS (reload_reg_class[i], reload_inmode[i])
== CLASS_MAX_NREGS (reload_reg_class[output_reload], == CLASS_MAX_NREGS (reload_reg_class[output_reload],
...@@ -3535,10 +3548,19 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -3535,10 +3548,19 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
we must change these to RELOAD_FOR_INPUT_ADDRESS. */ we must change these to RELOAD_FOR_INPUT_ADDRESS. */
if (modified[i] == RELOAD_WRITE) if (modified[i] == RELOAD_WRITE)
{
for (j = 0; j < n_reloads; j++) for (j = 0; j < n_reloads; j++)
if (reload_opnum[j] == i {
&& reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS) if (reload_opnum[j] == i)
{
if (reload_when_needed[j] == RELOAD_FOR_OUTPUT_ADDRESS)
reload_when_needed[j] = RELOAD_FOR_INPUT_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) else if (goal_alternative_matched[i] == -1)
operand_reloadnum[i] = operand_reloadnum[i] =
...@@ -3725,9 +3747,13 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -3725,9 +3747,13 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
for (j = i + 1; j < n_reloads; j++) for (j = i + 1; j < n_reloads; j++)
if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS 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_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]) && rtx_equal_p (reload_in[i], reload_in[j])
&& (operand_reloadnum[reload_opnum[i]] < 0 && (operand_reloadnum[reload_opnum[i]] < 0
|| reload_optional[operand_reloadnum[reload_opnum[i]]]) || reload_optional[operand_reloadnum[reload_opnum[i]]])
...@@ -3741,6 +3767,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -3741,6 +3767,10 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
if (replacements[k].what == j) if (replacements[k].what == j)
replacements[k].what = i; replacements[k].what = i;
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_when_needed[i] = RELOAD_FOR_OPERAND_ADDRESS;
reload_in[j] = 0; reload_in[j] = 0;
} }
...@@ -3770,14 +3800,17 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -3770,14 +3800,17 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
reload_when_needed[i] = address_type[reload_opnum[i]]; reload_when_needed[i] = address_type[reload_opnum[i]];
if ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS 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 && (operand_reloadnum[reload_opnum[i]] < 0
|| reload_optional[operand_reloadnum[reload_opnum[i]]])) || reload_optional[operand_reloadnum[reload_opnum[i]]]))
{ {
/* If we have a secondary reload to go along with this reload, /* If we have a secondary reload to go along with this reload,
change its type to RELOAD_FOR_OPADDR_ADDR. */ 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) && reload_secondary_in_reload[i] != -1)
{ {
int secondary_in_reload = reload_secondary_in_reload[i]; int secondary_in_reload = reload_secondary_in_reload[i];
...@@ -3792,7 +3825,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -3792,7 +3825,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
= RELOAD_FOR_OPADDR_ADDR; = 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) && reload_secondary_out_reload[i] != -1)
{ {
int secondary_out_reload = reload_secondary_out_reload[i]; int secondary_out_reload = reload_secondary_out_reload[i];
...@@ -3806,10 +3840,15 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -3806,10 +3840,15 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
reload_when_needed[reload_secondary_out_reload[secondary_out_reload]] reload_when_needed[reload_secondary_out_reload[secondary_out_reload]]
= RELOAD_FOR_OPADDR_ADDR; = RELOAD_FOR_OPADDR_ADDR;
} }
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_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 && operand_reloadnum[reload_opnum[i]] >= 0
&& (reload_when_needed[operand_reloadnum[reload_opnum[i]]] && (reload_when_needed[operand_reloadnum[reload_opnum[i]]]
== RELOAD_OTHER)) == RELOAD_OTHER))
...@@ -3827,6 +3866,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) ...@@ -3827,6 +3866,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
for (i = 0; i < n_reloads; i++) for (i = 0; i < n_reloads; i++)
if (reload_in[i] != 0 && reload_out[i] == 0 if (reload_in[i] != 0 && reload_out[i] == 0
&& (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS && (reload_when_needed[i] == RELOAD_FOR_OPERAND_ADDRESS
|| reload_when_needed[i] == RELOAD_FOR_OPADDR_ADDR
|| reload_when_needed[i] == RELOAD_FOR_OTHER_ADDRESS)) || reload_when_needed[i] == RELOAD_FOR_OTHER_ADDRESS))
for (j = 0; j < n_reloads; j++) for (j = 0; j < n_reloads; j++)
if (i != j && reload_in[j] != 0 && reload_out[j] == 0 if (i != j && reload_in[j] != 0 && reload_out[j] == 0
...@@ -4217,7 +4257,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels) ...@@ -4217,7 +4257,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
{ {
tem = make_memloc (ad, regno); tem = make_memloc (ad, regno);
find_reloads_address (GET_MODE (tem), NULL_PTR, XEXP (tem, 0), 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, push_reload (tem, NULL_RTX, loc, NULL_PTR,
reload_address_base_reg_class, reload_address_base_reg_class,
GET_MODE (ad), VOIDmode, 0, 0, GET_MODE (ad), VOIDmode, 0, 0,
...@@ -4292,7 +4333,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels) ...@@ -4292,7 +4333,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels)
indirect addresses are valid, reload the MEM into a register. */ indirect addresses are valid, reload the MEM into a register. */
tem = ad; tem = ad;
find_reloads_address (GET_MODE (ad), &tem, XEXP (ad, 0), &XEXP (ad, 0), 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 /* If tem was changed, then we must create a new memory reference to
hold it and store it back into memrefloc. */ hold it and store it back into memrefloc. */
...@@ -4815,7 +4857,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels) ...@@ -4815,7 +4857,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
rtx tem = make_memloc (XEXP (x, 0), regno); rtx tem = make_memloc (XEXP (x, 0), regno);
/* First reload the memory location's address. */ /* First reload the memory location's address. */
find_reloads_address (GET_MODE (tem), 0, XEXP (tem, 0), 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. */ /* Put this inside a new increment-expression. */
x = gen_rtx (GET_CODE (x), GET_MODE (x), tem); x = gen_rtx (GET_CODE (x), GET_MODE (x), tem);
/* Proceed to reload that, as if it contained a register. */ /* Proceed to reload that, as if it contained a register. */
...@@ -4883,7 +4926,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels) ...@@ -4883,7 +4926,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
reload1.c here. */ reload1.c here. */
find_reloads_address (GET_MODE (x), &XEXP (x, 0), find_reloads_address (GET_MODE (x), &XEXP (x, 0),
XEXP (XEXP (x, 0), 0), &XEXP (XEXP (x, 0), 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, reloadnum = push_reload (x, NULL_RTX, loc, NULL_PTR,
(context (context
...@@ -4915,7 +4958,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels) ...@@ -4915,7 +4958,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
reload1.c here. */ reload1.c here. */
find_reloads_address (GET_MODE (x), loc, XEXP (x, 0), &XEXP (x, 0), 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, push_reload (*loc, NULL_RTX, loc, NULL_PTR,
(context ? reload_address_index_reg_class (context ? reload_address_index_reg_class
: reload_address_base_reg_class), : reload_address_base_reg_class),
...@@ -4953,7 +4996,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels) ...@@ -4953,7 +4996,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels)
{ {
x = make_memloc (x, regno); x = make_memloc (x, regno);
find_reloads_address (GET_MODE (x), 0, XEXP (x, 0), &XEXP (x, 0), 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) if (reg_renumber[regno] >= 0)
...@@ -5959,7 +6002,9 @@ static char *reload_when_needed_name[] = ...@@ -5959,7 +6002,9 @@ static char *reload_when_needed_name[] =
"RELOAD_FOR_OUTPUT", "RELOAD_FOR_OUTPUT",
"RELOAD_FOR_INSN", "RELOAD_FOR_INSN",
"RELOAD_FOR_INPUT_ADDRESS", "RELOAD_FOR_INPUT_ADDRESS",
"RELOAD_FOR_INPADDR_ADDRESS",
"RELOAD_FOR_OUTPUT_ADDRESS", "RELOAD_FOR_OUTPUT_ADDRESS",
"RELOAD_FOR_OUTADDR_ADDRESS",
"RELOAD_FOR_OPERAND_ADDRESS", "RELOAD_FOR_OPERAND_ADDRESS",
"RELOAD_FOR_OPADDR_ADDR", "RELOAD_FOR_OPADDR_ADDR",
"RELOAD_OTHER", "RELOAD_OTHER",
......
...@@ -70,7 +70,9 @@ extern rtx reload_reg_rtx[MAX_RELOADS]; ...@@ -70,7 +70,9 @@ extern rtx reload_reg_rtx[MAX_RELOADS];
something used before or after the insn something used before or after the insn
RELOAD_FOR_INPUT_ADDRESS reload for parts of the address of an object RELOAD_FOR_INPUT_ADDRESS reload for parts of the address of an object
that is an input reload that is an input reload
RELOAD_FOR_OUTPUT_ADDRESS likewise, for output reload RELOAD_FOR_INPADDR_ADDRESS reload needed for RELOAD_FOR_INPUT_ADDRESS
RELOAD_FOR_OUTPUT_ADDRESS like RELOAD_FOR INPUT_ADDRESS, for output
RELOAD_FOR_OUTADDR_ADDRESS reload needed for RELOAD_FOR_OUTPUT_ADDRESS
RELOAD_FOR_OPERAND_ADDRESS reload for the address of a non-reloaded RELOAD_FOR_OPERAND_ADDRESS reload for the address of a non-reloaded
operand; these don't conflict with operand; these don't conflict with
any other addresses. any other addresses.
...@@ -86,7 +88,8 @@ extern rtx reload_reg_rtx[MAX_RELOADS]; ...@@ -86,7 +88,8 @@ extern rtx reload_reg_rtx[MAX_RELOADS];
enum reload_type enum reload_type
{ {
RELOAD_FOR_INPUT, RELOAD_FOR_OUTPUT, RELOAD_FOR_INSN, RELOAD_FOR_INPUT, RELOAD_FOR_OUTPUT, RELOAD_FOR_INSN,
RELOAD_FOR_INPUT_ADDRESS, RELOAD_FOR_OUTPUT_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_FOR_OPERAND_ADDRESS, RELOAD_FOR_OPADDR_ADDR,
RELOAD_OTHER, RELOAD_FOR_OTHER_ADDRESS RELOAD_OTHER, RELOAD_FOR_OTHER_ADDRESS
}; };
......
...@@ -1050,7 +1050,9 @@ reload (first, global, dumpfile) ...@@ -1050,7 +1050,9 @@ reload (first, global, dumpfile)
struct needs op_addr; struct needs op_addr;
struct needs op_addr_reload; struct needs op_addr_reload;
struct needs in_addr[MAX_RECOG_OPERANDS]; 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[MAX_RECOG_OPERANDS];
struct needs out_addr_addr[MAX_RECOG_OPERANDS];
} insn_needs; } insn_needs;
/* If needed, eliminate any eliminable registers. */ /* If needed, eliminate any eliminable registers. */
...@@ -1210,9 +1212,15 @@ reload (first, global, dumpfile) ...@@ -1210,9 +1212,15 @@ reload (first, global, dumpfile)
case RELOAD_FOR_INPUT_ADDRESS: case RELOAD_FOR_INPUT_ADDRESS:
this_needs = &insn_needs.in_addr[reload_opnum[i]]; this_needs = &insn_needs.in_addr[reload_opnum[i]];
break; break;
case RELOAD_FOR_INPADDR_ADDRESS:
this_needs = &insn_needs.in_addr_addr[reload_opnum[i]];
break;
case RELOAD_FOR_OUTPUT_ADDRESS: case RELOAD_FOR_OUTPUT_ADDRESS:
this_needs = &insn_needs.out_addr[reload_opnum[i]]; this_needs = &insn_needs.out_addr[reload_opnum[i]];
break; break;
case RELOAD_FOR_OUTADDR_ADDRESS:
this_needs = &insn_needs.out_addr_addr[reload_opnum[i]];
break;
case RELOAD_FOR_OPERAND_ADDRESS: case RELOAD_FOR_OPERAND_ADDRESS:
this_needs = &insn_needs.op_addr; this_needs = &insn_needs.op_addr;
break; break;
...@@ -1286,8 +1294,14 @@ reload (first, global, dumpfile) ...@@ -1286,8 +1294,14 @@ reload (first, global, dumpfile)
{ {
in_max in_max
= MAX (in_max, insn_needs.in_addr[k].regs[j][i]); = 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 out_max
= MAX (out_max, insn_needs.out_addr[k].regs[j][i]); = 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, /* RELOAD_FOR_INSN reloads conflict with inputs, outputs,
...@@ -1321,8 +1335,12 @@ reload (first, global, dumpfile) ...@@ -1321,8 +1335,12 @@ reload (first, global, dumpfile)
j < reload_n_operands; j++) 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[j].groups[i]);
in_max = MAX (in_max,
insn_needs.in_addr_addr[j].groups[i]);
out_max out_max
= MAX (out_max, insn_needs.out_addr[j].groups[i]); = 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], in_max = MAX (MAX (insn_needs.op_addr.groups[i],
...@@ -4277,8 +4295,12 @@ reload_reg_class_lower (r1p, r2p) ...@@ -4277,8 +4295,12 @@ reload_reg_class_lower (r1p, r2p)
static HARD_REG_SET reload_reg_used; static HARD_REG_SET reload_reg_used;
/* If reg is in use for a RELOAD_FOR_INPUT_ADDRESS reload for operand I. */ /* 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]; 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. */ /* 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]; 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. */ /* 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]; 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. */ /* If reg is in use for a RELOAD_FOR_OUTPUT reload for operand I. */
...@@ -4325,10 +4347,18 @@ mark_reload_reg_in_use (regno, opnum, type, mode) ...@@ -4325,10 +4347,18 @@ mark_reload_reg_in_use (regno, opnum, type, mode)
SET_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i); SET_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i);
break; break;
case RELOAD_FOR_INPADDR_ADDRESS:
SET_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], i);
break;
case RELOAD_FOR_OUTPUT_ADDRESS: case RELOAD_FOR_OUTPUT_ADDRESS:
SET_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i); SET_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i);
break; break;
case RELOAD_FOR_OUTADDR_ADDRESS:
SET_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], i);
break;
case RELOAD_FOR_OPERAND_ADDRESS: case RELOAD_FOR_OPERAND_ADDRESS:
SET_HARD_REG_BIT (reload_reg_used_in_op_addr, i); SET_HARD_REG_BIT (reload_reg_used_in_op_addr, i);
break; break;
...@@ -4382,10 +4412,18 @@ clear_reload_reg_in_use (regno, opnum, type, mode) ...@@ -4382,10 +4412,18 @@ clear_reload_reg_in_use (regno, opnum, type, mode)
CLEAR_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i); CLEAR_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i);
break; break;
case RELOAD_FOR_INPADDR_ADDRESS:
CLEAR_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], i);
break;
case RELOAD_FOR_OUTPUT_ADDRESS: case RELOAD_FOR_OUTPUT_ADDRESS:
CLEAR_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i); CLEAR_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i);
break; break;
case RELOAD_FOR_OUTADDR_ADDRESS:
CLEAR_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], i);
break;
case RELOAD_FOR_OPERAND_ADDRESS: case RELOAD_FOR_OPERAND_ADDRESS:
CLEAR_HARD_REG_BIT (reload_reg_used_in_op_addr, i); CLEAR_HARD_REG_BIT (reload_reg_used_in_op_addr, i);
break; break;
...@@ -4439,7 +4477,9 @@ reload_reg_free_p (regno, opnum, type) ...@@ -4439,7 +4477,9 @@ reload_reg_free_p (regno, opnum, type)
for (i = 0; i < reload_n_operands; i++) 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output_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_input[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0; return 0;
...@@ -4461,7 +4501,8 @@ reload_reg_free_p (regno, opnum, type) ...@@ -4461,7 +4501,8 @@ reload_reg_free_p (regno, opnum, type)
/* If it is used in a later operand's address, can't use it. */ /* If it is used in a later operand's address, can't use it. */
for (i = opnum + 1; i < reload_n_operands; i++) 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 0;
return 1; return 1;
...@@ -4469,7 +4510,21 @@ reload_reg_free_p (regno, opnum, type) ...@@ -4469,7 +4510,21 @@ reload_reg_free_p (regno, opnum, type)
case RELOAD_FOR_INPUT_ADDRESS: case RELOAD_FOR_INPUT_ADDRESS:
/* Can't use a register if it is used for an input address for this /* 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. */ 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; return 0;
for (i = 0; i < opnum; i++) for (i = 0; i < opnum; i++)
...@@ -4490,6 +4545,19 @@ reload_reg_free_p (regno, opnum, type) ...@@ -4490,6 +4545,19 @@ reload_reg_free_p (regno, opnum, type)
return 1; 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: case RELOAD_FOR_OPERAND_ADDRESS:
for (i = 0; i < reload_n_operands; i++) for (i = 0; i < reload_n_operands; i++)
if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
...@@ -4516,7 +4584,8 @@ reload_reg_free_p (regno, opnum, type) ...@@ -4516,7 +4584,8 @@ reload_reg_free_p (regno, opnum, type)
return 0; return 0;
for (i = 0; i <= opnum; i++) 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 0;
return 1; return 1;
...@@ -4570,12 +4639,14 @@ reload_reg_free_before_p (regno, opnum, type) ...@@ -4570,12 +4639,14 @@ reload_reg_free_before_p (regno, opnum, type)
the first place, since we know that it was allocated. */ the first place, since we know that it was allocated. */
case RELOAD_FOR_OUTPUT_ADDRESS: case RELOAD_FOR_OUTPUT_ADDRESS:
case RELOAD_FOR_OUTADDR_ADDRESS:
/* Earlier reloads are for earlier outputs or their addresses, /* Earlier reloads are for earlier outputs or their addresses,
any RELOAD_FOR_INSN reloads, any inputs or their addresses, or any 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_FOR_OTHER_ADDRESS reloads (we know it can't conflict with
RELOAD_OTHER).. */ RELOAD_OTHER).. */
for (i = 0; i < opnum; i++) 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0; return 0;
...@@ -4584,6 +4655,7 @@ reload_reg_free_before_p (regno, opnum, type) ...@@ -4584,6 +4655,7 @@ reload_reg_free_before_p (regno, opnum, type)
for (i = 0; i < reload_n_operands; i++) 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
return 0; return 0;
...@@ -4596,16 +4668,19 @@ reload_reg_free_before_p (regno, opnum, type) ...@@ -4596,16 +4668,19 @@ reload_reg_free_before_p (regno, opnum, type)
anything that can't be used for it, except that we've already anything that can't be used for it, except that we've already
tested for RELOAD_FOR_INSN objects. */ 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; return 0;
for (i = 0; i < opnum; i++) 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0; return 0;
for (i = 0; i < reload_n_operands; i++) 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno) || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)
|| TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno))
return 0; return 0;
...@@ -4619,7 +4694,8 @@ reload_reg_free_before_p (regno, opnum, type) ...@@ -4619,7 +4694,8 @@ reload_reg_free_before_p (regno, opnum, type)
test is input addresses and the addresses of OTHER items. */ test is input addresses and the addresses of OTHER items. */
for (i = 0; i < reload_n_operands; i++) 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 0;
return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno); return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
...@@ -4630,16 +4706,19 @@ reload_reg_free_before_p (regno, opnum, type) ...@@ -4630,16 +4706,19 @@ reload_reg_free_before_p (regno, opnum, type)
with), and addresses of RELOAD_OTHER objects. */ with), and addresses of RELOAD_OTHER objects. */
for (i = 0; i <= opnum; i++) 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 0;
return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno); return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
case RELOAD_FOR_INPUT_ADDRESS: case RELOAD_FOR_INPUT_ADDRESS:
case RELOAD_FOR_INPADDR_ADDRESS:
/* Similarly, all we have to check is for use in earlier inputs' /* Similarly, all we have to check is for use in earlier inputs'
addresses. */ addresses. */
for (i = 0; i < opnum; i++) 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 0;
return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno); return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
...@@ -4681,8 +4760,10 @@ reload_reg_reaches_end_p (regno, opnum, type) ...@@ -4681,8 +4760,10 @@ reload_reg_reaches_end_p (regno, opnum, type)
for (i = 0; i < reload_n_operands; i++) for (i = 0; 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[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_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_input[i], regno))
return 0; return 0;
...@@ -4691,6 +4772,7 @@ reload_reg_reaches_end_p (regno, opnum, type) ...@@ -4691,6 +4772,7 @@ reload_reg_reaches_end_p (regno, opnum, type)
&& ! TEST_HARD_REG_BIT (reload_reg_used, regno)); && ! TEST_HARD_REG_BIT (reload_reg_used, regno));
case RELOAD_FOR_INPUT_ADDRESS: case RELOAD_FOR_INPUT_ADDRESS:
case RELOAD_FOR_INPADDR_ADDRESS:
/* Similar, except that we check only for this and subsequent inputs /* Similar, except that we check only for this and subsequent inputs
and the address of only subsequent inputs and we do not need and the address of only subsequent inputs and we do not need
to check for RELOAD_OTHER objects since they are known not to to check for RELOAD_OTHER objects since they are known not to
...@@ -4701,11 +4783,13 @@ reload_reg_reaches_end_p (regno, opnum, type) ...@@ -4701,11 +4783,13 @@ reload_reg_reaches_end_p (regno, opnum, type)
return 0; return 0;
for (i = opnum + 1; i < reload_n_operands; i++) 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 0;
for (i = 0; i < reload_n_operands; i++) for (i = 0; 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0; return 0;
...@@ -4723,6 +4807,7 @@ reload_reg_reaches_end_p (regno, opnum, type) ...@@ -4723,6 +4807,7 @@ reload_reg_reaches_end_p (regno, opnum, type)
for (i = opnum + 1; i < reload_n_operands; i++) 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
return 0; return 0;
...@@ -4733,6 +4818,7 @@ reload_reg_reaches_end_p (regno, opnum, type) ...@@ -4733,6 +4818,7 @@ reload_reg_reaches_end_p (regno, opnum, type)
for (i = 0; i < reload_n_operands; i++) for (i = 0; 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0; return 0;
...@@ -4741,6 +4827,7 @@ reload_reg_reaches_end_p (regno, opnum, type) ...@@ -4741,6 +4827,7 @@ reload_reg_reaches_end_p (regno, opnum, type)
case RELOAD_FOR_OPADDR_ADDR: case RELOAD_FOR_OPADDR_ADDR:
for (i = 0; i < reload_n_operands; i++) for (i = 0; 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)
|| TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
return 0; return 0;
...@@ -4757,10 +4844,12 @@ reload_reg_reaches_end_p (regno, opnum, type) ...@@ -4757,10 +4844,12 @@ reload_reg_reaches_end_p (regno, opnum, type)
case RELOAD_FOR_OUTPUT: case RELOAD_FOR_OUTPUT:
case RELOAD_FOR_OUTPUT_ADDRESS: case RELOAD_FOR_OUTPUT_ADDRESS:
case RELOAD_FOR_OUTADDR_ADDRESS:
/* We already know these can't conflict with a later output. So the /* We already know these can't conflict with a later output. So the
only thing to check are later output addresses. */ only thing to check are later output addresses. */
for (i = opnum + 1; i < reload_n_operands; i++) 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 0;
return 1; return 1;
...@@ -4796,16 +4885,26 @@ reloads_conflict (r1, r2) ...@@ -4796,16 +4885,26 @@ reloads_conflict (r1, r2)
|| r2_type == RELOAD_FOR_OPERAND_ADDRESS || r2_type == RELOAD_FOR_OPERAND_ADDRESS
|| r2_type == RELOAD_FOR_OPADDR_ADDR || r2_type == RELOAD_FOR_OPADDR_ADDR
|| r2_type == RELOAD_FOR_INPUT || 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: case RELOAD_FOR_INPUT_ADDRESS:
return ((r2_type == RELOAD_FOR_INPUT_ADDRESS && r1_opnum == r2_opnum) return ((r2_type == RELOAD_FOR_INPUT_ADDRESS && r1_opnum == r2_opnum)
|| (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_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: case RELOAD_FOR_OUTPUT_ADDRESS:
return ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS && r2_opnum == r1_opnum) return ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS && r2_opnum == r1_opnum)
|| (r2_type == RELOAD_FOR_OUTPUT && 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: case RELOAD_FOR_OPERAND_ADDRESS:
return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN
|| r2_type == RELOAD_FOR_OPERAND_ADDRESS); || r2_type == RELOAD_FOR_OPERAND_ADDRESS);
...@@ -4816,7 +4915,8 @@ reloads_conflict (r1, r2) ...@@ -4816,7 +4915,8 @@ reloads_conflict (r1, r2)
case RELOAD_FOR_OUTPUT: case RELOAD_FOR_OUTPUT:
return (r2_type == RELOAD_FOR_INSN || r2_type == 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)); && r2_opnum >= r1_opnum));
case RELOAD_FOR_INSN: case RELOAD_FOR_INSN:
...@@ -5078,7 +5178,9 @@ choose_reload_regs (insn, avoid_return_reg) ...@@ -5078,7 +5178,9 @@ choose_reload_regs (insn, avoid_return_reg)
int save_reload_spill_index[MAX_RELOADS]; int save_reload_spill_index[MAX_RELOADS];
HARD_REG_SET save_reload_reg_used; 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_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_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_input[MAX_RECOG_OPERANDS];
HARD_REG_SET save_reload_reg_used_in_output[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; HARD_REG_SET save_reload_reg_used_in_op_addr;
...@@ -5103,7 +5205,9 @@ choose_reload_regs (insn, avoid_return_reg) ...@@ -5103,7 +5205,9 @@ choose_reload_regs (insn, avoid_return_reg)
CLEAR_HARD_REG_SET (reload_reg_used_in_output[i]); 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[i]);
CLEAR_HARD_REG_SET (reload_reg_used_in_input_addr[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_output_addr[i]);
CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
} }
#ifdef SMALL_REGISTER_CLASSES #ifdef SMALL_REGISTER_CLASSES
...@@ -5242,8 +5346,12 @@ choose_reload_regs (insn, avoid_return_reg) ...@@ -5242,8 +5346,12 @@ choose_reload_regs (insn, avoid_return_reg)
reload_reg_used_in_input[i]); reload_reg_used_in_input[i]);
COPY_HARD_REG_SET (save_reload_reg_used_in_input_addr[i], COPY_HARD_REG_SET (save_reload_reg_used_in_input_addr[i],
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], COPY_HARD_REG_SET (save_reload_reg_used_in_output_addr[i],
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. /* If -O, try first with inheritance, then turning it off.
...@@ -5621,8 +5729,12 @@ choose_reload_regs (insn, avoid_return_reg) ...@@ -5621,8 +5729,12 @@ choose_reload_regs (insn, avoid_return_reg)
save_reload_reg_used_in_output[i]); save_reload_reg_used_in_output[i]);
COPY_HARD_REG_SET (reload_reg_used_in_input_addr[i], COPY_HARD_REG_SET (reload_reg_used_in_input_addr[i],
save_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], COPY_HARD_REG_SET (reload_reg_used_in_output_addr[i],
save_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]);
} }
} }
...@@ -5796,8 +5908,9 @@ merge_assigned_reloads (insn) ...@@ -5796,8 +5908,9 @@ merge_assigned_reloads (insn)
&& reg_overlap_mentioned_for_reload_p (reload_in[j], && reg_overlap_mentioned_for_reload_p (reload_in[j],
reload_in[i])) reload_in[i]))
reload_when_needed[j] reload_when_needed[j]
= reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS = ((reload_when_needed[i] == RELOAD_FOR_INPUT_ADDRESS
? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER; || reload_when_needed[i] == RELOAD_FOR_INPADDR_ADDRESS)
? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER);
} }
} }
} }
...@@ -5814,8 +5927,10 @@ emit_reload_insns (insn) ...@@ -5814,8 +5927,10 @@ emit_reload_insns (insn)
rtx other_input_address_reload_insns = 0; rtx other_input_address_reload_insns = 0;
rtx other_input_reload_insns = 0; rtx other_input_reload_insns = 0;
rtx input_address_reload_insns[MAX_RECOG_OPERANDS]; 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_reload_insns[MAX_RECOG_OPERANDS];
rtx output_address_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 operand_reload_insns = 0;
rtx other_operand_reload_insns = 0; rtx other_operand_reload_insns = 0;
rtx other_output_reload_insns[MAX_RECOG_OPERANDS]; rtx other_output_reload_insns[MAX_RECOG_OPERANDS];
...@@ -5827,7 +5942,9 @@ emit_reload_insns (insn) ...@@ -5827,7 +5942,9 @@ emit_reload_insns (insn)
for (j = 0; j < reload_n_operands; j++) for (j = 0; j < reload_n_operands; j++)
input_reload_insns[j] = input_address_reload_insns[j] input_reload_insns[j] = input_address_reload_insns[j]
= inpaddr_address_reload_insns[j]
= output_reload_insns[j] = output_address_reload_insns[j] = output_reload_insns[j] = output_address_reload_insns[j]
= outaddr_address_reload_insns[j]
= other_output_reload_insns[j] = 0; = other_output_reload_insns[j] = 0;
/* Now output the instructions to copy the data into and out of the /* Now output the instructions to copy the data into and out of the
...@@ -6022,9 +6139,15 @@ emit_reload_insns (insn) ...@@ -6022,9 +6139,15 @@ emit_reload_insns (insn)
case RELOAD_FOR_INPUT_ADDRESS: case RELOAD_FOR_INPUT_ADDRESS:
where = &input_address_reload_insns[reload_opnum[j]]; where = &input_address_reload_insns[reload_opnum[j]];
break; break;
case RELOAD_FOR_INPADDR_ADDRESS:
where = &inpaddr_address_reload_insns[reload_opnum[j]];
break;
case RELOAD_FOR_OUTPUT_ADDRESS: case RELOAD_FOR_OUTPUT_ADDRESS:
where = &output_address_reload_insns[reload_opnum[j]]; where = &output_address_reload_insns[reload_opnum[j]];
break; break;
case RELOAD_FOR_OUTADDR_ADDRESS:
where = &outaddr_address_reload_insns[reload_opnum[j]];
break;
case RELOAD_FOR_OPERAND_ADDRESS: case RELOAD_FOR_OPERAND_ADDRESS:
where = &operand_reload_insns; where = &operand_reload_insns;
break; break;
...@@ -6627,8 +6750,9 @@ emit_reload_insns (insn) ...@@ -6627,8 +6750,9 @@ emit_reload_insns (insn)
RELOAD_OTHER reloads. RELOAD_OTHER reloads.
For each operand, any RELOAD_FOR_INPUT_ADDRESS reloads followed by For each operand, any RELOAD_FOR_INPADDR_ADDRESS reloads followed
the RELOAD_FOR_INPUT reload for the operand. by any RELOAD_FOR_INPUT_ADDRESS reloads followed by the
RELOAD_FOR_INPUT reload for the operand.
RELOAD_FOR_OPADDR_ADDRS reloads. RELOAD_FOR_OPADDR_ADDRS reloads.
...@@ -6636,16 +6760,18 @@ emit_reload_insns (insn) ...@@ -6636,16 +6760,18 @@ emit_reload_insns (insn)
After the insn being reloaded, we write the following: After the insn being reloaded, we write the following:
For each operand, any RELOAD_FOR_OUTPUT_ADDRESS reload followed by For each operand, any RELOAD_FOR_OUTADDR_ADDRESS reloads followed
the RELOAD_FOR_OUTPUT reload, followed by any RELOAD_OTHER output by any RELOAD_FOR_OUTPUT_ADDRESS reload followed by the
reloads for the operand. The RELOAD_OTHER output reloads are output RELOAD_FOR_OUTPUT reload, followed by any RELOAD_OTHER output
in descending order by reload number. */ 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_address_reload_insns, before_insn);
emit_insns_before (other_input_reload_insns, before_insn); emit_insns_before (other_input_reload_insns, before_insn);
for (j = 0; j < reload_n_operands; j++) 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_address_reload_insns[j], before_insn);
emit_insns_before (input_reload_insns[j], before_insn); emit_insns_before (input_reload_insns[j], before_insn);
} }
...@@ -6655,6 +6781,7 @@ emit_reload_insns (insn) ...@@ -6655,6 +6781,7 @@ emit_reload_insns (insn)
for (j = 0; j < reload_n_operands; j++) 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_address_reload_insns[j], following_insn);
emit_insns_before (output_reload_insns[j], following_insn); emit_insns_before (output_reload_insns[j], following_insn);
emit_insns_before (other_output_reload_insns[j], following_insn); emit_insns_before (other_output_reload_insns[j], following_insn);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment