This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
reg-stack fix (installing as obvious)
- To: gcc-patches at gcc dot gnu dot org
- Subject: reg-stack fix (installing as obvious)
- From: Jan Hubicka <jh at suse dot cz>
- Date: Sat, 8 Sep 2001 21:35:20 +0200
Hi,
in the last reg-stack change I made two thinkos that elliminated each other in
my testcase, but unfortunately not in the all cases.
The problem is that I've attempted to simulate fcmov as instruction that first
pops all arguments and then pushes result. This does not work when
top-of-stack argument is the first one, as the stack after it's "pop", the real
pop is emitted, but it contains wrong offset, as in fact no pop is done.
This patch contains sollution IMO easier to understand (and hopefully correct).
I first "simulate" fxch, but don't do it really and then reverse conditional
in fcmov to compensate the trick.
As the problem is common enought to break almost any FP code, I am installing
the patch as obvious once bootstrapping and regtesting with -match=athlon
complettes.
Honza
Sat Sep 8 22:42:14 CEST 2001 Jan Hubicka <jh@suse.cz>
* reg-stack.c (subst_stack_regs_pat): Fix fcmov reversal code.
*** reg-stack.c.old Sat Sep 8 21:12:41 2001
--- reg-stack.c Sat Sep 8 22:37:40 2001
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1797,1816 ****
|| (REGNO (*src2) == regstack->reg[regstack->top]
&& src2_note))
{
! /* We know that both sources "dies", as one dies and other
! is overwriten by the destination. Claim both sources
! to be dead, as the code bellow will properly pop the
! non-top-of-stack note and replace top-of-stack by the
! result by popping source first and then pushing result. */
! if (!src1_note)
! src1_note = REG_NOTES (insn)
! = gen_rtx_EXPR_LIST (REG_DEAD, *src1, REG_NOTES (insn));
! if (!src2_note)
! src2_note = REG_NOTES (insn)
! = gen_rtx_EXPR_LIST (REG_DEAD, *src2, REG_NOTES (insn));
!
! /* i386 do have comparison always reversible. */
PUT_CODE (XEXP (pat_src, 0),
reversed_comparison_code (XEXP (pat_src, 0), insn));
}
--- 1797,1814 ----
|| (REGNO (*src2) == regstack->reg[regstack->top]
&& src2_note))
{
+ int idx1 = (get_hard_regnum (regstack, *src1)
+ - FIRST_STACK_REG);
+ int idx2 = (get_hard_regnum (regstack, *src2)
+ - FIRST_STACK_REG);
+
+ /* Make reg-stack believe that the operands are already
+ swapped on the stack */
+ regstack->reg[regstack->top - idx1] = REGNO (*src2);
+ regstack->reg[regstack->top - idx2] = REGNO (*src1);
! /* Reverse condition to compensate the operand swap.
! i386 do have comparison always reversible. */
PUT_CODE (XEXP (pat_src, 0),
reversed_comparison_code (XEXP (pat_src, 0), insn));
}
*************** subst_stack_regs_pat (insn, regstack, pa
*** 1845,1855 ****
EMIT_AFTER);
}
else
! {
! CLEAR_HARD_REG_BIT (regstack->reg_set, regno);
! replace_reg (&XEXP (src_note[i], 0), FIRST_STACK_REG);
! regstack->top--;
! }
}
}
--- 1843,1851 ----
EMIT_AFTER);
}
else
! /* Top of stack never dies, as it is the
! destination. */
! abort ();
}
}