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> 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 * i386/sol2.h (LINK_SPEC): Do not pass "-z text" to the linker
......
...@@ -4115,6 +4115,8 @@ output_float_compare (insn, operands) ...@@ -4115,6 +4115,8 @@ output_float_compare (insn, operands)
rtx body = XVECEXP (PATTERN (insn), 0, 0); rtx body = XVECEXP (PATTERN (insn), 0, 0);
int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode; int unordered_compare = GET_MODE (SET_SRC (body)) == CCFPEQmode;
rtx tmp; rtx tmp;
int cc0_set = 1;
int i;
if (0 && TARGET_CMOVE && STACK_REG_P (operands[1])) if (0 && TARGET_CMOVE && STACK_REG_P (operands[1]))
{ {
...@@ -4138,7 +4140,7 @@ output_float_compare (insn, operands) ...@@ -4138,7 +4140,7 @@ output_float_compare (insn, operands)
if (STACK_REG_P (operands[1]) if (STACK_REG_P (operands[1])
&& stack_top_dies && stack_top_dies
&& find_regno_note (insn, REG_DEAD, REGNO (operands[1])) && 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 /* 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 is also a stack register that dies, then this must be a
...@@ -4150,7 +4152,7 @@ output_float_compare (insn, operands) ...@@ -4150,7 +4152,7 @@ output_float_compare (insn, operands)
{ {
output_asm_insn (AS2 (fucomip,%y1,%0), operands); output_asm_insn (AS2 (fucomip,%y1,%0), operands);
output_asm_insn (AS1 (fstp, %y0), operands); output_asm_insn (AS1 (fstp, %y0), operands);
return ""; cc0_set = 0;
} }
else else
output_asm_insn ("fucompp", operands); output_asm_insn ("fucompp", operands);
...@@ -4161,7 +4163,7 @@ output_float_compare (insn, operands) ...@@ -4161,7 +4163,7 @@ output_float_compare (insn, operands)
{ {
output_asm_insn (AS2 (fcomip, %y1,%0), operands); output_asm_insn (AS2 (fcomip, %y1,%0), operands);
output_asm_insn (AS1 (fstp, %y0), operands); output_asm_insn (AS1 (fstp, %y0), operands);
return ""; cc0_set = 0;
} }
else else
output_asm_insn ("fcompp", operands); output_asm_insn ("fcompp", operands);
...@@ -4186,15 +4188,39 @@ output_float_compare (insn, operands) ...@@ -4186,15 +4188,39 @@ output_float_compare (insn, operands)
if (cc_status.flags & CC_FCOMI) if (cc_status.flags & CC_FCOMI)
{ {
output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands); output_asm_insn (strcat (buf, AS2 (%z1,%y1,%0)), operands);
return ""; cc0_set = 0;
} }
else else
output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands); output_asm_insn (strcat (buf, AS1 (%z1,%y1)), operands);
} }
/* Now retrieve the condition code. */ /* 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 /* Output opcodes to transfer the results of FP compare or test INSN
......
...@@ -1470,9 +1470,12 @@ delete_insn_for_stacker (insn) ...@@ -1470,9 +1470,12 @@ delete_insn_for_stacker (insn)
/* Emit an insn to pop virtual register REG before or after 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 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 pop. WHEN is either emit_insn_before, emit_insn_after or NULL.
is represented as a SET whose destination is the register to be popped in case WHEN is NULL we don't really emit the insn, just modify stack
and source is the top of stack. A death note for the top of 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. */ cases the movdf pattern to pop. */
static rtx static rtx
...@@ -1490,14 +1493,18 @@ emit_pop_insn (insn, regstack, reg, when) ...@@ -1490,14 +1493,18 @@ emit_pop_insn (insn, regstack, reg, when)
if (hard_regno < FIRST_STACK_REG) if (hard_regno < FIRST_STACK_REG)
abort (); abort ();
pop_rtx = gen_rtx_SET (VOIDmode, FP_MODE_REG (hard_regno, DFmode), if (when)
FP_MODE_REG (FIRST_STACK_REG, DFmode)); {
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, REG_NOTES (pop_insn) = gen_rtx_EXPR_LIST (REG_DEAD,
FP_MODE_REG (FIRST_STACK_REG, DFmode), FP_MODE_REG (FIRST_STACK_REG,
REG_NOTES (pop_insn)); DFmode),
REG_NOTES (pop_insn));
}
regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)] regstack->reg[regstack->top - (hard_regno - FIRST_STACK_REG)]
= regstack->reg[regstack->top]; = regstack->reg[regstack->top];
...@@ -1757,10 +1764,18 @@ swap_rtx_condition (pat) ...@@ -1757,10 +1764,18 @@ swap_rtx_condition (pat)
/* Handle a comparison. Special care needs to be taken to avoid /* Handle a comparison. Special care needs to be taken to avoid
causing comparisons that a 387 cannot do correctly, such as EQ. 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 `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 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 static void
compare_for_stack_reg (insn, regstack, pat) compare_for_stack_reg (insn, regstack, pat)
...@@ -1772,6 +1787,7 @@ compare_for_stack_reg (insn, regstack, pat) ...@@ -1772,6 +1787,7 @@ compare_for_stack_reg (insn, regstack, pat)
rtx src1_note, src2_note; rtx src1_note, src2_note;
rtx cc0_user; rtx cc0_user;
int have_cmove; int have_cmove;
int hard_regno;
src1 = get_true_reg (&XEXP (SET_SRC (pat), 0)); src1 = get_true_reg (&XEXP (SET_SRC (pat), 0));
src2 = get_true_reg (&XEXP (SET_SRC (pat), 1)); src2 = get_true_reg (&XEXP (SET_SRC (pat), 1));
...@@ -1838,7 +1854,10 @@ compare_for_stack_reg (insn, regstack, pat) ...@@ -1838,7 +1854,10 @@ compare_for_stack_reg (insn, regstack, pat)
replace_reg (src1, FIRST_STACK_REG); replace_reg (src1, FIRST_STACK_REG);
if (STACK_REG_P (*src2)) 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) if (src1_note)
{ {
...@@ -1867,16 +1886,11 @@ compare_for_stack_reg (insn, regstack, pat) ...@@ -1867,16 +1886,11 @@ compare_for_stack_reg (insn, regstack, pat)
} }
else else
{ {
/* The 386 can only represent death of the first operand in /* Pop of second operand is handled using special REG_DEAD note
the case handled above. In all other cases, emit a separate because we can't emit pop insn after cc0 setter. */
pop and remove the death note from here. */
link_cc0_insns (insn);
remove_regno_note (insn, REG_DEAD, REGNO (XEXP (src2_note, 0)));
emit_pop_insn (insn, regstack, XEXP (src2_note, 0), emit_pop_insn (insn, regstack, XEXP (src2_note, 0), NULL);
emit_insn_after); 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