From a68b5e5247b3b8047aa104e39b61a7d8f6cfa57b Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Tue, 7 Sep 2010 13:50:17 -0700 Subject: [PATCH] Hookize exception personality output. * target.def (TARGET_ASM_EMIT_EXCEPT_PERSONALITY): New hook. * doc/tm.texi.in: Add doc marker. * doc/tm.texi: Rebuild. * except.c (switch_to_exception_section): Always build. (output_one_function_exception_table): Move section switch, personality output, and label output ... (output_function_exception_table): ... here. Use the new personality hook. * config/ia64/ia64.c (ia64_asm_emit_except_personality, ia64_asm_init_sections, TARGET_ASM_EMIT_EXCEPT_PERSONALITY, TARGET_ASM_INIT_SECTIONS): New. (ia64_asm_unwind_emit): Rename from process_for_unwind_directive, make static. (TARGET_ASM_UNWIND_EMIT): Update to match. * config/ia64/ia64-protos.h (process_for_unwind_directive): Remove. * config/arm/arm.c (arm_asm_emit_except_personality): New. (arm_asm_init_sections): New. (TARGET_ASM_EMIT_EXCEPT_PERSONALITY, TARGET_ASM_INIT_SECTIONS): New. From-SVN: r163968 --- gcc/ChangeLog | 23 ++++++++++++++++++++++ gcc/config/arm/arm.c | 27 +++++++++++++++++++++++++ gcc/config/ia64/ia64-protos.h | 1 - gcc/config/ia64/ia64.c | 32 +++++++++++++++++++++++++++--- gcc/doc/tm.texi | 4 ++++ gcc/doc/tm.texi.in | 2 ++ gcc/except.c | 37 ++++++++++++++--------------------- gcc/target.def | 9 +++++++++ 8 files changed, 109 insertions(+), 26 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 336341f08cc..bca06ce8835 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2010-09-07 Richard Henderson + + * target.def (TARGET_ASM_EMIT_EXCEPT_PERSONALITY): New hook. + * doc/tm.texi.in: Add doc marker. + * doc/tm.texi: Rebuild. + * except.c (switch_to_exception_section): Always build. + (output_one_function_exception_table): Move section switch, + personality output, and label output ... + (output_function_exception_table): ... here. Use the new + personality hook. + + * config/ia64/ia64.c (ia64_asm_emit_except_personality, + ia64_asm_init_sections, TARGET_ASM_EMIT_EXCEPT_PERSONALITY, + TARGET_ASM_INIT_SECTIONS): New. + (ia64_asm_unwind_emit): Rename from process_for_unwind_directive, + make static. + (TARGET_ASM_UNWIND_EMIT): Update to match. + * config/ia64/ia64-protos.h (process_for_unwind_directive): Remove. + + * config/arm/arm.c (arm_asm_emit_except_personality): New. + (arm_asm_init_sections): New. + (TARGET_ASM_EMIT_EXCEPT_PERSONALITY, TARGET_ASM_INIT_SECTIONS): New. + 2010-09-07 Ramana Radhakrishnan * config/arm/arm.md: Remove unused variable. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 440995ff420..1d547b0db5f 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -196,6 +196,8 @@ static bool arm_return_in_memory (const_tree, const_tree); #ifdef TARGET_UNWIND_INFO 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); #endif static void arm_dwarf_handle_frame_unspec (const char *, rtx, int); static rtx arm_dwarf_register_span (rtx); @@ -455,6 +457,12 @@ static const struct attribute_spec arm_attribute_table[] = #undef TARGET_ARM_EABI_UNWINDER #define TARGET_ARM_EABI_UNWINDER true + +#undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY +#define TARGET_ASM_EMIT_EXCEPT_PERSONALITY arm_asm_emit_except_personality + +#undef TARGET_ASM_INIT_SECTIONS +#define TARGET_ASM_INIT_SECTIONS arm_asm_init_sections #endif /* TARGET_UNWIND_INFO */ #undef TARGET_DWARF_HANDLE_FRAME_UNSPEC @@ -22209,6 +22217,25 @@ arm_output_ttype (rtx x) return TRUE; } + +/* Implement TARGET_ASM_EMIT_EXCEPT_PERSONALITY. */ + +static void +arm_asm_emit_except_personality (rtx personality) +{ + fputs ("\t.personality\t", asm_out_file); + output_addr_const (asm_out_file, personality); + fputc ('\n', asm_out_file); +} + +/* Implement TARGET_ASM_INITIALIZE_SECTIONS. */ + +static void +arm_asm_init_sections (void) +{ + exception_section = get_unnamed_section (0, output_section_asm_op, + "\t.handlerdata"); +} #endif /* TARGET_UNWIND_INFO */ diff --git a/gcc/config/ia64/ia64-protos.h b/gcc/config/ia64/ia64-protos.h index 0a5af40f489..4fc6a425691 100644 --- a/gcc/config/ia64/ia64-protos.h +++ b/gcc/config/ia64/ia64-protos.h @@ -59,7 +59,6 @@ extern void ia64_print_operand (FILE *, rtx, int); extern enum reg_class ia64_preferred_reload_class (rtx, enum reg_class); extern enum reg_class ia64_secondary_reload_class (enum reg_class, enum machine_mode, rtx); -extern void process_for_unwind_directive (FILE *, rtx); extern const char *get_bundle_name (int); #endif /* RTX_CODE */ diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c index 7f5d929ce36..17b6a47b0db 100644 --- a/gcc/config/ia64/ia64.c +++ b/gcc/config/ia64/ia64.c @@ -247,6 +247,10 @@ static int ia64_sched_reorder (FILE *, int, rtx *, int *, int); static int ia64_sched_reorder2 (FILE *, int, rtx *, int *, int); static int ia64_variable_issue (FILE *, int, rtx, int); +static void ia64_asm_unwind_emit (FILE *, rtx); +static void ia64_asm_emit_except_personality (rtx); +static void ia64_asm_init_sections (void); + static struct bundle_state *get_free_bundle_state (void); static void free_bundle_state (struct bundle_state *); static void initiate_bundle_states (void); @@ -521,7 +525,11 @@ static const struct attribute_spec ia64_attribute_table[] = #define TARGET_GIMPLIFY_VA_ARG_EXPR ia64_gimplify_va_arg #undef TARGET_ASM_UNWIND_EMIT -#define TARGET_ASM_UNWIND_EMIT process_for_unwind_directive +#define TARGET_ASM_UNWIND_EMIT ia64_asm_unwind_emit +#undef TARGET_ASM_EMIT_EXCEPT_PERSONALITY +#define TARGET_ASM_EMIT_EXCEPT_PERSONALITY ia64_asm_emit_except_personality +#undef TARGET_ASM_INIT_SECTIONS +#define TARGET_ASM_INIT_SECTIONS ia64_asm_init_sections #undef TARGET_SCALAR_MODE_SUPPORTED_P #define TARGET_SCALAR_MODE_SUPPORTED_P ia64_scalar_mode_supported_p @@ -9845,8 +9853,8 @@ process_set (FILE *asm_out_file, rtx pat, rtx insn, bool unwind, bool frame) /* This function looks at a single insn and emits any directives required to unwind this insn. */ -void -process_for_unwind_directive (FILE *asm_out_file, rtx insn) +static void +ia64_asm_unwind_emit (FILE *asm_out_file, rtx insn) { bool unwind = (flag_unwind_tables || (flag_exceptions && !USING_SJLJ_EXCEPTIONS)); @@ -9909,6 +9917,24 @@ process_for_unwind_directive (FILE *asm_out_file, rtx insn) } } +/* Implement TARGET_ASM_EMIT_EXCEPT_PERSONALITY. */ + +static void +ia64_asm_emit_except_personality (rtx personality) +{ + fputs ("\t.personality\t", asm_out_file); + output_addr_const (asm_out_file, personality); + fputc ('\n', asm_out_file); +} + +/* Implement TARGET_ASM_INITIALIZE_SECTIONS. */ + +static void +ia64_asm_init_sections (void) +{ + exception_section = get_unnamed_section (0, output_section_asm_op, + "\t.handlerdata"); +} enum ia64_builtins { diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index a8db902db7a..e60392f9fa8 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8744,6 +8744,10 @@ to be broken up according to function. The default is that no label is emitted. @end deftypefn +@deftypefn {Target Hook} void TARGET_ASM_EMIT_EXCEPT_PERSONALITY (rtx @var{personality}) +If the target implements @code{TARGET_ASM_UNWIND_EMIT}, this hook may be used to emit a directive to install a personality hook into the unwind info. This hook should not be used if dwarf2 unwind info is used. +@end deftypefn + @deftypefn {Target Hook} void TARGET_ASM_UNWIND_EMIT (FILE *@var{stream}, rtx @var{insn}) This target hook emits assembly directives required to unwind the given instruction. This is only used when TARGET_UNWIND_INFO is set. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 2efc1ae4eba..17fcd4bd4de 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -8734,6 +8734,8 @@ to be broken up according to function. The default is that no label is emitted. @end deftypefn +@hook TARGET_ASM_EMIT_EXCEPT_PERSONALITY + @hook TARGET_ASM_UNWIND_EMIT This target hook emits assembly directives required to unwind the given instruction. This is only used when TARGET_UNWIND_INFO is set. diff --git a/gcc/except.c b/gcc/except.c index 0df1996124b..bfffa447d9c 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2794,7 +2794,6 @@ sjlj_output_call_site_table (void) call_site_base += n; } -#ifndef TARGET_UNWIND_INFO /* Switch to the section that should be used for exception tables. */ static void @@ -2844,7 +2843,6 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname)) switch_to_section (s); } -#endif /* Output a reference from an exception table to the type_info object TYPE. @@ -2904,8 +2902,7 @@ output_ttype (tree type, int tt_format, int tt_format_size) } static void -output_one_function_exception_table (const char * ARG_UNUSED (fnname), - int section, rtx ARG_UNUSED (personality)) +output_one_function_exception_table (int section) { int tt_format, cs_format, lp_format, i; #ifdef HAVE_AS_LEB128 @@ -2918,20 +2915,6 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname), int have_tt_data; int tt_format_size = 0; -#ifdef TARGET_UNWIND_INFO - /* TODO: Move this into target file. */ - fputs ("\t.personality\t", asm_out_file); - output_addr_const (asm_out_file, personality); - fputs ("\n\t.handlerdata\n", asm_out_file); - /* Note that varasm still thinks we're in the function's code section. - The ".endp" directive that will immediately follow will take us back. */ -#else - switch_to_exception_section (fnname); -#endif - - /* If the target wants a label to begin the table, emit it here. */ - targetm.asm_out.emit_except_table_label (asm_out_file); - have_tt_data = (VEC_length (tree, cfun->eh->ttype_data) || (targetm.arm_eabi_unwinder ? VEC_length (tree, cfun->eh->ehspec_data.arm_eabi) @@ -3095,7 +3078,7 @@ output_one_function_exception_table (const char * ARG_UNUSED (fnname), } void -output_function_exception_table (const char * ARG_UNUSED (fnname)) +output_function_exception_table (const char *fnname) { rtx personality = get_personality_function (current_function_decl); @@ -3104,11 +3087,21 @@ output_function_exception_table (const char * ARG_UNUSED (fnname)) return; if (personality) - assemble_external_libcall (personality); + { + assemble_external_libcall (personality); - output_one_function_exception_table (fnname, 0, personality); + if (targetm.asm_out.emit_except_personality) + targetm.asm_out.emit_except_personality (personality); + } + + switch_to_exception_section (fnname); + + /* If the target wants a label to begin the table, emit it here. */ + targetm.asm_out.emit_except_table_label (asm_out_file); + + output_one_function_exception_table (0); if (crtl->eh.call_site_record[1] != NULL) - output_one_function_exception_table (fnname, 1, personality); + output_one_function_exception_table (1); switch_to_section (current_function_section ()); } diff --git a/gcc/target.def b/gcc/target.def index e62a977182d..6910ce9e232 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -145,6 +145,15 @@ DEFHOOK void, (FILE *stream), default_emit_except_table_label) +/* Emit a directive for setting the personality for the function. */ +DEFHOOK +(emit_except_personality, + "If the target implements @code{TARGET_ASM_UNWIND_EMIT}, this hook may be\ + used to emit a directive to install a personality hook into the unwind\ + info. This hook should not be used if dwarf2 unwind info is used.", + void, (rtx personality), + NULL) + /* Emit any directives required to unwind this instruction. */ DEFHOOK (unwind_emit,