OSDN Git Service

2006-12-13 Jakub Jelinek <jakub@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / reg-stack.c
index 83f4ebb..49c733e 100644 (file)
@@ -439,6 +439,11 @@ get_true_reg (rtx *pat)
        pat = & XEXP (*pat, 0);
        break;
 
+      case UNSPEC:
+       if (XINT (*pat, 1) == UNSPEC_TRUNC_NOOP)
+         pat = & XVECEXP (*pat, 0, 0);
+       return pat;
+
       case FLOAT_TRUNCATE:
        if (!flag_unsafe_math_optimizations)
          return pat;
@@ -1702,11 +1707,12 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
 
                /* Push the result back onto stack. Empty stack slot
                   will be filled in second part of insn.  */
-               if (STACK_REG_P (*dest)) {
-                 regstack->reg[regstack->top] = REGNO (*dest);
-                 SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
-                 replace_reg (dest, FIRST_STACK_REG);
-               }
+               if (STACK_REG_P (*dest))
+                 {
+                   regstack->reg[regstack->top] = REGNO (*dest);
+                   SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+                   replace_reg (dest, FIRST_STACK_REG);
+                 }
 
                replace_reg (src1, FIRST_STACK_REG);
                replace_reg (src2, FIRST_STACK_REG + 1);
@@ -1733,11 +1739,12 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
 
                /* Push the result back onto stack. Fill empty slot from
                   first part of insn and fix top of stack pointer.  */
-               if (STACK_REG_P (*dest)) {
-                 regstack->reg[regstack->top - 1] = REGNO (*dest);
-                 SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
-                 replace_reg (dest, FIRST_STACK_REG + 1);
-               }
+               if (STACK_REG_P (*dest))
+                 {
+                   regstack->reg[regstack->top - 1] = REGNO (*dest);
+                   SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+                   replace_reg (dest, FIRST_STACK_REG + 1);
+                 }
 
                replace_reg (src1, FIRST_STACK_REG);
                replace_reg (src2, FIRST_STACK_REG + 1);
@@ -1760,11 +1767,12 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
 
                /* Push the result back onto stack. Empty stack slot
                   will be filled in second part of insn.  */
-               if (STACK_REG_P (*dest)) {
-                 regstack->reg[regstack->top + 1] = REGNO (*dest);
-                 SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
-                 replace_reg (dest, FIRST_STACK_REG);
-               }
+               if (STACK_REG_P (*dest))
+                 {
+                   regstack->reg[regstack->top + 1] = REGNO (*dest);
+                   SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+                   replace_reg (dest, FIRST_STACK_REG);
+                 }
 
                replace_reg (src1, FIRST_STACK_REG);
                break;
@@ -1786,13 +1794,14 @@ subst_stack_regs_pat (rtx insn, stack regstack, rtx pat)
 
                /* Push the result back onto stack. Fill empty slot from
                   first part of insn and fix top of stack pointer.  */
-               if (STACK_REG_P (*dest)) {
-                 regstack->reg[regstack->top] = REGNO (*dest);
-                 SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
-                 replace_reg (dest, FIRST_STACK_REG + 1);
+               if (STACK_REG_P (*dest))
+                 {
+                   regstack->reg[regstack->top] = REGNO (*dest);
+                   SET_HARD_REG_BIT (regstack->reg_set, REGNO (*dest));
+                   replace_reg (dest, FIRST_STACK_REG + 1);
 
-                 regstack->top++;
-               }
+                   regstack->top++;
+                 }
 
                replace_reg (src1, FIRST_STACK_REG);
                break;
@@ -2282,6 +2291,16 @@ subst_stack_regs (rtx insn, stack regstack)
   if (NOTE_P (insn) || INSN_DELETED_P (insn))
     return control_flow_insn_deleted;
 
+  /* If this a noreturn call, we can't insert pop insns after it.
+     Instead, reset the stack state to empty.  */
+  if (CALL_P (insn)
+      && find_reg_note (insn, REG_NORETURN, NULL))
+    {
+      regstack->top = -1;
+      CLEAR_HARD_REG_SET (regstack->reg_set);
+      return control_flow_insn_deleted;
+    }
+
   /* If there is a REG_UNUSED note on a stack register on this insn,
      the indicated reg must be popped.  The REG_UNUSED note is removed,
      since the form of the newly emitted pop insn references the reg,