Commit e74389ff by Jan Hubicka Committed by Jeff Law

reg-stack.c: Do not emit pop insns after cc0 setter.

        * reg-stack.c: Do not emit pop insns after cc0 setter.
        (emit_pop_insn): Do not emit insn in case WHEN is NULL.
        (compare_for_stack_reg): Update REG_DEAD note and
        do not emit push insn.
        * i386.c: (output_float_compare): Handle new REG_DEAD notes.

From-SVN: r26965
parent 64c0b414
Sat Oct 31 05:08:34 CET 1998 Jan Hubicka (hubicka@freesoft.cz)
* reg-stack.c: Do not emit pop insns after cc0 setter.
(emit_pop_insn): Do not emit insn in case WHEN is NULL.
(compare_for_stack_reg): Update REG_DEAD note and
do not emit push insn.
* i386.c: (output_float_compare): Handle new REG_DEAD notes.
Mon May 17 01:57:37 1999 David Daney <daney@ibw.com.ni>
* i386/sol2.h (LINK_SPEC): Do not pass "-z text" to the linker
......
......@@ -4115,6 +4115,8 @@ output_float_compare (insn, operands)
rtx body = XVECEXP (PATTERN (insn), 0, 0);
int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
rtx tmp;
int cc0_set = 1;
int i;
if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
{
......@@ -4138,7 +4140,7 @@ output_float_compare (insn, operands)
if (STACK_REG_P (operands[1])
&& stack_top_dies
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
&& REGNO (operands[1]) != FIRST_STACK_REG)
&& REGNO (operands[1]) == FIRST_STACK_REG + 1)
{
/* If both the top of the 387 stack dies, and the other operand
is also a stack register that dies, then this must be a
......@@ -4150,7 +4152,7 @@ output_float_compare (insn, operands)
{
output_asm_insn (AS2 (fucomip,%y1,%0), operands);
output_asm_insn (AS1 (fstp, %y0), operands);
return "";
cc0_set = 0;
}
else
output_asm_insn ("fucompp", operands);
......@@ -4161,7 +4163,7 @@ output_float_compare (insn, operands)
{
output_asm_insn (AS2 (fcomip, %y1,%0), operands);
output_asm_insn (AS1 (fstp, %y0), operands);
return "";
cc0_set = 0;
}
else
output_asm_insn ("fcompp", operands);
......@@ -4186,15 +4188,39 @@ output_float_compare (insn, operands)
if (cc_status.flags & CC_FCOMI)
{
output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
return "";
cc0_set = 0;
}
else
output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
}
/* Now retrieve the condition code. */
if (cc0_set)
{
char *r = output_fp_cc0_set (insn);
if (r[0]) output_asm_insn (r, operands);
}
/* We emit fstp instruction after integer comparsions to improve
scheduling. */
for (i = 0; i < 2 ; i++)
{
if (STACK_REG_P (operands[i])
&& find_regno_note (insn, REG_DEAD, REGNO (operands[i]))
&& REGNO (operands[i]) != FIRST_STACK_REG
&& (!stack_top_dies || REGNO (operands[i]) != FIRST_STACK_REG + 1))
{
rtx xexp[i];
xexp[0] = gen_rtx_REG (DFmode,
REGNO (operands[i]) - (stack_top_dies != 0));
output_asm_insn (AS1 (fstp, %y0), xexp);
}
}
return "";
return output_fp_cc0_set (insn);
}
/* Output opcodes to transfer the results of FP compare or test INSN
......
......@@ -1470,9 +1470,12 @@ delete_insn_for_stacker (insn)
/* Emit an insn to pop virtual register REG before or after INSN.
REGSTACK is the stack state after INSN and is updated to reflect this
pop. WHEN is either emit_insn_before or emit_insn_after. A pop insn
is represented as a SET whose destination is the register to be popped
and source is the top of stack. A death note for the top of stack
pop. WHEN is either emit_insn_before, emit_insn_after or NULL.
in case WHEN is NULL we don't really emit the insn, just modify stack
information. Caller is expected to emit insn himself.
A pop insn is represented as a SET whose destination is the register to
be popped and source is the top of stack. A death note for the top of stack
cases the movdf pattern to pop. */
static rtx
......@@ -1490,14 +1493,18 @@ emit_pop_insn (insn, regstack, reg, when)
if (hard_regno < FIRST_STACK_REG)
abort ();
pop_rtx = gen_rtx_SET (VOIDmode, FP_MODE_REG (hard_regno, DFmode),
FP_MODE_REG (FIRST_STACK_REG, DFmode));
if (when)
{
pop_rtx = gen_rtx_SET (VOIDmode, FP_MODE_REG (hard_regno, DFmode),
FP_MODE_REG (FIRST_STACK_REG, DFmode));
pop_insn = (*when) (pop_rtx, insn);
pop_insn = (*when) (pop_rtx, insn);
REG_NOTES (pop_insn) = gen_rtx_EXPR_LIST (REG_DEAD,
FP_MODE_REG (FIRST_STACK_REG, DFmode),
REG_NOTES (pop_insn));
REG_NOTES (pop_insn) = gen_rtx_EXPR_LIST (REG_DEAD,
FP_MODE_REG (FIRST_STACK_REG,
DFmode),
REG_NOTES (pop_insn));
}
regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
= regstack->reg[regstack->top];
......@@ -1757,10 +1764,18 @@ swap_rtx_condition (pat)
/* Handle a comparison. Special care needs to be taken to avoid
causing comparisons that a 387 cannot do correctly, such as EQ.
Also, a pop insn may need to be emitted. The 387 does have an
Also, a fstp instruction may need to be emitted. The 387 does have an
`fcompp' insn that can pop two regs, but it is sometimes too expensive
to do this - a `fcomp' followed by a `fstpl %st(0)' may be easier to
set up. */
set up.
We can not handle this by emiting fpop instruction after compare, because
it appears between cc0 setter and user. So we emit only
REG_DEAD note and handle it as a special case in machine description.
This code used trick with delay_slot filling to emit pop insn after
comparsion but it didn't worked because it caused confusion with cc_status
in final pass. */
static void
compare_for_stack_reg (insn, regstack, pat)
......@@ -1772,6 +1787,7 @@ compare_for_stack_reg (insn, regstack, pat)
rtx src1_note, src2_note;
rtx cc0_user;
int have_cmove;
int hard_regno;
src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
......@@ -1838,7 +1854,10 @@ compare_for_stack_reg (insn, regstack, pat)
replace_reg (src1, FIRST_STACK_REG);
if (STACK_REG_P (*src2))
replace_reg (src2, get_hard_regnum (regstack, *src2));
{
hard_regno = get_hard_regnum (regstack, *src2);
replace_reg (src2, hard_regno);
}
if (src1_note)
{
......@@ -1867,16 +1886,11 @@ compare_for_stack_reg (insn, regstack, pat)
}
else
{
/* The 386 can only represent death of the first operand in
the case handled above. In all other cases, emit a separate
pop and remove the death note from here. */
link_cc0_insns (insn);
remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0)));
/* Pop of second operand is handled using special REG_DEAD note
because we can't emit pop insn after cc0 setter. */
emit_pop_insn (insn, regstack, XEXP (src2_note, 0),
emit_insn_after);
emit_pop_insn (insn, regstack, XEXP (src2_note, 0), NULL);
replace_reg (&XEXP (src2_note, 0), hard_regno);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment