reg-stack.c: Do not emit pop insns after cc0 setter.
authorJan Hubicka <hubicka@freesoft.cz>
Mon, 17 May 1999 02:31:35 +0000 (04:31 +0200)
committerJeff Law <law@gcc.gnu.org>
Mon, 17 May 1999 02:31:35 +0000 (20:31 -0600)
        * 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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/reg-stack.c

index 0853d93..a70aa9c 100644 (file)
@@ -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 <daney@ibw.com.ni>
 
        * i386/sol2.h (LINK_SPEC): Do not pass "-z text" to the linker
index 8c4aa28..2e8236d 100644 (file)
@@ -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);
 }
 \f
 /* Output opcodes to transfer the results of FP compare or test INSN
index 4a27296..787b5a1 100644 (file)
@@ -1470,9 +1470,12 @@ delete_insn_for_stacker (insn)
 \f
 /* 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);
        }
     }
 }