2016-03-24 03:05:01

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 01/31] bitops: add parity functions

From: Zeng Zhaoxiu <[email protected]>

When I do "grep parity -r linux", I found many parity calculations distributed in many drivers.
These patches provide generic and architecture-specific parity calculations.

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
include/asm-generic/bitops.h | 1 +
include/asm-generic/bitops/arch_parity.h | 39 +++++++++++++++++++++++++++++++
include/asm-generic/bitops/const_parity.h | 36 ++++++++++++++++++++++++++++
include/asm-generic/bitops/parity.h | 7 ++++++
include/linux/bitops.h | 5 ++++
5 files changed, 88 insertions(+)
create mode 100644 include/asm-generic/bitops/arch_parity.h
create mode 100644 include/asm-generic/bitops/const_parity.h
create mode 100644 include/asm-generic/bitops/parity.h

diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h
index dcdcacf..d85722f 100644
--- a/include/asm-generic/bitops.h
+++ b/include/asm-generic/bitops.h
@@ -27,6 +27,7 @@
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/atomic.h>
diff --git a/include/asm-generic/bitops/arch_parity.h b/include/asm-generic/bitops/arch_parity.h
new file mode 100644
index 0000000..8d51eb3
--- /dev/null
+++ b/include/asm-generic/bitops/arch_parity.h
@@ -0,0 +1,39 @@
+#ifndef _ASM_GENERIC_BITOPS_ARCH_PARITY_H_
+#define _ASM_GENERIC_BITOPS_ARCH_PARITY_H_
+
+#include <asm/types.h>
+
+/*
+ * Refrence to 'https://graphics.stanford.edu/~seander/bithacks.html#ParityParallel'.
+ */
+
+static inline unsigned int __arch_parity4(unsigned int w)
+{
+ w &= 0xf;
+ return (0x6996 >> w) & 1;
+}
+
+static inline unsigned int __arch_parity8(unsigned int w)
+{
+ w ^= w >> 4;
+ return __arch_parity4(w);
+}
+
+static inline unsigned int __arch_parity16(unsigned int w)
+{
+ w ^= w >> 8;
+ return __arch_parity8(w);
+}
+
+static inline unsigned int __arch_parity32(unsigned int w)
+{
+ w ^= w >> 16;
+ return __arch_parity16(w);
+}
+
+static inline unsigned int __arch_parity64(__u64 w)
+{
+ return __arch_parity32((unsigned int)(w >> 32) ^ (unsigned int)w);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_ARCH_PARITY_H_ */
diff --git a/include/asm-generic/bitops/const_parity.h b/include/asm-generic/bitops/const_parity.h
new file mode 100644
index 0000000..9590315
--- /dev/null
+++ b/include/asm-generic/bitops/const_parity.h
@@ -0,0 +1,36 @@
+#ifndef _ASM_GENERIC_BITOPS_CONST_PARITY_H_
+#define _ASM_GENERIC_BITOPS_CONST_PARITY_H_
+
+/*
+ * Compile time versions of __arch_parityN()
+ */
+#define __const_parity4(w) ((0x6996 >> ((w) & 0xf)) & 1)
+#define __const_parity8(w) (__const_parity4(w ^ (w >> 4)))
+#define __const_parity16(w) (__const_parity8(w ^ (w >> 8)))
+#define __const_parity32(w) (__const_parity16(w ^ (w >> 16)))
+#define __const_parity64(w) (__const_parity32(w ^ (w >> 32)))
+
+/*
+ * Generic interface.
+ */
+#define parity4(w) (__builtin_constant_p(w) ? __const_parity4(w) : __arch_parity4(w))
+#define parity8(w) (__builtin_constant_p(w) ? __const_parity8(w) : __arch_parity8(w))
+#define parity16(w) (__builtin_constant_p(w) ? __const_parity16(w) : __arch_parity16(w))
+#define parity32(w) (__builtin_constant_p(w) ? __const_parity32(w) : __arch_parity32(w))
+#define parity64(w) (__builtin_constant_p(w) ? __const_parity64(w) : __arch_parity64(w))
+
+/*
+ * Interface for known constant arguments
+ */
+#define PARITY4(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity4(w))
+#define PARITY8(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity8(w))
+#define PARITY16(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity16(w))
+#define PARITY32(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity32(w))
+#define PARITY64(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity64(w))
+
+/*
+ * Type invariant interface to the compile time constant parity functions.
+ */
+#define PARITY(w) PARITY64((u64)w)
+
+#endif /* _ASM_GENERIC_BITOPS_CONST_PARITY_H_ */
diff --git a/include/asm-generic/bitops/parity.h b/include/asm-generic/bitops/parity.h
new file mode 100644
index 0000000..a91dce7
--- /dev/null
+++ b/include/asm-generic/bitops/parity.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_GENERIC_BITOPS_PARITY_H_
+#define _ASM_GENERIC_BITOPS_PARITY_H_
+
+#include <asm-generic/bitops/arch_parity.h>
+#include <asm-generic/bitops/const_parity.h>
+
+#endif /* _ASM_GENERIC_BITOPS_PARITY_H_ */
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index defeaac..f91cb44 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -80,6 +80,11 @@ static __always_inline unsigned long hweight_long(unsigned long w)
return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
}

+static __always_inline unsigned int parity_long(unsigned long w)
+{
+ return sizeof(w) == 4 ? parity32(w) : parity64(w);
+}
+
/**
* rol64 - rotate a 64-bit value left
* @word: value to rotate
--
2.5.0


2016-03-24 08:38:27

by Denys Vlasenko

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

On 03/24/2016 04:03 AM, Zhaoxiu Zeng wrote:
> +/*
> + * Type invariant interface to the compile time constant parity functions.
> + */
> +#define PARITY(w) PARITY64((u64)w)

Can result in incorrect expansion of w. Should be PARITY64((u64)(w))

2016-03-24 22:28:18

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

On Thu, 24 Mar 2016 09:38:21 +0100 Denys Vlasenko <[email protected]> wrote:

> On 03/24/2016 04:03 AM, Zhaoxiu Zeng wrote:
> > +/*
> > + * Type invariant interface to the compile time constant parity functions.
> > + */
> > +#define PARITY(w) PARITY64((u64)w)
>
> Can result in incorrect expansion of w. Should be PARITY64((u64)(w))

And we seem to be missing the other 30 patches.

2016-03-26 22:08:31

by Martin Kepplinger

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

We do.

Am 24. März 2016 23:28:15 MEZ, schrieb Andrew Morton <[email protected]>:
>On Thu, 24 Mar 2016 09:38:21 +0100 Denys Vlasenko <[email protected]>
>wrote:
>
>> On 03/24/2016 04:03 AM, Zhaoxiu Zeng wrote:
>> > +/*
>> > + * Type invariant interface to the compile time constant parity
>functions.
>> > + */
>> > +#define PARITY(w) PARITY64((u64)w)
>>
>> Can result in incorrect expansion of w. Should be PARITY64((u64)(w))
>
>And we seem to be missing the other 30 patches.

--
Martin Kepplinger
http://martinkepplinger.com
sent from mobile

2016-03-27 03:34:32

by Zhaoxiu Zeng

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

On 2016/3/24 16:38, Denys Vlasenko wrote:
> On 03/24/2016 04:03 AM, Zhaoxiu Zeng wrote:
>> +/*
>> + * Type invariant interface to the compile time constant parity functions.
>> + */
>> +#define PARITY(w) PARITY64((u64)w)
>
> Can result in incorrect expansion of w. Should be PARITY64((u64)(w))
>
> .
>
Thanks. The new version has been fixed.


Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
include/asm-generic/bitops.h | 1 +
include/asm-generic/bitops/arch_parity.h | 39 +++++++++++++++++++++++++++++++
include/asm-generic/bitops/const_parity.h | 36 ++++++++++++++++++++++++++++
include/asm-generic/bitops/parity.h | 7 ++++++
include/linux/bitops.h | 5 ++++
5 files changed, 88 insertions(+)
create mode 100644 include/asm-generic/bitops/arch_parity.h
create mode 100644 include/asm-generic/bitops/const_parity.h
create mode 100644 include/asm-generic/bitops/parity.h

diff --git a/include/asm-generic/bitops.h b/include/asm-generic/bitops.h
index dcdcacf..d85722f 100644
--- a/include/asm-generic/bitops.h
+++ b/include/asm-generic/bitops.h
@@ -27,6 +27,7 @@
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/atomic.h>
diff --git a/include/asm-generic/bitops/arch_parity.h b/include/asm-generic/bitops/arch_parity.h
new file mode 100644
index 0000000..cddc555
--- /dev/null
+++ b/include/asm-generic/bitops/arch_parity.h
@@ -0,0 +1,39 @@
+#ifndef _ASM_GENERIC_BITOPS_ARCH_PARITY_H_
+#define _ASM_GENERIC_BITOPS_ARCH_PARITY_H_
+
+#include <asm/types.h>
+
+/*
+ * Refrence to 'https://graphics.stanford.edu/~seander/bithacks.html#ParityParallel'.
+ */
+
+static inline unsigned int __arch_parity4(unsigned int w)
+{
+ w &= 0xf;
+ return (0x6996 >> w) & 1;
+}
+
+static inline unsigned int __arch_parity8(unsigned int w)
+{
+ w ^= w >> 4;
+ return __arch_parity4(w);
+}
+
+static inline unsigned int __arch_parity16(unsigned int w)
+{
+ w ^= w >> 8;
+ return __arch_parity8(w);
+}
+
+static inline unsigned int __arch_parity32(unsigned int w)
+{
+ w ^= w >> 16;
+ return __arch_parity16(w);
+}
+
+static inline unsigned int __arch_parity64(__u64 w)
+{
+ return __arch_parity32((unsigned int)(w >> 32) ^ (unsigned int)w);
+}
+
+#endif /* _ASM_GENERIC_BITOPS_ARCH_PARITY_H_ */
diff --git a/include/asm-generic/bitops/const_parity.h b/include/asm-generic/bitops/const_parity.h
new file mode 100644
index 0000000..6af7987
--- /dev/null
+++ b/include/asm-generic/bitops/const_parity.h
@@ -0,0 +1,36 @@
+#ifndef _ASM_GENERIC_BITOPS_CONST_PARITY_H_
+#define _ASM_GENERIC_BITOPS_CONST_PARITY_H_
+
+/*
+ * Compile time versions of __arch_parityN()
+ */
+#define __const_parity4(w) ((0x6996 >> ((w) & 0xf)) & 1)
+#define __const_parity8(w) (__const_parity4((w) ^ ((w) >> 4)))
+#define __const_parity16(w) (__const_parity8((w) ^ ((w) >> 8)))
+#define __const_parity32(w) (__const_parity16((w) ^ ((w) >> 16)))
+#define __const_parity64(w) (__const_parity32((w) ^ ((w) >> 32)))
+
+/*
+ * Generic interface.
+ */
+#define parity4(w) (__builtin_constant_p(w) ? __const_parity4(w) : __arch_parity4(w))
+#define parity8(w) (__builtin_constant_p(w) ? __const_parity8(w) : __arch_parity8(w))
+#define parity16(w) (__builtin_constant_p(w) ? __const_parity16(w) : __arch_parity16(w))
+#define parity32(w) (__builtin_constant_p(w) ? __const_parity32(w) : __arch_parity32(w))
+#define parity64(w) (__builtin_constant_p(w) ? __const_parity64(w) : __arch_parity64(w))
+
+/*
+ * Interface for known constant arguments
+ */
+#define PARITY4(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity4(w))
+#define PARITY8(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity8(w))
+#define PARITY16(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity16(w))
+#define PARITY32(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity32(w))
+#define PARITY64(w) (BUILD_BUG_ON_ZERO(!__builtin_constant_p(w)) + __const_parity64(w))
+
+/*
+ * Type invariant interface to the compile time constant parity functions.
+ */
+#define PARITY(w) PARITY64((u64)(w))
+
+#endif /* _ASM_GENERIC_BITOPS_CONST_PARITY_H_ */
diff --git a/include/asm-generic/bitops/parity.h b/include/asm-generic/bitops/parity.h
new file mode 100644
index 0000000..a91dce7
--- /dev/null
+++ b/include/asm-generic/bitops/parity.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_GENERIC_BITOPS_PARITY_H_
+#define _ASM_GENERIC_BITOPS_PARITY_H_
+
+#include <asm-generic/bitops/arch_parity.h>
+#include <asm-generic/bitops/const_parity.h>
+
+#endif /* _ASM_GENERIC_BITOPS_PARITY_H_ */
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index defeaac..8952f88 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -80,6 +80,11 @@ static __always_inline unsigned long hweight_long(unsigned long w)
return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
}

+static __always_inline unsigned int parity_long(unsigned long w)
+{
+ return sizeof(w) == 4 ? parity32(w) : parity64(w);
+}
+
/**
* rol64 - rotate a 64-bit value left
* @word: value to rotate
--
2.5.5

2016-03-27 04:04:03

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 02/31] Include generic parity.h in some architectures' bitops.h

From: Zeng Zhaoxiu <[email protected]>

Use the generic version.

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/arc/include/asm/bitops.h | 1 +
arch/arm/include/asm/bitops.h | 1 +
arch/arm64/include/asm/bitops.h | 1 +
arch/c6x/include/asm/bitops.h | 1 +
arch/cris/include/asm/bitops.h | 1 +
arch/frv/include/asm/bitops.h | 1 +
arch/h8300/include/asm/bitops.h | 1 +
arch/hexagon/include/asm/bitops.h | 1 +
arch/m32r/include/asm/bitops.h | 1 +
arch/m68k/include/asm/bitops.h | 1 +
arch/metag/include/asm/bitops.h | 1 +
arch/mn10300/include/asm/bitops.h | 1 +
arch/openrisc/include/asm/bitops.h | 1 +
arch/parisc/include/asm/bitops.h | 1 +
arch/s390/include/asm/bitops.h | 1 +
arch/sh/include/asm/bitops.h | 1 +
arch/xtensa/include/asm/bitops.h | 1 +
17 files changed, 17 insertions(+)

diff --git a/arch/arc/include/asm/bitops.h b/arch/arc/include/asm/bitops.h
index 0352fb8..7967e47 100644
--- a/arch/arc/include/asm/bitops.h
+++ b/arch/arc/include/asm/bitops.h
@@ -370,6 +370,7 @@ static inline __attribute__ ((const)) int __ffs(unsigned long x)
#define ffz(x) __ffs(~(x))

#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/lock.h>
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index e943e6c..99f28a6 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -313,6 +313,7 @@ static inline unsigned long __ffs(unsigned long x)

#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>

#ifdef __ARMEB__
diff --git a/arch/arm64/include/asm/bitops.h b/arch/arm64/include/asm/bitops.h
index 9c19594..eac4965 100644
--- a/arch/arm64/include/asm/bitops.h
+++ b/arch/arm64/include/asm/bitops.h
@@ -44,6 +44,7 @@ extern int test_and_change_bit(int nr, volatile unsigned long *p);

#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/non-atomic.h>
diff --git a/arch/c6x/include/asm/bitops.h b/arch/c6x/include/asm/bitops.h
index f0ab012..94eb0d1 100644
--- a/arch/c6x/include/asm/bitops.h
+++ b/arch/c6x/include/asm/bitops.h
@@ -87,6 +87,7 @@ static inline int ffs(int x)

#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/atomic.h>
diff --git a/arch/cris/include/asm/bitops.h b/arch/cris/include/asm/bitops.h
index 8062cb5..06bc246 100644
--- a/arch/cris/include/asm/bitops.h
+++ b/arch/cris/include/asm/bitops.h
@@ -36,6 +36,7 @@
#include <asm-generic/bitops/__fls.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/lock.h>

diff --git a/arch/frv/include/asm/bitops.h b/arch/frv/include/asm/bitops.h
index 0df8e95..f2a7ee8 100644
--- a/arch/frv/include/asm/bitops.h
+++ b/arch/frv/include/asm/bitops.h
@@ -314,6 +314,7 @@ int __ilog2_u64(u64 n)

#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/le.h>
diff --git a/arch/h8300/include/asm/bitops.h b/arch/h8300/include/asm/bitops.h
index 05999ab..e392db2 100644
--- a/arch/h8300/include/asm/bitops.h
+++ b/arch/h8300/include/asm/bitops.h
@@ -172,6 +172,7 @@ static inline unsigned long __ffs(unsigned long word)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic.h>
diff --git a/arch/hexagon/include/asm/bitops.h b/arch/hexagon/include/asm/bitops.h
index 5e4a59b..2df614e 100644
--- a/arch/hexagon/include/asm/bitops.h
+++ b/arch/hexagon/include/asm/bitops.h
@@ -290,6 +290,7 @@ static inline unsigned long __fls(unsigned long word)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>

#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic.h>
diff --git a/arch/m32r/include/asm/bitops.h b/arch/m32r/include/asm/bitops.h
index 86ba2b4..e3cf46b 100644
--- a/arch/m32r/include/asm/bitops.h
+++ b/arch/m32r/include/asm/bitops.h
@@ -259,6 +259,7 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>

#endif /* __KERNEL__ */
diff --git a/arch/m68k/include/asm/bitops.h b/arch/m68k/include/asm/bitops.h
index b4a9b0d..fd673ea 100644
--- a/arch/m68k/include/asm/bitops.h
+++ b/arch/m68k/include/asm/bitops.h
@@ -519,6 +519,7 @@ static inline int __fls(int x)
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>
#endif /* __KERNEL__ */

diff --git a/arch/metag/include/asm/bitops.h b/arch/metag/include/asm/bitops.h
index 2671134..ad13087 100644
--- a/arch/metag/include/asm/bitops.h
+++ b/arch/metag/include/asm/bitops.h
@@ -118,6 +118,7 @@ static inline int test_and_change_bit(unsigned int bit,
#include <asm-generic/bitops/__fls.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/le.h>
diff --git a/arch/mn10300/include/asm/bitops.h b/arch/mn10300/include/asm/bitops.h
index fe6f8e2..60761b7 100644
--- a/arch/mn10300/include/asm/bitops.h
+++ b/arch/mn10300/include/asm/bitops.h
@@ -225,6 +225,7 @@ int ffs(int x)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/ext2-atomic-setbit.h>
#include <asm-generic/bitops/le.h>

diff --git a/arch/openrisc/include/asm/bitops.h b/arch/openrisc/include/asm/bitops.h
index 3003cda..8c97642 100644
--- a/arch/openrisc/include/asm/bitops.h
+++ b/arch/openrisc/include/asm/bitops.h
@@ -43,6 +43,7 @@
#include <asm-generic/bitops/sched.h>
#include <asm/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/atomic.h>
diff --git a/arch/parisc/include/asm/bitops.h b/arch/parisc/include/asm/bitops.h
index 3f9406d..867ba10 100644
--- a/arch/parisc/include/asm/bitops.h
+++ b/arch/parisc/include/asm/bitops.h
@@ -211,6 +211,7 @@ static __inline__ int fls(int x)
#include <asm-generic/bitops/__fls.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>

diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h
index 8043f10..198eead 100644
--- a/arch/s390/include/asm/bitops.h
+++ b/arch/s390/include/asm/bitops.h
@@ -460,6 +460,7 @@ static inline int fls(int word)
#include <asm-generic/bitops/ffz.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic-setbit.h>
diff --git a/arch/sh/include/asm/bitops.h b/arch/sh/include/asm/bitops.h
index fc8e652..4bf0c35 100644
--- a/arch/sh/include/asm/bitops.h
+++ b/arch/sh/include/asm/bitops.h
@@ -86,6 +86,7 @@ static inline unsigned long ffz(unsigned long word)
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/le.h>
diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h
index 3f44fa2..981fa83 100644
--- a/arch/xtensa/include/asm/bitops.h
+++ b/arch/xtensa/include/asm/bitops.h
@@ -229,6 +229,7 @@ test_and_change_bit(unsigned int bit, volatile unsigned long *p)
#include <asm-generic/bitops/ext2-atomic-setbit.h>

#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/sched.h>

--
2.5.5

2016-03-27 05:44:01

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 03/31] Add alpha-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/alpha/include/asm/bitops.h | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

diff --git a/arch/alpha/include/asm/bitops.h b/arch/alpha/include/asm/bitops.h
index 4bdfbd4..95a43fa 100644
--- a/arch/alpha/include/asm/bitops.h
+++ b/arch/alpha/include/asm/bitops.h
@@ -421,11 +421,38 @@ static inline unsigned int __arch_hweight8(unsigned int w)
{
return __arch_hweight64(w & 0xff);
}
+
+static inline unsigned int __arch_parity64(unsigned long w)
+{
+ return (unsigned int)__kernel_ctpop(w) & 1;
+}
+
+static inline unsigned int __arch_parity32(unsigned int w)
+{
+ return __arch_parity64(w);
+}
+
+static inline unsigned int __arch_parity16(unsigned int w)
+{
+ return __arch_parity64(w & 0xffff);
+}
+
+static inline unsigned int __arch_parity8(unsigned int w)
+{
+ return __arch_parity64(w & 0xff);
+}
+
+static inline unsigned int __arch_parity4(unsigned int w)
+{
+ return __arch_parity64(w & 0xf);
+}
#else
#include <asm-generic/bitops/arch_hweight.h>
+#include <asm-generic/bitops/arch_parity.h>
#endif

#include <asm-generic/bitops/const_hweight.h>
+#include <asm-generic/bitops/const_parity.h>

#endif /* __KERNEL__ */

--
2.5.5

2016-03-27 05:47:30

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 04/31] Add avr32-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/avr32/include/asm/bitops.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)

diff --git a/arch/avr32/include/asm/bitops.h b/arch/avr32/include/asm/bitops.h
index 910d537..80d7005 100644
--- a/arch/avr32/include/asm/bitops.h
+++ b/arch/avr32/include/asm/bitops.h
@@ -300,6 +300,38 @@ static inline int ffs(unsigned long word)
#include <asm-generic/bitops/hweight.h>
#include <asm-generic/bitops/lock.h>

+static inline unsigned int __arch_parity4(unsigned int w)
+{
+ w ^= w >> 2;
+ w ^= w >> 1;
+ return w & 1;
+}
+
+static inline unsigned int __arch_parity8(unsigned int w)
+{
+ w ^= w >> 4;
+ return __arch_parity4(w);
+}
+
+static inline unsigned int __arch_parity16(unsigned int w)
+{
+ w ^= w >> 8;
+ return __arch_parity8(w);
+}
+
+static inline unsigned int __arch_parity32(unsigned int w)
+{
+ w ^= w >> 16;
+ return __arch_parity16(w);
+}
+
+static inline unsigned int __arch_parity64(__u64 w)
+{
+ return __arch_parity32((unsigned int)(w >> 32) ^ (unsigned int)w);
+}
+
+#include <asm-generic/bitops/const_parity.h>
+
extern unsigned long find_next_zero_bit_le(const void *addr,
unsigned long size, unsigned long offset);
#define find_next_zero_bit_le find_next_zero_bit_le
--
2.5.5

2016-03-27 05:54:16

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 05/31] Add blackfin-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/blackfin/include/asm/bitops.h | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)

diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h
index b298b65..81b078a 100644
--- a/arch/blackfin/include/asm/bitops.h
+++ b/arch/blackfin/include/asm/bitops.h
@@ -23,6 +23,7 @@
#include <asm-generic/bitops/sched.h>
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/const_hweight.h>
+#include <asm-generic/bitops/const_parity.h>
#include <asm-generic/bitops/lock.h>

#include <asm-generic/bitops/ext2-atomic.h>
@@ -137,4 +138,34 @@ static inline unsigned int __arch_hweight8(unsigned int w)
return __arch_hweight32(w & 0xff);
}

+/*
+ * parityN: returns the parity of a N-bit word,
+ * i.e. the number of 1-bits in x modulo 2.
+ */
+
+static inline unsigned int __arch_parity32(unsigned int w)
+{
+ return __arch_hweight32(w) & 1;
+}
+
+static inline unsigned int __arch_parity64(__u64 w)
+{
+ return __arch_parity32((unsigned int)(w >> 32) ^ (unsigned int)w);
+}
+
+static inline unsigned int __arch_parity16(unsigned int w)
+{
+ return __arch_parity32(w & 0xffff);
+}
+
+static inline unsigned int __arch_parity8(unsigned int w)
+{
+ return __arch_parity32(w & 0xff);
+}
+
+static inline unsigned int __arch_parity4(unsigned int w)
+{
+ return __arch_parity32(w & 0xf);
+}
+
#endif /* _BLACKFIN_BITOPS_H */
--
2.5.5

2016-03-27 06:00:36

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 06/31] Add ia64-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/ia64/include/asm/bitops.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)

diff --git a/arch/ia64/include/asm/bitops.h b/arch/ia64/include/asm/bitops.h
index 71e8145..de13d89 100644
--- a/arch/ia64/include/asm/bitops.h
+++ b/arch/ia64/include/asm/bitops.h
@@ -439,6 +439,22 @@ static __inline__ unsigned long __arch_hweight64(unsigned long x)

#include <asm-generic/bitops/const_hweight.h>

+/*
+ * parityN: returns the parity of a N-bit word,
+ * i.e. the number of 1-bits in x modulo 2.
+ */
+static __inline__ unsigned int __arch_parity64(unsigned long x)
+{
+ return (unsigned int)ia64_popcnt(x) & 1;
+}
+
+#define __arch_parity32(x) ((unsigned int) __arch_parity64((x) & 0xfffffffful))
+#define __arch_parity16(x) ((unsigned int) __arch_parity64((x) & 0xfffful))
+#define __arch_parity8(x) ((unsigned int) __arch_parity64((x) & 0xfful))
+#define __arch_parity4(x) ((unsigned int) __arch_parity64((x) & 0xful))
+
+#include <asm-generic/bitops/const_parity.h>
+
#endif /* __KERNEL__ */

#include <asm-generic/bitops/find.h>
--
2.5.5

2016-03-27 06:06:53

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 07/31] Add mips-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/mips/include/asm/arch_parity.h | 44 +++++++++++++++++++++++++++++++++++++
arch/mips/include/asm/bitops.h | 3 +++
2 files changed, 47 insertions(+)
create mode 100644 arch/mips/include/asm/arch_parity.h

diff --git a/arch/mips/include/asm/arch_parity.h b/arch/mips/include/asm/arch_parity.h
new file mode 100644
index 0000000..23b3c23
--- /dev/null
+++ b/arch/mips/include/asm/arch_parity.h
@@ -0,0 +1,44 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef _ASM_ARCH_PARITY_H
+#define _ASM_ARCH_PARITY_H
+
+#ifdef ARCH_HAS_USABLE_BUILTIN_POPCOUNT
+
+#include <asm/types.h>
+
+static inline unsigned int __arch_parity32(unsigned int w)
+{
+ return __builtin_popcount(w) & 1;
+}
+
+static inline unsigned int __arch_parity16(unsigned int w)
+{
+ return __arch_parity32(w & 0xffff);
+}
+
+static inline unsigned int __arch_parity8(unsigned int w)
+{
+ return __arch_parity32(w & 0xff);
+}
+
+static inline unsigned int __arch_parity4(unsigned int w)
+{
+ return __arch_parity32(w & 0xf);
+}
+
+static inline unsigned int __arch_parity64(__u64 w)
+{
+ return (unsigned int)__builtin_popcountll(w) & 1;
+}
+
+#else
+#include <asm-generic/bitops/arch_hweight.h>
+#include <asm-generic/bitops/arch_parity.h>
+#endif
+
+#endif /* _ASM_ARCH_PARITY_H */
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index ce9666c..0b87734 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -626,6 +626,9 @@ static inline int ffs(int word)
#include <asm/arch_hweight.h>
#include <asm-generic/bitops/const_hweight.h>

+#include <asm/arch_parity.h>
+#include <asm-generic/bitops/const_parity.h>
+
#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic.h>

--
2.5.5

2016-03-27 06:11:21

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 08/31] Add tile-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/tile/include/asm/bitops.h | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)

diff --git a/arch/tile/include/asm/bitops.h b/arch/tile/include/asm/bitops.h
index 20caa34..370d007 100644
--- a/arch/tile/include/asm/bitops.h
+++ b/arch/tile/include/asm/bitops.h
@@ -81,10 +81,36 @@ static inline unsigned long __arch_hweight64(__u64 w)
return __builtin_popcountll(w);
}

+static inline unsigned int __arch_parity32(unsigned int w)
+{
+ return __builtin_popcount(w) & 1;
+}
+
+static inline unsigned int __arch_parity16(unsigned int w)
+{
+ return __arch_parity32(w & 0xffff);
+}
+
+static inline unsigned int __arch_parity8(unsigned int w)
+{
+ return __arch_parity32(w & 0xff);
+}
+
+static inline unsigned int __arch_parity4(unsigned int w)
+{
+ return __arch_parity32(w & 0xf);
+}
+
+static inline unsigned int __arch_parity64(__u64 w)
+{
+ return (unsigned int)__builtin_popcountll(w) & 1;
+}
+
#include <asm-generic/bitops/builtin-__ffs.h>
#include <asm-generic/bitops/builtin-__fls.h>
#include <asm-generic/bitops/builtin-ffs.h>
#include <asm-generic/bitops/const_hweight.h>
+#include <asm-generic/bitops/const_parity.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/sched.h>
--
2.5.5

2016-03-27 06:38:30

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 09/31] Add powerpc-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/powerpc/include/asm/bitops.h | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h
index 59abc62..90ee0f2 100644
--- a/arch/powerpc/include/asm/bitops.h
+++ b/arch/powerpc/include/asm/bitops.h
@@ -269,8 +269,15 @@ unsigned int __arch_hweight16(unsigned int w);
unsigned int __arch_hweight32(unsigned int w);
unsigned long __arch_hweight64(__u64 w);
#include <asm-generic/bitops/const_hweight.h>
+#define __arch_parity4(w) (__arch_hweight8((w) & 0xf) & 1)
+#define __arch_parity8(w) (__arch_hweight8(w) & 1)
+#define __arch_parity16(w) (__arch_hweight16(w) & 1)
+#define __arch_parity32(w) (__arch_hweight32(w) & 1)
+#define __arch_parity64(w) ((unsigned int)__arch_hweight64(w) & 1)
+#include <asm-generic/bitops/const_parity.h>
#else
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#endif

#include <asm-generic/bitops/find.h>
--
2.5.5

2016-03-27 06:43:54

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 10/31] Add sparc-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/sparc/include/asm/bitops_32.h | 1 +
arch/sparc/include/asm/bitops_64.h | 13 +++++++++++++
2 files changed, 14 insertions(+)

diff --git a/arch/sparc/include/asm/bitops_32.h b/arch/sparc/include/asm/bitops_32.h
index 600ed1d..8c41896 100644
--- a/arch/sparc/include/asm/bitops_32.h
+++ b/arch/sparc/include/asm/bitops_32.h
@@ -98,6 +98,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
#include <asm-generic/bitops/__fls.h>
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/parity.h>
#include <asm-generic/bitops/lock.h>
#include <asm-generic/bitops/find.h>
#include <asm-generic/bitops/le.h>
diff --git a/arch/sparc/include/asm/bitops_64.h b/arch/sparc/include/asm/bitops_64.h
index 2d52240..4d3dcb3 100644
--- a/arch/sparc/include/asm/bitops_64.h
+++ b/arch/sparc/include/asm/bitops_64.h
@@ -47,6 +47,19 @@ unsigned int __arch_hweight16(unsigned int w);
unsigned int __arch_hweight8(unsigned int w);

#include <asm-generic/bitops/const_hweight.h>
+
+/*
+ * parityN: returns the parity of a N-bit word,
+ * i.e. the number of 1-bits in x modulo 2.
+ */
+
+#define __arch_parity4(w) (__arch_hweight8((w) & 0xf) & 1)
+#define __arch_parity8(w) (__arch_hweight8(w) & 1)
+#define __arch_parity16(w) (__arch_hweight16(w) & 1)
+#define __arch_parity32(w) (__arch_hweight32(w) & 1)
+#define __arch_parity64(w) ((unsigned int)__arch_hweight64(w) & 1)
+
+#include <asm-generic/bitops/const_hweight.h>
#include <asm-generic/bitops/lock.h>
#endif /* __KERNEL__ */

--
2.5.5

2016-03-27 06:46:26

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 11/31] Add x86-specific parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/x86/include/asm/bitops.h | 12 ++++++++++++
1 file changed, 12 insertions(+)

diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index 7766d1c..d3210c0 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -501,6 +501,18 @@ static __always_inline int fls64(__u64 x)

#include <asm-generic/bitops/const_hweight.h>

+#define __arch_parity32(x) (__arch_hweight32(x) & 1)
+#define __arch_parity4(x) (__arch_parity32((x) & 0xf))
+#define __arch_parity8(x) (__arch_parity32((x) & 0xff))
+#define __arch_parity16(x) (__arch_parity32((x) & 0xffff))
+#ifdef CONFIG_X86_32
+#define __arch_parity64(x) (__arch_parity32((unsigned int)((x) >> 32) ^ (unsigned int)(x)))
+#else
+#define __arch_parity64(x) (__arch_hweight64(x) & 1)
+#endif
+
+#include <asm-generic/bitops/const_parity.h>
+
#include <asm-generic/bitops/le.h>

#include <asm-generic/bitops/ext2-atomic-setbit.h>
--
2.5.5

2016-03-27 06:52:18

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 12/31] sunrpc: auth_gss: use parity8

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
net/sunrpc/auth_gss/gss_krb5_keys.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/net/sunrpc/auth_gss/gss_krb5_keys.c b/net/sunrpc/auth_gss/gss_krb5_keys.c
index 8701331..c41b389 100644
--- a/net/sunrpc/auth_gss/gss_krb5_keys.c
+++ b/net/sunrpc/auth_gss/gss_krb5_keys.c
@@ -243,16 +243,12 @@ err_return:
return ret;
}

-#define smask(step) ((1<<step)-1)
-#define pstep(x, step) (((x)&smask(step))^(((x)>>step)&smask(step)))
-#define parity_char(x) pstep(pstep(pstep((x), 4), 2), 1)
-
static void mit_des_fixup_key_parity(u8 key[8])
{
int i;
for (i = 0; i < 8; i++) {
key[i] &= 0xfe;
- key[i] |= 1^parity_char(key[i]);
+ key[i] |= !parity8(key[i]);
}
}

--
2.5.5

2016-03-27 06:56:31

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 13/31] mips: use parity functions in cerr-sb1.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
arch/mips/mm/cerr-sb1.c | 67 +++++++++++++------------------------------------
1 file changed, 17 insertions(+), 50 deletions(-)

diff --git a/arch/mips/mm/cerr-sb1.c b/arch/mips/mm/cerr-sb1.c
index ee5c1ff..2e7d660 100644
--- a/arch/mips/mm/cerr-sb1.c
+++ b/arch/mips/mm/cerr-sb1.c
@@ -264,27 +264,6 @@ asmlinkage void sb1_cache_error(void)
#endif
}

