This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: patch libgcc2.c for c4x target
- From: Richard Henderson <rth at redhat dot com>
- To: Herman ten Brugge <hermantenbrugge at home dot nl>, Kazu Hirata <kazu at cs dot umass dot edu>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 8 Feb 2003 21:04:07 -0800
- Subject: Re: patch libgcc2.c for c4x target
- References: <20030205234038.GP19935@redhat.com> <20030206203536.121C7767AF@home.nl>
On Thu, Feb 06, 2003 at 09:35:35PM +0100, Herman ten Brugge wrote:
> I just checked optabs.c and saw the SImode/DImode code. I agree the
> patch is not correct without a change to this code as well.
> The QImode on the c4x target is 32 bits so I see no problem in
> changing the SImode into mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)
> and DImode into mode_for_size (LONG_LONG_TYPE_SIZE, MODE_INT, 0) in
> optabs.c
> Making this change to optabs.c and the suggested patch to libgcc2.c
> should work for all targets.
I've been looking at the optabs.c code and it does seem
decidedly wrong. How does the following work for yall
on c4x and h8300?
r~
* libgcc-std.ver (__clztf2): New.
(__ctztf2, __popcounttf2, __paritytf2): New.
* libgcc2.c (__clzSI2, __clzDI2, __ctzSI2, __ctzDI2, __popcountSI2,
__popcountDI2, __paritySI2, __parityDI2): Use UWmode and UDWmode;
adjust code to match the different type sizes.
* libgcc2.h (__clzSI2, __ctzSI2, __popcountSI2, __paritySI2,
__clzDI2, __ctzDI2, __popcountDI2, __parityDI2): New macros.
* optabs.c (init_integral_libfuncs): Don't hard-code SImode and
TImode; select word_mode and twice that.
(init_floating_libfuncs): Don't hard-code SFmode and TFmode;
select the modes from float, double, and long double.
(init_optabs): Remove duplicate initializations.
Index: libgcc-std.ver
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcc-std.ver,v
retrieving revision 1.17
diff -c -p -d -r1.17 libgcc-std.ver
*** libgcc-std.ver 1 Feb 2003 18:59:46 -0000 1.17
--- libgcc-std.ver 9 Feb 2003 04:54:39 -0000
*************** GCC_3.4 {
*** 186,195 ****
# bit scanning and counting built-ins
__clzsi2
__clzdi2
__ctzsi2
__ctzdi2
__popcountsi2
__popcountdi2
! __paritysi2
! __paritydi2
}
--- 186,199 ----
# bit scanning and counting built-ins
__clzsi2
__clzdi2
+ __clzti2
__ctzsi2
__ctzdi2
+ __ctzti2
__popcountsi2
__popcountdi2
! __popcountti2
! __paritysi2
! __paritydi2
! __parityti2
}
Index: libgcc2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcc2.c,v
retrieving revision 1.163
diff -c -p -d -r1.163 libgcc2.c
*** libgcc2.c 5 Feb 2003 00:52:23 -0000 1.163
--- libgcc2.c 9 Feb 2003 04:54:40 -0000
*************** const UQItype __clz_tab[] =
*** 539,553 ****
#ifdef L_clzsi2
#undef int
! extern int __clzsi2 (USItype x);
int
! __clzsi2 (USItype x)
{
- UWtype w = x;
Wtype ret;
! count_leading_zeros (ret, w);
! ret -= (sizeof(w) - sizeof(x)) * BITS_PER_UNIT;
return ret;
}
--- 539,551 ----
#ifdef L_clzsi2
#undef int
! extern int __clzSI2 (UWtype x);
int
! __clzSI2 (UWtype x)
{
Wtype ret;
! count_leading_zeros (ret, x);
return ret;
}
*************** __clzsi2 (USItype x)
*** 555,579 ****
#ifdef L_clzdi2
#undef int
! extern int __clzdi2 (UDItype x);
int
! __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;
--- 553,571 ----
#ifdef L_clzdi2
#undef int
! extern int __clzDI2 (UDWtype x);
int
! __clzDI2 (UDWtype x)
{
+ DWunion uu;
UWtype word;
Wtype ret, add;
! uu.ll = x;
! if (uu.s.high)
! word = uu.s.high, add = 0;
else
! word = uu.s.low, add = W_TYPE_SIZE;
count_leading_zeros (ret, word);
return ret + add;
*************** __clzdi2 (UDItype x)
*** 582,590 ****
#ifdef L_ctzsi2
#undef int
! extern int __ctzsi2 (USItype x);
int
! __ctzsi2 (USItype x)
{
Wtype ret;
--- 574,582 ----
#ifdef L_ctzsi2
#undef int
! extern int __ctzSI2 (UWtype x);
int
! __ctzSI2 (UWtype x)
{
Wtype ret;
*************** __ctzsi2 (USItype x)
*** 596,620 ****
#ifdef L_ctzdi2
#undef int
! extern int __ctzdi2 (UDItype x);
int
! __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;
--- 588,606 ----
#ifdef L_ctzdi2
#undef int
! extern int __ctzDI2 (UDWtype x);
int
! __ctzDI2 (UDWtype x)
{
+ DWunion uu;
UWtype word;
Wtype ret, add;
! uu.ll = x;
! if (uu.s.low)
! word = uu.s.low, add = 0;
else
! word = uu.s.high, add = W_TYPE_SIZE;
count_trailing_zeros (ret, word);
return ret + add;
*************** const UQItype __popcount_tab[] =
*** 642,698 ****
#ifdef L_popcountsi2
#undef int
! extern int __popcountsi2 (USItype x);
int
! __popcountsi2 (USItype x)
{
! return __popcount_tab[(x >> 0) & 0xff]
! + __popcount_tab[(x >> 8) & 0xff]
! + __popcount_tab[(x >> 16) & 0xff]
! + __popcount_tab[(x >> 24) & 0xff];
}
#endif
#ifdef L_popcountdi2
#undef int
! extern int __popcountdi2 (UDItype x);
int
! __popcountdi2 (UDItype x)
{
! return __popcount_tab[(x >> 0) & 0xff]
! + __popcount_tab[(x >> 8) & 0xff]
! + __popcount_tab[(x >> 16) & 0xff]
! + __popcount_tab[(x >> 24) & 0xff]
! + __popcount_tab[(x >> 32) & 0xff]
! + __popcount_tab[(x >> 40) & 0xff]
! + __popcount_tab[(x >> 48) & 0xff]
! + __popcount_tab[(x >> 56) & 0xff];
}
#endif
#ifdef L_paritysi2
#undef int
! extern int __paritysi2 (USItype x);
int
! __paritysi2 (USItype x)
{
! UWtype nx = x;
! nx ^= nx >> 16;
! nx ^= nx >> 8;
! nx ^= nx >> 4;
! nx &= 0xf;
! return (0x6996 >> nx) & 1;
}
#endif
#ifdef L_paritydi2
#undef int
! extern int __paritydi2 (UDItype x);
int
! __paritydi2 (UDItype x)
{
! UWtype nx = x ^ (x >> 32);
nx ^= nx >> 16;
nx ^= nx >> 8;
nx ^= nx >> 4;
nx &= 0xf;
--- 628,704 ----
#ifdef L_popcountsi2
#undef int
! extern int __popcountSI2 (UWtype x);
int
! __popcountSI2 (UWtype x)
{
! UWtype i, ret = 0;
!
! for (i = 0; i < W_TYPE_SIZE; i += 8)
! ret += __popcount_tab[(x >> i) & 0xff];
!
! return ret;
}
#endif
#ifdef L_popcountdi2
#undef int
! extern int __popcountDI2 (UDWtype x);
int
! __popcountDI2 (UDWtype x)
{
! UWtype i, ret = 0;
!
! for (i = 0; i < 2*W_TYPE_SIZE; i += 8)
! ret += __popcount_tab[(x >> i) & 0xff];
!
! return ret;
}
#endif
#ifdef L_paritysi2
#undef int
! extern int __paritySI2 (UWtype x);
int
! __paritySI2 (UWtype x)
{
! #if W_TYPE_SIZE > 64
! # error "fill out the table"
! #endif
! #if W_TYPE_SIZE > 32
! x ^= x >> 32;
! #endif
! #if W_TYPE_SIZE > 16
! x ^= x >> 16;
! #endif
! x ^= x >> 8;
! x ^= x >> 4;
! x &= 0xf;
! return (0x6996 >> x) & 1;
}
#endif
#ifdef L_paritydi2
#undef int
! extern int __parityDI2 (UDWtype x);
int
! __parityDI2 (UDWtype x)
{
! DWunion uu;
! UWtype nx;
!
! uu.ll = x;
! nx = uu.s.low ^ uu.s.high;
!
! #if W_TYPE_SIZE > 64
! # error "fill out the table"
! #endif
! #if W_TYPE_SIZE > 32
! nx ^= nx >> 32;
! #endif
! #if W_TYPE_SIZE > 16
nx ^= nx >> 16;
+ #endif
nx ^= nx >> 8;
nx ^= nx >> 4;
nx &= 0xf;
Index: libgcc2.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/libgcc2.h,v
retrieving revision 1.25
diff -c -p -d -r1.25 libgcc2.h
*** libgcc2.h 5 Feb 2003 00:52:24 -0000 1.25
--- libgcc2.h 9 Feb 2003 04:54:40 -0000
*************** typedef int word_type __attribute__ ((mo
*** 203,209 ****
--- 203,217 ----
#define __fixunssfSI __NW(fixunssf,)
#define __ffsSI2 __NW(ffs,2)
+ #define __clzSI2 __NW(clz,2)
+ #define __ctzSI2 __NW(ctz,2)
+ #define __popcountSI2 __NW(popcount,2)
+ #define __paritySI2 __NW(parity,2)
#define __ffsDI2 __NDW(ffs,2)
+ #define __clzDI2 __NDW(clz,2)
+ #define __ctzDI2 __NDW(ctz,2)
+ #define __popcountDI2 __NDW(popcount,2)
+ #define __parityDI2 __NDW(parity,2)
extern DWtype __muldi3 (DWtype, DWtype);
extern DWtype __divdi3 (DWtype, DWtype);
*************** extern DWtype __negdi2 (DWtype);
*** 225,244 ****
extern DWtype __lshrdi3 (DWtype, word_type);
extern DWtype __ashldi3 (DWtype, word_type);
extern DWtype __ashrdi3 (DWtype, word_type);
-
- /* ??? Ought to get these named properly for DSPs. */
- #if BITS_PER_UNIT != 8 || MIN_UNITS_PER_WORD < 4
- # undef L_clzsi2
- # undef L_ctzsi2
- # undef L_popcountsi2
- # undef L_paritysi2
- # if LONG_LONG_TYPE_SIZE <= 32
- # undef L_clzdi2
- # undef L_ctzdi2
- # undef L_popcountdi2
- # undef L_paritydi2
- # endif
- #endif
/* __udiv_w_sdiv is static inline when building other libgcc2 portions. */
#if (!defined(L_udivdi3) && !defined(L_divdi3) && \
--- 233,238 ----
Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.162
diff -c -p -d -r1.162 optabs.c
*** optabs.c 9 Feb 2003 04:25:16 -0000 1.162
--- optabs.c 9 Feb 2003 04:54:40 -0000
*************** init_integral_libfuncs (optable, opname,
*** 5396,5402 ****
const char *opname;
int suffix;
{
! init_libfuncs (optable, SImode, TImode, opname, suffix);
}
/* Initialize the libfunc fields of an entire group of entries in some
--- 5396,5404 ----
const char *opname;
int suffix;
{
! init_libfuncs (optable, word_mode,
! mode_for_size (2*BITS_PER_WORD, MODE_INT, 0),
! opname, suffix);
}
/* Initialize the libfunc fields of an entire group of entries in some
*************** init_floating_libfuncs (optable, opname,
*** 5410,5416 ****
const char *opname;
int suffix;
{
! init_libfuncs (optable, SFmode, TFmode, opname, suffix);
}
rtx
--- 5412,5428 ----
const char *opname;
int suffix;
{
! enum machine_mode fmode, dmode, lmode;
!
! fmode = TYPE_MODE (float_type_node);
! dmode = TYPE_MODE (double_type_node);
! lmode = TYPE_MODE (long_double_type_node);
!
! init_libfuncs (optable, fmode, fmode, opname, suffix);
! if (dmode != fmode)
! init_libfuncs (optable, dmode, dmode, opname, suffix);
! if (lmode != dmode)
! init_libfuncs (optable, lmode, lmode, opname, suffix);
}
rtx
*************** init_optabs ()
*** 5659,5675 ****
/* The ffs function operates on `int'. */
ffs_optab->handlers[(int) mode_for_size (INT_TYPE_SIZE, MODE_INT, 0)].libfunc
= init_one_libfunc ("ffs");
- ffs_optab->handlers[(int) DImode].libfunc = init_one_libfunc ("__ffsdi2");
- clz_optab->handlers[(int) SImode].libfunc = init_one_libfunc ("__clzsi2");
- clz_optab->handlers[(int) DImode].libfunc = init_one_libfunc ("__clzdi2");
- ctz_optab->handlers[(int) SImode].libfunc = init_one_libfunc ("__ctzsi2");
- ctz_optab->handlers[(int) DImode].libfunc = init_one_libfunc ("__ctzdi2");
- popcount_optab->handlers[(int) SImode].libfunc
- = init_one_libfunc ("__popcountsi2");
- popcount_optab->handlers[(int) DImode].libfunc
- = init_one_libfunc ("__popcountdi2");
- parity_optab->handlers[(int) SImode].libfunc = init_one_libfunc ("__paritysi2");
- parity_optab->handlers[(int) DImode].libfunc = init_one_libfunc ("__paritydi2");
extendsfdf2_libfunc = init_one_libfunc ("__extendsfdf2");
extendsfxf2_libfunc = init_one_libfunc ("__extendsfxf2");
--- 5671,5676 ----