OSDN Git Service

* ggc.h (GGC_RESIZEVAR): New, reorder macros.
[pf3gnuchains/gcc-fork.git] / gcc / caller-save.c
index 82672e0..c6a685b 100644 (file)
@@ -113,6 +113,7 @@ reg_save_code (int reg, enum machine_mode mode)
   if (!HARD_REGNO_MODE_OK (reg, mode))
      {
        cached_reg_save_code[reg][mode] = -1;
+       cached_reg_restore_code[reg][mode] = -1;
        return -1;
      }
 
@@ -124,6 +125,7 @@ reg_save_code (int reg, enum machine_mode mode)
 
   /* Force re-recognition of the modified insns.  */
   INSN_CODE (saveinsn) = -1;
+  INSN_CODE (restinsn) = -1;
 
   cached_reg_save_code[reg][mode] = recog_memoized (saveinsn);
   cached_reg_restore_code[reg][mode] = recog_memoized (restinsn);
@@ -702,6 +704,11 @@ insert_restore (struct insn_chain *chain, int before_p, int regno,
     mem = adjust_address (mem, save_mode[regno], 0);
   else
     mem = copy_rtx (mem);
+
+  /* Verify that the alignment of spill space is equal to or greater
+     than required.  */
+  gcc_assert (GET_MODE_ALIGNMENT (GET_MODE (mem)) <= MEM_ALIGN (mem));
+
   pat = gen_rtx_SET (VOIDmode,
                     gen_rtx_REG (GET_MODE (mem),
                                  regno), mem);
@@ -774,6 +781,11 @@ insert_save (struct insn_chain *chain, int before_p, int regno,
     mem = adjust_address (mem, save_mode[regno], 0);
   else
     mem = copy_rtx (mem);
+
+  /* Verify that the alignment of spill space is equal to or greater
+     than required.  */
+  gcc_assert (GET_MODE_ALIGNMENT (GET_MODE (mem)) <= MEM_ALIGN (mem));
+
   pat = gen_rtx_SET (VOIDmode, mem,
                     gen_rtx_REG (GET_MODE (mem),
                                  regno));
@@ -848,6 +860,38 @@ insert_one_insn (struct insn_chain *chain, int before_p, int code, rtx pat)
                SET_REGNO_REG_SET (&new->live_throughout, regno + i);
            }
        }
+
+      /* If CHAIN->INSN is a call, then the registers which contain
+        the arguments to the function are live in the new insn.  */
+      if (CALL_P (chain->insn))
+       {
+         for (link = CALL_INSN_FUNCTION_USAGE (chain->insn);
+              link != NULL_RTX;
+              link = XEXP (link, 1))
+           {
+             rtx arg = XEXP (link, 0);
+
+             if (GET_CODE (arg) == USE)
+               {
+                 rtx reg = XEXP (arg, 0);
+
+                 if (REG_P (reg))
+                   {
+                     int i, regno = REGNO (reg);
+
+                     /* Registers in CALL_INSN_FUNCTION_USAGE are always
+                        hard registers.  */
+                     gcc_assert (regno < FIRST_PSEUDO_REGISTER);
+
+                     for (i = hard_regno_nregs[regno][GET_MODE (reg)] - 1;
+                          i >= 0; i--)
+                       SET_REGNO_REG_SET (&new->live_throughout, regno + i);
+                   }
+               }
+           }
+         
+       }
+
       CLEAR_REG_SET (&new->dead_or_set);
       if (chain->insn == BB_HEAD (BASIC_BLOCK (chain->block)))
        BB_HEAD (BASIC_BLOCK (chain->block)) = new->insn;