-
-/* Parity lookup table. */
-static const uint8_t parity[256] = {
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
- 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
- 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
- 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
- 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
- 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
- 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
- 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
- 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
- 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
-};
-
/* Masks to select bits for Hamming parity, mask_72_64[i] for bit[i] */
static const uint64_t mask_72_64[8] = {
0x0738C808099264FFULL,
@@ -298,34 +277,28 @@ static const uint64_t mask_72_64[8] = {
};

/* Calculate the parity on a range of bits */
-static char range_parity(uint64_t dword, int max, int min)
+static inline char range_parity(uint64_t dword, int max, int min)
{
- char parity = 0;
- int i;
- dword >>= min;
- for (i=max-min; i>=0; i--) {
- if (dword & 0x1)
- parity = !parity;
- dword >>= 1;
+ int n = max - min + 1;
+ if (__builtin_constant_p(n)) {
+ if (n <= 8)
+ return parity8((unsigned int)(dword >> min) & ((1U << n) - 1));
+ if (n <= 16)
+ return parity16((unsigned int)(dword >> min) & ((1U << n) - 1));
+ if (n <= 32)
+ return parity32((unsigned int)(dword >> min) & ((1U << n) - 1));
}
- return parity;
+ return parity64((dword >> min) & ((1ULL << n) - 1));
}

/* Calculate the 4-bit even byte-parity for an instruction */
-static unsigned char inst_parity(uint32_t word)
+static inline unsigned char inst_parity(uint32_t word)
{
- int i, j;
- char parity = 0;
- for (j=0; j<4; j++) {
- char byte_parity = 0;
- for (i=0; i<8; i++) {
- if (word & 0x80000000)
- byte_parity = !byte_parity;
- word <<= 1;
- }
- parity <<= 1;
- parity |= byte_parity;
- }
+ char parity;
+ parity = parity8(word >> 24) << 3;
+ parity |= parity8(word >> 16) << 2;
+ parity |= parity8(word >> 8) << 1;
+ parity |= parity8(word);
return parity;
}

@@ -436,7 +409,6 @@ static uint32_t extract_ic(unsigned short addr, int data)
static uint8_t dc_ecc(uint64_t dword)
{
uint64_t t;
- uint32_t w;
uint8_t p;
int i;

@@ -445,12 +417,7 @@ static uint8_t dc_ecc(uint64_t dword)
{
p <<= 1;
t = dword & mask_72_64[i];
- w = (uint32_t)(t >> 32);
- p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
- ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
- w = (uint32_t)(t & 0xFFFFFFFF);
- p ^= (parity[w>>24] ^ parity[(w>>16) & 0xFF]
- ^ parity[(w>>8) & 0xFF] ^ parity[w & 0xFF]);
+ p |= parity64(t);
}
return p;
}
--
2.5.5

2016-03-27 07:02:19

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 14/31] lib: bch: use parity32

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
lib/bch.c | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/lib/bch.c b/lib/bch.c
index bc89dfe4..6c6e8d4 100644
--- a/lib/bch.c
+++ b/lib/bch.c
@@ -278,18 +278,6 @@ static inline int deg(unsigned int poly)
return fls(poly)-1;
}

-static inline int parity(unsigned int x)
-{
- /*
- * public domain code snippet, lifted from
- * http://www-graphics.stanford.edu/~seander/bithacks.html
- */
- x ^= x >> 1;
- x ^= x >> 2;
- x = (x & 0x11111111U) * 0x11111111U;
- return (x >> 28) & 1;
-}
-
/* Galois field basic operations: multiply, divide, inverse, etc. */

static inline unsigned int gf_mul(struct bch_control *bch, unsigned int a,
@@ -494,7 +482,7 @@ static int solve_linear_system(struct bch_control *bch, unsigned int *rows,
tmp = 0;
for (r = m-1; r >= 0; r--) {
mask = rows[r] & (tmp|1);
- tmp |= parity(mask) << (m-r);
+ tmp |= parity32(mask) << (m-r);
}
sol[p] = tmp >> 1;
}
--
2.5.5

2016-03-27 07:06:35

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 15/31] media: use parity8 in vivid-vbi-gen.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/media/platform/vivid/vivid-vbi-gen.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/vivid/vivid-vbi-gen.c b/drivers/media/platform/vivid/vivid-vbi-gen.c
index a2159de..d5ba0fc 100644
--- a/drivers/media/platform/vivid/vivid-vbi-gen.c
+++ b/drivers/media/platform/vivid/vivid-vbi-gen.c
@@ -175,14 +175,9 @@ static const u8 vivid_cc_sequence2[30] = {
0x14, 0x2f, /* End of Caption */
};

-static u8 calc_parity(u8 val)
+static inline u8 calc_parity(u8 val)
{
- unsigned i;
- unsigned tot = 0;
-
- for (i = 0; i < 7; i++)
- tot += (val & (1 << i)) ? 1 : 0;
- return val | ((tot & 1) ? 0 : 0x80);
+ return (!parity8(val) << 7) | val;
}

static void vivid_vbi_gen_set_time_of_day(u8 *packet)
--
2.5.5

2016-03-27 07:10:51

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 16/31] media: saa7115: use parity functions

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/media/i2c/saa7115.c | 17 ++---------------
1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/drivers/media/i2c/saa7115.c b/drivers/media/i2c/saa7115.c
index d2a1ce2..4c22df8 100644
--- a/drivers/media/i2c/saa7115.c
+++ b/drivers/media/i2c/saa7115.c
@@ -672,15 +672,6 @@ static const unsigned char saa7115_init_misc[] = {
0x00, 0x00
};

-static int saa711x_odd_parity(u8 c)
-{
- c ^= (c >> 4);
- c ^= (c >> 2);
- c ^= (c >> 1);
-
- return c & 1;
-}
-
static int saa711x_decode_vps(u8 *dst, u8 *p)
{
static const u8 biphase_tbl[] = {
@@ -733,7 +724,6 @@ static int saa711x_decode_wss(u8 *p)
static const int wss_bits[8] = {
0, 0, 0, 1, 0, 1, 1, 1
};
- unsigned char parity;
int wss = 0;
int i;

@@ -745,11 +735,8 @@ static int saa711x_decode_wss(u8 *p)
return -1;
wss |= b2 << i;
}
- parity = wss & 15;
- parity ^= parity >> 2;
- parity ^= parity >> 1;

- if (!(parity & 1))
+ if (!parity4(wss))
return -1;

return wss;
@@ -1235,7 +1222,7 @@ static int saa711x_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vb
vbi->type = V4L2_SLICED_TELETEXT_B;
break;
case 4:
- if (!saa711x_odd_parity(p[0]) || !saa711x_odd_parity(p[1]))
+ if (!parity8(p[0]) || !parity8(p[1]))
return 0;
vbi->type = V4L2_SLICED_CAPTION_525;
break;
--
2.5.5

2016-03-27 07:13:46

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 17/31] input: joystick: use parity32 in grip_mp.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/input/joystick/grip_mp.c | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)

diff --git a/drivers/input/joystick/grip_mp.c b/drivers/input/joystick/grip_mp.c
index 573191d..3e29eb1 100644
--- a/drivers/input/joystick/grip_mp.c
+++ b/drivers/input/joystick/grip_mp.c
@@ -112,20 +112,6 @@ static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5
static int register_slot(int i, struct grip_mp *grip);

/*
- * Returns whether an odd or even number of bits are on in pkt.
- */
-
-static int bit_parity(u32 pkt)
-{
- int x = pkt ^ (pkt >> 16);
- x ^= x >> 8;
- x ^= x >> 4;
- x ^= x >> 2;
- x ^= x >> 1;
- return x & 1;
-}
-
-/*
* Poll gameport; return true if all bits set in 'onbits' are on and
* all bits set in 'offbits' are off.
*/
@@ -235,7 +221,7 @@ static int mp_io(struct gameport* gameport, int sendflags, int sendcode, u32 *pa
pkt = (pkt >> 2) | 0xf0000000;
}

- if (bit_parity(pkt) == 1)
+ if (parity32(pkt))
return IO_RESET;

/* Acknowledge packet receipt */
--
2.5.5

2016-03-27 07:16:11

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 18/31] input: joystick: use parity64 in sidewinder.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/input/joystick/sidewinder.c | 24 ++++--------------------
1 file changed, 4 insertions(+), 20 deletions(-)

diff --git a/drivers/input/joystick/sidewinder.c b/drivers/input/joystick/sidewinder.c
index 4a95b22..7ea486e 100644
--- a/drivers/input/joystick/sidewinder.c
+++ b/drivers/input/joystick/sidewinder.c
@@ -259,22 +259,6 @@ static void sw_init_digital(struct gameport *gameport)
}

/*
- * sw_parity() computes parity of __u64
- */
-
-static int sw_parity(__u64 t)
-{
- int x = t ^ (t >> 32);
-
- x ^= x >> 16;
- x ^= x >> 8;
- x ^= x >> 4;
- x ^= x >> 2;
- x ^= x >> 1;
- return x & 1;
-}
-
-/*
* sw_ccheck() checks synchronization bits and computes checksum of nibbles.
*/

@@ -334,7 +318,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)

for (i = 0; i < sw->number; i ++) {

- if (sw_parity(GB(i*15,15)))
+ if (parity64(GB(i*15,15)))
return -1;

input_report_abs(sw->dev[i], ABS_X, GB(i*15+3,1) - GB(i*15+2,1));
@@ -351,7 +335,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)
case SW_ID_PP:
case SW_ID_FFP:

- if (!sw_parity(GB(0,48)) || (hat = GB(42,4)) > 8)
+ if (!parity64(GB(0,48)) || (hat = GB(42,4)) > 8)
return -1;

dev = sw->dev[0];
@@ -372,7 +356,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)

case SW_ID_FSP:

- if (!sw_parity(GB(0,43)) || (hat = GB(28,4)) > 8)
+ if (!parity64(GB(0,43)) || (hat = GB(28,4)) > 8)
return -1;

dev = sw->dev[0];
@@ -397,7 +381,7 @@ static int sw_parse(unsigned char *buf, struct sw *sw)

case SW_ID_FFW:

- if (!sw_parity(GB(0,33)))
+ if (!parity64(GB(0,33)))
return -1;

dev = sw->dev[0];
--
2.5.5

2016-03-27 07:18:56

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 19/31] input: serio: use parity16 in ams_delta_serio.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/input/serio/ams_delta_serio.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c
index 45887e3..85459b3 100644
--- a/drivers/input/serio/ams_delta_serio.c
+++ b/drivers/input/serio/ams_delta_serio.c
@@ -48,13 +48,9 @@ static int check_data(int data)
data);
return SERIO_FRAME;
}
- /* calculate the parity */
- for (i = 1; i < 10; i++) {
- if (data & (1 << i))
- parity++;
- }
/* it should be odd */
- if (!(parity & 0x01)) {
+ parity = parity16(data & 0x3fe);
+ if (!parity) {
dev_warn(&ams_delta_serio->dev,
"paritiy check failed, data=0x%X parity=0x%X\n",
data, parity);
--
2.5.5

2016-03-27 07:21:31

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 20/31] scsi: use parity32 in isci/phy.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/scsi/isci/phy.c | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index cb87b2e..0b87ff4 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -122,8 +122,6 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
int phy_idx = iphy->phy_index;
struct sci_phy_cap phy_cap;
u32 phy_configuration;
- u32 parity_check = 0;
- u32 parity_count = 0;
u32 llctl, link_rate;
u32 clksm_value = 0;
u32 sp_timeouts = 0;
@@ -223,19 +221,11 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
}

/* The SAS specification indicates that the phy_capabilities that
- * are transmitted shall have an even parity. Calculate the parity.
+ * are transmitted shall have an even parity. If parity indicates
+ * there are an odd number of bits set, then set the parity bit
+ * to 1 in the phy capabilities.
*/
- parity_check = phy_cap.all;
- while (parity_check != 0) {
- if (parity_check & 0x1)
- parity_count++;
- parity_check >>= 1;
- }
-
- /* If parity indicates there are an odd number of bits set, then
- * set the parity bit to 1 in the phy capabilities.
- */
- if ((parity_count % 2) != 0)
+ if (parity32(phy_cap.all))
phy_cap.parity = 1;

writel(phy_cap.all, &llr->phy_capabilities);
--
2.5.5

2016-03-27 07:26:24

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 21/31] mtd: use parity16 in ssfdc.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/mtd/ssfdc.c | 20 ++------------------
1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
index daf82ba..b4d9144 100644
--- a/drivers/mtd/ssfdc.c
+++ b/drivers/mtd/ssfdc.c
@@ -182,24 +182,10 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
return 0;
}

