reload.c (find_reloads_address): Make return value tri-state.
* reload.c (find_reloads_address): Make return value tri-state. Return -1 if LEGITIMIZE_RELOAD_ADDRESS succeeded. (find_reloads): Assume that reloaded addresses match 'o' or EXTRA_MEMORY_CONSTRAINT constraints only if find_reloads_address returned 1 (not -1). Omit optional reloads for address operands only if find_reloads_address returned 1 (not -1). * config/s390/s390.c (legitimize_reload_address): New function. * config/s390/s390-protos.h (legitimize_reload_address): Declare. * config/s390/s390.h (LEGITIMIZE_RELOAD_ADDRESS): Define. Call legitimize_reload_address. From-SVN: r86388
This commit is contained in:
parent
7f5e63076a
commit
0b540f12b0
|
@ -1,3 +1,17 @@
|
|||
2004-08-22 Ulrich Weigand <uweigand@de.ibm.com>
|
||||
|
||||
* reload.c (find_reloads_address): Make return value tri-state.
|
||||
Return -1 if LEGITIMIZE_RELOAD_ADDRESS succeeded.
|
||||
(find_reloads): Assume that reloaded addresses match 'o' or
|
||||
EXTRA_MEMORY_CONSTRAINT constraints only if find_reloads_address
|
||||
returned 1 (not -1). Omit optional reloads for address operands
|
||||
only if find_reloads_address returned 1 (not -1).
|
||||
|
||||
* config/s390/s390.c (legitimize_reload_address): New function.
|
||||
* config/s390/s390-protos.h (legitimize_reload_address): Declare.
|
||||
* config/s390/s390.h (LEGITIMIZE_RELOAD_ADDRESS): Define. Call
|
||||
legitimize_reload_address.
|
||||
|
||||
2004-08-22 Richard Hendersion <rth@redhat.com>
|
||||
|
||||
* tree.h (SAVE_EXPR_RESOLVED_P): New.
|
||||
|
|
|
@ -65,6 +65,7 @@ extern int legitimate_reload_constant_p (rtx);
|
|||
extern int legitimate_address_p (enum machine_mode, rtx, int);
|
||||
extern rtx legitimize_pic_address (rtx, rtx);
|
||||
extern rtx legitimize_address (rtx, rtx, enum machine_mode);
|
||||
extern rtx legitimize_reload_address (rtx, enum machine_mode, int, int);
|
||||
extern enum reg_class s390_preferred_reload_class (rtx, enum reg_class);
|
||||
extern enum reg_class s390_secondary_input_reload_class (enum reg_class,
|
||||
enum machine_mode,
|
||||
|
|
|
@ -3210,6 +3210,52 @@ legitimize_address (register rtx x, register rtx oldx ATTRIBUTE_UNUSED,
|
|||
return x;
|
||||
}
|
||||
|
||||
/* Try a machine-dependent way of reloading an illegitimate address AD
|
||||
operand. If we find one, push the reload and and return the new address.
|
||||
|
||||
MODE is the mode of the enclosing MEM. OPNUM is the operand number
|
||||
and TYPE is the reload type of the current reload. */
|
||||
|
||||
rtx
|
||||
legitimize_reload_address (rtx ad, enum machine_mode mode ATTRIBUTE_UNUSED,
|
||||
int opnum, int type)
|
||||
{
|
||||
if (!optimize || TARGET_LONG_DISPLACEMENT)
|
||||
return NULL_RTX;
|
||||
|
||||
if (GET_CODE (ad) == PLUS)
|
||||
{
|
||||
rtx tem = simplify_binary_operation (PLUS, Pmode,
|
||||
XEXP (ad, 0), XEXP (ad, 1));
|
||||
if (tem)
|
||||
ad = tem;
|
||||
}
|
||||
|
||||
if (GET_CODE (ad) == PLUS
|
||||
&& GET_CODE (XEXP (ad, 0)) == REG
|
||||
&& GET_CODE (XEXP (ad, 1)) == CONST_INT
|
||||
&& !DISP_IN_RANGE (INTVAL (XEXP (ad, 1))))
|
||||
{
|
||||
HOST_WIDE_INT lower = INTVAL (XEXP (ad, 1)) & 0xfff;
|
||||
HOST_WIDE_INT upper = INTVAL (XEXP (ad, 1)) ^ lower;
|
||||
rtx cst, tem, new;
|
||||
|
||||
cst = GEN_INT (upper);
|
||||
if (!legitimate_reload_constant_p (cst))
|
||||
cst = force_const_mem (Pmode, cst);
|
||||
|
||||
tem = gen_rtx_PLUS (Pmode, XEXP (ad, 0), cst);
|
||||
new = gen_rtx_PLUS (Pmode, tem, GEN_INT (lower));
|
||||
|
||||
push_reload (XEXP (tem, 1), 0, &XEXP (tem, 1), 0,
|
||||
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
|
||||
opnum, (enum reload_type) type);
|
||||
return new;
|
||||
}
|
||||
|
||||
return NULL_RTX;
|
||||
}
|
||||
|
||||
/* Emit code to move LEN bytes from DST to SRC. */
|
||||
|
||||
void
|
||||
|
|
|
@ -819,6 +819,19 @@ CUMULATIVE_ARGS;
|
|||
goto WIN; \
|
||||
}
|
||||
|
||||
/* Try a machine-dependent way of reloading an illegitimate address
|
||||
operand. If we find one, push the reload and jump to WIN. This
|
||||
macro is used in only one place: `find_reloads_address' in reload.c. */
|
||||
#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
|
||||
do { \
|
||||
rtx new = legitimize_reload_address (AD, MODE, OPNUM, (int)(TYPE)); \
|
||||
if (new) \
|
||||
{ \
|
||||
(AD) = new; \
|
||||
goto WIN; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Nonzero if the constant value X is a legitimate general operand.
|
||||
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
|
||||
#define LEGITIMATE_CONSTANT_P(X) \
|
||||
|
|
19
gcc/reload.c
19
gcc/reload.c
|
@ -2485,9 +2485,11 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
|||
a register. */
|
||||
enum reg_class preferred_class[MAX_RECOG_OPERANDS];
|
||||
char pref_or_nothing[MAX_RECOG_OPERANDS];
|
||||
/* Nonzero for a MEM operand whose entire address needs a reload. */
|
||||
/* Nonzero for a MEM operand whose entire address needs a reload.
|
||||
May be -1 to indicate the entire address may or may not need a reload. */
|
||||
int address_reloaded[MAX_RECOG_OPERANDS];
|
||||
/* Nonzero for an address operand that needs to be completely reloaded. */
|
||||
/* Nonzero for an address operand that needs to be completely reloaded.
|
||||
May be -1 to indicate the entire operand may or may not need a reload. */
|
||||
int address_operand_reloaded[MAX_RECOG_OPERANDS];
|
||||
/* Value of enum reload_type to use for operand. */
|
||||
enum reload_type operand_type[MAX_RECOG_OPERANDS];
|
||||
|
@ -3180,7 +3182,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
|||
: offsettable_nonstrict_memref_p (operand))
|
||||
/* A reloaded address is offsettable because it is now
|
||||
just a simple register indirect. */
|
||||
|| address_reloaded[i]))
|
||||
|| address_reloaded[i] == 1))
|
||||
|| (REG_P (operand)
|
||||
&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
|
||||
&& reg_renumber[REGNO (operand)] < 0
|
||||
|
@ -3291,7 +3293,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
|||
/* If the address was already reloaded,
|
||||
we win as well. */
|
||||
else if (MEM_P (operand)
|
||||
&& address_reloaded[i])
|
||||
&& address_reloaded[i] == 1)
|
||||
win = 1;
|
||||
/* Likewise if the address will be reloaded because
|
||||
reg_equiv_address is nonzero. For reg_equiv_mem
|
||||
|
@ -3891,7 +3893,7 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known,
|
|||
}
|
||||
else if (goal_alternative_matched[i] < 0
|
||||
&& goal_alternative_matches[i] < 0
|
||||
&& !address_operand_reloaded[i]
|
||||
&& address_operand_reloaded[i] != 1
|
||||
&& optimize)
|
||||
{
|
||||
/* For each non-matching operand that's a MEM or a pseudo-register
|
||||
|
@ -4631,8 +4633,9 @@ maybe_memory_address_p (enum machine_mode mode, rtx ad, rtx *part)
|
|||
to determine if we may generate output reloads, and where to put USEs
|
||||
for pseudos that we have to replace with stack slots.
|
||||
|
||||
Value is nonzero if this address is reloaded or replaced as a whole.
|
||||
This is interesting to the caller if the address is an autoincrement.
|
||||
Value is one if this address is reloaded or replaced as a whole; it is
|
||||
zero if the top level of this address was not reloaded or replaced, and
|
||||
it is -1 if it may or may not have been reloaded or replaced.
|
||||
|
||||
Note that there is no verification that the address will be valid after
|
||||
this routine does its work. Instead, we rely on the fact that the address
|
||||
|
@ -4771,7 +4774,7 @@ find_reloads_address (enum machine_mode mode, rtx *memrefloc, rtx ad,
|
|||
*memrefloc = copy_rtx (*memrefloc);
|
||||
XEXP (*memrefloc, 0) = ad;
|
||||
move_replacements (&ad, &XEXP (*memrefloc, 0));
|
||||
return 1;
|
||||
return -1;
|
||||
}
|
||||
while (0);
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue