From c7ff6e7a7a943f9eed6a66dd41c8e35e9df2bf6c Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Fri, 6 Jul 2007 10:47:31 +0000 Subject: [PATCH] libgcc2.h (word_type): Type definition removed. 2007-07-06 Andreas Krebbel * libgcc2.h (word_type): Type definition removed. (cmp_return_type, shift_count_type): Type definitions added. (__lshrdi3, __ashldi3, __ashrdi3): word_type of second parameter replaced with shift_count_type. (__cmpdi2, __ucmpdi2): word_type of return type replaced with cmp_return_type. * libgcc2.c (__udivmoddi4, __moddi3): Type of local variable c changed from word_type to Wtype. (__lshrdi3, __ashldi3, __ashrdi3): word_type of second parameter replaced with shift_count_type. (__cmpdi2, __ucmpdi2): word_type of return type replaced with cmp_return_type. * c-common.c (handle_mode_attribute): Handling for libgcc_cmp_return and libgcc_shift_count attribute added. * target-def.h (TARGET_LIBGCC_CMP_RETURN_MODE, TARGET_LIBGCC_SHIFT_COUNT_MODE): New target hooks defined. (TARGET_INITIALIZER): New target hooks added. * targhooks.c (default_libgcc_cmp_return_mode, default_libgcc_shift_count_mode): Default implementations for the new target hooks added. * targhooks.h (default_libgcc_cmp_return_mode, default_libgcc_shift_count_mode): Function prototypes added. * target.h (struct gcc_target): Fields for the new target hooks added. * optabs.c (expand_binop): Use shift_count_mode when expanding shift as library call. (prepare_cmp_insn): Use cmp_return_mode when expanding comparison as library call. * doc/tm.texi (TARGET_LIBGCC_CMP_RETURN_MODE, TARGET_LIBGCC_SHIFT_COUNT_MODE): Documentation added. * config/s390/s390.c (s390_libgcc_cmp_return_mode, s390_libgcc_shift_count_mode): Functions added. (TARGET_LIBGCC_CMP_RETURN_MODE, TARGET_LIBGCC_SHIFT_COUNT_MODE): Target hooks defined. From-SVN: r126410 --- gcc/ChangeLog | 38 ++++++++++++++++++++++++++++++++++++++ gcc/c-common.c | 4 ++++ gcc/config/s390/s390.c | 18 ++++++++++++++++++ gcc/doc/tm.texi | 14 ++++++++++++++ gcc/libgcc2.c | 22 +++++++++++----------- gcc/libgcc2.h | 13 +++++++------ gcc/optabs.c | 7 ++++--- gcc/target-def.h | 6 ++++++ gcc/target.h | 6 ++++++ gcc/targhooks.c | 12 ++++++++++++ gcc/targhooks.h | 2 ++ 11 files changed, 122 insertions(+), 20 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3d7ac294485..6fab5404205 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,41 @@ +2007-07-06 Andreas Krebbel + + * libgcc2.h (word_type): Type definition removed. + (cmp_return_type, shift_count_type): Type definitions added. + (__lshrdi3, __ashldi3, __ashrdi3): word_type of second parameter + replaced with shift_count_type. + (__cmpdi2, __ucmpdi2): word_type of return type replaced with + cmp_return_type. + * libgcc2.c (__udivmoddi4, __moddi3): Type of local variable c + changed from word_type to Wtype. + (__lshrdi3, __ashldi3, __ashrdi3): word_type of second parameter + replaced with shift_count_type. + (__cmpdi2, __ucmpdi2): word_type of return type replaced with + cmp_return_type. + * c-common.c (handle_mode_attribute): Handling for libgcc_cmp_return and + libgcc_shift_count attribute added. + * target-def.h (TARGET_LIBGCC_CMP_RETURN_MODE, + TARGET_LIBGCC_SHIFT_COUNT_MODE): New target hooks defined. + (TARGET_INITIALIZER): New target hooks added. + * targhooks.c (default_libgcc_cmp_return_mode, + default_libgcc_shift_count_mode): Default implementations for the new + target hooks added. + * targhooks.h (default_libgcc_cmp_return_mode, + default_libgcc_shift_count_mode): Function prototypes added. + * target.h (struct gcc_target): Fields for the new target hooks added. + * optabs.c (expand_binop): Use shift_count_mode when expanding shift + as library call. + (prepare_cmp_insn): Use cmp_return_mode when expanding comparison as + library call. + + * doc/tm.texi (TARGET_LIBGCC_CMP_RETURN_MODE, + TARGET_LIBGCC_SHIFT_COUNT_MODE): Documentation added. + + * config/s390/s390.c (s390_libgcc_cmp_return_mode, + s390_libgcc_shift_count_mode): Functions added. + (TARGET_LIBGCC_CMP_RETURN_MODE, TARGET_LIBGCC_SHIFT_COUNT_MODE): Target + hooks defined. + 2007-07-06 Richard Sandiford * config/mips/mips.c (compute_frame_size): Restore the original diff --git a/gcc/c-common.c b/gcc/c-common.c index 0682a487d42..cc8c7ff945a 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -4975,6 +4975,10 @@ handle_mode_attribute (tree *node, tree name, tree args, mode = word_mode; else if (!strcmp (p, "pointer")) mode = ptr_mode; + else if (!strcmp (p, "libgcc_cmp_return")) + mode = targetm.libgcc_cmp_return_mode (); + else if (!strcmp (p, "libgcc_shift_count")) + mode = targetm.libgcc_shift_count_mode (); else for (j = 0; j < NUM_MACHINE_MODES; j++) if (!strcmp (p, GET_MODE_NAME (j))) diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index b13415cb679..572c8f62972 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -323,6 +323,18 @@ struct machine_function GTY(()) #define REGNO_PAIR_OK(REGNO, MODE) \ (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1)) +static enum machine_mode +s390_libgcc_cmp_return_mode (void) +{ + return TARGET_64BIT ? DImode : SImode; +} + +static enum machine_mode +s390_libgcc_shift_count_mode (void) +{ + return TARGET_64BIT ? DImode : SImode; +} + /* Return true if the back end supports mode MODE. */ static bool s390_scalar_mode_supported_p (enum machine_mode mode) @@ -9341,6 +9353,12 @@ s390_reorg (void) #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD s390_secondary_reload +#undef TARGET_LIBGCC_CMP_RETURN_MODE +#define TARGET_LIBGCC_CMP_RETURN_MODE s390_libgcc_cmp_return_mode + +#undef TARGET_LIBGCC_SHIFT_COUNT_MODE +#define TARGET_LIBGCC_SHIFT_COUNT_MODE s390_libgcc_shift_count_mode + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-s390.h" diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index ceeec115008..3a66303a5d9 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1334,6 +1334,20 @@ You would most commonly define this macro if the @code{allocate_stack} pattern needs to support both a 32- and a 64-bit mode. @end defmac +@deftypefn {Target Hook} {enum machine_mode} TARGET_LIBGCC_CMP_RETURN_MODE () +This target hook should return the mode to be used for the return value +of compare instructions expanded to libgcc calls. If not defined +@code{word_mode} is returned which is the right choice for a majority of +targets. +@end deftypefn + +@deftypefn {Target Hook} {enum machine_mode} TARGET_LIBGCC_SHIFT_COUNT_MODE () +This target hook should return the mode to be used for the shift count operand +of shift instructions expanded to libgcc calls. If not defined +@code{word_mode} is returned which is the right choice for a majority of +targets. +@end deftypefn + @defmac TARGET_FLOAT_FORMAT A code distinguishing the floating point format of the target machine. There are four defined values: diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index dd26a6e5ca0..5351a3b1cfa 100644 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -406,16 +406,16 @@ __mulvDI3 (DWtype u, DWtype v) /* Unless shift functions are defined with full ANSI prototypes, - parameter b will be promoted to int if word_type is smaller than an int. */ + parameter b will be promoted to int if shift_count_type is smaller than an int. */ #ifdef L_lshrdi3 DWtype -__lshrdi3 (DWtype u, word_type b) +__lshrdi3 (DWtype u, shift_count_type b) { if (b == 0) return u; const DWunion uu = {.ll = u}; - const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; + const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; DWunion w; if (bm <= 0) @@ -437,13 +437,13 @@ __lshrdi3 (DWtype u, word_type b) #ifdef L_ashldi3 DWtype -__ashldi3 (DWtype u, word_type b) +__ashldi3 (DWtype u, shift_count_type b) { if (b == 0) return u; const DWunion uu = {.ll = u}; - const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; + const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; DWunion w; if (bm <= 0) @@ -465,13 +465,13 @@ __ashldi3 (DWtype u, word_type b) #ifdef L_ashrdi3 DWtype -__ashrdi3 (DWtype u, word_type b) +__ashrdi3 (DWtype u, shift_count_type b) { if (b == 0) return u; const DWunion uu = {.ll = u}; - const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; + const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b; DWunion w; if (bm <= 0) @@ -1082,7 +1082,7 @@ __udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) DWtype __divdi3 (DWtype u, DWtype v) { - word_type c = 0; + Wtype c = 0; DWunion uu = {.ll = u}; DWunion vv = {.ll = v}; DWtype w; @@ -1106,7 +1106,7 @@ __divdi3 (DWtype u, DWtype v) DWtype __moddi3 (DWtype u, DWtype v) { - word_type c = 0; + Wtype c = 0; DWunion uu = {.ll = u}; DWunion vv = {.ll = v}; DWtype w; @@ -1146,7 +1146,7 @@ __udivdi3 (UDWtype n, UDWtype d) #endif #ifdef L_cmpdi2 -word_type +cmp_return_type __cmpdi2 (DWtype a, DWtype b) { const DWunion au = {.ll = a}; @@ -1165,7 +1165,7 @@ __cmpdi2 (DWtype a, DWtype b) #endif #ifdef L_ucmpdi2 -word_type +cmp_return_type __ucmpdi2 (DWtype a, DWtype b) { const DWunion au = {.ll = a}; diff --git a/gcc/libgcc2.h b/gcc/libgcc2.h index d6b980e339c..944f6faca1c 100644 --- a/gcc/libgcc2.h +++ b/gcc/libgcc2.h @@ -173,7 +173,8 @@ typedef float TFtype __attribute__ ((mode (TF))); typedef _Complex float TCtype __attribute__ ((mode (TC))); #endif -typedef int word_type __attribute__ ((mode (__word__))); +typedef int cmp_return_type __attribute__((mode (__libgcc_cmp_return__))); +typedef int shift_count_type __attribute__((mode (__libgcc_shift_count__))); /* Make sure that we don't accidentally use any normal C language built-in type names in the first part of this file. Instead we want to use *only* @@ -329,9 +330,9 @@ extern UDWtype __udivmoddi4 (UDWtype, UDWtype, UDWtype *); extern DWtype __negdi2 (DWtype); #endif -extern DWtype __lshrdi3 (DWtype, word_type); -extern DWtype __ashldi3 (DWtype, word_type); -extern DWtype __ashrdi3 (DWtype, word_type); +extern DWtype __lshrdi3 (DWtype, shift_count_type); +extern DWtype __ashldi3 (DWtype, shift_count_type); +extern DWtype __ashrdi3 (DWtype, shift_count_type); /* __udiv_w_sdiv is static inline when building other libgcc2 portions. */ #if (!defined(L_udivdi3) && !defined(L_divdi3) && \ @@ -339,8 +340,8 @@ extern DWtype __ashrdi3 (DWtype, word_type); extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype); #endif -extern word_type __cmpdi2 (DWtype, DWtype); -extern word_type __ucmpdi2 (DWtype, DWtype); +extern cmp_return_type __cmpdi2 (DWtype, DWtype); +extern cmp_return_type __ucmpdi2 (DWtype, DWtype); #if MIN_UNITS_PER_WORD > 1 extern SItype __bswapsi2 (SItype); diff --git a/gcc/optabs.c b/gcc/optabs.c index 11d88f50714..9cd550763ff 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -1980,10 +1980,10 @@ expand_binop (enum machine_mode mode, optab binoptab, rtx op0, rtx op1, if (shift_op) { - op1_mode = word_mode; + op1_mode = targetm.libgcc_shift_count_mode (); /* Specify unsigned here, since negative shift counts are meaningless. */ - op1x = convert_to_mode (word_mode, op1, 1); + op1x = convert_to_mode (op1_mode, op1, 1); } if (GET_MODE (op0) != VOIDmode @@ -3909,7 +3909,8 @@ prepare_cmp_insn (rtx *px, rtx *py, enum rtx_code *pcomparison, rtx size, libfunc = ucmp_optab->handlers[(int) mode].libfunc; result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK, - word_mode, 2, x, mode, y, mode); + targetm.libgcc_cmp_return_mode (), + 2, x, mode, y, mode); /* There are two kinds of comparison routines. Biased routines return 0/1/2, and unbiased routines return -1/0/1. Other parts diff --git a/gcc/target-def.h b/gcc/target-def.h index e5eae407620..31cb8f85882 100644 --- a/gcc/target-def.h +++ b/gcc/target-def.h @@ -374,6 +374,10 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. /* In except.c */ #define TARGET_EH_RETURN_FILTER_MODE default_eh_return_filter_mode +/* In libgcc2.c */ +#define TARGET_LIBGCC_CMP_RETURN_MODE default_libgcc_cmp_return_mode +#define TARGET_LIBGCC_SHIFT_COUNT_MODE default_libgcc_shift_count_mode + /* In tree.c. */ #define TARGET_MERGE_DECL_ATTRIBUTES merge_decl_attributes #define TARGET_MERGE_TYPE_ATTRIBUTES merge_type_attributes @@ -669,6 +673,8 @@ Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. TARGET_HANDLE_OPTION, \ TARGET_HELP, \ TARGET_EH_RETURN_FILTER_MODE, \ + TARGET_LIBGCC_CMP_RETURN_MODE, \ + TARGET_LIBGCC_SHIFT_COUNT_MODE, \ TARGET_MERGE_DECL_ATTRIBUTES, \ TARGET_MERGE_TYPE_ATTRIBUTES, \ TARGET_ATTRIBUTE_TABLE, \ diff --git a/gcc/target.h b/gcc/target.h index 4e84e5ab229..89ad0df087f 100644 --- a/gcc/target.h +++ b/gcc/target.h @@ -432,6 +432,12 @@ struct gcc_target /* Return machine mode for filter value. */ enum machine_mode (* eh_return_filter_mode) (void); + /* Return machine mode for libgcc expanded cmp instructions. */ + enum machine_mode (* libgcc_cmp_return_mode) (void); + + /* Return machine mode for libgcc expanded shift instructions. */ + enum machine_mode (* libgcc_shift_count_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 cc375890fc5..b063e72305d 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -140,6 +140,18 @@ default_eh_return_filter_mode (void) return word_mode; } +enum machine_mode +default_libgcc_cmp_return_mode (void) +{ + return word_mode; +} + +enum machine_mode +default_libgcc_shift_count_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 c69be80f3d2..a326194b4a3 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -31,6 +31,8 @@ extern rtx default_builtin_setjmp_frame_value (void); 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 unsigned HOST_WIDE_INT default_shift_truncation_mask (enum machine_mode); extern unsigned int default_min_divisions_for_recip_mul (enum machine_mode);