summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@redhat.co.uk>2000-12-20 13:47:24 +0000
committerBernd Schmidt <bernds@gcc.gnu.org>2000-12-20 13:47:24 +0000
commitb1077f68f454e38b818d6b65dd5380b42e75ae62 (patch)
treece06737a8f5d19eb0e5209fa69a3d4564d2376aa
parentf69c613535d7d437af028adeea759109865ee554 (diff)
downloadgcc-b1077f68f454e38b818d6b65dd5380b42e75ae62.tar.gz
Handle multiword hard regs properly in find_equiv_reg
From-SVN: r38396
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/reload.c76
2 files changed, 64 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 09a5fad2321..49b0610895a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2000-12-20 Bernd Schmidt <bernds@redhat.co.uk>
+
+ Thu Nov 2 19:20:12 2000 J"orn Rennecke <amylaar@redhat.com>
+ * reload.c (find_equiv_reg): Test all hard registers for membership
+ in the requested class.
+
+ Sun Apr 23 16:24:35 2000 Denis Chertykov <denisc@overta.ru>
+ * reload.c (find_equiv_reg): Checks all valueno regs
+ as a reload_reg_p regs.
+
+ Fri Apr 21 14:58:29 2000 Denis Chertykov <denisc@overta.ru>
+ * reload.c (find_equiv_reg): Checks all valueno and regno regs
+ as a call-clobbered regs.
+
2000-12-18 Bernd Schmidt <bernds@redhat.co.uk>
2000-09-15 Bernd Schmidt <bernds@redhat.co.uk>
diff --git a/gcc/reload.c b/gcc/reload.c
index 7aa297150e8..5b828670df2 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -6274,16 +6274,29 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
&& (valtry
= operand_subword (SET_DEST (pat), 1, 0, VOIDmode))
&& (valueno = true_regnum (valtry)) >= 0)))
- if (other >= 0
- ? valueno == other
- : ((unsigned) valueno < FIRST_PSEUDO_REGISTER
- && TEST_HARD_REG_BIT (reg_class_contents[(int) class],
- valueno)))
- {
- value = valtry;
- where = p;
- break;
- }
+ {
+ if (other >= 0)
+ {
+ if (valueno != other)
+ continue;
+ }
+ else if ((unsigned) valueno >= FIRST_PSEUDO_REGISTER)
+ continue;
+ else
+ {
+ int i;
+
+ for (i = HARD_REGNO_NREGS (valueno, mode) - 1; i >= 0; i--)
+ if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
+ valueno + i))
+ break;
+ if (i >= 0)
+ continue;
+ }
+ value = valtry;
+ where = p;
+ break;
+ }
}
}
@@ -6326,15 +6339,22 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
&& regno < valueno + HARD_REGNO_NREGS (valueno, mode))
return 0;
+ nregs = HARD_REGNO_NREGS (regno, mode);
+ valuenregs = HARD_REGNO_NREGS (valueno, mode);
+
/* Reject VALUE if it is one of the regs reserved for reloads.
Reload1 knows how to reuse them anyway, and it would get
confused if we allocated one without its knowledge.
(Now that insns introduced by reload are ignored above,
this case shouldn't happen, but I'm not positive.) */
- if (reload_reg_p != 0 && reload_reg_p != (short *) (HOST_WIDE_INT) 1
- && reload_reg_p[valueno] >= 0)
- return 0;
+ if (reload_reg_p != 0 && reload_reg_p != (short *) (HOST_WIDE_INT) 1)
+ {
+ int i;
+ for (i = 0; i < valuenregs; ++i)
+ if (reload_reg_p[valueno + i] >= 0)
+ return 0;
+ }
/* On some machines, certain regs must always be rejected
because they don't behave the way ordinary registers do. */
@@ -6344,9 +6364,6 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
return 0;
#endif
- nregs = HARD_REGNO_NREGS (regno, mode);
- valuenregs = HARD_REGNO_NREGS (valueno, mode);
-
/* Reject VALUE if it is a register being used for an input reload
even if it is not one of those reserved. */
@@ -6382,16 +6399,23 @@ find_equiv_reg (goal, insn, class, other, reload_reg_p, goalreg, mode)
/* Don't trust the conversion past a function call
if either of the two is in a call-clobbered register, or memory. */
- if (GET_CODE (p) == CALL_INSN
- && ((regno >= 0 && regno < FIRST_PSEUDO_REGISTER
- && call_used_regs[regno])
- ||
- (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER
- && call_used_regs[valueno])
- ||
- goal_mem
- || need_stable_sp))
- return 0;
+ if (GET_CODE (p) == CALL_INSN)
+ {
+ int i;
+
+ if (goal_mem || need_stable_sp)
+ return 0;
+
+ if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER)
+ for (i = 0; i < nregs; ++i)
+ if (call_used_regs[regno + i])
+ return 0;
+
+ if (valueno >= 0 && valueno < FIRST_PSEUDO_REGISTER)
+ for (i = 0; i < valuenregs; ++i)
+ if (call_used_regs[valueno + i])
+ return 0;
+ }
#ifdef NON_SAVING_SETJMP
if (NON_SAVING_SETJMP && GET_CODE (p) == NOTE