This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC,PATCH] 2 new mode attributes to replace mode(word) uses in libgcc


Hi,

> Let's just make the variable 'c' in __divdi3 and __moddi3 have type
> int, rather than fuss with word_type or Wtype.  I can't see any
> disadvantage to that.
Standard C data types are not allowed in libgcc.  Although it would be
ok for this flag variable the standard data types are disabled by
overriding them using macros.

> When I look at your patch, there seems to be something missing: you
> haven't changed optabs.c.  It seems to me that you need to change
> optabs.c to use cmp_return_mode and shift_count_mode.  You should use
> cmp_return_mode rather than word_mode in prepare_cmp_insn.  And you
> should use shift_count_mode in expand_binop if shift_op. 
Yes, this was missing. I've added those bits in the attached patch.

I was wondering about prepare_float_lib_cmp. There is also used word_mode
as return mode which looks wrong to me since the eq<float mode> functions
in soft-fp are all defined with int as return type. So I've changed this
to TYPE_MODE (integer_type_node).

Bootstrapping on i686, s390 and s390x.

OK for mainline - given no testsuite regressions occur?

Bye,

-Andreas-


2007-05-31  Andreas Krebbel  <krebbel1@de.ibm.com>

	* 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.
	(prepare_float_lib_cmp): Use integer type as return type.

	* 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.


