2006-02-01 09:16:06

by Akinobu Mita

[permalink] [raw]
Subject: [patch 14/44] generic hweight{64,32,16,8}()


This patch introduces the C-language equivalents of the functions below:

unsigned int hweight32(unsigned int w);
unsigned int hweight16(unsigned int w);
unsigned int hweight8(unsigned int w);
unsigned long hweight64(__u64 w);

In include/asm-generic/bitops/hweight.h

This code largely copied from:
include/linux/bitops.h

Signed-off-by: Akinobu Mita <[email protected]>
include/asm-generic/bitops/hweight.h | 54 +++++++++++++++++++++++++++++++++++
1 files changed, 54 insertions(+)

Index: 2.6-git/include/asm-generic/bitops/hweight.h
===================================================================
--- /dev/null
+++ 2.6-git/include/asm-generic/bitops/hweight.h
@@ -0,0 +1,54 @@
+#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
+#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
+
+#include <asm/types.h>
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+static inline unsigned int hweight32(unsigned int w)
+{
+ unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
+ res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+ res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+ res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+ return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+
+static inline unsigned int hweight16(unsigned int w)
+{
+ unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
+ res = (res & 0x3333) + ((res >> 2) & 0x3333);
+ res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
+ return (res & 0x00FF) + ((res >> 8) & 0x00FF);
+}
+
+static inline unsigned int hweight8(unsigned int w)
+{
+ unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
+ res = (res & 0x33) + ((res >> 2) & 0x33);
+ return (res & 0x0F) + ((res >> 4) & 0x0F);
+}
+
+static inline unsigned long hweight64(__u64 w)
+{
+#if BITS_PER_LONG == 32
+ return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+#elif BITS_PER_LONG == 64
+ u64 res;
+ res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
+ res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
+ res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
+ res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
+ res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
+ return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
+#else
+#error BITS_PER_LONG not defined
+#endif
+}
+
+#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */

--


2006-02-01 09:08:11

by Andi Kleen

[permalink] [raw]
Subject: Re: [patch 14/44] generic hweight{64,32,16,8}()

On Wednesday 01 February 2006 10:02, Akinobu Mita wrote:

> +static inline unsigned int hweight32(unsigned int w)
> +{
> + unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
> + res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
> + res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
> + res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
> + return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
> +}

How large are these functions on x86? Maybe it would be better to not inline them,
but put it into some C file out of line.

-Andi

2006-02-01 09:26:29

by Michael Tokarev

[permalink] [raw]
Subject: Re: [patch 14/44] generic hweight{64,32,16,8}()

Andi Kleen wrote:
> On Wednesday 01 February 2006 10:02, Akinobu Mita wrote:
>
>>+static inline unsigned int hweight32(unsigned int w)
[]
> How large are these functions on x86? Maybe it would be better to not inline them,
> but put it into some C file out of line.

hweight8 47 bytes
hweight16 76 bytes
hweight32 97 bytes
hweight64 56 bytes (NOT inlining hweight32)
hweight64 197 bytes (inlining hweight32)

Those are when compiled as separate non-inlined functions,
with pushl %ebp and ret.

/mjt

2006-02-01 10:48:25

by Andi Kleen

[permalink] [raw]
Subject: Re: [patch 14/44] generic hweight{64,32,16,8}()

On Wednesday 01 February 2006 10:26, Michael Tokarev wrote:
> Andi Kleen wrote:
> > On Wednesday 01 February 2006 10:02, Akinobu Mita wrote:
> >
> >>+static inline unsigned int hweight32(unsigned int w)
> []
> > How large are these functions on x86? Maybe it would be better to not inline them,
> > but put it into some C file out of line.
>
> hweight8 47 bytes
> hweight16 76 bytes
> hweight32 97 bytes
> hweight64 56 bytes (NOT inlining hweight32)
> hweight64 197 bytes (inlining hweight32)
>
> Those are when compiled as separate non-inlined functions,
> with pushl %ebp and ret.

This would argue for moving them out of line.

-Andi

2006-02-02 12:50:20

by Akinobu Mita

[permalink] [raw]
Subject: Re: [patch 14/44] generic hweight{64,32,16,8}()

On Wed, Feb 01, 2006 at 11:24:27AM +0100, Andi Kleen wrote:
> On Wednesday 01 February 2006 10:26, Michael Tokarev wrote:
> > Andi Kleen wrote:
> > > On Wednesday 01 February 2006 10:02, Akinobu Mita wrote:
> > >
> > >>+static inline unsigned int hweight32(unsigned int w)
> > []
> > > How large are these functions on x86? Maybe it would be better to not inline them,
> > > but put it into some C file out of line.
> >
> > hweight8 47 bytes
> > hweight16 76 bytes
> > hweight32 97 bytes
> > hweight64 56 bytes (NOT inlining hweight32)
> > hweight64 197 bytes (inlining hweight32)
> >
> > Those are when compiled as separate non-inlined functions,
> > with pushl %ebp and ret.
>
> This would argue for moving them out of line.

This patch will put hweight*() into lib/hweight.c

Index: 2.6-git/include/asm-generic/bitops/hweight.h
===================================================================
--- 2.6-git.orig/include/asm-generic/bitops/hweight.h
+++ 2.6-git/include/asm-generic/bitops/hweight.h
@@ -1,54 +1,9 @@
#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
#define _ASM_GENERIC_BITOPS_HWEIGHT_H_

-#include <asm/types.h>
-
-/**
- * hweightN - returns the hamming weight of a N-bit word
- * @x: the word to weigh
- *
- * The Hamming Weight of a number is the total number of bits set in it.
- */
-
-static inline unsigned int hweight32(unsigned int w)
-{
- unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
- res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
- res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
- res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
- return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
-}
-
-static inline unsigned int hweight16(unsigned int w)
-{
- unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
- res = (res & 0x3333) + ((res >> 2) & 0x3333);
- res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
- return (res & 0x00FF) + ((res >> 8) & 0x00FF);
-}
-
-static inline unsigned int hweight8(unsigned int w)
-{
- unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
- res = (res & 0x33) + ((res >> 2) & 0x33);
- return (res & 0x0F) + ((res >> 4) & 0x0F);
-}
-
-static inline unsigned long hweight64(__u64 w)
-{
-#if BITS_PER_LONG == 32
- return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
-#elif BITS_PER_LONG == 64
- u64 res;
- res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
- res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
- res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
- res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
- res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
- return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
-#else
-#error BITS_PER_LONG not defined
-#endif
-}
+extern unsigned int hweight32(unsigned int w);
+extern unsigned int hweight16(unsigned int w);
+extern unsigned int hweight8(unsigned int w);
+extern unsigned long hweight64(__u64 w);

#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
Index: 2.6-git/lib/Makefile
===================================================================
--- 2.6-git.orig/lib/Makefile
+++ 2.6-git/lib/Makefile
@@ -5,7 +5,7 @@
lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \
bust_spinlocks.o rbtree.o radix-tree.o dump_stack.o \
idr.o div64.o int_sqrt.o bitmap.o extable.o prio_tree.o \
- sha1.o
+ sha1.o hweight.o

lib-y += kobject.o kref.o kobject_uevent.o klist.o

Index: 2.6-git/lib/hweight.c
===================================================================
--- /dev/null
+++ 2.6-git/lib/hweight.c
@@ -0,0 +1,54 @@
+#include <linux/module.h>
+#include <asm/types.h>
+
+/**
+ * hweightN - returns the hamming weight of a N-bit word
+ * @x: the word to weigh
+ *
+ * The Hamming Weight of a number is the total number of bits set in it.
+ */
+
+unsigned int hweight32(unsigned int w)
+{
+ unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
+ res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+ res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+ res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+ return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+EXPORT_SYMBOL(hweight32);
+
+unsigned int hweight16(unsigned int w)
+{
+ unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
+ res = (res & 0x3333) + ((res >> 2) & 0x3333);
+ res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
+ return (res & 0x00FF) + ((res >> 8) & 0x00FF);
+}
+EXPORT_SYMBOL(hweight16);
+
+unsigned int hweight8(unsigned int w)
+{
+ unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
+ res = (res & 0x33) + ((res >> 2) & 0x33);
+ return (res & 0x0F) + ((res >> 4) & 0x0F);
+}
+EXPORT_SYMBOL(hweight8);
+
+unsigned long hweight64(__u64 w)
+{
+#if BITS_PER_LONG == 32
+ return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
+#elif BITS_PER_LONG == 64
+ u64 res;
+ res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
+ res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
+ res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
+ res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
+ res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
+ return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
+#else
+#error BITS_PER_LONG not defined
+#endif
+}
+EXPORT_SYMBOL(hweight64);

2006-02-02 14:11:09

by Gabriel Paubert

[permalink] [raw]
Subject: Re: [patch 14/44] generic hweight{64,32,16,8}()

On Wed, Feb 01, 2006 at 06:02:38PM +0900, Akinobu Mita wrote:
>
> This patch introduces the C-language equivalents of the functions below:
>
> unsigned int hweight32(unsigned int w);
> unsigned int hweight16(unsigned int w);
> unsigned int hweight8(unsigned int w);
> unsigned long hweight64(__u64 w);
>
> In include/asm-generic/bitops/hweight.h
>
> This code largely copied from:
> include/linux/bitops.h
>
> Signed-off-by: Akinobu Mita <[email protected]>
> include/asm-generic/bitops/hweight.h | 54 +++++++++++++++++++++++++++++++++++
> 1 files changed, 54 insertions(+)
>
> Index: 2.6-git/include/asm-generic/bitops/hweight.h
> ===================================================================
> --- /dev/null
> +++ 2.6-git/include/asm-generic/bitops/hweight.h
> @@ -0,0 +1,54 @@
> +#ifndef _ASM_GENERIC_BITOPS_HWEIGHT_H_
> +#define _ASM_GENERIC_BITOPS_HWEIGHT_H_
> +
> +#include <asm/types.h>
> +
> +/**
> + * hweightN - returns the hamming weight of a N-bit word
> + * @x: the word to weigh
> + *
> + * The Hamming Weight of a number is the total number of bits set in it.
> + */
> +
> +static inline unsigned int hweight32(unsigned int w)
> +{
> + unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
> + res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
> + res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
> + res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
> + return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
> +}


The first step can be implemented slightly better:

unsigned int res = w-((w>>1)&0x55555555);

as I found once on the web[1].

Several of the following steps can also be simplified
by omitting the masking when the result can't possibly
cause a carry to propagate too far.

This might also have a non negligible impact
on code size.


> +
> +static inline unsigned int hweight16(unsigned int w)
> +{
> + unsigned int res = (w & 0x5555) + ((w >> 1) & 0x5555);
> + res = (res & 0x3333) + ((res >> 2) & 0x3333);
> + res = (res & 0x0F0F) + ((res >> 4) & 0x0F0F);
> + return (res & 0x00FF) + ((res >> 8) & 0x00FF);
> +}
> +
> +static inline unsigned int hweight8(unsigned int w)
> +{
> + unsigned int res = (w & 0x55) + ((w >> 1) & 0x55);
> + res = (res & 0x33) + ((res >> 2) & 0x33);
> + return (res & 0x0F) + ((res >> 4) & 0x0F);
> +}
> +
> +static inline unsigned long hweight64(__u64 w)
> +{
> +#if BITS_PER_LONG == 32
> + return hweight32((unsigned int)(w >> 32)) + hweight32((unsigned int)w);
> +#elif BITS_PER_LONG == 64
> + u64 res;
> + res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);
> + res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
> + res = (res & 0x0F0F0F0F0F0F0F0Ful) + ((res >> 4) & 0x0F0F0F0F0F0F0F0Ful);
> + res = (res & 0x00FF00FF00FF00FFul) + ((res >> 8) & 0x00FF00FF00FF00FFul);
> + res = (res & 0x0000FFFF0000FFFFul) + ((res >> 16) & 0x0000FFFF0000FFFFul);
> + return (res & 0x00000000FFFFFFFFul) + ((res >> 32) & 0x00000000FFFFFFFFul);
> +#else
> +#error BITS_PER_LONG not defined
> +#endif
> +}
> +
> +#endif /* _ASM_GENERIC_BITOPS_HWEIGHT_H_ */
>


Regards,
Gabriel

[1] It might be better to write the first line

unsigned res = w - ((w&0xaaaaaaaa)>>1);

but I can never remember what the C standard guarantess about
right shifts values (very little IIRC). I believe that it will
work properly on all architectures that GCC supports, however,
and that it will help on many.

2006-02-03 08:33:44

by Ulrich Eckhardt

[permalink] [raw]
Subject: Re: [patch 14/44] generic hweight{64,32,16,8}()

On Wednesday 01 February 2006 10:02, Akinobu Mita wrote:
> unsigned int hweight32(unsigned int w);
> unsigned int hweight16(unsigned int w);
> unsigned int hweight8(unsigned int w);
> unsigned long hweight64(__u64 w);

IMHO, this should use explicitly sized integers like __u8, __u16 etc, unless
there are stringent reasons like better register use - which is hard to tell
for generic C code. Also, why on earth is the returntype for hweight64 a
long?

> +static inline unsigned int hweight32(unsigned int w)
> +{
> + unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
> + res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
[...]

Why not use unsigned constants here?

> +static inline unsigned long hweight64(__u64 w)
> +{
[..]
> + u64 res;
> + res = (w & 0x5555555555555555ul) + ((w >> 1) & 0x5555555555555555ul);

Why not use initialisation here, too?

just my 2c

Uli

2006-02-06 11:53:03

by Akinobu Mita

[permalink] [raw]
Subject: Re: [patch 14/44] generic hweight{64,32,16,8}()

On Thu, Feb 02, 2006 at 02:26:38AM +0100, Gabriel Paubert wrote:
>
> The first step can be implemented slightly better:
>
> unsigned int res = w-((w>>1)&0x55555555);
>

Yes. I've got many advices about hweight speedup.


static unsigned int hweight32(unsigned int w)
{
unsigned int res = w - ((w >> 1) & 0x55555555);
res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
res = (res + (res >> 4)) & 0x0F0F0F0F;
res = res + (res >> 8);
return (res + (res >> 16)) & 0x000000FF;
}

static unsigned int hweight16(unsigned int w)
{
unsigned int res = w - ((w >> 1) & 0x5555);
res = (res & 0x3333) + ((res >> 2) & 0x3333);
res = (res + (res >> 4)) & 0x0F0F;
return (res + (res >> 8)) & 0x00FF;
}

static unsigned int hweight8(unsigned int w)
{
unsigned int res = w - ((w >> 1) & 0x55);
res = (res & 0x33) + ((res >> 2) & 0x33);
return (res + (res >> 4)) & 0x0F;
}

static unsigned long hweight64(__u64 w)
{
#if BITS_PER_LONG < 64
return hweight32((unsigned int)(w >> 32)) +
hweight32((unsigned int)w);
#else
__u64 res = w - ((w >> 1) & 0x5555555555555555ul);
res = (res & 0x3333333333333333ul) + ((res >> 2) & 0x3333333333333333ul);
res = (res + (res >> 4)) & 0x0F0F0F0F0F0F0F0Ful;
res = res + (res >> 8);
res = res + (res >> 16);
return (res + (res >> 32)) & 0x00000000000000FFul;
#endif
}

2006-02-09 05:55:38

by Akinobu Mita

[permalink] [raw]
Subject: [PATCH] alpha: remove __alpha_cix__ and __alpha_fix__

On Thu, Feb 02, 2006 at 09:50:07PM +0900, mita wrote:
> This patch will put hweight*() into lib/hweight.c

I realized that this patch broke ia64 and alpha.
I want to fix it by making new config option like CONFIG_GENERIC_HWEIGHT.
But there is a difficulty to define CONFIG_GENERIC_HWEIGHT on alpha.
So I want to add the patch below. Does it cause anything bad?

Index: 2.6-git/arch/alpha/lib/ev6-memchr.S
===================================================================
--- 2.6-git.orig/arch/alpha/lib/ev6-memchr.S
+++ 2.6-git/arch/alpha/lib/ev6-memchr.S
@@ -84,7 +84,7 @@ $last_quad:
beq $2, $not_found # U : U L U L

$found_it:
-#if defined(__alpha_fix__) && defined(__alpha_cix__)
+#ifdef CONFIG_ALPHA_EV67
/*
* Since we are guaranteed to have set one of the bits, we don't
* have to worry about coming back with a 0x40 out of cttz...
Index: 2.6-git/arch/alpha/lib/fpreg.c
===================================================================
--- 2.6-git.orig/arch/alpha/lib/fpreg.c
+++ 2.6-git/arch/alpha/lib/fpreg.c
@@ -4,7 +4,7 @@
* (C) Copyright 1998 Linus Torvalds
*/

-#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
#define STT(reg,val) asm volatile ("ftoit $f"#reg",%0" : "=r"(val));
#else
#define STT(reg,val) asm volatile ("stt $f"#reg",%0" : "=m"(val));
@@ -53,7 +53,7 @@ alpha_read_fp_reg (unsigned long reg)
return val;
}

-#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
#define LDT(reg,val) asm volatile ("itoft %0,$f"#reg : : "r"(val));
#else
#define LDT(reg,val) asm volatile ("ldt $f"#reg",%0" : : "m"(val));
@@ -98,7 +98,7 @@ alpha_write_fp_reg (unsigned long reg, u
}
}

-#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
#define STS(reg,val) asm volatile ("ftois $f"#reg",%0" : "=r"(val));
#else
#define STS(reg,val) asm volatile ("sts $f"#reg",%0" : "=m"(val));
@@ -147,7 +147,7 @@ alpha_read_fp_reg_s (unsigned long reg)
return val;
}

