summaryrefslogtreecommitdiff
path: root/gcc/libgcc2.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-02-01 19:00:02 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-02-01 19:00:02 +0000
commit6a08d0ab0eb03f322e976916df71162aca59b6b6 (patch)
treedf0468b560ad2e3e7a8fb8def8c31b83ba736922 /gcc/libgcc2.c
parentb43a3b626e56b15297fba1230313b18a4d5bb76d (diff)
downloadgcc-6a08d0ab0eb03f322e976916df71162aca59b6b6.tar.gz
2003-02-01 Richard Henderson <rth@redhat.com>
* optabs.c (expand_unop): Use word_mode for outmode of bit scaners. * libgcc2.c (__ffsdi2, __clzsi2, __clzdi2, __ctzsi2, __ctzdi2, __popcountsi2, __popcountdi2, __paritysi2 __paritydi2): Change return type to Wtype. * libgcc-std.ver (GCC_3.4): Fix inheritance. * config/i386/i386.md (ffssi2): Use nonimmediate_operand for expander input constraint. 2003-02-01 Falk Hueffner <falk.hueffner@student.uni-tuebingen.de> * optabs.h (optab_index): Add OTI_clz, OTI_ctz, OTI_popcount and OTI_parity. (clz_optab, ctz_optab, popcount_optab, parity_optab): New. * optabs.c (widen_clz, expand_parity): New. (expand_unop): Handle clz and parity. Hardcode SImode as outmode for libcalls to clz, ctz, popcount, and parity. (init_optabs): Init clz_optab, ctz_optab, popcount_optab and parity_optab, and set up libfunc handlers. * libgcc2.c (__clzsi2, __clzdi2, __ctzsi2, __ctzdi2, __popcountsi2, __popcountdi2, __paritysi2 __paritydi2, __popcount_tab): New. * libgcc2.h: Declare them. * libgcc-std.ver (GCC_3.4): Add new functions from libgcc2.c. * genopinit.c (optabs): Add clz_optab, ctz_optab, popcount_optab and parity_optab. * builtin-types.def (BT_FN_INT_LONG, BT_FN_INT_LONGLONG): New. * builtins.def (BUILT_IN_CLZ, BUILT_IN_CTZ, BUILT_IN_POPCOUNT, BUILT_IN_PARITY, BUILT_IN_FFSL, BUILT_IN_CLZL, BUILT_IN_CTZL, BUILT_IN_POPCOUNTL, BUILT_IN_PARITYL, BUILT_IN_FFSLL, BUILT_IN_CLZLL, BUILT_IN_CTZLL, BUILT_IN_POPCOUNTLL, BUILT_IN_PARITYLL): New. * builtins.c (expand_builtin_unop): Rename from expand_builtin_ffs and add optab argument. (expand_builtin): Expand BUILT_IN_{FFS,CLZ,POPCOUNT,PARITY}*. * tree.def (CLZ_EXPR, CTZ_EXPR, POPCOUNT_EXPR, PARITY_EXPR): New. * expr.c (expand_expr): Handle them. * fold-const.c (tree_expr_nonnegative_p): Likewise. * rtl.def (CLZ, CTZ, POPCOUNT, PARITY): New. * reload1.c (eliminate_regs): Handle them. (elimination_effects): Likewise. * function.c (instantiate_virtual_regs_1): Likewise * genattrtab.c (check_attr_value): Likewise. * simplify-rtx.c (simplify_unary_operation): Likewise. * c-common.c (c_common_truthvalue_conversion): Handle POPCOUNT_EXPR. * combine.c (combine_simplify_rtx): Handle POPCOUNT and PARITY. (nonzero_bits): Handle CLZ, CTZ, POPCOUNT and PARITY. * config/alpha/alpha.md (clzdi2, ctzdi2, popcountdi2): New. * config/arm/arm.c (arm_init_builtins): Rename __builtin_clz to __builtin_arm_clz. * Makefile.in (LIB2FUNCS_1, LIB2FUNCS_2): Move... * mklibgcc.in (lib2funcs): ...here and merge. Add new members. * doc/extend.texi (Other Builtins): Add new builtins. * doc/md.texi (Standard Names): Add new patterns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@62252 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/libgcc2.c')
-rw-r--r--gcc/libgcc2.c152
1 files changed, 151 insertions, 1 deletions
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index deb772fa629..5de1edecd8c 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -331,7 +331,7 @@ __ashrdi3 (DWtype u, word_type b)
#endif
#ifdef L_ffsdi2
-DWtype
+Wtype
__ffsdi2 (DWtype u)
{
DWunion uu;
@@ -495,6 +495,11 @@ __udiv_w_sdiv (UWtype *rp __attribute__ ((__unused__)),
#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[] =
{
@@ -508,6 +513,151 @@ const UQItype __clz_tab[] =
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
};
#endif
+
+#ifdef L_clzsi2
+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
+
+#ifdef L_clzdi2
+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
+
+#ifdef L_ctzsi2
+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
+
+#ifdef L_ctzdi2
+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
+const UQItype __popcount_tab[] =
+{
+ 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
+ 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
+};
+#endif
+
+#ifdef L_popcountsi2
+Wtype
+__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
+Wtype
+__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
+Wtype
+__paritysi2 (USItype x)
+{
+ x ^= x >> 16;
+ x ^= x >> 8;
+ return __popcount_tab[x & 0xff] & 1;
+}
+#endif
+
+#ifdef L_paritydi2
+Wtype
+__paritydi2 (UDItype x)
+{
+ Wtype nx = x ^ (x >> 32);
+ nx ^= nx >> 16;
+ nx ^= nx >> 8;
+ return __popcount_tab[nx & 0xff] & 1;
+}
+#endif
#ifdef L_udivmoddi4