From 7b0518e33c7818cbaa640257226e13513e86671e Mon Sep 17 00:00:00 2001 From: Ulrich Weigand <uweigand@de.ibm.com> Date: Wed, 18 Jun 2008 20:49:12 +0000 Subject: [PATCH] targhooks.h (struct gcc_target): New member unwind_word_mode. * targhooks.h (struct gcc_target): New member unwind_word_mode. (default_unwind_word_mode): Add prototype. * targhooks.c (default_unwind_word_mode): New function. (default_eh_return_filter_mode): Return targetm.unwind_word_mode () instead of word_mode. * target-def.h (TARGET_UNWIND_WORD_MODE): New macro. (TARGET_INITIALIZER): Use it. * c-common.c (handle_mode_attribute): Support "unwind_word" mode attribute. * unwind-generic.h (_Unwind_Word, _Unwind_Sword): Use it. * except.c (init_eh): Use targetm.unwind_word_mode () instead of word_mode to access SjLj_Function_Context member "data". (sjlj_emit_dispatch_table): Likewise. Also, perform type conversion from targetm.eh_return_filter_mode () to targetm.unwind_word_mode () if they differ. * builtin-types.def (BT_UNWINDWORD): New primitive type. (BT_FN_UNWINDWORD_PTR): New function type. (BT_FN_WORD_PTR): Remove. * builtins.def (BUILT_IN_EXTEND_POINTER): Use BT_FN_UNWINDWORD_PTR. * except.c (expand_builtin_extend_pointer): Convert pointer to targetm.unwind_word_mode () instead of word_mode. * config/spu/spu-protos.h (spu_eh_return_filter_mode): Remove. * config/spu/spu.c (spu_eh_return_filter_mode): Remove. (spu_unwind_word_mode): New function. (TARGET_EH_RETURN_FILTER_MODE): Do not define. (TARGET_UNWIND_WORD_MODE): Define. * config/spu/t-spu-elf (TARGET_LIBGCC2_CFLAGS): Remove -D__word__=SI. From-SVN: r136912 --- gcc/ChangeLog | 34 ++++++++++++++++++++++++++++++++++ gcc/builtin-types.def | 4 +++- gcc/builtins.def | 2 +- gcc/c-common.c | 2 ++ gcc/config/spu/spu-protos.h | 2 -- gcc/config/spu/spu.c | 14 +++++++------- gcc/config/spu/t-spu-elf | 4 +--- gcc/except.c | 16 +++++++++++----- gcc/target-def.h | 4 ++++ gcc/target.h | 3 +++ gcc/targhooks.c | 8 +++++++- gcc/targhooks.h | 1 + gcc/unwind-generic.h | 4 ++-- 13 files changed, 76 insertions(+), 22 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60d200739187..a4a237a31a57 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,37 @@ +2008-06-18 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> + + * targhooks.h (struct gcc_target): New member unwind_word_mode. + (default_unwind_word_mode): Add prototype. + * targhooks.c (default_unwind_word_mode): New function. + (default_eh_return_filter_mode): Return targetm.unwind_word_mode () + instead of word_mode. + * target-def.h (TARGET_UNWIND_WORD_MODE): New macro. + (TARGET_INITIALIZER): Use it. + + * c-common.c (handle_mode_attribute): Support "unwind_word" + mode attribute. + * unwind-generic.h (_Unwind_Word, _Unwind_Sword): Use it. + + * except.c (init_eh): Use targetm.unwind_word_mode () instead of + word_mode to access SjLj_Function_Context member "data". + (sjlj_emit_dispatch_table): Likewise. Also, perform type + conversion from targetm.eh_return_filter_mode () to + targetm.unwind_word_mode () if they differ. + + * builtin-types.def (BT_UNWINDWORD): New primitive type. + (BT_FN_UNWINDWORD_PTR): New function type. + (BT_FN_WORD_PTR): Remove. + * builtins.def (BUILT_IN_EXTEND_POINTER): Use BT_FN_UNWINDWORD_PTR. + * except.c (expand_builtin_extend_pointer): Convert pointer to + targetm.unwind_word_mode () instead of word_mode. + + * config/spu/spu-protos.h (spu_eh_return_filter_mode): Remove. + * config/spu/spu.c (spu_eh_return_filter_mode): Remove. + (spu_unwind_word_mode): New function. + (TARGET_EH_RETURN_FILTER_MODE): Do not define. + (TARGET_UNWIND_WORD_MODE): Define. + * config/spu/t-spu-elf (TARGET_LIBGCC2_CFLAGS): Remove -D__word__=SI. + 2008-06-18 Ulrich Weigand <Ulrich.Weigand@de.ibm.com> * config/spu/spu.c (reg_align): Remove. diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index 7d25e5aad6da..4676dd7641b2 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -77,6 +77,8 @@ DEF_PRIMITIVE_TYPE (BT_UINTMAX, uintmax_type_node) DEF_PRIMITIVE_TYPE (BT_UINT32, uint32_type_node) DEF_PRIMITIVE_TYPE (BT_UINT64, uint64_type_node) DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 1)) +DEF_PRIMITIVE_TYPE (BT_UNWINDWORD, (*lang_hooks.types.type_for_mode) + (targetm.unwind_word_mode (), 1)) DEF_PRIMITIVE_TYPE (BT_FLOAT, float_type_node) DEF_PRIMITIVE_TYPE (BT_DOUBLE, double_type_node) DEF_PRIMITIVE_TYPE (BT_LONGDOUBLE, long_double_type_node) @@ -203,7 +205,7 @@ DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT64_CONST_STRING, BT_DFLOAT64, BT_CONST_STRING) DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT128_CONST_STRING, BT_DFLOAT128, BT_CONST_STRING) DEF_FUNCTION_TYPE_1 (BT_FN_STRING_CONST_STRING, BT_STRING, BT_CONST_STRING) -DEF_FUNCTION_TYPE_1 (BT_FN_WORD_PTR, BT_WORD, BT_PTR) +DEF_FUNCTION_TYPE_1 (BT_FN_UNWINDWORD_PTR, BT_UNWINDWORD, BT_PTR) DEF_FUNCTION_TYPE_1 (BT_FN_INT_WINT, BT_INT, BT_WINT) DEF_FUNCTION_TYPE_1 (BT_FN_WINT_WINT, BT_WINT, BT_WINT) DEF_FUNCTION_TYPE_1 (BT_FN_DFLOAT32_DFLOAT32, BT_DFLOAT32, BT_DFLOAT32) diff --git a/gcc/builtins.def b/gcc/builtins.def index 310e5f456a79..009c35f8934d 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -635,7 +635,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVP, "execvp", BT_FN_INT_CONST_STRING_PT DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECVE, "execve", BT_FN_INT_CONST_STRING_PTR_CONST_STRING_PTR_CONST_STRING, ATTR_NOTHROW_LIST) DEF_LIB_BUILTIN (BUILT_IN_EXIT, "exit", BT_FN_VOID_INT, ATTR_NORETURN_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_EXPECT, "expect", BT_FN_LONG_LONG_LONG, ATTR_CONST_NOTHROW_LIST) -DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_WORD_PTR, ATTR_CONST_NOTHROW_LIST) +DEF_GCC_BUILTIN (BUILT_IN_EXTEND_POINTER, "extend_pointer", BT_FN_UNWINDWORD_PTR, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_EXTRACT_RETURN_ADDR, "extract_return_addr", BT_FN_PTR_PTR, ATTR_NULL) DEF_EXT_LIB_BUILTIN (BUILT_IN_FFS, "ffs", BT_FN_INT_INT, ATTR_CONST_NOTHROW_LIST) DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LIST) diff --git a/gcc/c-common.c b/gcc/c-common.c index b783c5340123..ca051c888767 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -5292,6 +5292,8 @@ handle_mode_attribute (tree *node, tree name, tree args, mode = targetm.libgcc_cmp_return_mode (); else if (!strcmp (p, "libgcc_shift_count")) mode = targetm.libgcc_shift_count_mode (); + else if (!strcmp (p, "unwind_word")) + mode = targetm.unwind_word_mode (); else for (j = 0; j < NUM_MACHINE_MODES; j++) if (!strcmp (p, GET_MODE_NAME (j))) diff --git a/gcc/config/spu/spu-protos.h b/gcc/config/spu/spu-protos.h index e2c339bf1c5b..a6b465ecff75 100644 --- a/gcc/config/spu/spu-protos.h +++ b/gcc/config/spu/spu-protos.h @@ -19,7 +19,6 @@ #include "rtl.h" -extern enum machine_mode spu_eh_return_filter_mode (void); extern void spu_cpu_cpp_builtins (struct cpp_reader * pfile); extern void builtin_define_std (const char *); extern void spu_optimization_options (int level, int size); @@ -76,7 +75,6 @@ extern rtx gen_cpat_const (rtx * ops); extern void constant_to_array (enum machine_mode mode, rtx x, unsigned char *arr); extern rtx array_to_constant (enum machine_mode mode, unsigned char *arr); -extern enum machine_mode spu_eh_return_filter_mode (void); extern void spu_allocate_stack (rtx op0, rtx op1); extern void spu_restore_stack_nonlocal (rtx op0, rtx op1); extern void spu_restore_stack_block (rtx op0, rtx op1); diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c index 4347d59d810f..4dd3d7cc0fe5 100644 --- a/gcc/config/spu/spu.c +++ b/gcc/config/spu/spu.c @@ -176,6 +176,8 @@ static int cpat_info(unsigned char *arr, int size, int *prun, int *pstart); static enum immediate_class classify_immediate (rtx op, enum machine_mode mode); +static enum machine_mode spu_unwind_word_mode (void); + static enum machine_mode spu_libgcc_cmp_return_mode (void); @@ -193,8 +195,8 @@ tree spu_builtin_types[SPU_BTI_MAX]; #undef TARGET_EXPAND_BUILTIN #define TARGET_EXPAND_BUILTIN spu_expand_builtin -#undef TARGET_EH_RETURN_FILTER_MODE -#define TARGET_EH_RETURN_FILTER_MODE spu_eh_return_filter_mode +#undef TARGET_UNWIND_WORD_MODE +#define TARGET_UNWIND_WORD_MODE spu_unwind_word_mode /* The .8byte directive doesn't seem to work well for a 32 bit architecture. */ @@ -4304,12 +4306,10 @@ spu_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total) return true; } -enum machine_mode -spu_eh_return_filter_mode (void) +static enum machine_mode +spu_unwind_word_mode (void) { - /* We would like this to be SImode, but sjlj exceptions seems to work - only with word_mode. */ - return TImode; + return SImode; } /* Decide whether we can make a sibling call to a function. DECL is the diff --git a/gcc/config/spu/t-spu-elf b/gcc/config/spu/t-spu-elf index ea9825ac4971..0a3947d90175 100644 --- a/gcc/config/spu/t-spu-elf +++ b/gcc/config/spu/t-spu-elf @@ -19,9 +19,7 @@ LIBGCC1 = CROSS_LIBGCC1 = -# On SPU __word__ is TImode which is too inefficient and incomplete for -# implementing libgcc routines. -TARGET_LIBGCC2_CFLAGS = -fPIC -D__word__=SI -mwarn-reloc -D__IN_LIBGCC2 +TARGET_LIBGCC2_CFLAGS = -fPIC -mwarn-reloc -D__IN_LIBGCC2 LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/spu/float_unssidf.c \ $(srcdir)/config/spu/float_unsdidf.c \ diff --git a/gcc/except.c b/gcc/except.c index 8ebfd7fa1db6..e6a16507cdb5 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -338,7 +338,8 @@ init_eh (void) DECL_FIELD_CONTEXT (f_cs) = sjlj_fc_type_node; tmp = build_index_type (build_int_cst (NULL_TREE, 4 - 1)); - tmp = build_array_type (lang_hooks.types.type_for_mode (word_mode, 1), + tmp = build_array_type (lang_hooks.types.type_for_mode + (targetm.unwind_word_mode (), 1), tmp); f_data = build_decl (FIELD_DECL, get_identifier ("__data"), tmp); DECL_FIELD_CONTEXT (f_data) = sjlj_fc_type_node; @@ -1932,6 +1933,8 @@ sjlj_emit_function_exit (void) static void sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info) { + enum machine_mode unwind_word_mode = targetm.unwind_word_mode (); + enum machine_mode filter_mode = targetm.eh_return_filter_mode (); int i, first_reachable; rtx mem, dispatch, seq, fc; rtx before; @@ -1954,8 +1957,8 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info) sjlj_fc_call_site_ofs); dispatch = copy_to_reg (mem); - mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs); - if (word_mode != ptr_mode) + mem = adjust_address (fc, unwind_word_mode, sjlj_fc_data_ofs); + if (unwind_word_mode != ptr_mode) { #ifdef POINTERS_EXTEND_UNSIGNED mem = convert_memory_address (ptr_mode, mem); @@ -1965,7 +1968,10 @@ sjlj_emit_dispatch_table (rtx dispatch_label, struct sjlj_lp_info *lp_info) } emit_move_insn (crtl->eh.exc_ptr, mem); - mem = adjust_address (fc, word_mode, sjlj_fc_data_ofs + UNITS_PER_WORD); + mem = adjust_address (fc, unwind_word_mode, + sjlj_fc_data_ofs + GET_MODE_SIZE (unwind_word_mode)); + if (unwind_word_mode != filter_mode) + mem = convert_to_mode (filter_mode, mem, 0); emit_move_insn (crtl->eh.filter, mem); /* Jump to one of the directly reachable regions. */ @@ -3002,7 +3008,7 @@ expand_builtin_extend_pointer (tree addr_tree) extend = 1; #endif - return convert_modes (word_mode, ptr_mode, addr, extend); + return convert_modes (targetm.unwind_word_mode (), ptr_mode, addr, extend); } /* In the following functions, we represent entries in the action table diff --git a/gcc/target-def.h b/gcc/target-def.h index 69b6169bf47b..2692e94aabc9 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -388,6 +388,9 @@ #define TARGET_LIBGCC_CMP_RETURN_MODE default_libgcc_cmp_return_mode #define TARGET_LIBGCC_SHIFT_COUNT_MODE default_libgcc_shift_count_mode +/* In unwind-generic.h. */ +#define TARGET_UNWIND_WORD_MODE default_unwind_word_mode + /* In tree.c. */ #define TARGET_MERGE_DECL_ATTRIBUTES merge_decl_attributes #define TARGET_MERGE_TYPE_ATTRIBUTES merge_type_attributes @@ -761,6 +764,7 @@ TARGET_EH_RETURN_FILTER_MODE, \ TARGET_LIBGCC_CMP_RETURN_MODE, \ TARGET_LIBGCC_SHIFT_COUNT_MODE, \ + TARGET_UNWIND_WORD_MODE, \ TARGET_MERGE_DECL_ATTRIBUTES, \ TARGET_MERGE_TYPE_ATTRIBUTES, \ TARGET_ATTRIBUTE_TABLE, \ diff --git a/gcc/target.h b/gcc/target.h index 9b87dc5c3096..012d1c0099ba 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -463,6 +463,9 @@ struct gcc_target /* Return machine mode for libgcc expanded shift instructions. */ enum machine_mode (* libgcc_shift_count_mode) (void); + /* Return machine mode to be used for _Unwind_Word type. */ + enum machine_mode (* unwind_word_mode) (void); + /* Given two decls, merge their attributes and return the result. */ tree (* merge_decl_attributes) (tree, tree); diff --git a/gcc/targhooks.c b/gcc/targhooks.c index d719f5f21957..7e931c5ed9d3 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -152,7 +152,7 @@ default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED) enum machine_mode default_eh_return_filter_mode (void) { - return word_mode; + return targetm.unwind_word_mode (); } enum machine_mode @@ -167,6 +167,12 @@ default_libgcc_shift_count_mode (void) return word_mode; } +enum machine_mode +default_unwind_word_mode (void) +{ + return word_mode; +} + /* The default implementation of TARGET_SHIFT_TRUNCATION_MASK. */ unsigned HOST_WIDE_INT diff --git a/gcc/targhooks.h b/gcc/targhooks.h index c94dd069f5e1..5aebc7e667b2 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -34,6 +34,7 @@ extern bool default_pretend_outgoing_varargs_named (CUMULATIVE_ARGS *); extern enum machine_mode default_eh_return_filter_mode (void); extern enum machine_mode default_libgcc_cmp_return_mode (void); extern enum machine_mode default_libgcc_shift_count_mode (void); +extern enum machine_mode default_unwind_word_mode (void); extern unsigned HOST_WIDE_INT default_shift_truncation_mask (enum machine_mode); extern unsigned int default_min_divisions_for_recip_mul (enum machine_mode); diff --git a/gcc/unwind-generic.h b/gcc/unwind-generic.h index aca6639dc887..5e0f608d8eaa 100644 --- a/gcc/unwind-generic.h +++ b/gcc/unwind-generic.h @@ -43,8 +43,8 @@ extern "C" { /* @@@ The IA-64 ABI uses uint64 throughout. Most places this is inefficient for 32-bit and smaller machines. */ -typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); -typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); +typedef unsigned _Unwind_Word __attribute__((__mode__(__unwind_word__))); +typedef signed _Unwind_Sword __attribute__((__mode__(__unwind_word__))); #if defined(__ia64__) && defined(__hpux__) typedef unsigned _Unwind_Ptr __attribute__((__mode__(__word__))); #else -- GitLab