PR ada/20548
* expr.h (anti_adjust_stack_and_probe): Declare.
* explow.c (anti_adjust_stack_and_probe): Make global, add ADJUST_BACK
parameter and rewrite head comment.
(allocate_dynamic_stack_space): Adjust call to above function.
* function.c (expand_function_end): Handle STACK_CHECK_MOVING_SP.
* tree.h (dwarf2out_args_size): Delete.
* dwarf2out.c (dwarf2out_args_size): Make static and move around.
(dwarf2out_args_size_adjust): Delete prototype and move around.
(dwarf2out_frame_debug_expr): Do not record arg size adjustments for
ACCUMULATE_OUTGOING_ARGS targets.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154079
138bc75d-0d04-0410-961f-
82ee72b054a4
2009-11-10 Eric Botcazou <ebotcazou@adacore.com>
+ PR target/10127
+ PR ada/20548
+ * expr.h (anti_adjust_stack_and_probe): Declare.
+ * explow.c (anti_adjust_stack_and_probe): Make global, add ADJUST_BACK
+ parameter and rewrite head comment.
+ (allocate_dynamic_stack_space): Adjust call to above function.
+ * function.c (expand_function_end): Handle STACK_CHECK_MOVING_SP.
+
+ * tree.h (dwarf2out_args_size): Delete.
+ * dwarf2out.c (dwarf2out_args_size): Make static and move around.
+ (dwarf2out_args_size_adjust): Delete prototype and move around.
+ (dwarf2out_frame_debug_expr): Do not record arg size adjustments for
+ ACCUMULATE_OUTGOING_ARGS targets.
+
+2009-11-10 Eric Botcazou <ebotcazou@adacore.com>
+
* config/sparc/sparc.c (print_operand) <')'>: Test for a non-null
DECL_SIZE of DECL_RESULT before evaluating it.
static void output_cfi_directive (dw_cfi_ref);
static void output_call_frame_info (int);
static void dwarf2out_note_section_used (void);
-static void dwarf2out_stack_adjust (rtx, bool);
-static void dwarf2out_args_size_adjust (HOST_WIDE_INT, const char *);
static void flush_queued_reg_saves (void);
static bool clobbers_queued_reg_save (const_rtx);
static void dwarf2out_frame_debug_expr (rtx, const char *);
add_fde_cfi (label, cfi);
}
-/* Add a CFI to update the running total of the size of arguments
- pushed onto the stack. */
-
-void
-dwarf2out_args_size (const char *label, HOST_WIDE_INT size)
-{
- dw_cfi_ref cfi;
-
- if (size == old_args_size)
- return;
-
- old_args_size = size;
-
- cfi = new_cfi ();
- cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
- cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
- add_fde_cfi (label, cfi);
-}
-
/* Entry point for saving a register to the stack. REG is the GCC register
number. LABEL and OFFSET are passed to reg_save. */
VEC_free (rtx, heap, next);
}
+/* Add a CFI to update the running total of the size of arguments
+ pushed onto the stack. */
+
+static void
+dwarf2out_args_size (const char *label, HOST_WIDE_INT size)
+{
+ dw_cfi_ref cfi;
+
+ if (size == old_args_size)
+ return;
+
+ old_args_size = size;
+
+ cfi = new_cfi ();
+ cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
+ cfi->dw_cfi_oprnd1.dw_cfi_offset = size;
+ add_fde_cfi (label, cfi);
+}
+
+/* Adjust args_size based on stack adjustment OFFSET. */
+
+static void
+dwarf2out_args_size_adjust (HOST_WIDE_INT offset, const char *label)
+{
+ if (cfa.reg == STACK_POINTER_REGNUM)
+ cfa.offset += offset;
+
+ if (cfa_store.reg == STACK_POINTER_REGNUM)
+ cfa_store.offset += offset;
+
+#ifndef STACK_GROWS_DOWNWARD
+ offset = -offset;
+#endif
+
+ args_size += offset;
+ if (args_size < 0)
+ args_size = 0;
+
+ def_cfa_1 (label, &cfa);
+ if (flag_asynchronous_unwind_tables)
+ dwarf2out_args_size (label, args_size);
+}
/* Check INSN to see if it looks like a push or a stack adjustment, and
make a note of it if it does. EH uses this information to find out how
dwarf2out_args_size_adjust (offset, label);
}
-/* Adjust args_size based on stack adjustment OFFSET. */
-
-static void
-dwarf2out_args_size_adjust (HOST_WIDE_INT offset, const char *label)
-{
- if (cfa.reg == STACK_POINTER_REGNUM)
- cfa.offset += offset;
-
- if (cfa_store.reg == STACK_POINTER_REGNUM)
- cfa_store.offset += offset;
-
-#ifndef STACK_GROWS_DOWNWARD
- offset = -offset;
-#endif
-
- args_size += offset;
- if (args_size < 0)
- args_size = 0;
-
- def_cfa_1 (label, &cfa);
- if (flag_asynchronous_unwind_tables)
- dwarf2out_args_size (label, args_size);
-}
-
#endif
/* We delay emitting a register save until either (a) we reach the end
&& (!MEM_P (SET_DEST (elem)) || GET_CODE (expr) == SEQUENCE)
&& (RTX_FRAME_RELATED_P (elem) || par_index == 0))
dwarf2out_frame_debug_expr (elem, label);
- else if (GET_CODE (elem) == SET
+ else if (!ACCUMULATE_OUTGOING_ARGS
+ && GET_CODE (elem) == SET
&& par_index != 0
&& !RTX_FRAME_RELATED_P (elem))
{
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. */
}
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);
}
}
-/* 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. */
}
}
- /* 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
/* Add some bytes to the stack. An rtx says how many. */
extern void anti_adjust_stack (rtx);
+/* Add some bytes to the stack while probing it. An rtx says how many. */
+extern void anti_adjust_stack_and_probe (rtx, bool);
+
/* This enum is used for the following two functions. */
enum save_level {SAVE_BLOCK, SAVE_FUNCTION, SAVE_NONLOCAL};
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
if (CALL_P (insn))
{
+ rtx max_frame_size = GEN_INT (STACK_CHECK_MAX_FRAME_SIZE);
start_sequence ();
- probe_stack_range (STACK_OLD_CHECK_PROTECT,
- GEN_INT (STACK_CHECK_MAX_FRAME_SIZE));
+ if (STACK_CHECK_MOVING_SP)
+ anti_adjust_stack_and_probe (max_frame_size, true);
+ else
+ probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
seq = get_insns ();
end_sequence ();
emit_insn_before (seq, stack_check_probe_note);
extern void dwarf2out_window_save (const char *);
-/* Add a CFI to update the running total of the size of arguments pushed
- onto the stack. */
-
-extern void dwarf2out_args_size (const char *, HOST_WIDE_INT);
-
/* Entry point for saving a register to the stack. */
extern void dwarf2out_reg_save (const char *, unsigned, HOST_WIDE_INT);