OSDN Git Service

* configure.in: Fix typo.
[pf3gnuchains/gcc-fork.git] / gcc / reg-stack.c
index ff896fd..965aad0 100644 (file)
@@ -1,6 +1,6 @@
 /* Register to Stack convert for GNU compiler.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
 \f
 #include "config.h"
 #include "system.h"
+#include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "rtl.h"
 #include "tm_p.h"
@@ -222,7 +224,7 @@ enum emit_where
 /* The block we're currently working on.  */
 static basic_block current_block;
 
-/* This is the register file for all register after conversion */
+/* This is the register file for all register after conversion */
 static rtx
   FP_mode_reg[LAST_STACK_REG+1-FIRST_STACK_REG][(int) MAX_MACHINE_MODE];
 
@@ -268,7 +270,7 @@ static rtx next_flags_user          PARAMS ((rtx));
 static void record_label_references    PARAMS ((rtx, rtx));
 static bool compensate_edge            PARAMS ((edge, FILE *));
 \f
-/* Return non-zero if any stack register is mentioned somewhere within PAT.  */
+/* Return nonzero if any stack register is mentioned somewhere within PAT.  */
 
 static int
 stack_regs_mentioned_p (pat)
@@ -353,7 +355,7 @@ next_flags_user (insn)
   return NULL_RTX;
 }
 \f
-/* Reorganise the stack into ascending numbers,
+/* Reorganize the stack into ascending numbers,
    after this insn.  */
 
 static void
@@ -379,7 +381,7 @@ straighten_stack (insn, regstack)
   change_stack (insn, regstack, &temp_stack, EMIT_AFTER);
 }
 
-/* Pop a register from the stack */
+/* Pop a register from the stack */
 
 static void
 pop_stack (regstack, regno)
@@ -390,7 +392,7 @@ pop_stack (regstack, regno)
 
   CLEAR_HARD_REG_BIT (regstack->reg_set, regno);
   regstack->top--;
