aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/reload.c26
-rw-r--r--gcc/reload.h2
-rw-r--r--gcc/reload1.c4
4 files changed, 26 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ae3626f..a477e6f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -2,7 +2,10 @@
* rtl.c (class_narrowest_mode): Add entries for MODE_VECTOR_INT and
MODE_VECTOR_FLOAT.
-
+ * reload.c (regno_clobbered_p): Accept new arg, MODE, and use it
+ to handle multiword modes correctly. All callers and the declaration
+ changed.
+
2000-09-06 Mark Mitchell <mark@codesourcery.com>
* c-common.h (prep_stmt): Declare.
diff --git a/gcc/reload.c b/gcc/reload.c
index ee2fa48..d83b1f6 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -4519,7 +4519,7 @@ find_reloads_address (mode, memrefloc, ad, loc, opnum, type, ind_levels, insn)
else if (regno < FIRST_PSEUDO_REGISTER
&& REGNO_MODE_OK_FOR_BASE_P (regno, mode)
- && ! regno_clobbered_p (regno, this_insn))
+ && ! regno_clobbered_p (regno, this_insn, mode))
return 0;
/* If we do not have one of the cases above, we must do the reload. */
@@ -5427,7 +5427,7 @@ find_reloads_address_1 (mode, x, context, loc, opnum, type, ind_levels, insn)
in this insn, reload it into some other register to be safe.
The CLOBBER is supposed to make the register unavailable
from before this insn to after it. */
- if (regno_clobbered_p (regno, this_insn))
+ if (regno_clobbered_p (regno, this_insn, GET_MODE (x)))
{
push_reload (x, NULL_RTX, loc, NULL_PTR,
(context ? INDEX_REG_CLASS : BASE_REG_CLASS),
@@ -6544,13 +6544,21 @@ find_inc_amount (x, inced)
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
int
-regno_clobbered_p (regno, insn)
+regno_clobbered_p (regno, insn, mode)
unsigned int regno;
rtx insn;
+ enum machine_mode mode;
{
+ int nregs = HARD_REGNO_NREGS (regno, mode);
+ int endregno = regno + nregs;
+
if (GET_CODE (PATTERN (insn)) == CLOBBER
&& GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
- return REGNO (XEXP (PATTERN (insn), 0)) == regno;
+ {
+ int test = REGNO (XEXP (PATTERN (insn), 0));
+
+ return regno >= test && test < endregno;
+ }
if (GET_CODE (PATTERN (insn)) == PARALLEL)
{
@@ -6559,9 +6567,13 @@ regno_clobbered_p (regno, insn)
for (; i >= 0; i--)
{
rtx elt = XVECEXP (PATTERN (insn), 0, i);
- if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG
- && REGNO (XEXP (elt, 0)) == regno)
- return 1;
+ if (GET_CODE (elt) == CLOBBER && GET_CODE (XEXP (elt, 0)) == REG)
+ {
+ int test = REGNO (XEXP (elt, 0));
+
+ if (regno >= test && test < endregno)
+ return 1;
+ }
}
}
diff --git a/gcc/reload.h b/gcc/reload.h
index 5561197..a2df3b1 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -335,7 +335,7 @@ extern rtx find_equiv_reg PARAMS ((rtx, rtx, enum reg_class, int, short *,
int, enum machine_mode));
/* Return 1 if register REGNO is the subject of a clobber in insn INSN. */
-extern int regno_clobbered_p PARAMS ((unsigned int, rtx));
+extern int regno_clobbered_p PARAMS ((unsigned int, rtx, enum machine_mode));
/* Return 1 if X is an operand of an insn that is being earlyclobbered. */
int earlyclobber_operand_p PARAMS ((rtx));
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 8c3ef56..b09f9eb 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -5514,7 +5514,7 @@ choose_reload_regs (chain)
In particular, we then can't use EQUIV for a
RELOAD_FOR_OUTPUT_ADDRESS reload. */
- if (equiv != 0 && regno_clobbered_p (regno, insn))
+ if (equiv != 0 && regno_clobbered_p (regno, insn, rld[r].mode))
{
switch (rld[r].when_needed)
{
@@ -6536,7 +6536,7 @@ emit_output_reload_insns (chain, rl, j)
|| !(set = single_set (insn))
|| rtx_equal_p (old, SET_DEST (set))
|| !reg_mentioned_p (old, SET_SRC (set))
- || !regno_clobbered_p (REGNO (old), insn))
+ || !regno_clobbered_p (REGNO (old), insn, rl->mode))
gen_reload (old, reloadreg, rl->opnum,
rl->when_needed);
}