+2018-01-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR debug/81570
+ PR debug/83728
+ * dwarf2cfi.c (DEFAULT_INCOMING_FRAME_SP_OFFSET): Define to
+ INCOMING_FRAME_SP_OFFSET if not defined.
+ (scan_trace): Add ENTRY argument. If true and
+ DEFAULT_INCOMING_FRAME_SP_OFFSET != INCOMING_FRAME_SP_OFFSET,
+ emit a note to adjust the CFA offset.
+ (create_cfi_notes): Adjust scan_trace callers.
+ (create_cie_data): Use DEFAULT_INCOMING_FRAME_SP_OFFSET rather than
+ INCOMING_FRAME_SP_OFFSET in the CIE.
+ * config/i386/i386.h (DEFAULT_INCOMING_FRAME_SP_OFFSET): Define.
+ * config/stormy16/stormy16.h (DEFAULT_INCOMING_FRAME_SP_OFFSET):
+ Likewise.
+ * doc/tm.texi.in (DEFAULT_INCOMING_FRAME_SP_OFFSET): Document.
+ * doc/tm.texi: Regenerated.
+
2018-01-19 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
PR rtl-optimization/83147
(cfun->machine->func_type == TYPE_EXCEPTION \
? 2 * UNITS_PER_WORD : UNITS_PER_WORD)
+/* The value of INCOMING_FRAME_SP_OFFSET the assembler assumes in
+ .cfi_startproc. */
+#define DEFAULT_INCOMING_FRAME_SP_OFFSET UNITS_PER_WORD
+
/* Describe how we implement __builtin_eh_return. */
#define EH_RETURN_DATA_REGNO(N) ((N) <= DX_REG ? (N) : INVALID_REGNUM)
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, CX_REG)
#define INCOMING_FRAME_SP_OFFSET (xstormy16_interrupt_function_p () ? -6 : -4)
+#define DEFAULT_INCOMING_FRAME_SP_OFFSET -4
\f
/* Register That Address the Stack Frame. */
debugging information like that provided by DWARF 2.
@end defmac
+@defmac DEFAULT_INCOMING_FRAME_SP_OFFSET
+Like @code{INCOMING_FRAME_SP_OFFSET}, but must be the same for all
+functions of the same ABI, and when using GAS @code{.cfi_*} directives
+must also agree with the default CFI GAS emits. Define this macro
+only if @code{INCOMING_FRAME_SP_OFFSET} can have different values
+between different functions of the same ABI or when
+@code{INCOMING_FRAME_SP_OFFSET} does not agree with GAS default CFI.
+@end defmac
+
@defmac ARG_POINTER_CFA_OFFSET (@var{fundecl})
A C expression whose value is an integer giving the offset, in bytes,
from the argument pointer to the canonical frame address (cfa). The
debugging information like that provided by DWARF 2.
@end defmac
+@defmac DEFAULT_INCOMING_FRAME_SP_OFFSET
+Like @code{INCOMING_FRAME_SP_OFFSET}, but must be the same for all
+functions of the same ABI, and when using GAS @code{.cfi_*} directives
+must also agree with the default CFI GAS emits. Define this macro
+only if @code{INCOMING_FRAME_SP_OFFSET} can have different values
+between different functions of the same ABI or when
+@code{INCOMING_FRAME_SP_OFFSET} does not agree with GAS default CFI.
+@end defmac
+
@defmac ARG_POINTER_CFA_OFFSET (@var{fundecl})
A C expression whose value is an integer giving the offset, in bytes,
from the argument pointer to the canonical frame address (cfa). The
#ifndef INCOMING_RETURN_ADDR_RTX
#define INCOMING_RETURN_ADDR_RTX (gcc_unreachable (), NULL_RTX)
#endif
+
+#ifndef DEFAULT_INCOMING_FRAME_SP_OFFSET
+#define DEFAULT_INCOMING_FRAME_SP_OFFSET INCOMING_FRAME_SP_OFFSET
+#endif
\f
/* A collected description of an entire row of the abstract CFI table. */
struct GTY(()) dw_cfi_row
instructions therein. */
static void
-scan_trace (dw_trace_info *trace)
+scan_trace (dw_trace_info *trace, bool entry)
{
rtx_insn *prev, *insn = trace->head;
dw_cfa_location this_cfa;
this_cfa = cur_row->cfa;
cur_cfa = &this_cfa;
+ /* If the current function starts with a non-standard incoming frame
+ sp offset, emit a note before the first instruction. */
+ if (entry
+ && DEFAULT_INCOMING_FRAME_SP_OFFSET != INCOMING_FRAME_SP_OFFSET)
+ {
+ add_cfi_insn = insn;
+ gcc_assert (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED);
+ this_cfa.offset = INCOMING_FRAME_SP_OFFSET;
+ def_cfa_1 (&this_cfa);
+ }
+
for (prev = insn, insn = NEXT_INSN (insn);
insn;
prev = insn, insn = NEXT_INSN (insn))
/* Always begin at the entry trace. */
ti = &trace_info[0];
- scan_trace (ti);
+ scan_trace (ti, true);
while (!trace_work_list.is_empty ())
{
ti = trace_work_list.pop ();
- scan_trace (ti);
+ scan_trace (ti, false);
}
queued_reg_saves.release ();
/* On entry, the Canonical Frame Address is at SP. */
memset (&loc, 0, sizeof (loc));
loc.reg = dw_stack_pointer_regnum;
- loc.offset = INCOMING_FRAME_SP_OFFSET;
+ /* create_cie_data is called just once per TU, and when using .cfi_startproc
+ is even done by the assembler rather than the compiler. If the target
+ has different incoming frame sp offsets depending on what kind of
+ function it is, use a single constant offset for the target and
+ if needed, adjust before the first instruction in insn stream. */
+ loc.offset = DEFAULT_INCOMING_FRAME_SP_OFFSET;
def_cfa_1 (&loc);
if (targetm.debug_unwind_info () == UI_DWARF2