-#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
#define LDS(reg,val) asm volatile ("itofs %0,$f"#reg : : "r"(val));
#else
#define LDS(reg,val) asm volatile ("lds $f"#reg",%0" : : "m"(val));
Index: 2.6-git/include/asm-alpha/bitops.h
===================================================================
--- 2.6-git.orig/include/asm-alpha/bitops.h
+++ 2.6-git/include/asm-alpha/bitops.h
@@ -261,7 +261,7 @@ static inline unsigned long ffz_b(unsign

static inline unsigned long ffz(unsigned long word)
{
-#if defined(__alpha_cix__) && defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
/* Whee. EV67 can calculate it directly. */
return __kernel_cttz(~word);
#else
@@ -281,7 +281,7 @@ static inline unsigned long ffz(unsigned
*/
static inline unsigned long __ffs(unsigned long word)
{
-#if defined(__alpha_cix__) && defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
/* Whee. EV67 can calculate it directly. */
return __kernel_cttz(word);
#else
@@ -313,7 +313,7 @@ static inline int ffs(int word)
/*
* fls: find last bit set.
*/
-#if defined(__alpha_cix__) && defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
static inline int fls(int word)
{
return 64 - __kernel_ctlz(word & 0xffffffff);
@@ -326,7 +326,7 @@ static inline int fls(int word)
/* Compute powers of two for the given integer. */
static inline long floor_log2(unsigned long word)
{
-#if defined(__alpha_cix__) && defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
return 63 - __kernel_ctlz(word);
#else
long bit;
@@ -347,7 +347,7 @@ static inline long ceil_log2(unsigned lo
* of bits set) of a N-bit word
*/

-#if defined(__alpha_cix__) && defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67)
/* Whee. EV67 can calculate it directly. */
static inline unsigned long hweight64(unsigned long w)
{
Index: 2.6-git/include/asm-alpha/fpu.h
===================================================================
--- 2.6-git.orig/include/asm-alpha/fpu.h
+++ 2.6-git/include/asm-alpha/fpu.h
@@ -130,7 +130,7 @@ rdfpcr(void)
{
unsigned long tmp, ret;

-#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
__asm__ __volatile__ (
"ftoit $f0,%0\n\t"
"mf_fpcr $f0\n\t"
@@ -154,7 +154,7 @@ wrfpcr(unsigned long val)
{
unsigned long tmp;

-#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#if defined(CONFIG_ALPHA_EV6) || defined(CONFIG_ALPHA_EV67)
__asm__ __volatile__ (
"ftoit $f0,%0\n\t"
"itoft %1,$f0\n\t"

2006-02-09 19:12:55

by Richard Henderson

[permalink] [raw]
Subject: Re: [PATCH] alpha: remove __alpha_cix__ and __alpha_fix__

On Thu, Feb 09, 2006 at 02:55:31PM +0900, Akinobu Mita wrote:
> -#if defined(__alpha_fix__) && defined(__alpha_cix__)
> +#ifdef CONFIG_ALPHA_EV67

What in the world is this supposed to fix? You aren't seriously
suggesting that the compiler has stopped defining these, have you?


r~

2006-02-10 05:40:51

by Akinobu Mita

[permalink] [raw]
Subject: Re: [PATCH] alpha: remove __alpha_cix__ and __alpha_fix__

On Thu, Feb 09, 2006 at 11:12:36AM -0800, Richard Henderson wrote:
> On Thu, Feb 09, 2006 at 02:55:31PM +0900, Akinobu Mita wrote:
> > -#if defined(__alpha_fix__) && defined(__alpha_cix__)
> > +#ifdef CONFIG_ALPHA_EV67
>
> What in the world is this supposed to fix? You aren't seriously
> suggesting that the compiler has stopped defining these, have you?

I just want to imply the use of optimized hweight*() routines to
kbuild system. In other word I want to tell the kbuild system
the condition of "defined(__alpha_fix__) && defined(__alpha_cix__)".

So I suggested to add previous patch and write below lines in
arch/alpha/Kconfig

config GENERIC_HWEIGHT
bool
default y if !ALPHA_EV6 && !ALPHA_EV67

Also, I wonder why there are such gcc builtin definition in kernel code.
Even if the gcc built with the support architecture extensions like CIX
and FIX, It doesn't mean the vmlinux built by that gcc always run
on those machines.