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]

streamline libgcc clz, ctz, parity


Using the longlong.h implementations of count_leading_zeros
and count_trailing_zeros means that we can get arch-specific
code that you wouldn't necessarily want to inline, e.g. the
Alpha version pre-CIX extension, or the PA version.

Marking the tables ATTRIBUTE_HIDDEN means that the compiler
can often use a shorter PIC sequence to reference the data.
E.g. pc-relative instead of through the GOT.

Finally, on most targets getting the (pic) address of 
__popcount_tab is more expensive than continuing to simplify
the parity with shifts.


r~


        * libgcc2.c: Include auto-host.h.
        (ATTRIBUTE_HIDDEN): New.
        (__clz_tab): Don't declare here for clz and ctz.
        (__clzsi2, __clzdi2): Use count_leading_zeros.
        (__ctzsi2, __ctzdi2): Use count_trailing_zeros.
        (__popcount_tab): Mark ATTRIBUTE_HIDDEN.
        (__paritysi2, __paritydi2): Use shifts instead of __popcount_tab.
        * longlong.h (__clz_tab): Mark ATTRIBUTE_HIDDEN.

Index: libgcc2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcc2.c,v
retrieving revision 1.158
diff -c -p -d -r1.158 libgcc2.c
*** libgcc2.c	1 Feb 2003 18:59:46 -0000	1.158
--- libgcc2.c	1 Feb 2003 20:58:12 -0000
*************** along with GCC; see the file COPYING.  I
*** 29,38 ****
  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.  */
  
  /* It is incorrect to include config.h here, because this file is being
     compiled for the target, and hence definitions concerning only the host
     do not apply.  */
- 
  #include "tconfig.h"
  #include "tsystem.h"
  #include "coretypes.h"
--- 29,42 ----
  Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.  */
  
+ 
+ /* We include auto-host.h here to get HAVE_GAS_HIDDEN.  This is
+    supposedly valid even though this is a "target" file.  */
+ #include "auto-host.h"
+ 
  /* It is incorrect to include config.h here, because this file is being
     compiled for the target, and hence definitions concerning only the host
     do not apply.  */
  #include "tconfig.h"
  #include "tsystem.h"
  #include "coretypes.h"
*************** Software Foundation, 59 Temple Place - S
*** 43,48 ****
--- 47,58 ----
  #undef abort
  #endif
  
+ #ifdef HAVE_GAS_HIDDEN
+ #define ATTRIBUTE_HIDDEN  __attribute__ ((__visibility__ ("hidden")))
+ #else
+ #define ATTRIBUTE_HIDDEN
+ #endif
+ 
  #include "libgcc2.h"
  
  #ifdef DECLARE_LIBRARY_RENAMES
*************** __udiv_w_sdiv (UWtype *rp __attribute__ 
*** 495,505 ****
  #define L_udivmoddi4
  #endif
  
- #if (defined (L_clzsi2) || defined (L_clzdi2) || \
-      defined (L_ctzsi2) || defined (L_ctzdi2))
- extern const UQItype __clz_tab[];
- #endif
- 
  #ifdef L_clz
  const UQItype __clz_tab[] =
  {
--- 505,510 ----
*************** const UQItype __clz_tab[] =
*** 518,539 ****
  Wtype
  __clzsi2 (USItype x)
  {
!   Wtype a;
  
!   /* Note that we've already verified that BITS_PER_UNIT == 8, and
!      thus SItype is 32 bits wide.  */
!   if (x < (1 << 2 * 8))
!     if (x < (1 << 1 * 8))
!       a = 0 * 8;
!     else
!       a = 1 * 8;
!   else
!     if (x < (1 << 3 * 8))
!       a = 2 * 8;
!     else
!       a = 3 * 8;
  
!   return 32 - (__clz_tab[x >> a] + a);
  }
  #endif
  
--- 523,535 ----
  Wtype
  __clzsi2 (USItype x)
  {
!   UWtype w = x;
!   Wtype ret;
  
!   count_leading_zeros (ret, w);
!   ret -= (sizeof(w) - sizeof(x)) * BITS_PER_UNIT;
  
!   return ret;
  }
  #endif
  
*************** __clzsi2 (USItype x)
*** 541,555 ****
  Wtype
  __clzdi2 (UDItype x)
  {
!   Wtype a;
  
!   /* Note that we've already verified that BITS_PER_UNIT == 8, and
!      thus DItype is 64 bits wide.  */
!   for (a = 64 - 8; a > 0; a -= 8)
!     if (((x >> a) & 0xff) != 0)
!       break;
  
!   return 64 - (__clz_tab[x >> a] + a);
  }
  #endif
  
--- 537,560 ----
  Wtype
  __clzdi2 (UDItype x)
  {
!   UWtype word;
!   Wtype ret, add;
  
!   if (sizeof(x) > sizeof(word))
!     {
!       DWunion uu;
  
!       uu.ll = x;
!       if (uu.s.high)
! 	word = uu.s.high, add = 0;
!       else
! 	word = uu.s.low, add = W_TYPE_SIZE;
!     }
!   else
!     word = x, add = (Wtype)(sizeof(x) - sizeof(word)) * BITS_PER_UNIT;
! 
!   count_leading_zeros (ret, word);
!   return ret + add;
  }
  #endif
  
*************** __clzdi2 (UDItype x)
*** 557,580 ****
  Wtype
  __ctzsi2 (USItype x)
  {
!   Wtype a;
! 
!   x = x & -x;
  
!   /* Note that we've already verified that BITS_PER_UNIT == 8, and
!      thus SItype is 32 bits wide.  */
!   if (x < (1 << 2 * 8))
!     if (x < (1 << 1 * 8))
!       a = 0 * 8;
!     else
!       a = 1 * 8;
!   else
!     if (x < (1 << 3 * 8))
!       a = 2 * 8;
!     else
!       a = 3 * 8;
  
!   return __clz_tab[x >> a] + a - 1;
  }
  #endif
  
--- 562,572 ----
  Wtype
  __ctzsi2 (USItype x)
  {
!   Wtype ret;
  
!   count_trailing_zeros (ret, x);
  
!   return ret;
  }
  #endif
  
*************** __ctzsi2 (USItype x)
*** 582,601 ****
  Wtype
  __ctzdi2 (UDItype x)
  {
!   Wtype a;
  
!   x = x & -x;
!   for (a = 64 - 8; a > 0; a -= 8)
!     if (((x >> a) & 0xff) != 0)
!       break;
  
!   return __clz_tab[x >> a] + a - 1;
  }
  #endif
  
! #if (defined (L_popcountsi2) || defined (L_popcountdi2) || \
!      defined (L_paritysi2) || defined (L_paritydi2))
! extern const UQItype __popcount_tab[];
  #endif
  
  #ifdef L_popcount_tab