-  /* If regno was not at the top of stack then adjust stack */
+  /* If regno was not at the top of stack then adjust stack */
   if (regstack->reg [top] != regno)
     {
       int i;
@@ -476,7 +478,7 @@ reg_to_stack (first, file)
   /* A QNaN for initializing uninitialized variables.
 
      ??? We can't load from constant memory in PIC mode, because
-     we're insertting these instructions before the prologue and
+     we're inserting these instructions before the prologue and
      the PIC register hasn't been set up.  In that case, fall back
      on zero, which we can get from `ldz'.  */
 
@@ -564,7 +566,7 @@ get_true_reg (pat)
     switch (GET_CODE (*pat))
       {
       case SUBREG:
-       /* Eliminate FP subregister accesses in favour of the
+       /* Eliminate FP subregister accesses in favor of the
           actual FP register in use.  */
        {
          rtx subreg;
@@ -744,7 +746,7 @@ check_asm_stack_operands (insn)
       malformed_asm = 1;
     }
 
-  /* Enfore rule #3: If any input operand uses the "f" constraint, all
+  /* Enforce rule #3: If any input operand uses the "f" constraint, all
      output constraints must use the "&" earlyclobber.
 
      ??? Detect this more deterministically by having constrain_asm_operands
@@ -1125,7 +1127,7 @@ move_for_stack_reg (insn, regstack, pat)
          return;
        }
 
-      /* The destination ought to be dead */
+      /* The destination ought to be dead */
       if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
        abort ();
 
@@ -1181,7 +1183,7 @@ move_for_stack_reg (insn, regstack, pat)
         stack. The stack mapping is changed to reflect that DEST is
         now at top of stack.  */
 
-      /* The destination ought to be dead */
+      /* The destination ought to be dead */
       if (get_hard_regnum (regstack, dest) >= FIRST_STACK_REG)
        abort ();
 
@@ -1687,7 +1689,7 @@ subst_stack_regs_pat (insn, regstack, pat)
                replace_reg (dest, get_hard_regnum (regstack, *dest));
              }
 
-           /* Keep operand 1 maching with destination.  */
+           /* Keep operand 1 matching with destination.  */
            if (GET_RTX_CLASS (GET_CODE (pat_src)) == 'c'
                && REG_P (*src1) && REG_P (*src2)
                && REGNO (*src1) != REGNO (*dest))
@@ -1724,6 +1726,73 @@ subst_stack_regs_pat (insn, regstack, pat)
                replace_reg (src1, FIRST_STACK_REG);
                break;
 
+             case UNSPEC_FPATAN:
+               /* These insns operate on the top two stack slots.  */
+
+               src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
+               src2 = get_true_reg (&XVECEXP (pat_src, 0, 1));
+
+               src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
+               src2_note = find_regno_note (insn, REG_DEAD, REGNO (*src2));
+
+               {
+                 struct stack_def temp_stack;
+                 int regno, j, k, temp;
+
+                 temp_stack = *regstack;
+
+                 /* Place operand 1 at the top of stack.  */
+                 regno = get_hard_regnum (&temp_stack, *src1);
+                 if (regno < 0)
+                   abort ();
+                 if (regno != FIRST_STACK_REG)
+                   {
+                     k = temp_stack.top - (regno - FIRST_STACK_REG);
+                     j = temp_stack.top;
+
+                     temp = temp_stack.reg[k];
+                     temp_stack.reg[k] = temp_stack.reg[j];
+                     temp_stack.reg[j] = temp;
+                   }
+
+                 /* Place operand 2 next on the stack.  */
+                 regno = get_hard_regnum (&temp_stack, *src2);
+                 if (regno < 0)
+                   abort ();
+                 if (regno != FIRST_STACK_REG + 1)
+                   {
+                     k = temp_stack.top - (regno - FIRST_STACK_REG);
+                     j = temp_stack.top - 1;
+
+                     temp = temp_stack.reg[k];
+                     temp_stack.reg[k] = temp_stack.reg[j];
+                     temp_stack.reg[j] = temp;
+                   }
+
+                 change_stack (insn, regstack, &temp_stack, EMIT_BEFORE);
+               }
+
+               replace_reg (src1, FIRST_STACK_REG);
+               replace_reg (src2, FIRST_STACK_REG + 1);
+
+               if (src1_note)
+                 replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
+               if (src2_note)
+                 replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);
+
+               /* Pop both input operands from the stack.  */
+               CLEAR_HARD_REG_BIT (regstack->reg_set,
+                                   regstack->reg[regstack->top]);
+               CLEAR_HARD_REG_BIT (regstack->reg_set,
+                                   regstack->reg[regstack->top - 1]);
+               regstack->top -= 2;
+
+               /* Push the result back onto the stack.  */
+               regstack->reg[++regstack->top] = REGNO (*dest);
+               SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+               replace_reg (dest, FIRST_STACK_REG);
+               break;
+
              case UNSPEC_SAHF:
                /* (unspec [(unspec [(compare)] UNSPEC_FNSTSW)] UNSPEC_SAHF)
                   The combination matches the PPRO fcomi instruction.  */
@@ -2404,7 +2473,7 @@ convert_regs_entry ()
      the push/pop code happy, and to not scrog the register stack, we
      must put something in these registers.  Use a QNaN.
 
-     Note that we are insertting converted code here.  This code is
+     Note that we are inserting converted code here.  This code is
      never seen by the convert_regs pass.  */
 
   for (e = ENTRY_BLOCK_PTR->succ; e ; e = e->succ_next)
@@ -2462,7 +2531,7 @@ convert_regs_exit ()
       output_stack->top = value_reg_high - value_reg_low;
       for (reg = value_reg_low; reg <= value_reg_high; ++reg)
        {
-         output_stack->reg[reg - value_reg_low] = reg;
+         output_stack->reg[value_reg_high - reg] = reg;
          SET_HARD_REG_BIT (output_stack->reg_set, reg);
        }
     }
@@ -2553,7 +2622,11 @@ compensate_edge (e, file)
       abort ();
     eh1:
 
+      /* We are sure that there is st(0) live, otherwise we won't compensate.
+        For complex return values, we may have st(1) live as well.  */
       SET_HARD_REG_BIT (tmp, FIRST_STACK_REG);
+      if (TEST_HARD_REG_BIT (regstack.reg_set, FIRST_STACK_REG + 1))
+        SET_HARD_REG_BIT (tmp, FIRST_STACK_REG + 1);
       GO_IF_HARD_REG_EQUAL (regstack.reg_set, tmp, eh2);
       abort ();
     eh2: