@@ -966,6 +966,10 @@ fstack-check
Common Report Var(flag_stack_check)
Insert stack checking code into the program
+fstack-probe
+Common Report Var(flag_stack_probe)
+Insert stack checking code into the program
+
fstack-limit
Common
@@ -1071,6 +1071,9 @@ update_nonlocal_goto_save_area (void)
rtx
allocate_dynamic_stack_space (rtx size, rtx target, int known_align)
{
+ rtx loop_lab, end_lab, last_size;
+ int probe_pass = 0;
+
/* If we're asking for zero bytes, it doesn't matter what we point
to since we can't dereference it. But return a reasonable
address anyway. */
@@ -1203,6 +1206,24 @@ allocate_dynamic_stack_space (rtx size,
mark_reg_pointer (target, known_align);
+ if (flag_stack_probe)
+ {
+ size = copy_to_mode_reg (Pmode, convert_to_mode (Pmode, size, 1));
+ loop_lab = gen_label_rtx ();
+ end_lab = gen_label_rtx ();
+ emit_label (loop_lab);
+#ifndef STACK_GROWS_DOWNWARD
+#error stack must grow down
+#endif
+ emit_cmp_and_jump_insns (size, GEN_INT (STACK_CHECK_PROBE_INTERVAL), LTU,
+ NULL_RTX, Pmode, 1, end_lab);
+ last_size = expand_binop (Pmode, sub_optab, size, GEN_INT (STACK_CHECK_PROBE_INTERVAL), size,
+ 1, OPTAB_WIDEN);
+ gcc_assert (last_size == size);
+ size = GEN_INT (STACK_CHECK_PROBE_INTERVAL);
+ }
+
+again:
/* Perform the required allocation from the stack. Some systems do
this differently than simply incrementing/decrementing from the
stack pointer, such as acquiring the space by calling malloc(). */
@@ -1264,6 +1285,15 @@ allocate_dynamic_stack_space (rtx size,
emit_move_insn (target, virtual_stack_dynamic_rtx);
#endif
}
+ if (flag_stack_probe && probe_pass == 0)
+ {
+ probe_pass = 1;
+ emit_stack_probe (target);
+ emit_jump (loop_lab);
+ emit_label (end_lab);
+ size = last_size;
+ goto again;
+ }
if (MUST_ALIGN)
{
@@ -1280,6 +1310,8 @@ allocate_dynamic_stack_space (rtx size,
GEN_INT (BIGGEST_ALIGNMENT / BITS_PER_UNIT),
NULL_RTX, 1);
}
+ if (flag_stack_probe)
+ emit_stack_probe (target);
/* Record the new stack level for nonlocal gotos. */
if (cfun->nonlocal_goto_save_area != 0)