--- 574,603 ----
  Wtype
  __ctzdi2 (UDItype x)
  {
!   UWtype word;
!   Wtype ret, add;
  
!   if (sizeof(x) > sizeof(word))
!     {
!       DWunion uu;
  
!       uu.ll = x;
!       if (uu.s.low)
! 	word = uu.s.low, add = 0;
!       else
! 	word = uu.s.high, add = W_TYPE_SIZE;
!     }
!   else
!     word = x, add = 0;
! 
!   count_trailing_zeros (ret, word);
!   return ret + add;
  }
  #endif
  
! #if (defined (L_popcountsi2) || defined (L_popcountdi2)	\
!      || defined (L_popcount_tab))
! extern const UQItype __popcount_tab[] ATTRIBUTE_HIDDEN;
  #endif
  
  #ifdef L_popcount_tab
*************** __popcountdi2 (UDItype x)
*** 642,650 ****
  Wtype
  __paritysi2 (USItype x)
  {
!   x ^= x >> 16;
!   x ^= x >> 8;
!   return __popcount_tab[x & 0xff] & 1;
  }
  #endif
  
--- 644,656 ----
  Wtype
  __paritysi2 (USItype x)
  {
!   UWtype nx = x;
!   nx ^= nx >> 16;
!   nx ^= nx >> 8;
!   nx ^= nx >> 4;
!   nx ^= nx >> 2;
!   nx ^= nx >> 1;
!   return nx & 1;
  }
  #endif
  
*************** __paritysi2 (USItype x)
*** 652,661 ****
  Wtype
  __paritydi2 (UDItype x)
  {
!   Wtype nx = x ^ (x >> 32);
    nx ^= nx >> 16;
    nx ^= nx >> 8;
!   return __popcount_tab[nx & 0xff] & 1;
  }
  #endif
  
--- 658,670 ----
  Wtype
  __paritydi2 (UDItype x)
  {
!   UWtype nx = x ^ (x >> 32);
    nx ^= nx >> 16;
    nx ^= nx >> 8;
!   nx ^= nx >> 4;
!   nx ^= nx >> 2;
!   nx ^= nx >> 1;
!   return nx & 1;
  }
  #endif
  
Index: longlong.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/longlong.h,v
retrieving revision 1.33
diff -c -p -d -r1.33 longlong.h
*** longlong.h	3 Oct 2002 20:39:08 -0000	1.33
--- longlong.h	1 Feb 2003 20:58:12 -0000
*************** extern UDItype __udiv_qrnnd (UDItype *, 
*** 134,140 ****
    __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X))
  #define COUNT_LEADING_ZEROS_0 64
  #else
! extern const UQItype __clz_tab[];
  #define count_leading_zeros(COUNT,X) \
    do {									\
      UDItype __xr = (X), __t, __a;					\
--- 134,140 ----
    __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X))
  #define COUNT_LEADING_ZEROS_0 64
  #else
! extern const UQItype __clz_tab[] ATTRIBUTE_HIDDEN;
  #define count_leading_zeros(COUNT,X) \
    do {									\
      UDItype __xr = (X), __t, __a;					\
*************** UDItype __umulsidi3 (USItype, USItype);
*** 1287,1293 ****
  #endif
  
  #if !defined (count_leading_zeros)
! extern const UQItype __clz_tab[];
  #define count_leading_zeros(count, x) \
    do {									\
      UWtype __xr = (x);							\
--- 1287,1293 ----
  #endif
  
  #if !defined (count_leading_zeros)
! extern const UQItype __clz_tab[] ATTRIBUTE_HIDDEN;
  #define count_leading_zeros(count, x) \
    do {									\
      UWtype __xr = (x);							\


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