diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-02-03 18:04:00 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-02-03 18:04:00 +0000 |
commit | 9e53d777afe63f0ba62c349fa995521aa80ba4af (patch) | |
tree | 8507c30ec93900ecf31eb989170ec7ad89a5a432 | |
parent | 1962056ca825b29be1fe8d3d80add107fbf6df27 (diff) | |
download | gcc-9e53d777afe63f0ba62c349fa995521aa80ba4af.tar.gz |
Add INPADDR_ADDRESS and OUTADDR_ADDRESS reload types
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@13600 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/reload.c | 85 | ||||
-rw-r--r-- | gcc/reload.h | 7 | ||||
-rw-r--r-- | gcc/reload1.c | 165 |
3 files changed, 216 insertions, 41 deletions
diff --git a/gcc/reload.c b/gcc/reload.c index e1f5f912687..f1b79234c27 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -296,6 +296,15 @@ static int output_reloadnum; || (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 *)); @@ -359,7 +368,10 @@ push_secondary_reload (in_p, x, opnum, optional, reload_class, reload_mode, 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; @@ -1528,6 +1540,7 @@ combine_reloads () 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], @@ -3535,10 +3548,19 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) 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] = @@ -3725,9 +3747,13 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) 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]]]) @@ -3741,7 +3767,11 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) 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; } } @@ -3770,14 +3800,17 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) 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]; @@ -3792,7 +3825,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) = 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]; @@ -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_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)) @@ -3827,6 +3866,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p) 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 @@ -4217,7 +4257,8 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels) { 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, @@ -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. */ 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. */ @@ -4815,7 +4857,8 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels) 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. */ @@ -4883,7 +4926,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels) 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 @@ -4915,7 +4958,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels) 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), @@ -4953,7 +4996,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels) { 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) @@ -5958,8 +6001,10 @@ static char *reload_when_needed_name[] = "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", diff --git a/gcc/reload.h b/gcc/reload.h index c8ebbd34bda..ae6ce54cece 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -70,7 +70,9 @@ extern rtx reload_reg_rtx[MAX_RELOADS]; something used before or after the insn RELOAD_FOR_INPUT_ADDRESS reload for parts of the address of an object 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 operand; these don't conflict with any other addresses. @@ -86,7 +88,8 @@ extern rtx reload_reg_rtx[MAX_RELOADS]; enum reload_type { 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_OTHER, RELOAD_FOR_OTHER_ADDRESS }; diff --git a/gcc/reload1.c b/gcc/reload1.c index d4f21408954..d380b532ae0 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1050,7 +1050,9 @@ reload (first, global, dumpfile) 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. */ @@ -1210,9 +1212,15 @@ reload (first, global, dumpfile) 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; @@ -1286,8 +1294,14 @@ reload (first, global, dumpfile) { 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, @@ -1321,8 +1335,12 @@ reload (first, global, dumpfile) 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], @@ -4277,8 +4295,12 @@ reload_reg_class_lower (r1p, r2p) 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. */ @@ -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); 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; @@ -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); 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; @@ -4439,7 +4477,9 @@ reload_reg_free_p (regno, opnum, type) 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; @@ -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. */ 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; @@ -4469,7 +4510,21 @@ reload_reg_free_p (regno, opnum, type) 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++) @@ -4490,6 +4545,19 @@ reload_reg_free_p (regno, opnum, type) 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)) @@ -4516,7 +4584,8 @@ reload_reg_free_p (regno, opnum, type) 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; @@ -4570,12 +4639,14 @@ reload_reg_free_before_p (regno, opnum, type) 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; @@ -4584,6 +4655,7 @@ reload_reg_free_before_p (regno, opnum, type) 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; @@ -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 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; @@ -4619,7 +4694,8 @@ reload_reg_free_before_p (regno, opnum, type) 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); @@ -4630,16 +4706,19 @@ reload_reg_free_before_p (regno, opnum, type) 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); @@ -4681,8 +4760,10 @@ reload_reg_reaches_end_p (regno, opnum, type) 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; @@ -4691,6 +4772,7 @@ reload_reg_reaches_end_p (regno, opnum, type) && ! 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 @@ -4701,11 +4783,13 @@ reload_reg_reaches_end_p (regno, opnum, type) 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; @@ -4723,6 +4807,7 @@ reload_reg_reaches_end_p (regno, opnum, type) 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; @@ -4733,6 +4818,7 @@ reload_reg_reaches_end_p (regno, opnum, type) 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; @@ -4741,6 +4827,7 @@ reload_reg_reaches_end_p (regno, opnum, type) 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; @@ -4757,10 +4844,12 @@ reload_reg_reaches_end_p (regno, opnum, type) 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; @@ -4796,16 +4885,26 @@ reloads_conflict (r1, r2) || 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); @@ -4816,7 +4915,8 @@ reloads_conflict (r1, r2) 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: @@ -5078,7 +5178,9 @@ choose_reload_regs (insn, avoid_return_reg) 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; @@ -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_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 @@ -5242,8 +5346,12 @@ choose_reload_regs (insn, avoid_return_reg) 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. @@ -5621,8 +5729,12 @@ choose_reload_regs (insn, avoid_return_reg) 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]); } } @@ -5796,8 +5908,9 @@ merge_assigned_reloads (insn) && 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); } } } @@ -5814,8 +5927,10 @@ emit_reload_insns (insn) 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]; @@ -5827,7 +5942,9 @@ emit_reload_insns (insn) 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 @@ -6022,9 +6139,15 @@ emit_reload_insns (insn) 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; @@ -6627,8 +6750,9 @@ emit_reload_insns (insn) 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. @@ -6636,16 +6760,18 @@ emit_reload_insns (insn) 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); } @@ -6655,6 +6781,7 @@ emit_reload_insns (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); |