OSDN Git Service

2009-07-23 Paul Thomas <pault@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / explow.c
index 0bbbc00..09f786a 100644 (file)
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "diagnostic-core.h"
 #include "toplev.h"
 #include "rtl.h"
 #include "tree.h"
@@ -33,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "function.h"
 #include "expr.h"
 #include "optabs.h"
+#include "libfuncs.h"
 #include "hard-reg-set.h"
 #include "insn-config.h"
 #include "ggc.h"
@@ -42,8 +44,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "output.h"
 
 static rtx break_out_memory_refs (rtx);
-static void emit_stack_probe (rtx);
-static void anti_adjust_stack_and_probe (rtx);
 
 
 /* Truncate and perhaps sign-extend C as appropriate for MODE.  */
@@ -1308,7 +1308,7 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
        }
 
       if (flag_stack_check && STACK_CHECK_MOVING_SP)
-       anti_adjust_stack_and_probe (size);
+       anti_adjust_stack_and_probe (size, false);
       else
        anti_adjust_stack (size);
 
@@ -1347,14 +1347,15 @@ allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
 static GTY(()) rtx stack_check_libfunc;
 
 void
-set_stack_check_libfunc (rtx libfunc)
+set_stack_check_libfunc (const char *libfunc_name)
 {
-  stack_check_libfunc = libfunc;
+  gcc_assert (stack_check_libfunc == NULL_RTX);
+  stack_check_libfunc = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
 }
 \f
 /* Emit one stack probe at ADDRESS, an address within the stack.  */
 
-static void
+void
 emit_stack_probe (rtx address)
 {
   rtx memref = gen_rtx_MEM (word_mode, address);
@@ -1367,9 +1368,6 @@ emit_stack_probe (rtx address)
     emit_insn (gen_probe_stack (memref));
   else
 #endif
-  if (STACK_CHECK_PROBE_LOAD)
-    emit_move_insn (gen_reg_rtx (word_mode), memref);
-  else
     emit_move_insn (memref, const0_rtx);
 }
 
@@ -1404,7 +1402,8 @@ probe_stack_range (HOST_WIDE_INT first, rtx size)
                                 gen_rtx_fmt_ee (STACK_GROW_OP, Pmode,
                                                 stack_pointer_rtx,
                                                 plus_constant (size, first)));
-      emit_library_call (stack_check_libfunc, LCT_NORMAL, VOIDmode, 1, addr);
+      emit_library_call (stack_check_libfunc, LCT_NORMAL, VOIDmode, 1, addr,
+                        Pmode);
     }
 
   /* Next see if we have an insn to check the stack.  */
@@ -1544,13 +1543,17 @@ probe_stack_range (HOST_WIDE_INT first, rtx size)
     }
 }
 
-/* Adjust the stack by SIZE bytes while probing it.  Note that we skip the
-   probe for the first interval + a small dope of 4 words and instead probe
-   that many bytes past the specified size to maintain a protection area.  */
+/* Adjust the stack pointer by minus SIZE (an rtx for a number of bytes)
+   while probing it.  This pushes when SIZE is positive.  SIZE need not
+   be constant.  If ADJUST_BACK is true, adjust back the stack pointer
+   by plus SIZE at the end.  */
 
-static void
-anti_adjust_stack_and_probe (rtx size)
+void
+anti_adjust_stack_and_probe (rtx size, bool adjust_back)
 {
+  /* We skip the probe for the first interval + a small dope of 4 words and
+     probe that many bytes past the specified size to maintain a protection
+     area at the botton of the stack.  */
   const int dope = 4 * UNITS_PER_WORD;
 
   /* First ensure SIZE is Pmode.  */
@@ -1564,7 +1567,7 @@ anti_adjust_stack_and_probe (rtx size)
       HOST_WIDE_INT isize = INTVAL (size), i;
       bool first_probe = true;
 
-      /* Adjust SP and probe to PROBE_INTERVAL + N * PROBE_INTERVAL for
+      /* Adjust SP and probe at PROBE_INTERVAL + N * PROBE_INTERVAL for
         values of N from 1 until it exceeds SIZE.  If only one probe is
         needed, this will not generate any code.  Then adjust and probe
         to PROBE_INTERVAL + SIZE.  */
@@ -1620,13 +1623,13 @@ anti_adjust_stack_and_probe (rtx size)
 
       /* Step 3: the loop
 
-         while (SP != LAST_ADDR)
-           {
-             SP = SP + PROBE_INTERVAL
-             probe at SP
-           }
+        while (SP != LAST_ADDR)
+          {
+            SP = SP + PROBE_INTERVAL
+            probe at SP
+          }
 
-        adjusts SP and probes to PROBE_INTERVAL + N * PROBE_INTERVAL for
+        adjusts SP and probes at PROBE_INTERVAL + N * PROBE_INTERVAL for
         values of N from 1 until it is equal to ROUNDED_SIZE.  */
 
       emit_label (loop_lab);
@@ -1644,7 +1647,7 @@ anti_adjust_stack_and_probe (rtx size)
       emit_label (end_lab);
 
 
-      /* Step 4: adjust SP and probe to PROBE_INTERVAL + SIZE if we cannot
+      /* Step 4: adjust SP and probe at PROBE_INTERVAL + SIZE if we cannot
         assert at compile-time that SIZE is equal to ROUNDED_SIZE.  */
 
       /* TEMP = SIZE - ROUNDED_SIZE.  */
@@ -1659,8 +1662,11 @@ anti_adjust_stack_and_probe (rtx size)
        }
     }
 
-  /* Adjust back to account for the additional first interval.  */
-  adjust_stack (GEN_INT (PROBE_INTERVAL + dope));
+  /* Adjust back and account for the additional first interval.  */
+  if (adjust_back)
+    adjust_stack (plus_constant (size, PROBE_INTERVAL + dope));
+  else
+    adjust_stack (GEN_INT (PROBE_INTERVAL + dope));
 }
 
 /* Return an rtx representing the register or memory location