The final pass of gcc uses dwarf information to generate unwind tables and
directives (e.g., with command line option -fexceptions). Dwarf information
generated for epilogues should be ignored when generating unwind info,
because the ARM ABI only allows unwind at procedure boundaries. This patch
adds a flag unwind_in_epilogue for it. It wasn't needed in the past, because
there was no dwarf info generated for epilogues, but recent patches for
epilogue generation in RTL added it.
No regression on qemu.
2012-07-20 Greta Yorsh <greta.yo...@arm.com>
* config/arm/arm.c (arm_unwind_function_begin_epilogue): New
function.
(unwind_in_epilogue) New static variable.
(arm_unwind_emit) Use unwind_in_epilogue flag.
(arm_asm_emit_except_personality) Clear unwind_in_epilogue flag.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 9f0023f..137980a 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -213,6 +213,7 @@ static void arm_unwind_emit (FILE *, rtx);
static bool arm_output_ttype (rtx);
static void arm_asm_emit_except_personality (rtx);
static void arm_asm_init_sections (void);
+static void arm_unwind_function_begin_epilogue (FILE *);
#endif
static rtx arm_dwarf_register_span (rtx);
@@ -521,6 +522,9 @@ static const struct attribute_spec arm_attribute_table[] =
#undef TARGET_ASM_INIT_SECTIONS
#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections
+
+#undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
+#define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE arm_unwind_function_begin_epilogue
#endif /* ARM_UNWIND_INFO */
#undef TARGET_DWARF_REGISTER_SPAN
@@ -811,6 +815,11 @@ unsigned arm_pic_register = INVALID_REGNUM;
the next function. */
static int after_arm_reorg = 0;
+#if ARM_UNWIND_INFO
+/* Set when epilogue begins and reset at the end of epilogue. */
+static bool unwind_in_epilogue = false;
+#endif
+
enum arm_pcs arm_pcs_default;
/* For an explanation of these variables, see final_prescan_insn below. */
@@ -24813,6 +24822,9 @@ arm_unwind_emit (FILE * asm_out_file, rtx insn)
rtx note, pat;
bool handled_one = false;
+ if (unwind_in_epilogue)
+ return;
+
if (arm_except_unwind_info (&global_options) != UI_TARGET)
return;
@@ -24911,6 +24923,7 @@ arm_output_ttype (rtx x)
static void
arm_asm_emit_except_personality (rtx personality)
{
+ unwind_in_epilogue = false;
fputs ("\t.personality\t", asm_out_file);
output_addr_const (asm_out_file, personality);
fputc ('\n', asm_out_file);
@@ -24924,6 +24937,14 @@ arm_asm_init_sections (void)
exception_section = get_unnamed_section (0, output_section_asm_op,
"\t.handlerdata");
}
+
+/* Implement TARGET_ASM_FUNCTION_BEGIN_EPILOGUE. */
+static void
+arm_unwind_function_begin_epilogue (FILE *file)
+{
+ unwind_in_epilogue = true;
+}
+
#endif /* ARM_UNWIND_INFO */
/* Output unwind directives for the start/end of a function. */