-/* Parity calculator on a word of n bit size */
-static int get_parity(int number, int size)
-{
- int k;
- int parity;
-
- parity = 1;
- for (k = 0; k < size; k++) {
- parity += (number >> k);
- parity &= 1;
- }
- return parity;
-}
-
/* Read and validate the logical block address field stored in the OOB */
static int get_logical_address(uint8_t *oob_buf)
{
- int block_address, parity;
+ int block_address;
int offset[2] = {6, 11}; /* offset of the 2 address fields within OOB */
int j;
int ok = 0;
@@ -215,11 +201,9 @@ static int get_logical_address(uint8_t *oob_buf)

/* Check for the signature bits in the address field (MSBits) */
if ((block_address & ~0x7FF) == 0x1000) {
- parity = block_address & 0x01;
block_address &= 0x7FF;
- block_address >>= 1;

- if (get_parity(block_address, 10) != parity) {
+ if (!parity16(block_address)) {
pr_debug("SSFDC_RO: logical address field%d"
"parity error(0x%04X)\n", j+1,
block_address);
--
2.5.5

2016-03-27 07:28:11

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 22/31] mtd: use parity functions in inftlcore.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/mtd/inftlcore.c | 17 ++++-------------
1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/mtd/inftlcore.c b/drivers/mtd/inftlcore.c
index b66b541..29567bb 100644
--- a/drivers/mtd/inftlcore.c
+++ b/drivers/mtd/inftlcore.c
@@ -457,15 +457,6 @@ static u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
return INFTL_foldchain(inftl, LongestChain, pendingblock);
}

-static int nrbits(unsigned int val, int bitcount)
-{
- int i, total = 0;
-
- for (i = 0; (i < bitcount); i++)
- total += (((0x1 << i) & val) ? 1 : 0);
- return total;
-}
-
/*
* INFTL_findwriteunit: Return the unit number into which we can write
* for this block. Make it available if it isn't already.
@@ -593,10 +584,10 @@ hitused:
if (prev_block < inftl->nb_blocks)
prev_block -= inftl->firstEUN;

- parity = (nrbits(thisVUC, 16) & 0x1) ? 0x1 : 0;
- parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
- parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
- parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
+ parity = parity16(thisVUC);
+ parity |= parity16(prev_block) << 1;
+ parity |= parity8(anac) << 2;
+ parity |= parity8(nacs) << 3;

oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
--
2.5.5

2016-03-27 07:31:33

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 23/31] crypto: qat: use parity functions in qat_hal.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/crypto/qat/qat_common/qat_hal.c | 32 ++++++++++----------------------
1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/drivers/crypto/qat/qat_common/qat_hal.c b/drivers/crypto/qat/qat_common/qat_hal.c
index 1e480f1..318558f 100644
--- a/drivers/crypto/qat/qat_common/qat_hal.c
+++ b/drivers/crypto/qat/qat_common/qat_hal.c
@@ -546,17 +546,6 @@ static void qat_hal_disable_ctx(struct icp_qat_fw_loader_handle *handle,
qat_hal_wr_ae_csr(handle, ae, CTX_ENABLES, ctx);
}

-static uint64_t qat_hal_parity_64bit(uint64_t word)
-{
- word ^= word >> 1;
- word ^= word >> 2;
- word ^= word >> 4;
- word ^= word >> 8;
- word ^= word >> 16;
- word ^= word >> 32;
- return word & 1;
-}
-
static uint64_t qat_hal_set_uword_ecc(uint64_t uword)
{
uint64_t bit0_mask = 0xff800007fffULL, bit1_mask = 0x1f801ff801fULL,
@@ -566,13 +555,13 @@ static uint64_t qat_hal_set_uword_ecc(uint64_t uword)

/* clear the ecc bits */
uword &= ~(0x7fULL << 0x2C);
- uword |= qat_hal_parity_64bit(bit0_mask & uword) << 0x2C;
- uword |= qat_hal_parity_64bit(bit1_mask & uword) << 0x2D;
- uword |= qat_hal_parity_64bit(bit2_mask & uword) << 0x2E;
- uword |= qat_hal_parity_64bit(bit3_mask & uword) << 0x2F;
- uword |= qat_hal_parity_64bit(bit4_mask & uword) << 0x30;
- uword |= qat_hal_parity_64bit(bit5_mask & uword) << 0x31;
- uword |= qat_hal_parity_64bit(bit6_mask & uword) << 0x32;
+ uword |= (uint64_t)parity64(bit0_mask & uword) << 0x2C;
+ uword |= (uint64_t)parity64(bit1_mask & uword) << 0x2D;
+ uword |= (uint64_t)parity64(bit2_mask & uword) << 0x2E;
+ uword |= (uint64_t)parity64(bit3_mask & uword) << 0x2F;
+ uword |= (uint64_t)parity64(bit4_mask & uword) << 0x30;
+ uword |= (uint64_t)parity64(bit5_mask & uword) << 0x31;
+ uword |= (uint64_t)parity64(bit6_mask & uword) << 0x32;
return uword;
}

@@ -853,15 +842,14 @@ void qat_hal_wr_umem(struct icp_qat_fw_loader_handle *handle,
uaddr |= UA_ECS;
qat_hal_wr_ae_csr(handle, ae, USTORE_ADDRESS, uaddr);
for (i = 0; i < words_num; i++) {
- unsigned int uwrd_lo, uwrd_hi, tmp;
+ unsigned int uwrd_lo, uwrd_hi;

uwrd_lo = ((data[i] & 0xfff0000) << 4) | (0x3 << 18) |
((data[i] & 0xff00) << 2) |
(0x3 << 8) | (data[i] & 0xff);
uwrd_hi = (0xf << 4) | ((data[i] & 0xf0000000) >> 28);
- uwrd_hi |= (hweight32(data[i] & 0xffff) & 0x1) << 8;
- tmp = ((data[i] >> 0x10) & 0xffff);
- uwrd_hi |= (hweight32(tmp) & 0x1) << 9;
+ uwrd_hi |= parity16(data[i]) << 8;
+ uwrd_hi |= parity16(data[i] >> 16) << 9;
qat_hal_wr_ae_csr(handle, ae, USTORE_DATA_LOWER, uwrd_lo);
qat_hal_wr_ae_csr(handle, ae, USTORE_DATA_UPPER, uwrd_hi);
}
--
2.5.5

2016-03-27 07:34:03

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 24/31] mtd: use parity16 in sm_ftl.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/mtd/sm_ftl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c
index b096f8b..2244588 100644
--- a/drivers/mtd/sm_ftl.c
+++ b/drivers/mtd/sm_ftl.c
@@ -136,7 +136,7 @@ static int sm_get_lba(uint8_t *lba)
return -2;

/* check parity - endianness doesn't matter */
- if (hweight16(*(uint16_t *)lba) & 1)
+ if (parity16(*(uint16_t *)lba))
return -2;

return (lba[1] >> 1) | ((lba[0] & 0x07) << 7);
@@ -183,7 +183,7 @@ static void sm_write_lba(struct sm_oob *oob, uint16_t lba)
tmp[0] = 0x10 | ((lba >> 7) & 0x07);
tmp[1] = (lba << 1) & 0xFF;

- if (hweight16(*(uint16_t *)tmp) & 0x01)
+ if (parity16(*(uint16_t *)tmp))
tmp[1] |= 1;

oob->lba_copy1[0] = oob->lba_copy2[0] = tmp[0];
--
2.5.5

2016-03-27 07:37:06

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 25/31] ethernet: use parity8 in sun/niu.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/net/ethernet/sun/niu.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 9cc4564..8c344ef 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -2742,18 +2742,12 @@ static int niu_set_alt_mac_rdc_table(struct niu *np, int idx,

static u64 vlan_entry_set_parity(u64 reg_val)
{
- u64 port01_mask;
- u64 port23_mask;
-
- port01_mask = 0x00ff;
- port23_mask = 0xff00;
-
- if (hweight64(reg_val & port01_mask) & 1)
+ if (parity8(reg_val))
reg_val |= ENET_VLAN_TBL_PARITY0;
else
reg_val &= ~ENET_VLAN_TBL_PARITY0;

- if (hweight64(reg_val & port23_mask) & 1)
+ if (parity8((unsigned int)reg_val >> 8))
reg_val |= ENET_VLAN_TBL_PARITY1;
else
reg_val &= ~ENET_VLAN_TBL_PARITY1;
--
2.5.5

2016-03-27 07:39:02

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 26/31] input: serio: use parity8 in pcips2.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/input/serio/pcips2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/serio/pcips2.c b/drivers/input/serio/pcips2.c
index e862c6e..a51e7f0 100644
--- a/drivers/input/serio/pcips2.c
+++ b/drivers/input/serio/pcips2.c
@@ -77,7 +77,7 @@ static irqreturn_t pcips2_interrupt(int irq, void *devid)

flag = (status & PS2_STAT_PARITY) ? 0 : SERIO_PARITY;

- if (hweight8(scancode) & 1)
+ if (parity8(scancode))
flag ^= SERIO_PARITY;

serio_interrupt(ps2if->io, scancode, flag);
--
2.5.5

2016-03-27 07:40:45

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 27/31] input: serio: use parity8 in sa1111ps2.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/input/serio/sa1111ps2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/input/serio/sa1111ps2.c b/drivers/input/serio/sa1111ps2.c
index b3e6889..324b193 100644
--- a/drivers/input/serio/sa1111ps2.c
+++ b/drivers/input/serio/sa1111ps2.c
@@ -74,7 +74,7 @@ static irqreturn_t ps2_rxint(int irq, void *dev_id)

scancode = sa1111_readl(ps2if->base + PS2DATA) & 0xff;

- if (hweight8(scancode) & 1)
+ if (parity8(scancode))
flag ^= SERIO_PARITY;

serio_interrupt(ps2if->io, scancode, flag);
--
2.5.5

2016-03-27 07:42:54

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 28/31] iio: gyro: use parity32 in adxrs450.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/iio/gyro/adxrs450.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c
index a330d42..f1f19fc20 100644
--- a/drivers/iio/gyro/adxrs450.c
+++ b/drivers/iio/gyro/adxrs450.c
@@ -108,9 +108,7 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,

mutex_lock(&st->buf_lock);
tx = ADXRS450_READ_DATA | (reg_address << 17);
-
- if (!(hweight32(tx) & 1))
- tx |= ADXRS450_P;
+ tx |= !parity32(tx) * ADXRS450_P;

st->tx = cpu_to_be32(tx);
ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
@@ -144,9 +142,7 @@ static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,

mutex_lock(&st->buf_lock);
tx = ADXRS450_WRITE_DATA | (reg_address << 17) | (val << 1);
-
- if (!(hweight32(tx) & 1))
- tx |= ADXRS450_P;
+ tx |= !parity32(tx) * ADXRS450_P;

st->tx = cpu_to_be32(tx);
ret = spi_write(st->us, &st->tx, sizeof(st->tx));
--
2.5.5

2016-03-27 07:45:11

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 29/31] serial: use parity32 in max3100.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/tty/serial/max3100.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/max3100.c b/drivers/tty/serial/max3100.c
index 5c4c280..a0cc84a 100644
--- a/drivers/tty/serial/max3100.c
+++ b/drivers/tty/serial/max3100.c
@@ -155,7 +155,7 @@ static int max3100_do_parity(struct max3100_port *s, u16 c)
else
c &= 0xff;

- parity = parity ^ (hweight8(c) & 1);
+ parity ^= parity8(c);
return parity;
}

--
2.5.5

2016-03-27 07:48:59

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 30/31] input: mouse: use parity8 in elantech

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/input/mouse/elantech.c | 10 +++-------
drivers/input/mouse/elantech.h | 1 -
2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
index 78f93cf..778b5d1 100644
--- a/drivers/input/mouse/elantech.c
+++ b/drivers/input/mouse/elantech.c
@@ -693,9 +693,9 @@ static int elantech_packet_check_v1(struct psmouse *psmouse)

p3 = (packet[0] & 0x04) >> 2;

- return etd->parity[packet[1]] == p1 &&
- etd->parity[packet[2]] == p2 &&
- etd->parity[packet[3]] == p3;
+ return parity8(packet[1]) != p1 &&
+ parity8(packet[2]) != p2 &&
+ parity8(packet[3]) != p3;
}