Index: gcc/libgcc2.h
===================================================================
*** gcc/libgcc2.h.orig	2007-05-29 08:59:17.000000000 +0200
--- gcc/libgcc2.h	2007-05-30 16:47:54.000000000 +0200
*************** typedef		float TFtype	__attribute__ ((mo
*** 173,179 ****
  typedef _Complex float TCtype	__attribute__ ((mode (TC)));
  #endif
  
! typedef int word_type __attribute__ ((mode (__word__)));
  
  /* 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*
--- 173,180 ----
  typedef _Complex float TCtype	__attribute__ ((mode (TC)));
  #endif
  
! 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*
*************** extern UDWtype __udivmoddi4 (UDWtype, UD
*** 329,337 ****
  extern DWtype __negdi2 (DWtype);
  #endif
  
! extern DWtype __lshrdi3 (DWtype, word_type);
! extern DWtype __ashldi3 (DWtype, word_type);
! extern DWtype __ashrdi3 (DWtype, word_type);
  
  /* __udiv_w_sdiv is static inline when building other libgcc2 portions.  */
  #if (!defined(L_udivdi3) && !defined(L_divdi3) && \
--- 330,338 ----
  extern DWtype __negdi2 (DWtype);
  #endif
  
! 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) && \
*************** extern DWtype __ashrdi3 (DWtype, word_ty
*** 339,346 ****
  extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);
  #endif
  
! extern word_type __cmpdi2 (DWtype, DWtype);
! extern word_type __ucmpdi2 (DWtype, DWtype);
  
  extern Wtype __absvSI2 (Wtype);
  extern Wtype __addvSI3 (Wtype, Wtype);
--- 340,347 ----
  extern UWtype __udiv_w_sdiv (UWtype *, UWtype, UWtype, UWtype);
  #endif
  
! extern cmp_return_type __cmpdi2 (DWtype, DWtype);
! extern cmp_return_type __ucmpdi2 (DWtype, DWtype);
  
  extern Wtype __absvSI2 (Wtype);
  extern Wtype __addvSI3 (Wtype, Wtype);
Index: gcc/libgcc2.c
===================================================================
*** gcc/libgcc2.c.orig	2007-05-29 08:59:17.000000000 +0200
--- gcc/libgcc2.c	2007-05-30 16:47:54.000000000 +0200
*************** __mulvDI3 (DWtype u, DWtype v)
*** 406,421 ****
  
  
  /* Unless shift functions are defined with full ANSI prototypes,
!    parameter b will be promoted to int if word_type is smaller than an int.  */
  #ifdef L_lshrdi3
  DWtype
! __lshrdi3 (DWtype u, word_type b)
  {
    if (b == 0)
      return u;
  
    const DWunion uu = {.ll = u};
!   const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
    DWunion w;
  
    if (bm <= 0)
--- 406,421 ----
  
  
  /* Unless shift functions are defined with full ANSI prototypes,
!    parameter b will be promoted to int if shift_count_type is smaller than an int.  */
  #ifdef L_lshrdi3
  DWtype
! __lshrdi3 (DWtype u, shift_count_type b)
  {
    if (b == 0)
      return u;
  
    const DWunion uu = {.ll = u};
!   const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
    DWunion w;
  
    if (bm <= 0)
*************** __lshrdi3 (DWtype u, word_type b)
*** 437,449 ****
  
  #ifdef L_ashldi3
  DWtype
! __ashldi3 (DWtype u, word_type b)
  {
    if (b == 0)
      return u;
  
    const DWunion uu = {.ll = u};
!   const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
    DWunion w;
  
    if (bm <= 0)
--- 437,449 ----
  
  #ifdef L_ashldi3
  DWtype
! __ashldi3 (DWtype u, shift_count_type b)
  {
    if (b == 0)
      return u;
  
    const DWunion uu = {.ll = u};
!   const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
    DWunion w;
  
    if (bm <= 0)
*************** __ashldi3 (DWtype u, word_type b)
*** 465,477 ****
  
  #ifdef L_ashrdi3
  DWtype
! __ashrdi3 (DWtype u, word_type b)
  {
    if (b == 0)
      return u;
  
    const DWunion uu = {.ll = u};
!   const word_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
    DWunion w;
  
    if (bm <= 0)
--- 465,477 ----
  
  #ifdef L_ashrdi3
  DWtype
! __ashrdi3 (DWtype u, shift_count_type b)
  {
    if (b == 0)
      return u;
  
    const DWunion uu = {.ll = u};
!   const shift_count_type bm = (sizeof (Wtype) * BITS_PER_UNIT) - b;
    DWunion w;
  
    if (bm <= 0)
*************** __udivmoddi4 (UDWtype n, UDWtype d, UDWt
*** 1082,1088 ****
  DWtype
  __divdi3 (DWtype u, DWtype v)
  {
!   word_type c = 0;
    DWunion uu = {.ll = u};
    DWunion vv = {.ll = v};
    DWtype w;
--- 1082,1088 ----
  DWtype
  __divdi3 (DWtype u, DWtype v)
  {
!   Wtype c = 0;
    DWunion uu = {.ll = u};
    DWunion vv = {.ll = v};
    DWtype w;
*************** __divdi3 (DWtype u, DWtype v)
*** 1106,1112 ****
  DWtype
  __moddi3 (DWtype u, DWtype v)
  {
!   word_type c = 0;
    DWunion uu = {.ll = u};
    DWunion vv = {.ll = v};
    DWtype w;
--- 1106,1112 ----
  DWtype
  __moddi3 (DWtype u, DWtype v)
  {
!   Wtype c = 0;
    DWunion uu = {.ll = u};
    DWunion vv = {.ll = v};
    DWtype w;
*************** __udivdi3 (UDWtype n, UDWtype d)
*** 1146,1152 ****
  #endif
  
  #ifdef L_cmpdi2
! word_type
  __cmpdi2 (DWtype a, DWtype b)
  {
    const DWunion au = {.ll = a};
--- 1146,1152 ----
  #endif
  
  #ifdef L_cmpdi2
! cmp_return_type
  __cmpdi2 (DWtype a, DWtype b)
  {
    const DWunion au = {.ll = a};
*************** __cmpdi2 (DWtype a, DWtype b)
*** 1165,1171 ****
  #endif
  
  #ifdef L_ucmpdi2
! word_type
  __ucmpdi2 (DWtype a, DWtype b)
  {
    const DWunion au = {.ll = a};
--- 1165,1171 ----
  #endif
  
  #ifdef L_ucmpdi2
! cmp_return_type
  __ucmpdi2 (DWtype a, DWtype b)
  {
    const DWunion au = {.ll = a};
Index: gcc/c-common.c
===================================================================
*** gcc/c-common.c.orig	2007-05-30 16:06:18.000000000 +0200
--- gcc/c-common.c	2007-05-30 16:47:54.000000000 +0200
*************** handle_mode_attribute (tree *node, tree 
*** 4996,5001 ****
--- 4996,5005 ----
  	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)))
Index: gcc/target-def.h
===================================================================
*** gcc/target-def.h.orig	2007-05-30 16:06:18.000000000 +0200
--- gcc/target-def.h	2007-05-30 16:47:54.000000000 +0200
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 371,376 ****
--- 371,380 ----
  /* 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
*************** Foundation, 51 Franklin Street, Fifth Fl
*** 653,658 ****
--- 657,664 ----
    TARGET_DEFAULT_TARGET_FLAGS,			\
    TARGET_HANDLE_OPTION,				\
    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,			\
Index: gcc/targhooks.c
===================================================================
*** gcc/targhooks.c.orig	2007-05-30 16:06:18.000000000 +0200
--- gcc/targhooks.c	2007-05-30 16:47:54.000000000 +0200
*************** default_eh_return_filter_mode (void)
*** 140,145 ****
--- 140,157 ----
    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
Index: gcc/targhooks.h
===================================================================
*** gcc/targhooks.h.orig	2007-05-30 16:06:18.000000000 +0200
--- gcc/targhooks.h	2007-05-30 16:47:54.000000000 +0200
*************** extern rtx default_builtin_setjmp_frame_
*** 31,36 ****
--- 31,38 ----
  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);
Index: gcc/doc/tm.texi
===================================================================
*** gcc/doc/tm.texi.orig	2007-05-30 16:06:12.000000000 +0200
--- gcc/doc/tm.texi	2007-05-30 16:47:54.000000000 +0200
*************** You would most commonly define this macr
*** 1327,1332 ****
--- 1327,1346 ----
  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:
Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig	2007-05-29 08:59:17.000000000 +0200
--- gcc/config/s390/s390.c	2007-05-30 16:47:54.000000000 +0200
*************** struct machine_function GTY(())
*** 322,327 ****
--- 322,339 ----
  #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)
*************** s390_reorg (void)
*** 9339,9344 ****
--- 9351,9362 ----
  #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"
Index: gcc/target.h
===================================================================
*** gcc/target.h.orig	2007-05-30 16:06:18.000000000 +0200
--- gcc/target.h	2007-05-30 16:47:54.000000000 +0200
*************** struct gcc_target
*** 428,433 ****
--- 428,439 ----
    /* 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);
  
Index: gcc/optabs.c
===================================================================
*** gcc/optabs.c.orig	2007-05-29 08:59:17.000000000 +0200
--- gcc/optabs.c	2007-05-31 10:31:36.000000000 +0200
*************** expand_binop (enum machine_mode mode, op
*** 1948,1957 ****
  
        if (shift_op)
  	{
! 	  op1_mode = word_mode;
  	  /* Specify unsigned here,
  	     since negative shift counts are meaningless.  */
! 	  op1x = convert_to_mode (word_mode, op1, 1);
  	}
  
        if (GET_MODE (op0) != VOIDmode
--- 1948,1957 ----
  
        if (shift_op)
  	{
! 	  op1_mode = targetm.libgcc_shift_count_mode ();
  	  /* Specify unsigned here,
  	     since negative shift counts are meaningless.  */
! 	  op1x = convert_to_mode (op1_mode, op1, 1);
  	}
  
        if (GET_MODE (op0) != VOIDmode
*************** prepare_cmp_insn (rtx *px, rtx *py, enum
*** 3868,3874 ****
  	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);
  
        /* There are two kinds of comparison routines. Biased routines
  	 return 0/1/2, and unbiased routines return -1/0/1. Other parts
--- 3868,3875 ----
  	libfunc = ucmp_optab->handlers[(int) mode].libfunc;
  
        result = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST_MAKE_BLOCK,
! 					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
*************** prepare_float_lib_cmp (rtx *px, rtx *py,
*** 4153,4159 ****
  
    start_sequence ();
    value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
! 				   word_mode, 2, x, mode, y, mode);
    insns = get_insns ();
    end_sequence ();
  
--- 4154,4161 ----
  
    start_sequence ();
    value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
! 				   TYPE_MODE (integer_type_node),
! 				   2, x, mode, y, mode);
    insns = get_insns ();
    end_sequence ();
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]