From: Jan Hubicka Date: Mon, 17 May 1999 02:31:35 +0000 (+0200) Subject: reg-stack.c: Do not emit pop insns after cc0 setter. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e74389ffa1e8ba281899529f68430a4ea374869f;p=platform%2Fupstream%2Fgcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0853d93..a70aa9c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +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 * i386/sol2.h (LINK_SPEC): Do not pass "-z text" to the linker diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 8c4aa28..2e8236d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -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 diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 4a27296..787b5a1 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -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); } } }