static int elantech_debounce_check_v2(struct psmouse *psmouse)
@@ -1635,10 +1635,6 @@ int elantech_init(struct psmouse *psmouse)

psmouse_reset(psmouse);

- etd->parity[0] = 1;
- for (i = 1; i < 256; i++)
- etd->parity[i] = etd->parity[i & (i - 1)] ^ 1;
-
/*
* Do the version query again so we can store the result
*/
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h
index e1cbf40..542c5d9 100644
--- a/drivers/input/mouse/elantech.h
+++ b/drivers/input/mouse/elantech.h
@@ -141,7 +141,6 @@ struct elantech_data {
unsigned int y_max;
unsigned int width;
struct finger_pos mt[ETP_MAX_FINGERS];
- unsigned char parity[256];
int (*send_cmd)(struct psmouse *psmouse, unsigned char c, unsigned char *param);
void (*original_set_rate)(struct psmouse *psmouse, unsigned int rate);
};
--
2.5.5

2016-03-27 07:50:37

by Zhaoxiu Zeng

[permalink] [raw]
Subject: [PATCH 31/31] ethernet: broadcom: use parity8 in tg3.c

From: Zeng Zhaoxiu <[email protected]>

Signed-off-by: Zeng Zhaoxiu <[email protected]>
---
drivers/net/ethernet/broadcom/tg3.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 3010080..802a429 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -12939,11 +12939,7 @@ static int tg3_test_nvram(struct tg3 *tp)

err = -EIO;
for (i = 0; i < NVRAM_SELFBOOT_DATA_SIZE; i++) {
- u8 hw8 = hweight8(data[i]);
-
- if ((hw8 & 0x1) && parity[i])
- goto out;
- else if (!(hw8 & 0x1) && !parity[i])
+ if (parity8(data[i]) == !!parity[i])
goto out;
}
err = 0;
--
2.5.5

2016-03-27 07:52:01

by Zhaoxiu Zeng

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

On 2016/3/27 6:08, Martin Kepplinger wrote:
> We do.
>
> Am 24. März 2016 23:28:15 MEZ, schrieb Andrew Morton <[email protected]>:
>> On Thu, 24 Mar 2016 09:38:21 +0100 Denys Vlasenko <[email protected]>
>> wrote:
>>
>>> On 03/24/2016 04:03 AM, Zhaoxiu Zeng wrote:
>>>> +/*
>>>> + * Type invariant interface to the compile time constant parity
>> functions.
>>>> + */
>>>> +#define PARITY(w) PARITY64((u64)w)
>>>
>>> Can result in incorrect expansion of w. Should be PARITY64((u64)(w))
>>
>> And we seem to be missing the other 30 patches.
>

Sorry,I got some problems with my gmail.

2016-03-27 12:44:12

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

Hi Zeng.

Looking through the arch specific implementations of __arch_parity().
Some architectures uses #defines, other uses inline static functions.

Any particular reason that you select one approach over the other
in the different cases?

ia64:
+#define __arch_parity32(x) ((unsigned int) __arch_parity64((x) & 0xfffffffful))
+#define __arch_parity16(x) ((unsigned int) __arch_parity64((x) & 0xfffful))
+#define __arch_parity8(x) ((unsigned int) __arch_parity64((x) & 0xfful))
+#define __arch_parity4(x) ((unsigned int) __arch_parity64((x) & 0xful))

tile:
+static inline unsigned int __arch_parity32(unsigned int w)
+{
+ return __builtin_popcount(w) & 1;
+}
+
+static inline unsigned int __arch_parity16(unsigned int w)
+{
+ return __arch_parity32(w & 0xffff);
+}
+
+static inline unsigned int __arch_parity8(unsigned int w)
+{
+ return __arch_parity32(w & 0xff);
+}
+
+static inline unsigned int __arch_parity4(unsigned int w)
+{
+ return __arch_parity32(w & 0xf);
+}

Just two examples.

Adding the parity helpers seems like veny nice simplifications.

A few comments to some of those I looked at.
(I am not subscribed to lkml, so you get it as comments here)

[PATCH 21/31] mtd: use parity16 in ssfdc.c
The original code semes to check that the parity equals the
value of first bit in the address.
This seems lost after the conversion.

[PATCH 20/31] scsi: use parity32 in isci/phy.c
+ if (parity32(phy_cap.all))
phy_cap.parity = 1;
Could be written like this - simpler IMO:
phy_cap.parity = parity32(phy_cap.all);


Sam

2016-03-27 13:38:59

by Zhaoxiu Zeng

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

On 2016/3/27 20:44, Sam Ravnborg wrote:
> Hi Zeng.
>
> Looking through the arch specific implementations of __arch_parity().
> Some architectures uses #defines, other uses inline static functions.
>
> Any particular reason that you select one approach over the other
> in the different cases?
>
> ia64:
> +#define __arch_parity32(x) ((unsigned int) __arch_parity64((x) & 0xfffffffful))
> +#define __arch_parity16(x) ((unsigned int) __arch_parity64((x) & 0xfffful))
> +#define __arch_parity8(x) ((unsigned int) __arch_parity64((x) & 0xfful))
> +#define __arch_parity4(x) ((unsigned int) __arch_parity64((x) & 0xful))
>
> tile:
> +static inline unsigned int __arch_parity32(unsigned int w)
> +{
> + return __builtin_popcount(w) & 1;
> +}
> +
> +static inline unsigned int __arch_parity16(unsigned int w)
> +{
> + return __arch_parity32(w & 0xffff);
> +}
> +
> +static inline unsigned int __arch_parity8(unsigned int w)
> +{
> + return __arch_parity32(w & 0xff);
> +}
> +
> +static inline unsigned int __arch_parity4(unsigned int w)
> +{
> + return __arch_parity32(w & 0xf);
> +}
>

No particular reason, just like the architecture's __arch_hweightN.

> Just two examples.
>
> Adding the parity helpers seems like veny nice simplifications.
>
> A few comments to some of those I looked at.
> (I am not subscribed to lkml, so you get it as comments here)
>

I think the conversion is simple and readable.

> [PATCH 21/31] mtd: use parity16 in ssfdc.c
> The original code semes to check that the parity equals the
> value of first bit in the address.
> This seems lost after the conversion.
>

The original get_parity return 1 if the number is even, so
if block_address is valid, "block_address & 0x7ff" must be odd.

> [PATCH 20/31] scsi: use parity32 in isci/phy.c
> + if (parity32(phy_cap.all))
> phy_cap.parity = 1;
> Could be written like this - simpler IMO:
> phy_cap.parity = parity32(phy_cap.all);
>
>
> Sam
>
Yes. Thanks!

2016-03-27 17:56:23

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

> > Any particular reason that you select one approach over the other
> > in the different cases?
>
> No particular reason, just like the architecture's __arch_hweightN.

The general recommendatiosn these days are to use static inline
for code to get better type check.
And it would also be nice to be consistent across architectures.

Sam

2016-03-28 02:15:32

by Zhaoxiu Zeng

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

On 2016年03月27日 21:38, zhaoxiu.zeng wrote:
> On 2016/3/27 20:44, Sam Ravnborg wrote:
>> Hi Zeng.
>>
>> Looking through the arch specific implementations of __arch_parity().
>> Some architectures uses #defines, other uses inline static functions.
>>
>> Any particular reason that you select one approach over the other
>> in the different cases?
>>
>> ia64:
>> +#define __arch_parity32(x) ((unsigned int) __arch_parity64((x) & 0xfffffffful))
>> +#define __arch_parity16(x) ((unsigned int) __arch_parity64((x) & 0xfffful))
>> +#define __arch_parity8(x) ((unsigned int) __arch_parity64((x) & 0xfful))
>> +#define __arch_parity4(x) ((unsigned int) __arch_parity64((x) & 0xful))
>>
>> tile:
>> +static inline unsigned int __arch_parity32(unsigned int w)
>> +{
>> + return __builtin_popcount(w) & 1;
>> +}
>> +
>> +static inline unsigned int __arch_parity16(unsigned int w)
>> +{
>> + return __arch_parity32(w & 0xffff);
>> +}
>> +
>> +static inline unsigned int __arch_parity8(unsigned int w)
>> +{
>> + return __arch_parity32(w & 0xff);
>> +}
>> +
>> +static inline unsigned int __arch_parity4(unsigned int w)
>> +{
>> + return __arch_parity32(w & 0xf);
>> +}
>>
> No particular reason, just like the architecture's __arch_hweightN.
>
>> Just two examples.
>>
>> Adding the parity helpers seems like veny nice simplifications.
>>
>> A few comments to some of those I looked at.
>> (I am not subscribed to lkml, so you get it as comments here)
>>
> I think the conversion is simple and readable.
>
>> [PATCH 21/31] mtd: use parity16 in ssfdc.c
>> The original code semes to check that the parity equals the
>> value of first bit in the address.
>> This seems lost after the conversion.
>>
> The original get_parity return 1 if the number is even, so
> if block_address is valid, "block_address & 0x7ff" must be odd.
Make corrections:

The original get_parity return 1 if hweight of the input number is even, so
if block_address is valid, hweight of "block_address & 0x7ff" must be odd.

>
>> [PATCH 20/31] scsi: use parity32 in isci/phy.c
>> + if (parity32(phy_cap.all))
>> phy_cap.parity = 1;
>> Could be written like this - simpler IMO:
>> phy_cap.parity = parity32(phy_cap.all);
>>
>>
>> Sam
>>
> Yes. Thanks!
>

2016-03-28 02:43:12

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 10/31] Add sparc-specific parity functions

From: "zhaoxiu.zeng" <[email protected]>
Date: Sun, 27 Mar 2016 14:43:10 +0800

> +
> +/*
> + * parityN: returns the parity of a N-bit word,
> + * i.e. the number of 1-bits in x modulo 2.
> + */
> +
> +#define __arch_parity4(w) (__arch_hweight8((w) & 0xf) & 1)
> +#define __arch_parity8(w) (__arch_hweight8(w) & 1)
> +#define __arch_parity16(w) (__arch_hweight16(w) & 1)
> +#define __arch_parity32(w) (__arch_hweight32(w) & 1)
> +#define __arch_parity64(w) ((unsigned int)__arch_hweight64(w) & 1)

This looks like asm-generic/ material to me.

2016-03-28 02:44:50

by Zhaoxiu Zeng

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

OK, I will do the V2 patches soon.
In addition, the best is to provide asm version parity functions for
powerpc, sparc, and x86.

在 2016年03月28日 01:56, Sam Ravnborg 写道:
>>> Any particular reason that you select one approach over the other
>>> in the different cases?
>> No particular reason, just like the architecture's __arch_hweightN.
> The general recommendatiosn these days are to use static inline
> for code to get better type check.
> And it would also be nice to be consistent across architectures.
>
> Sam

2016-03-28 05:44:20

by Zhaoxiu Zeng

[permalink] [raw]
Subject: Re: [PATCH 10/31] Add sparc-specific parity functions

在 2016年03月28日 10:43, David Miller 写道:
> From: "zhaoxiu.zeng" <[email protected]>
> Date: Sun, 27 Mar 2016 14:43:10 +0800
>
>> +
>> +/*
>> + * parityN: returns the parity of a N-bit word,
>> + * i.e. the number of 1-bits in x modulo 2.
>> + */
>> +
>> +#define __arch_parity4(w) (__arch_hweight8((w) & 0xf) & 1)
>> +#define __arch_parity8(w) (__arch_hweight8(w) & 1)
>> +#define __arch_parity16(w) (__arch_hweight16(w) & 1)
>> +#define __arch_parity32(w) (__arch_hweight32(w) & 1)
>> +#define __arch_parity64(w) ((unsigned int)__arch_hweight64(w) & 1)
> This looks like asm-generic/ material to me.

This is generic for the architectures which have popcount instruction,
but more higher costs than asm-generic/ for others.


2016-03-28 06:51:22

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

> diff --git a/include/asm-generic/bitops/arch_parity.h b/include/asm-generic/bitops/arch_parity.h
> new file mode 100644
> index 0000000..cddc555
> --- /dev/null
> +++ b/include/asm-generic/bitops/arch_parity.h
> @@ -0,0 +1,39 @@
> +#ifndef _ASM_GENERIC_BITOPS_ARCH_PARITY_H_
> +#define _ASM_GENERIC_BITOPS_ARCH_PARITY_H_
> +
> +#include <asm/types.h>
> +
> +/*
> + * Refrence to 'https://graphics.stanford.edu/~seander/bithacks.html#ParityParallel'.
> + */
> +
> +static inline unsigned int __arch_parity4(unsigned int w)
> +{
> + w &= 0xf;
> + return (0x6996 >> w) & 1;
> +}
> +
> +static inline unsigned int __arch_parity8(unsigned int w)
> +{
> + w ^= w >> 4;
> + return __arch_parity4(w);
> +}
> +
> +static inline unsigned int __arch_parity16(unsigned int w)
> +{
> + w ^= w >> 8;
> + return __arch_parity8(w);
> +}
> +
> +static inline unsigned int __arch_parity32(unsigned int w)
> +{
> + w ^= w >> 16;
> + return __arch_parity16(w);
> +}
> +
> +static inline unsigned int __arch_parity64(__u64 w)
> +{
> + return __arch_parity32((unsigned int)(w >> 32) ^ (unsigned int)w);
> +}
Defining these as static inlines in asm-generic prevent an architecture
from selecting between a more optimal asm version or the generic version
at run-time.
sparc would benefit from this as only some sparc chips supports popc.
See how this is done for hweight*

Sam

2016-03-28 08:35:48

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH 28/31] iio: gyro: use parity32 in adxrs450.c

On 27/03/16 08:42, zhaoxiu.zeng wrote:
> From: Zeng Zhaoxiu <[email protected]>
>
> Signed-off-by: Zeng Zhaoxiu <[email protected]>
Interesting. Whilst obviously correct I wonder if this obscures the
intent of the code a little. Lars, what do you think?

Jonathan
> ---
> drivers/iio/gyro/adxrs450.c | 8 ++------
> 1 file changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/iio/gyro/adxrs450.c b/drivers/iio/gyro/adxrs450.c
> index a330d42..f1f19fc20 100644
> --- a/drivers/iio/gyro/adxrs450.c
> +++ b/drivers/iio/gyro/adxrs450.c
> @@ -108,9 +108,7 @@ static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev,
>
> mutex_lock(&st->buf_lock);
> tx = ADXRS450_READ_DATA | (reg_address << 17);
> -
> - if (!(hweight32(tx) & 1))
> - tx |= ADXRS450_P;
> + tx |= !parity32(tx) * ADXRS450_P;
>
> st->tx = cpu_to_be32(tx);
> ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
> @@ -144,9 +142,7 @@ static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev,
>
> mutex_lock(&st->buf_lock);
> tx = ADXRS450_WRITE_DATA | (reg_address << 17) | (val << 1);
> -
> - if (!(hweight32(tx) & 1))
> - tx |= ADXRS450_P;
> + tx |= !parity32(tx) * ADXRS450_P;
>
> st->tx = cpu_to_be32(tx);
> ret = spi_write(st->us, &st->tx, sizeof(st->tx));
>

2016-03-28 09:22:31

by Lars-Peter Clausen

[permalink] [raw]
Subject: Re: [PATCH 28/31] iio: gyro: use parity32 in adxrs450.c

On 03/28/2016 10:35 AM, Jonathan Cameron wrote:
> On 27/03/16 08:42, zhaoxiu.zeng wrote:
>> From: Zeng Zhaoxiu <[email protected]>
>>
>> Signed-off-by: Zeng Zhaoxiu <[email protected]>
> Interesting. Whilst obviously correct I wonder if this obscures the
> intent of the code a little. Lars, what do you think?

The parity function is newly introduced in this series and can be more
efficient that just hw_weight() & 1 on certain architectures. Since the
result is the same using it is certainly an improvement. But ...

[...]
>> - if (!(hweight32(tx) & 1))
>> - tx |= ADXRS450_P;
>> + tx |= !parity32(tx) * ADXRS450_P;

... this should still be

if (!parity32(tx))
tx |= ADXRS450_P;

Otherwise it's a bit too much obfuscated for my taste. Just leave it to the
compiler to optimize it as it sees it fit.

2016-03-28 14:34:04

by Michal Nazarewicz

[permalink] [raw]
Subject: Re: [PATCH 25/31] ethernet: use parity8 in sun/niu.c

On Sun, Mar 27 2016, zhaoxiu zeng wrote:
> From: Zeng Zhaoxiu <[email protected]>
>
> Signed-off-by: Zeng Zhaoxiu <[email protected]>

No idea why I’ve been CC’d, but code looks good to me so:

Acked-by: Michal Nazarewicz <[email protected]>

> ---
> drivers/net/ethernet/sun/niu.c | 10 ++--------
> 1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
> index 9cc4564..8c344ef 100644
> --- a/drivers/net/ethernet/sun/niu.c
> +++ b/drivers/net/ethernet/sun/niu.c
> @@ -2742,18 +2742,12 @@ static int niu_set_alt_mac_rdc_table(struct niu *np, int idx,
>
> static u64 vlan_entry_set_parity(u64 reg_val)
> {
> - u64 port01_mask;
> - u64 port23_mask;
> -
> - port01_mask = 0x00ff;
> - port23_mask = 0xff00;
> -
> - if (hweight64(reg_val & port01_mask) & 1)
> + if (parity8(reg_val))
> reg_val |= ENET_VLAN_TBL_PARITY0;
> else
> reg_val &= ~ENET_VLAN_TBL_PARITY0;
>
> - if (hweight64(reg_val & port23_mask) & 1)
> + if (parity8((unsigned int)reg_val >> 8))
> reg_val |= ENET_VLAN_TBL_PARITY1;
> else
> reg_val &= ~ENET_VLAN_TBL_PARITY1;
> --
> 2.5.5
>

--
Best regards
ミハウ “????????????????86” ナザレヴイツ
«If at first you don’t succeed, give up skydiving»

2016-03-28 15:37:51

by Sam Ravnborg

[permalink] [raw]
Subject: Re: [PATCH 10/31] Add sparc-specific parity functions

On Mon, Mar 28, 2016 at 11:29:15AM -0400, David Miller wrote:
> From: Zeng Zhaoxiu <[email protected]>
> Date: Mon, 28 Mar 2016 13:44:03 +0800
>
> > 在 2016年03月28日 10:43, David Miller 写道:
> >> From: "zhaoxiu.zeng" <[email protected]>
> >> Date: Sun, 27 Mar 2016 14:43:10 +0800
> >>
> >>> +
> >>> +/*
> >>> + * parityN: returns the parity of a N-bit word,
> >>> + * i.e. the number of 1-bits in x modulo 2.
> >>> + */
> >>> +
> >>> +#define __arch_parity4(w) (__arch_hweight8((w) & 0xf) & 1)
> >>> +#define __arch_parity8(w) (__arch_hweight8(w) & 1)
> >>> +#define __arch_parity16(w) (__arch_hweight16(w) & 1)
> >>> +#define __arch_parity32(w) (__arch_hweight32(w) & 1)
> >>> +#define __arch_parity64(w) ((unsigned int)__arch_hweight64(w) & 1)
> >> This looks like asm-generic/ material to me.
> >
> > This is generic for the architectures which have popcount instruction,
> > but more higher costs than asm-generic/ for others.
>
> Which is why said stanza's in the asm-generic header should be triggered
> by a CPP define or similar.
For sparc we would need to do a run-time patch as far as I see.

If popc is availble then use of hweight* should be fine.
But without popc then I think the generic implementation that
uses the stanford algorithm would be most efficient,
rather than the base this on the generic hweight functions.

Sam

2016-03-28 15:47:03

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 10/31] Add sparc-specific parity functions

From: Sam Ravnborg <[email protected]>
Date: Mon, 28 Mar 2016 17:37:43 +0200

> If popc is availble then use of hweight* should be fine.
> But without popc then I think the generic implementation that
> uses the stanford algorithm would be most efficient,
> rather than the base this on the generic hweight functions.

Agreed.

2016-03-28 17:25:10

by David Daney

[permalink] [raw]
Subject: Re: [PATCH 07/31] Add mips-specific parity functions

On 03/26/2016 11:06 PM, zhaoxiu.zeng wrote:
> From: Zeng Zhaoxiu <[email protected]>
>

There is nothing MIPS specific here. Why not put it in asm-generic or
some similar place where it can be shared by all architectures?

Also, are you sure __builtin_popcount() is available on all GCC versions
that are supported for building the kernel?

David Daney


> Signed-off-by: Zeng Zhaoxiu <[email protected]>
> ---
> arch/mips/include/asm/arch_parity.h | 44 +++++++++++++++++++++++++++++++++++++
> arch/mips/include/asm/bitops.h | 3 +++
> 2 files changed, 47 insertions(+)
> create mode 100644 arch/mips/include/asm/arch_parity.h
>
> diff --git a/arch/mips/include/asm/arch_parity.h b/arch/mips/include/asm/arch_parity.h
> new file mode 100644
> index 0000000..23b3c23
> --- /dev/null
> +++ b/arch/mips/include/asm/arch_parity.h
> @@ -0,0 +1,44 @@
> +/*
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License. See the file "COPYING" in the main directory of this archive
> + * for more details.
> + *
> + */
> +#ifndef _ASM_ARCH_PARITY_H
> +#define _ASM_ARCH_PARITY_H
> +
> +#ifdef ARCH_HAS_USABLE_BUILTIN_POPCOUNT
> +
> +#include <asm/types.h>
> +
> +static inline unsigned int __arch_parity32(unsigned int w)
> +{
> + return __builtin_popcount(w) & 1;
> +}
> +
> +static inline unsigned int __arch_parity16(unsigned int w)
> +{
> + return __arch_parity32(w & 0xffff);
> +}
> +
> +static inline unsigned int __arch_parity8(unsigned int w)
> +{
> + return __arch_parity32(w & 0xff);
> +}
> +
> +static inline unsigned int __arch_parity4(unsigned int w)
> +{
> + return __arch_parity32(w & 0xf);
> +}
> +
> +static inline unsigned int __arch_parity64(__u64 w)
> +{
> + return (unsigned int)__builtin_popcountll(w) & 1;
> +}
> +
> +#else
> +#include <asm-generic/bitops/arch_hweight.h>
> +#include <asm-generic/bitops/arch_parity.h>
> +#endif
> +
> +#endif /* _ASM_ARCH_PARITY_H */
> diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
> index ce9666c..0b87734 100644
> --- a/arch/mips/include/asm/bitops.h
> +++ b/arch/mips/include/asm/bitops.h
> @@ -626,6 +626,9 @@ static inline int ffs(int word)
> #include <asm/arch_hweight.h>
> #include <asm-generic/bitops/const_hweight.h>
>
> +#include <asm/arch_parity.h>
> +#include <asm-generic/bitops/const_parity.h>
> +
> #include <asm-generic/bitops/le.h>
> #include <asm-generic/bitops/ext2-atomic.h>
>
>

2016-03-28 18:33:31

by Richard Henderson

[permalink] [raw]
Subject: Re: [PATCH 03/31] Add alpha-specific parity functions

On 03/26/2016 10:43 PM, zhaoxiu.zeng wrote:
> From: Zeng Zhaoxiu <[email protected]>
>
> Signed-off-by: Zeng Zhaoxiu <[email protected]>
> ---
> arch/alpha/include/asm/bitops.h | 27 +++++++++++++++++++++++++++
> 1 file changed, 27 insertions(+)

Acked-by: Richard Henderson <[email protected]>


r~

Subject: Re: [PATCH 04/31] Add avr32-specific parity functions

Around Sun 27 Mar 2016 13:47:02 +0800 or thereabout, zhaoxiu.zeng wrote:
> From: Zeng Zhaoxiu <[email protected]>
>
> Signed-off-by: Zeng Zhaoxiu <[email protected]>

Acked-by: Hans-Christian Noren Egtvedt <[email protected]>

> ---
> arch/avr32/include/asm/bitops.h | 32 ++++++++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)

<snipp diff>

--
Best regards, Hans-Christian Noren Egtvedt

2016-03-29 02:15:58

by Zhaoxiu Zeng

[permalink] [raw]
Subject: Re: [PATCH 07/31] Add mips-specific parity functions



在 2016年03月29日 01:25, David Daney 写道:
> On 03/26/2016 11:06 PM, zhaoxiu.zeng wrote:
>> From: Zeng Zhaoxiu <[email protected]>
>>
>
> There is nothing MIPS specific here. Why not put it in asm-generic or
> some similar place where it can be shared by all architectures?
>
> Also, are you sure __builtin_popcount() is available on all GCC
> versions that are supported for building the kernel?
>
> David Daney
>

Refrence to arch_hweight.h.

In the 68th line of
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h, we can
see:

#ifdef __OCTEON__
/*
* All gcc versions that have OCTEON support define __OCTEON__ and have the
* __builtin_popcount support.
*/
#define ARCH_HAS_USABLE_BUILTIN_POPCOUNT 1
#endif

/*
* All gcc versions that have OCTEON support define __OCTEON__ and have the
* __builtin_popcount support.
*/

>> Signed-off-by: Zeng Zhaoxiu <[email protected]>
>> ---
>> arch/mips/include/asm/arch_parity.h | 44
>> +++++++++++++++++++++++++++++++++++++
>> arch/mips/include/asm/bitops.h | 3 +++
>> 2 files changed, 47 insertions(+)
>> create mode 100644 arch/mips/include/asm/arch_parity.h
>>
>> diff --git a/arch/mips/include/asm/arch_parity.h
>> b/arch/mips/include/asm/arch_parity.h
>> new file mode 100644
>> index 0000000..23b3c23
>> --- /dev/null
>> +++ b/arch/mips/include/asm/arch_parity.h
>> @@ -0,0 +1,44 @@
>> +/*
>> + * This file is subject to the terms and conditions of the GNU
>> General Public
>> + * License. See the file "COPYING" in the main directory of this
>> archive
>> + * for more details.
>> + *
>> + */
>> +#ifndef _ASM_ARCH_PARITY_H
>> +#define _ASM_ARCH_PARITY_H
>> +
>> +#ifdef ARCH_HAS_USABLE_BUILTIN_POPCOUNT
>> +
>> +#include <asm/types.h>
>> +
>> +static inline unsigned int __arch_parity32(unsigned int w)
>> +{
>> + return __builtin_popcount(w) & 1;
>> +}
>> +
>> +static inline unsigned int __arch_parity16(unsigned int w)
>> +{
>> + return __arch_parity32(w & 0xffff);
>> +}
>> +
>> +static inline unsigned int __arch_parity8(unsigned int w)
>> +{
>> + return __arch_parity32(w & 0xff);
>> +}
>> +
>> +static inline unsigned int __arch_parity4(unsigned int w)
>> +{
>> + return __arch_parity32(w & 0xf);
>> +}
>> +
>> +static inline unsigned int __arch_parity64(__u64 w)
>> +{
>> + return (unsigned int)__builtin_popcountll(w) & 1;
>> +}
>> +
>> +#else
>> +#include <asm-generic/bitops/arch_hweight.h>
>> +#include <asm-generic/bitops/arch_parity.h>
>> +#endif
>> +
>> +#endif /* _ASM_ARCH_PARITY_H */
>> diff --git a/arch/mips/include/asm/bitops.h
>> b/arch/mips/include/asm/bitops.h
>> index ce9666c..0b87734 100644
>> --- a/arch/mips/include/asm/bitops.h
>> +++ b/arch/mips/include/asm/bitops.h
>> @@ -626,6 +626,9 @@ static inline int ffs(int word)
>> #include <asm/arch_hweight.h>
>> #include <asm-generic/bitops/const_hweight.h>
>>
>> +#include <asm/arch_parity.h>
>> +#include <asm-generic/bitops/const_parity.h>
>> +
>> #include <asm-generic/bitops/le.h>
>> #include <asm-generic/bitops/ext2-atomic.h>
>>
>>
>

2016-03-29 02:27:46

by Zhaoxiu Zeng

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

在 2016年03月28日 14:51, Sam Ravnborg 写道:
>> diff --git a/include/asm-generic/bitops/arch_parity.h b/include/asm-generic/bitops/arch_parity.h
>> new file mode 100644
>> index 0000000..cddc555
>> --- /dev/null
>> +++ b/include/asm-generic/bitops/arch_parity.h
>> @@ -0,0 +1,39 @@
>> +#ifndef _ASM_GENERIC_BITOPS_ARCH_PARITY_H_
>> +#define _ASM_GENERIC_BITOPS_ARCH_PARITY_H_
>> +
>> +#include <asm/types.h>
>> +
>> +/*
>> + * Refrence to 'https://graphics.stanford.edu/~seander/bithacks.html#ParityParallel'.
>> + */
>> +
>> +static inline unsigned int __arch_parity4(unsigned int w)
>> +{
>> + w &= 0xf;
>> + return (0x6996 >> w) & 1;
>> +}
>> +
>> +static inline unsigned int __arch_parity8(unsigned int w)
>> +{
>> + w ^= w >> 4;
>> + return __arch_parity4(w);
>> +}
>> +
>> +static inline unsigned int __arch_parity16(unsigned int w)
>> +{
>> + w ^= w >> 8;
>> + return __arch_parity8(w);
>> +}
>> +
>> +static inline unsigned int __arch_parity32(unsigned int w)
>> +{
>> + w ^= w >> 16;
>> + return __arch_parity16(w);
>> +}
>> +
>> +static inline unsigned int __arch_parity64(__u64 w)
>> +{
>> + return __arch_parity32((unsigned int)(w >> 32) ^ (unsigned int)w);
>> +}
> Defining these as static inlines in asm-generic prevent an architecture
> from selecting between a more optimal asm version or the generic version
> at run-time.
> sparc would benefit from this as only some sparc chips supports popc.
> See how this is done for hweight*
>
> Sam

Thanks. I will try.

2016-03-29 02:56:14

by Joe Perches

[permalink] [raw]
Subject: Re: [PATCH 01/31] bitops: add parity functions

On Tue, 2016-03-29 at 10:27 +0800, Zeng Zhaoxiu wrote:
> 在 2016年03月28日 14:51, Sam Ravnborg 写道:
[]
> > Defining these as static inlines in asm-generic prevent an
> > architecture
> > from selecting between a more optimal asm version or the generic version
> > at run-time.
> > sparc would benefit from this as only some sparc chips supports popc.
> > See how this is done for hweight*
> >
> > Sam
> Thanks. I will try.

You might also try to describe in any commit message
and perhaps the internal documentation why using gcc's
__builtin_parity isn't appropriate.

2016-03-29 12:12:07

by Alan Cox

[permalink] [raw]
Subject: Re: [PATCH 11/31] Add x86-specific parity functions

On Sun, 27 Mar 2016 14:45:50 +0800
"zhaoxiu.zeng" <[email protected]> wrote:

> From: Zeng Zhaoxiu <[email protected]>
>
> Signed-off-by: Zeng Zhaoxiu <[email protected]>
> ---
> arch/x86/include/asm/bitops.h | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
> index 7766d1c..d3210c0 100644
> --- a/arch/x86/include/asm/bitops.h
> +++ b/arch/x86/include/asm/bitops.h
> @@ -501,6 +501,18 @@ static __always_inline int fls64(__u64 x)
>
> #include <asm-generic/bitops/const_hweight.h>
>
> +#define __arch_parity32(x) (__arch_hweight32(x) & 1)
> +#define __arch_parity4(x) (__arch_parity32((x) & 0xf))
> +#define __arch_parity8(x) (__arch_parity32((x) & 0xff))
> +#define __arch_parity16(x) (__arch_parity32((x) & 0xffff))
> +#ifdef CONFIG_X86_32
> +#define __arch_parity64(x) (__arch_parity32((unsigned int)((x) >> 32) ^ (unsigned int)(x)))
> +#else
> +#define __arch_parity64(x) (__arch_hweight64(x) & 1)
> +#endif

arch_hweight32() is a subroutine call to a helper on x86 and the rest
appears to make no sense for this CPU. Gcc has its own parity helper and
even if you are not using that the CPU itself has a parity flag for doing
8bit parity so you just use TEST/J[N]P for parity 8 (and the obvious for 4
and 16). For 32bit parity there is __builtin_parity(). For 64bit
__builtin_parityll().

Alan


2016-03-28 15:29:22

by David Miller

[permalink] [raw]
Subject: Re: [PATCH 10/31] Add sparc-specific parity functions

From: Zeng Zhaoxiu <[email protected]>
Date: Mon, 28 Mar 2016 13:44:03 +0800

> $B:_(B 2016$BG/(B03$B7n(B28$BF|(B 10:43, David Miller $B<LF;(B:
>> From: "zhaoxiu.zeng" <[email protected]>
>> Date: Sun, 27 Mar 2016 14:43:10 +0800
>>
>>> +
>>> +/*
>>> + * parityN: returns the parity of a N-bit word,
>>> + * i.e. the number of 1-bits in x modulo 2.
>>> + */
>>> +
>>> +#define __arch_parity4(w) (__arch_hweight8((w) & 0xf) & 1)
>>> +#define __arch_parity8(w) (__arch_hweight8(w) & 1)
>>> +#define __arch_parity16(w) (__arch_hweight16(w) & 1)
>>> +#define __arch_parity32(w) (__arch_hweight32(w) & 1)
>>> +#define __arch_parity64(w) ((unsigned int)__arch_hweight64(w) & 1)
>> This looks like asm-generic/ material to me.
>
> This is generic for the architectures which have popcount instruction,
> but more higher costs than asm-generic/ for others.

Which is why said stanza's in the asm-generic header should be triggered
by a CPP define or similar.

2016-04-01 23:48:54

by Brian Norris

[permalink] [raw]
Subject: Re: [PATCH 21/31] mtd: use parity16 in ssfdc.c

On Sun, Mar 27, 2016 at 03:24:59PM +0800, zhaoxiu.zeng wrote:
> From: Zeng Zhaoxiu <[email protected]>
>
> Signed-off-by: Zeng Zhaoxiu <[email protected]>

I'm not CC'd on the rest of this series, where you defined parity16().
And I doubt you've tested this. So I'm not applying.

Brian

> drivers/mtd/ssfdc.c | 20 ++------------------
> 1 file changed, 2 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/mtd/ssfdc.c b/drivers/mtd/ssfdc.c
> index daf82ba..b4d9144 100644
> --- a/drivers/mtd/ssfdc.c
> +++ b/drivers/mtd/ssfdc.c
> @@ -182,24 +182,10 @@ static int read_raw_oob(struct mtd_info *mtd, loff_t offs, uint8_t *buf)
> return 0;
> }
>
> -/* Parity calculator on a word of n bit size */
> -static int get_parity(int number, int size)
> -{
> - int k;
> - int parity;
> -
> - parity = 1;
> - for (k = 0; k < size; k++) {
> - parity += (number >> k);
> - parity &= 1;
> - }
> - return parity;
> -}
> -
> /* Read and validate the logical block address field stored in the OOB */
> static int get_logical_address(uint8_t *oob_buf)
> {
> - int block_address, parity;
> + int block_address;
> int offset[2] = {6, 11}; /* offset of the 2 address fields within OOB */
> int j;
> int ok = 0;
> @@ -215,11 +201,9 @@ static int get_logical_address(uint8_t *oob_buf)
>
> /* Check for the signature bits in the address field (MSBits) */
> if ((block_address & ~0x7FF) == 0x1000) {
> - parity = block_address & 0x01;
> block_address &= 0x7FF;
> - block_address >>= 1;
>
> - if (get_parity(block_address, 10) != parity) {
> + if (!parity16(block_address)) {
> pr_debug("SSFDC_RO: logical address field%d"
> "parity error(0x%04X)\n", j+1,
> block_address);
> --
> 2.5.5
>