OSDN Git Service

cp:
[pf3gnuchains/gcc-fork.git] / gcc / reg-stack.c
index 6c20446..2bf0fe7 100644 (file)
 #include "output.h"
 #include "basic-block.h"
 #include "varray.h"
+#include "reload.h"
 
 #ifdef STACK_REGS
 
@@ -661,7 +662,20 @@ check_asm_stack_operands (insn)
            malformed_asm = 1;
          }
         else
-         reg_used_as_output[REGNO (recog_data.operand[i])] = 1;
+         {
+           int j;
+
+           for (j = 0; j < n_clobbers; j++)
+             if (REGNO (recog_data.operand[i]) == REGNO (clobber_reg[j]))
+               {
+                 error_for_asm (insn, "Output constraint %d cannot be specified together with \"%s\" clobber",
+                                i, reg_names [REGNO (clobber_reg[j])]);
+                 malformed_asm = 1;
+                 break;
+               }
+           if (j == n_clobbers)
+             reg_used_as_output[REGNO (recog_data.operand[i])] = 1;
+         }
       }
 
 
@@ -906,6 +920,23 @@ emit_pop_insn (insn, regstack, reg, where)
   rtx pop_insn, pop_rtx;
   int hard_regno;
 
+  /* For complex types take care to pop both halves.  These may survive in
+     CLOBBER and USE expressions.  */
+  if (COMPLEX_MODE_P (GET_MODE (reg)))
+    {
+      rtx reg1 = FP_MODE_REG (REGNO (reg), DFmode);
+      rtx reg2 = FP_MODE_REG (REGNO (reg) + 1, DFmode);
+
+      pop_insn = NULL_RTX;
+      if (get_hard_regnum (regstack, reg1) >= 0)
+         pop_insn = emit_pop_insn (insn, regstack, reg1, where);
+      if (get_hard_regnum (regstack, reg2) >= 0)
+         pop_insn = emit_pop_insn (insn, regstack, reg2, where);
+      if (!pop_insn)
+       abort ();
+      return pop_insn;
+    }
+
   hard_regno = get_hard_regnum (regstack, reg);
 
   if (hard_regno < FIRST_STACK_REG)
@@ -973,6 +1004,7 @@ emit_swap_insn (insn, regstack, reg)
       while (tmp != limit)
        {
          if (GET_CODE (tmp) == CODE_LABEL
+             || GET_CODE (tmp) == CALL_INSN
              || NOTE_INSN_BASIC_BLOCK_P (tmp)
              || (GET_CODE (tmp) == INSN
                  && stack_regs_mentioned (tmp)))
@@ -1129,9 +1161,12 @@ move_for_stack_reg (insn, regstack, pat)
             stack is not full, and then write the value to memory via
             a pop.  */
          rtx push_rtx, push_insn;
-         rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, XFmode);
+         rtx top_stack_reg = FP_MODE_REG (FIRST_STACK_REG, GET_MODE (src));
 
-         push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
+         if (GET_MODE (src) == TFmode)
+           push_rtx = gen_movtf (top_stack_reg, top_stack_reg);
+         else
+           push_rtx = gen_movxf (top_stack_reg, top_stack_reg);
          push_insn = emit_insn_before (push_rtx, insn);
          REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, top_stack_reg,
                                                REG_NOTES (insn));
@@ -1447,6 +1482,15 @@ subst_stack_regs_pat (insn, regstack, pat)
                    PATTERN (insn) = pat;
                    move_for_stack_reg (insn, regstack, pat);
                  }
+               if (! note && COMPLEX_MODE_P (GET_MODE (*dest))
+                   && get_hard_regnum (regstack, FP_MODE_REG (REGNO (*dest), DFmode)) == -1)
+                 {
+                   pat = gen_rtx_SET (VOIDmode,
+                                      FP_MODE_REG (REGNO (*dest) + 1, SFmode),
+                                      nan);
+                   PATTERN (insn) = pat;
+                   move_for_stack_reg (insn, regstack, pat);
+                 }
              }
          }
        break;
@@ -1454,7 +1498,7 @@ subst_stack_regs_pat (insn, regstack, pat)
 
     case SET:
       {
-       rtx *src1 = (rtx *) NULL_PTR, *src2;
+       rtx *src1 = (rtx *) 0, *src2;
        rtx src1_note, src2_note;
        rtx pat_src;