bitops: add parity functions
Subsystems (33)
PATCH v2 1/30 bitops: add parity functions
From: Zhaoxiu Zeng <[email protected]>
These patches provide generic and architecture-specific odd parity calculations.
I did not use GCC's __builtin_parity* functions, based on the following reasons:
1. I don't know where to identify which version of GCC from the beginning supported __builtin_parity for the architecture.
2. For the architectures that doesn't have popcount instruction, GCC
instead use
"call __paritysi2" (__paritydi2 for 64-bits). So if use
__builtin_parity, we must
provide __paritysi2 and __paritydi2 functions for these architectures. Additionally, parity4,8,16 might be "__builtin_parity(x & mask)",
but the "& mask"
operation is totally unnecessary.
3. For the architectures that have popcount instruction, we do the
same things.
4. For powerpc, sparc, and x86, we do runtime patching to use
popcount instruction
if the CPU support.
I have compiled successfully with x86_64_defconfig, i386_defconfig, pseries_defconfig and sparc64_defconfig. And I used the following codes to test:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef __x86_64__
/* popcnt %edi, %eax -- redundant REX prefix for alignment */
#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
/* popcnt %rdi, %rax */
#define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"
#define REG_IN "D"
#define REG_OUT "a"
#else
/* popcnt %eax, %eax */
#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0"
#define REG_IN "a"
#define REG_OUT "a"
#endif
static inline int c_parity4(unsigned int w)
{
w &= 0xf;
return (0x6996 >> w) & 1;
}
static inline int c_parity8(unsigned int w)
{
w ^= w >> 4;
return c_parity4(w);
}
static inline int c_parity16(unsigned int w)
{
w ^= w >> 8;
return c_parity8(w);
}
static inline int c_parity32(unsigned int w)
{
w ^= w >> 16;
return c_parity16(w);
}
static inline int c_parity64(uint64_t w)
{
return c_parity32((unsigned int)w ^ (unsigned int)(w >> 32));
}
static inline int asm_parity4(unsigned int w)
{
unsigned int res = 0;
asm("test $0xf, %1 \n"
"setpo %b0 \n"
: "+q" (res)
: "r" (w)
: "cc");
return res;
}
static inline int asm_parity8(unsigned int w)
{
unsigned int res = 0;
asm("test %1, %1 \n"
"setpo %b0 \n"
: "+q" (res)
: "r" (w)
: "cc");
return res;
}
static inline int asm_parity16(unsigned int w)
{
unsigned int res = 0;
asm("xor %h1, %b1 \n"
"setpo %b0 \n"
: "+q" (res), "+q" (w)
: : "cc");
return res;
}
static inline int asm_parity32_1(unsigned int w)
{
unsigned int res;
w ^= w >> 16;
asm("xor %%ah, %%al \n"
"mov $0, %%eax \n"
"setpo %%al \n"
: "=a" (res)
: "a" (w)
: "cc");
return res;
}
static inline int asm_parity32_2(unsigned int w)
{
unsigned int res;
asm(POPCNT32 " \n"
"andl $1, %0 \n"
: "="REG_OUT (res)
: REG_IN (w)
: "cc");
return res;
}
#ifdef __x86_64__
static inline int asm_parity64_1(uint64_t w)
{
unsigned int res = (unsigned int)w ^ (unsigned int)(w >> 32);
res ^= res >> 16;
asm("xor %%ah, %%al \n"
"mov $0, %%eax \n"
"setpo %%al \n"
: "=a" (res)
: "a" (res)
: "cc");
return res;
}
static inline int asm_parity64_2(uint64_t w)
{
unsigned int res;
asm(POPCNT64 " \n"
"andl $1, %0 \n"
: "="REG_OUT (res)
: REG_IN (w)
: "cc");
return res;
}
#else
static inline int asm_parity64_1(uint64_t w)
{
return asm_parity32_1((unsigned int)(w >> 32) ^ (unsigned int)w);
}
static inline int asm_parity64_2(uint64_t w)
{
return asm_parity32_2((unsigned int)(w >> 32) ^ (unsigned int)w);
}
#endif
int main(int argc, char **argv)
{
int ok = 1;
int count = 1000, i;
if (argc >= 2)
count = atoi(argv[1]);
srand((unsigned)time(NULL));
for (i = 0; i < count; i++) {
uint64_t w = rand() | (uint64_t)rand() << 32;
int p4_1 = c_parity4(w);
int p4_2 = asm_parity4(w);
int p8_1 = c_parity8(w);
int p8_2 = asm_parity8(w);
int p16_1 = c_parity16(w);
int p16_2 = asm_parity16(w);
int p32_1 = c_parity32(w);
int p32_2 = asm_parity32_1(w);
int p32_3 = asm_parity32_2(w);
int p64_1 = c_parity64(w);
int p64_2 = asm_parity64_1(w);
int p64_3 = asm_parity64_2(w);
if (p4_1 != p4_2 ||
p8_1 != p8_2 ||
p16_1 != p16_2 ||
p32_1 != p32_2 || p32_1 != p32_3 ||
p64_1 != p64_2 || p64_1 != p64_3) {
fprintf(stderr, "Err: %llx\n"
"\tc_parity4 = %d, asm_parity4 = %d,\n"
"\tc_parity8 = %d, asm_parity8 = %d,\n"
"\tc_parity16 = %d, asm_parity16 = %d,\n"
"\tc_parity32 = %d, asm_parity32_1 = %d,
asm_parity32_2 = %d\n"
"\tc_parity64 = %d, asm_parity64_1 = %d,
asm_parity64_2 = %d\n",
w, p4_1, p4_2, p8_1, p8_2, p16_1, p16_2,
p32_1, p32_2, p32_3, p64_1, p64_2, p64_3);
ok = 0;
}
}
fprintf(stderr, "%s\n", ok ? "OK" : "FAIL");
return 0;
}--- 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
include/asm-generic/bitops.h +1 -0
@@ -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>
include/asm-generic/bitops/arch_parity.h new file +39 -0
@@ -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_ */
include/asm-generic/bitops/const_parity.h new file +36 -0
@@ -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_ */
include/asm-generic/bitops/parity.h new file +7 -0
@@ -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_ */
include/linux/bitops.h +5 -0
@@ -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
Signature · 1 line
2.5.0
PATCH v2 2/30 Include generic parity.h in some architectures' bitops.h
From: Zhaoxiu Zeng <[email protected]>
Use the generic version
--- arch/arc/include/asm/bitops.h | 1 + arch/arm/include/asm/bitops.h | 1 + arch/arm64/include/asm/bitops.h | 1 + arch/avr32/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 + 18 files changed, 18 insertions(+)
arch/arc/include/asm/bitops.h +0 -0
@@ -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>
arch/arm/include/asm/bitops.h +1 -0
@@ -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__
(quoted diff) +0 -0
b/arch/arm64/include/asm/bitops.h
index 9c19594..eac4965 100644
arch/arm64/include/asm/bitops.h +0 -0
@@ -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>
(quoted diff) +0 -0
b/arch/avr32/include/asm/bitops.h
index 910d537..9f4a2ce 100644
arch/avr32/include/asm/bitops.h +1 -0
@@ -298,6 +298,7 @@ static inline int ffs(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/lock.h> extern unsigned long find_next_zero_bit_le(const void *addr,
arch/c6x/include/asm/bitops.h +1 -0
@@ -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>
arch/cris/include/asm/bitops.h +1 -0
@@ -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>
arch/frv/include/asm/bitops.h +1 -0
@@ -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>
(quoted diff) +0 -0
b/arch/h8300/include/asm/bitops.h
index 05999ab..e392db2 100644
arch/h8300/include/asm/bitops.h +1 -0
@@ -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>
(quoted diff) +0 -0
b/arch/hexagon/include/asm/bitops.h
index 5e4a59b..2df614e 100644
arch/hexagon/include/asm/bitops.h +1 -0
@@ -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>
arch/m32r/include/asm/bitops.h +0 -0
@@ -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__ */
arch/m68k/include/asm/bitops.h +1 -0
@@ -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__ */
(quoted diff) +0 -0
b/arch/metag/include/asm/bitops.h
index 2671134..ad13087 100644
arch/metag/include/asm/bitops.h +1 -0
@@ -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>
(quoted diff) +0 -0
b/arch/mn10300/include/asm/bitops.h
index fe6f8e2..60761b7 100644
arch/mn10300/include/asm/bitops.h +1 -0
@@ -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>
(quoted diff) +0 -0
b/arch/openrisc/include/asm/bitops.h
index 3003cda..8c97642 100644
arch/openrisc/include/asm/bitops.h +1 -0
@@ -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>
(quoted diff) +0 -0
b/arch/parisc/include/asm/bitops.h
index 3f9406d..867ba10 100644
arch/parisc/include/asm/bitops.h +1 -0
@@ -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>
arch/s390/include/asm/bitops.h +1 -0
@@ -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>
arch/sh/include/asm/bitops.h +1 -0
@@ -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>
(quoted diff) +0 -0
b/arch/xtensa/include/asm/bitops.h
index 3f44fa2..981fa83 100644
arch/xtensa/include/asm/bitops.h +0 -0
@@ -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>
Signature · 1 line
2.5.0
PATCH v2 2/30 Include generic parity.h in some architectures' bitops.h
From: Zhaoxiu Zeng <[email protected]>
Use the generic version
--- arch/arc/include/asm/bitops.h | 1 + arch/arm/include/asm/bitops.h | 1 + arch/arm64/include/asm/bitops.h | 1 + arch/avr32/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 + 18 files changed, 18 insertions(+)
arch/arc/include/asm/bitops.h +1 -0
@@ -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>
arch/arm/include/asm/bitops.h +1 -0
@@ -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__
arch/arm64/include/asm/bitops.h +1 -0
@@ -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>
arch/avr32/include/asm/bitops.h +1 -0
@@ -298,6 +298,7 @@ static inline int ffs(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/lock.h> extern unsigned long find_next_zero_bit_le(const void *addr,
arch/c6x/include/asm/bitops.h +1 -0
@@ -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>
arch/cris/include/asm/bitops.h +1 -0
@@ -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>
arch/frv/include/asm/bitops.h +1 -0
@@ -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>
arch/h8300/include/asm/bitops.h +1 -0
@@ -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>
arch/hexagon/include/asm/bitops.h +1 -0
@@ -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>
arch/m32r/include/asm/bitops.h +1 -0
@@ -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__ */
arch/m68k/include/asm/bitops.h +1 -0
@@ -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__ */
arch/metag/include/asm/bitops.h +1 -0
@@ -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>
arch/mn10300/include/asm/bitops.h +1 -0
@@ -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>
arch/openrisc/include/asm/bitops.h +1 -0
@@ -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>
arch/parisc/include/asm/bitops.h +1 -0
@@ -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>
arch/s390/include/asm/bitops.h +1 -0
@@ -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>
arch/sh/include/asm/bitops.h +1 -0
@@ -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>
arch/xtensa/include/asm/bitops.h +1 -0
@@ -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>
Signature · 1 line
2.5.0
PATCH v2 2/30 Include generic parity.h in some architectures' bitops.h
Hi?Zhaoxiu,
Quoted 24 lines · On Wed, 2016-04-06 at 16:41 +0800, zengzhaoxiu at 163.com wrote:
From: Zhaoxiu Zeng <[email protected]>
Use the generic version
Signed-off-by Zhaoxiu Zeng <[email protected]>---
?arch/arc/include/asm/bitops.h??????| 1 + ?arch/arm/include/asm/bitops.h??????| 1 + ?arch/arm64/include/asm/bitops.h????| 1 + ?arch/avr32/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 +
Quoted 1 line
?18 files changed, 18 insertions(+)
Could you please include a changelog below your commit message? Otherwise it's barely possible to understand what that v2 improves/fixes.
Also it makes sense to send at least cover letter to all people mentioned at least in one patch of the series. That gives an idea what this series does and in particular why patch I'm mentioned in is required.
-Alexey
PATCH v2 2/30 Include generic parity.h in some architectures' bitops.h
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
Use the generic version
--- arch/arc/include/asm/bitops.h | 1 + arch/arm/include/asm/bitops.h | 1 + arch/arm64/include/asm/bitops.h | 1 + arch/avr32/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 + 18 files changed, 18 insertions(+)
arch/arc/include/asm/bitops.h +1 -0
@@ -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>
arch/arm/include/asm/bitops.h +1 -0
@@ -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__
arch/arm64/include/asm/bitops.h +1 -0
@@ -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>
arch/avr32/include/asm/bitops.h +1 -0
@@ -298,6 +298,7 @@ static inline int ffs(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/lock.h> extern unsigned long find_next_zero_bit_le(const void *addr,
arch/c6x/include/asm/bitops.h +1 -0
@@ -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>
arch/cris/include/asm/bitops.h +1 -0
@@ -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>
arch/frv/include/asm/bitops.h +1 -0
@@ -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>
arch/h8300/include/asm/bitops.h +1 -0
@@ -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>
arch/hexagon/include/asm/bitops.h +1 -0
@@ -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>
arch/m32r/include/asm/bitops.h +1 -0
@@ -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__ */
arch/m68k/include/asm/bitops.h +1 -0
@@ -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__ */
arch/metag/include/asm/bitops.h +1 -0
@@ -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>
arch/mn10300/include/asm/bitops.h +1 -0
@@ -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>
arch/openrisc/include/asm/bitops.h +1 -0
@@ -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>
arch/parisc/include/asm/bitops.h +1 -0
@@ -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>
arch/s390/include/asm/bitops.h +1 -0
@@ -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>
arch/sh/include/asm/bitops.h +1 -0
@@ -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>
arch/xtensa/include/asm/bitops.h +1 -0
@@ -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>
Signature · 1 line
2.5.0
PATCH v2 2/30 Include generic parity.h in some architectures' bitops.h
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
Use the generic version
--- arch/arc/include/asm/bitops.h | 1 + arch/arm/include/asm/bitops.h | 1 + arch/arm64/include/asm/bitops.h | 1 + arch/avr32/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 + 18 files changed, 18 insertions(+)
arch/arc/include/asm/bitops.h +1 -0
@@ -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>
arch/arm/include/asm/bitops.h +1 -0
@@ -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__
arch/arm64/include/asm/bitops.h +1 -0
@@ -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>
arch/avr32/include/asm/bitops.h +1 -0
@@ -298,6 +298,7 @@ static inline int ffs(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/lock.h> extern unsigned long find_next_zero_bit_le(const void *addr,
arch/c6x/include/asm/bitops.h +1 -0
@@ -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>
arch/cris/include/asm/bitops.h +1 -0
@@ -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>
arch/frv/include/asm/bitops.h +1 -0
@@ -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>
arch/h8300/include/asm/bitops.h +1 -0
@@ -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>
arch/hexagon/include/asm/bitops.h +1 -0
@@ -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>
arch/m32r/include/asm/bitops.h +1 -0
@@ -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__ */
arch/m68k/include/asm/bitops.h +1 -0
@@ -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__ */
arch/metag/include/asm/bitops.h +1 -0
@@ -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>
arch/mn10300/include/asm/bitops.h +1 -0
@@ -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>
arch/openrisc/include/asm/bitops.h +1 -0
@@ -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>
arch/parisc/include/asm/bitops.h +1 -0
@@ -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>
arch/s390/include/asm/bitops.h +1 -0
@@ -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>
arch/sh/include/asm/bitops.h +1 -0
@@ -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>
arch/xtensa/include/asm/bitops.h +1 -0
@@ -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>
Signature · 1 line
2.5.0
Quoted 4 lines · Zeng Zhaoxiu
From: Zhaoxiu Zeng <[email protected]>
These patches provide generic and architecture-specific odd parity calculations.
Hi Zeng.
Can you please fix your mail script.
I see only 1/30 (sent to linux-arch) - and patch looks mangeled (broken lines) No mail was sent to sparclinux - but sparc was mentioned.
git send-mail usually do the trick.
Sam
Quoted 7 lines · Sam Ravnborg
Quoted 4 lines · Zeng Zhaoxiu
From: Zhaoxiu Zeng <[email protected]>
These patches provide generic and architecture-specific odd parity calculations.
Hi Zeng.
Quoted 7 lines
Can you please fix your mail script.
I see only 1/30 (sent to linux-arch) - and patch looks mangeled (broken lines) No mail was sent to sparclinux - but sparc was mentioned.git send-mail usually do the trick.
Sam
When I do "git send-email", I got:
...
5.7.14 JTibJDWdGxPcfa-E9KgtF-grMQl9w> Please log in via your web browser and 5.7.14 then try again.
5.7.14 Learn more at
5.7.14 https://support.google.com/mail/answer/78754 zp5sm464879pac.9 - gsmtp
...
So I use thunderbird to send email, but the text wrap error.
Quoted 24 lines · Zeng Zhaoxiu
Quoted 7 lines · Sam Ravnborg
Quoted 4 lines · Zeng Zhaoxiu
From: Zhaoxiu Zeng <[email protected]>
These patches provide generic and architecture-specific odd parity calculations.
Hi Zeng.
Quoted 7 lines
Can you please fix your mail script.
I see only 1/30 (sent to linux-arch) - and patch looks mangeled (broken lines) No mail was sent to sparclinux - but sparc was mentioned.git send-mail usually do the trick.
Sam
When I do "git send-email", I got:
...
5.7.14 JTibJDWdGxPcfa-E9KgtF-grMQl9w> Please log in via your web browser and 5.7.14 then try again.
5.7.14 Learn more at
5.7.14 https://support.google.com/mail/answer/78754 zp5sm464879pac.9 - gsmtp
...
Quoted 1 line
So I use thunderbird to send email, but the text wrap error.
Please try to search for "How to configure git send-email to use Gmail" and follow the instructions given in some of the links.
Test with your own mail address before you send to a list.
Also linux-arch only saw 1/30 - make sure to address this too.
Sam
PATCH v2 1/30 bitops: add parity functions
In reply to Sam RavnborgFrom: Zhaoxiu Zeng <[email protected]>
These patches provide generic and architecture-specific odd parity calculations.
I did not use GCC's __builtin_parity* functions, based on the following reasons:
1. I don't know where to identify which version of GCC from the beginning supported __builtin_parity for the architecture.
2. For the architecture that doesn't has popcount instruction, GCC instead use "call __paritysi2" (__paritydi2 for 64-bits). So if use __builtin_parity, we must provide __paritysi2 and __paritydi2 functions for these architectures. Additionally, parity4,8,16 might be "__builtin_parity(x & mask)", but the "& mask" operation is totally unnecessary.
3. For the architecture that has popcount instruction, we do the same things.
4. For powerpc64, sparc64, and x86, we do runtime patching to use popcount instruction if the CPU support.
I have compiled successfully with x86_64_defconfig, i386_defconfig, pseries_defconfig and sparc64_defconfig. And I used the following codes to test:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#ifdef __x86_64__
/* popcnt %edi, %eax -- redundant REX prefix for alignment */
#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7"
/* popcnt %rdi, %rax */
#define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"
#define REG_IN "D"
#define REG_OUT "a"
#else
/* popcnt %eax, %eax */
#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0"
#define REG_IN "a"
#define REG_OUT "a"
#endif
static inline int c_parity4(unsigned int w)
{
w &= 0xf;
return (0x6996 >> w) & 1;
}
static inline int c_parity8(unsigned int w)
{
w ^= w >> 4;
return c_parity4(w);
}
static inline int c_parity16(unsigned int w)
{
w ^= w >> 8;
return c_parity8(w);
}
static inline int c_parity32(unsigned int w)
{
w ^= w >> 16;
return c_parity16(w);
}
static inline int c_parity64(uint64_t w)
{
return c_parity32((unsigned int)w ^ (unsigned int)(w >> 32));
}
static inline int asm_parity4(unsigned int w)
{
unsigned int res = 0;
asm("test $0xf, %1 \n"
"setpo %b0 \n"
: "+q" (res)
: "r" (w)
: "cc");
return res;
}
static inline int asm_parity8(unsigned int w)
{
unsigned int res = 0;
asm("test %1, %1 \n"
"setpo %b0 \n"
: "+q" (res)
: "r" (w)
: "cc");
return res;
}
static inline int asm_parity16(unsigned int w)
{
unsigned int res = 0;
asm("xor %h1, %b1 \n"
"setpo %b0 \n"
: "+q" (res), "+q" (w)
: : "cc");
return res;
}
static inline int asm_parity32_1(unsigned int w)
{
unsigned int res;
w ^= w >> 16;
asm("xor %%ah, %%al \n"
"mov $0, %%eax \n"
"setpo %%al \n"
: "=a" (res)
: "a" (w)
: "cc");
return res;
}
static inline int asm_parity32_2(unsigned int w)
{
unsigned int res;
asm(POPCNT32 " \n"
"andl $1, %0 \n"
: "="REG_OUT (res)
: REG_IN (w)
: "cc");
return res;
}
#ifdef __x86_64__
static inline int asm_parity64_1(uint64_t w)
{
unsigned int res = (unsigned int)w ^ (unsigned int)(w >> 32);
res ^= res >> 16;
asm("xor %%ah, %%al \n"
"mov $0, %%eax \n"
"setpo %%al \n"
: "=a" (res)
: "a" (res)
: "cc");
return res;
}
static inline int asm_parity64_2(uint64_t w)
{
unsigned int res;
asm(POPCNT64 " \n"
"andl $1, %0 \n"
: "="REG_OUT (res)
: REG_IN (w)
: "cc");
return res;
}
#else
static inline int asm_parity64_1(uint64_t w)
{
return asm_parity32_1((unsigned int)(w >> 32) ^ (unsigned int)w);
}
static inline int asm_parity64_2(uint64_t w)
{
return asm_parity32_2((unsigned int)(w >> 32) ^ (unsigned int)w);
}
#endif
int main(int argc, char **argv)
{
int ok = 1;
int count = 1000, i;
if (argc >= 2)
count = atoi(argv[1]);
srand((unsigned)time(NULL));
for (i = 0; i < count; i++) {
uint64_t w = rand() | (uint64_t)rand() << 32;
int p4_1 = c_parity4(w);
int p4_2 = asm_parity4(w);
int p8_1 = c_parity8(w);
int p8_2 = asm_parity8(w);
int p16_1 = c_parity16(w);
int p16_2 = asm_parity16(w);
int p32_1 = c_parity32(w);
int p32_2 = asm_parity32_1(w);
int p32_3 = asm_parity32_2(w);
int p64_1 = c_parity64(w);
int p64_2 = asm_parity64_1(w);
int p64_3 = asm_parity64_2(w);
if (p4_1 != p4_2 ||
p8_1 != p8_2 ||
p16_1 != p16_2 ||
p32_1 != p32_2 || p32_1 != p32_3 ||
p64_1 != p64_2 || p64_1 != p64_3) {
fprintf(stderr, "Err: %llx\n"
"\tc_parity4 = %d, asm_parity4 = %d,\n"
"\tc_parity8 = %d, asm_parity8 = %d,\n"
"\tc_parity16 = %d, asm_parity16 = %d,\n"
"\tc_parity32 = %d, asm_parity32_1 = %d, asm_parity32_2 = %d\n"
"\tc_parity64 = %d, asm_parity64_1 = %d, asm_parity64_2 = %d\n",
w, p4_1, p4_2, p8_1, p8_2, p16_1, p16_2, p32_1, p32_2, p32_3, p64_1, p64_2, p64_3);
ok = 0;
}
}
fprintf(stderr, "%s\n", ok ? "OK" : "FAIL");
return 0;
}--- 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
include/asm-generic/bitops.h +1 -0
@@ -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>
include/asm-generic/bitops/arch_parity.h new file +39 -0
@@ -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_ */
include/asm-generic/bitops/const_parity.h new file +36 -0
@@ -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_ */
include/asm-generic/bitops/parity.h new file +7 -0
@@ -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_ */
include/linux/bitops.h +5 -0
@@ -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
Signature · 1 line
2.5.0
PATCH v2 3/30 Add alpha-specific parity functions
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- arch/alpha/include/asm/bitops.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
arch/alpha/include/asm/bitops.h +27 -0
@@ -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__ */
Signature · 1 line
2.5.0
PATCH v2 4/30 Add blackfin-specific parity functions
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- arch/blackfin/include/asm/bitops.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
arch/blackfin/include/asm/bitops.h +31 -0
@@ -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 w 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 */
Signature · 1 line
2.5.0
PATCH v2 5/30 Add ia64-specific parity functions
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- arch/ia64/include/asm/bitops.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
arch/ia64/include/asm/bitops.h +31 -0
@@ -439,6 +439,37 @@ 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 ; +} + +static __inline__unsigned int __arch_parity32 (unsigned int x) +{ +return __arch_parity64 ((unsigned long )x <<32 ); +} + +static __inline__unsigned int __arch_parity16 (unsigned int x) +{ +return __arch_parity64 ((unsigned long )x <<48 ); +} + +static __inline__unsigned int __arch_parity8 (unsigned int x) +{ +return __arch_parity64 ((unsigned long )x <<56 ); +} + +static __inline__unsigned int __arch_parity4 (unsigned int x) +{ +return __arch_parity64 ((unsigned long )x <<60 ); +} + +#include <asm-generic/bitops/const_parity.h> +#endif /* __KERNEL__ */ #include <asm-generic/bitops/find.h>
Signature · 1 line
2.5.0
PATCH v2 6/30 Add mips-specific parity functions
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
Lifted from arch_hweight.h
--- 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
arch/mips/include/asm/arch_parity.h new file +44 -0
@@ -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 */
arch/mips/include/asm/bitops.h +3 -0
@@ -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>
Signature · 1 line
2.5.0
PATCH v2 6/30 Add mips-specific parity functions
From: Zhaoxiu Zeng <[email protected]>
Lifted from arch_hweight.h
--- arch/mips/include/asm/arch_parity.h | 43 +++++++++++++++++++++++++++++++++++++ arch/mips/include/asm/bitops.h | 3 +++ 2 files changed, 46 insertions(+) create mode 100644 arch/mips/include/asm/arch_parity.h
arch/mips/include/asm/arch_parity.h new file +43 -0
@@ -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_parity.h> +#endif + +#endif /* _ASM_ARCH_PARITY_H */
arch/mips/include/asm/bitops.h +3 -0
@@ -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>
Signature · 1 line
2.5.0
PATCH v2 7/30 Add powerpc-specific parity functions
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
Use runtime patching for ppc64, lifted from hweight_64
--- arch/powerpc/include/asm/bitops.h | 11 ++++ arch/powerpc/lib/Makefile | 2 +- arch/powerpc/lib/parity_64.S | 107 ++++++++++++++++++++++++++++++++++++++ arch/powerpc/lib/ppc_ksyms.c | 5 ++ 4 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/lib/parity_64.S
arch/powerpc/include/asm/bitops.h +11 -0
@@ -269,8 +269,19 @@ 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> +static inline unsigned int __arch_parity4 (unsigned int w) +{ + w &=0xf ; +return (0x6996 >> w) &1 ; +} +unsigned int __arch_parity8 (unsigned int w); +unsigned int __arch_parity16 (unsigned int w); +unsigned int __arch_parity32 (unsigned int w); +unsigned int __arch_parity64 (__u64 w); +#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>
arch/powerpc/lib/Makefile +1 -1
@@ -16,7 +16,7 @@ obj-$(CONFIG_PPC32) += div64.o copy_32.o obj64-y += copypage_64.o copyuser_64.o usercopy_64.o mem_64.o hweight_64.o \ copyuser_power7.o string_64.o copypage_power7.o memcpy_power7.o \ - memcpy_64.o memcmp_64.o + memcpy_64.o memcmp_64.o parity_64.o obj64-$(CONFIG_SMP) += locks.o obj64-$(CONFIG_ALTIVEC) += vmx-helper.o
arch/powerpc/lib/parity_64.S new file +107 -0
107 lines not on this page · raw message
arch/powerpc/lib/ppc_ksyms.c +5 -0
@@ -30,4 +30,9 @@ EXPORT_SYMBOL(__arch_hweight8);EXPORT_SYMBOL (__arch_hweight16);EXPORT_SYMBOL (__arch_hweight32);EXPORT_SYMBOL (__arch_hweight64); + +EXPORT_SYMBOL (__arch_parity8); +EXPORT_SYMBOL (__arch_parity16); +EXPORT_SYMBOL (__arch_parity32); +EXPORT_SYMBOL (__arch_parity64);#endif
Signature · 1 line
2.5.0
PATCH v2 8/30 Add sparc-specific parity functions
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
Use runtime patching for sparc64, lifted from hweight
--- arch/sparc/include/asm/bitops_32.h | 1 + arch/sparc/include/asm/bitops_64.h | 18 ++++++++ arch/sparc/kernel/sparc_ksyms_64.c | 6 +++ arch/sparc/lib/Makefile | 2 +- arch/sparc/lib/parity.S | 93 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 arch/sparc/lib/parity.S
arch/sparc/include/asm/bitops_32.h +1 -0
@@ -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>
arch/sparc/include/asm/bitops_64.h +18 -0
@@ -47,6 +47,24 @@ 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 w modulo 2. +*/ + +static inline unsigned int __arch_parity4 (unsigned int w) +{ + w &=0xf ; +return (0x6996 >> w) &1 ; +} +unsigned int __arch_parity8 (unsigned int w); +unsigned int __arch_parity16 (unsigned int w); +unsigned int __arch_parity32 (unsigned int w); +unsigned int __arch_parity64 (__u64 w); + +#include <asm-generic/bitops/const_parity.h> +#include <asm-generic/bitops/lock.h> #endif /* __KERNEL__ */
arch/sparc/kernel/sparc_ksyms_64.c +6 -0
@@ -45,6 +45,12 @@ EXPORT_SYMBOL(__arch_hweight16);EXPORT_SYMBOL (__arch_hweight32);EXPORT_SYMBOL (__arch_hweight64); +/* from parity.S */ +EXPORT_SYMBOL (__arch_parity8); +EXPORT_SYMBOL (__arch_parity16); +EXPORT_SYMBOL (__arch_parity32); +EXPORT_SYMBOL (__arch_parity64); +/* from ffs_ffz.S */ EXPORT_SYMBOL (ffs);EXPORT_SYMBOL (__ffs);
arch/sparc/lib/Makefile +1 -1
@@ -39,7 +39,7 @@ lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o -lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o +lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o parity.o obj-$(CONFIG_SPARC64) += iomap.o obj-$(CONFIG_SPARC32) += atomic32.o ucmpdi2.o
arch/sparc/lib/parity.S new file +93 -0
93 lines not on this page · raw message
Signature · 1 line
2.5.0
Re: [PATCH v2 08/30] Add sparc-specific parity functions
Quoted 8 lines · On Wed, Apr 06, 2016 at 05:07:27PM +0800, [email protected] wrote:
arch/sparc/lib/parity.S new file +6
-0+static inline unsigned int __arch_parity4(unsigned int w) + return (0x6996 >> w) & 1; +ENTRY(__arch_parity8) + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 +ENTRY(__arch_parity16)
arch/sparc/lib/parity.S line 83
Quoted 10 lines
arch/sparc/lib/parity.S new file +8
-0+ sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 +ENTRY(__arch_parity32) + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 +ENTRY(__arch_parity64) + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1
Given how many times the magic constant is repeated, maybe it would make sense to give it a name?
Signature · 1 line
2. That which causes joy or happiness.
Re: [PATCH v2 08/30] Add sparc-specific parity functions
In reply to [email protected]Hi Zeng.
Quoted 2 lines
Use runtime patching for sparc64, lifted from hweight
No errors found in patch - but a few comments.
In general patch looks good.
Quoted 6 lines
+++
b/arch/sparc/include/asm/bitops_64.harch/sparc/include/asm/bitops_64.h +1
-0@@ -47,6 +47,24 @@ unsigned int __arch_hweight16(unsigned int w);unsigned int __arch_hweight8 (unsigned int w);#include <asm-generic/bitops/const_hweight.h> +
arch/sparc/include/asm/bitops_64.h unsigned int __arch_hweight16(unsigned int w); · line 60
Quoted 10 lines
arch/sparc/include/asm/bitops_64.h +10
-0+/* +* parityN: returns the parity of a N-bit word, +* i.e. the number of 1-bits in w modulo 2. +*/ + +static inline unsigned int __arch_parity4 (unsigned int w) +{ + w &=0xf ; +return (0x6996 >> w) &1 ; +}
As Josef already said - this constant should have a name. PARITY_BIT
?
arch/sparc/kernel/sparc_ksyms_64.c EXPORT_SYMBOL(__arch_hweight16); · line 52
Quoted 10 lines
arch/sparc/kernel/sparc_ksyms_64.c +6
-0+++ b/arch/sparc/kernel/sparc_ksyms_64.c@@ -45,6 +45,12 @@ EXPORT_SYMBOL(__arch_hweight16);EXPORT_SYMBOL (__arch_hweight32);EXPORT_SYMBOL (__arch_hweight64); +/* from parity.S */ +EXPORT_SYMBOL (__arch_parity8); +EXPORT_SYMBOL (__arch_parity16); +EXPORT_SYMBOL (__arch_parity32); +EXPORT_SYMBOL (__arch_parity64);
Did you compile this?
I wonder if bitops_64.h is indirectly included.
Quoted 9 lines
index 0000000..b1945e3
arch/sparc/lib/parity.S new file +5
-0@@ -0,0 +1,93 @@ +#include <linux/linkage.h> + + .text + .align 32 +
arch/sparc/lib/parity.S line 15
Quoted 10 lines
arch/sparc/lib/parity.S new file +10
-0+ENTRY(__arch_parity8) + srl %o0, 4, %g1 + xor %o0, %g1, %o0 + and %o0, 0xf, %o0 + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 + srl %g1, %o0, %o0 + retl + and %o0, 1, %o0 +ENDPROC(__arch_parity8)
I know the level of comments in hweight is equal to none. But please do not follow this bad example.
At least for each function a one-liner of the C code. And in the top of the file maybe two lines that the functions are patched at run-time if the processor has popc available.
Sam
Re: [PATCH v2 08/30] Add sparc-specific parity functions
Quoted 5 lines · Sam Ravnborg
Hi Zeng.
Quoted 1 line
Use runtime patching for sparc64, lifted from hweight
No errors found in patch - but a few comments.
In general patch looks good.
Thanks. Sparc, powerpc, and x86 are all new to me.
Quoted 4 lines
Quoted 4 lines
+++
b/arch/sparc/include/asm/bitops_64.harch/sparc/include/asm/bitops_64.h +0
-0@@ -47,6 +47,24 @@ unsigned int __arch_hweight16(unsigned int w);unsigned int __arch_hweight8 (unsigned int w);
Quoted 16 lines
arch/sparc/include/asm/bitops_64.h unsigned int __arch_hweight16(unsigned int w); · line 60
Quoted 12 lines
arch/sparc/include/asm/bitops_64.h +11
-0#include <asm-generic/bitops/const_hweight.h> + +/* +* parityN: returns the parity of a N-bit word, +* i.e. the number of 1-bits in w modulo 2. +*/ + +static inline unsigned int __arch_parity4 (unsigned int w) +{ + w &=0xf ; +return (0x6996 >> w) &1 ; +}As Josef already said - this constant should have a name.
PARITY_BIT
?
Maybe PARITY_MAGIC?
Quoted 5 lines
Quoted 5 lines
arch/sparc/kernel/sparc_ksyms_64.c +1
-0+++ b/arch/sparc/kernel/sparc_ksyms_64.c@@ -45,6 +45,12 @@ EXPORT_SYMBOL(__arch_hweight16);EXPORT_SYMBOL (__arch_hweight32);EXPORT_SYMBOL (__arch_hweight64);
Quoted 7 lines
arch/sparc/kernel/sparc_ksyms_64.c EXPORT_SYMBOL(__arch_hweight16); · line 52
Quoted 5 lines
arch/sparc/kernel/sparc_ksyms_64.c +5
-0+/* from parity.S */ +EXPORT_SYMBOL (__arch_parity8); +EXPORT_SYMBOL (__arch_parity16); +EXPORT_SYMBOL (__arch_parity32); +EXPORT_SYMBOL (__arch_parity64);Did you compile this?
I wonder ifbitops_64.his indirectly included.
Yes.
Quoted 26 lines
Quoted 9 lines
index 0000000..b1945e3
arch/sparc/lib/parity.S new file +5
-0@@ -0,0 +1,93 @@ +#include <linux/linkage.h> + + .text + .align 32 +arch/sparc/lib/parity.S line 15
Quoted 10 lines
arch/sparc/lib/parity.S new file +10
-0+ENTRY(__arch_parity8) + srl %o0, 4, %g1 + xor %o0, %g1, %o0 + and %o0, 0xf, %o0 + sethi %hi(0x6996), %g1 + or %g1, %lo(0x6996), %g1 + srl %g1, %o0, %o0 + retl + and %o0, 1, %o0 +ENDPROC(__arch_parity8)I know the level of comments in hweight is equal to none. But please do not follow this bad example.
At least for each function a one-liner of the C code. And in the top of the file maybe two lines that the functions are patched at run-time if the processor has popc available.
Quoted 1 line
Sam
OK. I will try, but my english is very poor! :-)
PATCH v2 9/30 Add tile-specific parity functions
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- arch/tile/include/asm/bitops.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
arch/tile/include/asm/bitops.h +26 -0
@@ -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>
Signature · 1 line
2.5.0
Re: [PATCH v2 09/30] Add tile-specific parity functions
Quoted 6 lines · On 4/6/2016 5:08 AM, [email protected] wrote:
From: Zhaoxiu Zeng<[email protected]>
Signed-off-by Zhaoxiu Zeng<[email protected]>--- arch/tile/include/asm/bitops.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Since all the code you are adding here is architecture-independent, I think it would make more sense to have it be in a file like include/asm-generic/bitops/parity-popcount.h, which can then be included from arch/tile/include/asm/bitops.h.
Signature · 2 lines
Chris Metcalf, Mellanox Technologies http://www.mellanox.com
Re: [PATCH v2 09/30] Add tile-specific parity functions
Quoted 8 lines · Chris Metcalf
Quoted 6 lines · On 4/6/2016 5:08 AM, [email protected] wrote:
From: Zhaoxiu Zeng<[email protected]>
Signed-off-by Zhaoxiu Zeng<[email protected]>--- arch/tile/include/asm/bitops.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
Quoted 5 lines
Since all the code you are adding here is architecture-independent, I think it would make more sense to have it be in a file like
include/asm-generic/bitops/parity-popcount.h, which can then be included fromarch/tile/include/asm/bitops.h.
Agreed, thanks!
PATCH v2 10/30 Add x86-specific parity functions
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
Use alternatives, lifted from arch_hweight
--- arch/x86/include/asm/arch_hweight.h | 5 ++ arch/x86/include/asm/arch_parity.h | 102 ++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/bitops.h | 4 +- arch/x86/lib/Makefile | 8 +++ arch/x86/lib/parity.c | 32 ++++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/arch_parity.h create mode 100644 arch/x86/lib/parity.c
arch/x86/include/asm/arch_hweight.h +5 -0
@@ -63,4 +63,9 @@ static __always_inline unsigned long __arch_hweight64(__u64 w) }#endif /* CONFIG_X86_32 */ +#undef POPCNT32 +#undef POPCNT64 +#undef REG_IN +#undef REG_OUT +#endif
arch/x86/include/asm/arch_parity.h new file +100 -0
100 lines not on this page · raw message
+
+#endif
arch/x86/include/asm/bitops.h +3 -1
@@ -498,9 +498,11 @@ static __always_inline int fls64(__u64 x)#include <asm-generic/bitops/sched.h> #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-setbit.h>
arch/x86/lib/Makefile +8 -0
@@ -4,6 +4,9 @@ # Produces uninteresting flaky coverage. KCOV_INSTRUMENT_delay.o := n +# Kernel does not boot if we instrument this file as it uses custom calling +# convention (see CONFIG_ARCH_HWEIGHT_CFLAGS). +KCOV_INSTRUMENT_parity.o := n inat_tables_script = $(srctree)/arch/x86/tools/gen-insn-attr-x86.awk inat_tables_maps = $(srctree)/arch/x86/lib/x86-opcode-map.txt
@@ -45,3 +48,8 @@ else lib-y += copy_user_64.o lib-y += cmpxchg16b_emu.o endif + +GCOV_PROFILE_parity.o := n +CFLAGS_parity.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) +obj-y += parity.o +
arch/x86/lib/parity.c new file +32 -0
@@ -0,0 +1,32 @@ +#include <linux/export.h> +#include <linux/bitops.h> + +unsigned int __sw_parity32 (unsigned int w) +{ +unsigned int res; + w ^= w >>16 ; + asm("xor %%ah, %%al \n" +"mov $0, %%eax \n" +"setpo %%al \n" + :"=a" (res) + :"a" (w) + :"cc" ); +return res; +} +EXPORT_SYMBOL (__sw_parity32); + +#ifndef CONFIG_X86_32 +unsigned int __sw_parity64 (__u64 w) +{ +unsigned int res = (unsigned int )w ^ (unsigned int )(w >>32 ); + res ^= res >>16 ; + asm("xor %%ah, %%al \n" +"mov $0, %%eax \n" +"setpo %%al \n" + :"=a" (res) + :"a" (res) + :"cc" ); +return res; +} +EXPORT_SYMBOL (__sw_parity64); +#endif
Signature · 1 line
2.5.0
Re: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 14 lines · On Wed, Apr 06, 2016 at 05:14:45PM +0800, [email protected] wrote:
From: Zhaoxiu Zeng <[email protected]>
Use alternatives, lifted from
arch_hweightSigned-off-by Zhaoxiu Zeng <[email protected]>--- arch/x86/include/asm/arch_hweight.h | 5 ++ arch/x86/include/asm/arch_parity.h | 102 ++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/bitops.h | 4 +- arch/x86/lib/Makefile | 8 +++ arch/x86/lib/parity.c | 32 ++++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/arch_parity.h create mode 100644 arch/x86/lib/parity.c
...
arch/x86/include/asm/arch_parity.h line 73
Quoted 8 lines
arch/x86/include/asm/arch_parity.h new file +8
-0+static __always_inline unsigned int __arch_parity32(unsigned int w) +{ +unsigned int res; + + asm(ALTERNATIVE("call __sw_parity32", POPCNT32 "; and $1, %0", X86_FEATURE_POPCNT) + : "="REG_OUT (res) + : REG_IN (w) + : "cc");
So why all that churn instead of simply doing:
static __always_inline unsigned int __arch_parity32(unsigned int w)
{
return hweight32(w) & 1;
}Ditto for the 64-bit version.
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- Re: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 29 lines · On Wed, 6 Apr 2016 12:13:00 +0200 Borislav Petkov <[email protected]> wrote:
Quoted 14 lines · On Wed, Apr 06, 2016 at 05:14:45PM +0800, [email protected] wrote:
From: Zhaoxiu Zeng <[email protected]>
Use alternatives, lifted from
arch_hweightSigned-off-by Zhaoxiu Zeng <[email protected]>--- arch/x86/include/asm/arch_hweight.h | 5 ++ arch/x86/include/asm/arch_parity.h | 102 ++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/bitops.h | 4 +- arch/x86/lib/Makefile | 8 +++ arch/x86/lib/parity.c | 32 ++++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/arch_parity.h create mode 100644 arch/x86/lib/parity.c...
arch/x86/include/asm/arch_parity.h line 73
Quoted 8 lines
arch/x86/include/asm/arch_parity.h new file +8
-0+static __always_inline unsigned int __arch_parity32(unsigned int w) +{ +unsigned int res; + + asm(ALTERNATIVE("call __sw_parity32", POPCNT32 "; and $1, %0", X86_FEATURE_POPCNT) + : "="REG_OUT (res) + : REG_IN (w) + : "cc");So why all that churn instead of simply doing:
Quoted 6 lines
static
__always_inlineunsigned int__arch_parity32(unsigned int w){ return hweight32(w) & 1; }Ditto for the 64-bit version.
Even that would still be wrong for the smaller parity values. The CPU supports 8bit parity directly going back to the 8086 so the implementation for 8bit and I think 16bit is still wrong.
Alan
Re: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 3 lines · One Thousand Gnomes
Even that would still be wrong for the smaller parity values. The CPU supports 8bit parity directly going back to the 8086 so the implementation for 8bit and I think 16bit is still wrong.
I was objecting to the unnecessary replication of the hweight/popcnt glue.
And yes, one could look up the definition of the parity flag on x86 and then base the implementation of all those smaller ones on that as the hardware does it for one practically for free there.
:-)
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- Re: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 4 lines · Borislav Petkov
Quoted 3 lines · One Thousand Gnomes
Even that would still be wrong for the smaller parity values. The CPU supports 8bit parity directly going back to the 8086 so the implementation for 8bit and I think 16bit is still wrong.
Quoted 9 lines
I was objecting to the unnecessary replication of the hweight/popcnt glue.
And yes, one could look up the definition of the parity flag on x86 and then base the implementation of all those smaller ones on that as the hardware does it for one practically for free there.
:-)
SETcc (SETPO etc.) added since 80386, is this a problem?
Re: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 1 line · Zeng Zhaoxiu
SETcc (SETPO etc.) added since 80386, is this a problem?
Sounds to me you didn't make the effort to look up the definition of the Parity Flag...
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- Re: [PATCH v2 10/30] Add x86-specific parity functions
In reply to One Thousand GnomesQuoted 5 lines · One Thousand Gnomes
Even that would still be wrong for the smaller parity values. The CPU supports 8bit parity directly going back to the 8086 so the implementation for 8bit and I think 16bit is still wrong.
Alan
I don't know where the errors. X86 is new to me.
The definition of the parity flag on x86 from Wikipedia:
In x86 processors, the parity flag reflects the parity only of the least significant byte of the result, and is set if the number of set bits of ones is even. According to 80386 Intel manual, the parity flag is changed in the x86 processor family by the following instructions:
All arithmetic instructions;
Compare instruction (equivalent to a subtract instruction without storing the result);
Logical instructions - XOR, AND, OR;
the TEST instruction (equivalent to the AND instruction without storing the result).
the POPF instructionRe: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 1 line · Zeng Zhaoxiu
I don't know where the errors. X86 is new to me.
Ok, let me try again by pasting here the relevant text from the manual:
"Parity Flag (PF). Bit 2. Hardware sets the parity flag to 1 if there is an even number of 1 bits in the least-significant byte of the last result of certain operations. Otherwise (i.e., for an odd number of 1 bits), hardware clears the flag to 0. Software can read the flag to implement parity checking."
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- Re: [PATCH v2 10/30] Add x86-specific parity functions
In reply to Borislav PetkovQuoted 27 lines · Borislav Petkov
Quoted 14 lines · On Wed, Apr 06, 2016 at 05:14:45PM +0800, [email protected] wrote:
From: Zhaoxiu Zeng <[email protected]>
Use alternatives, lifted from
arch_hweightSigned-off-by Zhaoxiu Zeng <[email protected]>--- arch/x86/include/asm/arch_hweight.h | 5 ++ arch/x86/include/asm/arch_parity.h | 102 ++++++++++++++++++++++++++++++++++++ arch/x86/include/asm/bitops.h | 4 +- arch/x86/lib/Makefile | 8 +++ arch/x86/lib/parity.c | 32 ++++++++++++ 5 files changed, 150 insertions(+), 1 deletion(-)create mode 100644
arch/x86/include/asm/arch_parity.hcreate mode 100644arch/x86/lib/parity.c...
arch/x86/include/asm/arch_parity.h line 73
Quoted 8 lines
arch/x86/include/asm/arch_parity.h new file +8
-0+static __always_inline unsigned int __arch_parity32(unsigned int w) +{ +unsigned int res; + + asm(ALTERNATIVE("call __sw_parity32", POPCNT32 "; and $1, %0", X86_FEATURE_POPCNT) + : "="REG_OUT (res) + : REG_IN (w) + : "cc");So why all that churn instead of simply doing:
Quoted 7 lines
static
__always_inlineunsigned int__arch_parity32(unsigned int w){ return hweight32(w) & 1; }Ditto for the 64-bit version.
__sw_parity32 is faster than __sw_hweight32.
I don't know how many CPUs do not support the popc, if they are outdated, use __arch_hweight32 is the easiest way.
Re: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 3 lines · Zeng Zhaoxiu
__sw_parity32is faster than__sw_hweight32.
I don't know how many CPUs do not support the popc, if they are outdated, use__arch_hweight32is the easiest way.
I don't really understand what you're trying to tell me here. And it's not like I didn't try.
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- Re: [PATCH v2 10/30] Add x86-specific parity functions
In reply to [email protected]Quoted 3 lines · [email protected] writes:
From: Zhaoxiu Zeng <[email protected]>
Use alternatives, lifted from
arch_hweight
Is there actually anything performance critical in the kernel that uses parity?
FWIW the arch hweight custom calling convention is a problem for LTO because it needs different special flags, so I usually have to disable it. Likely other reasonable usages, such as automatic source code analysis, and other tool chain based usages have similar problems.
As far as I can tell both for hweight and likely for parity it is badly overengineering and normal calling conventions would work as well, and cause much less problems.
So if parity is really worth adding here (which I find doubtful, but you may have numbers), please add it without these magic calling hacks.
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only
Re: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 17 lines · Andi Kleen
Quoted 3 lines · [email protected] writes:
From: Zhaoxiu Zeng <[email protected]>
Use alternatives, lifted from
arch_hweightIs there actually anything performance critical in the kernel that uses parity?
FWIW the arch hweight custom calling convention is a problem for LTO because it needs different special flags, so I usually have to disable it. Likely other reasonable usages, such as automatic source code analysis, and other tool chain based usages have similar problems.
As far as I can tell both for hweight and likely for parity it is badly overengineering and normal calling conventions would work as well, and cause much less problems.
Quoted 6 lines
So if parity is really worth adding here (which I find doubtful, but you may have numbers), please add it without these magic calling hacks.
-Andi
Thanks. I will instead use __arch_hweight.
Re: [PATCH v2 10/30] Add x86-specific parity functions
In reply to Andi KleenQuoted 14 lines · Andi Kleen
Quoted 3 lines · [email protected] writes:
From: Zhaoxiu Zeng <[email protected]>
Use alternatives, lifted from
arch_hweightIs there actually anything performance critical in the kernel that uses parity?
FWIW the arch hweight custom calling convention is a problem for LTO because it needs different special flags, so I usually have to disable it. Likely other reasonable usages, such as automatic source code analysis, and other tool chain based usages have similar problems.
Quoted 7 lines
As far as I can tell both for hweight and likely for parity it is badly overengineering and normal calling conventions would work as well, and cause much less problems.
So if parity is really worth adding here (which I find doubtful, but you may have numbers), please add it without these magic calling hacks.
Hweight custom calling convention caused crashes with KCOV coverage. We had to disable instrumentation of the file.
Re: [PATCH v2 10/30] Add x86-specific parity functions
Quoted 2 lines · Dmitry Vyukov
Hweight custom calling convention caused crashes with KCOV coverage. We had to disable instrumentation of the file.
I guess we can do something like this:
if (likely(static_cpu_has(X86_FEATURE_POPCNT)))
asm volatile(POPCNT32
: "="REG_OUT (res)
: REG_IN (w));
else
res = __sw_hweight32(w);and get rid of the custom calling convention.
Along with some numbers showing that the change doesn't cause any noticeable slowdown...
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- RFC PATCH 1/1 x86/hweight: Get rid of the special calling convention
Quoted 9 lines · Borislav Petkov
I guess we can do something like this:
if (likely(static_cpu_has(X86_FEATURE_POPCNT))) asm volatile(POPCNT32 : "="REG_OUT (res) : REG_IN (w)); else res = __sw_hweight32(w);
Quoted 4 lines
and get rid of the custom calling convention.
Along with some numbers showing that the change doesn't cause any noticeable slowdown...
Ok, here's something which seems to build and boot in kvm.
I like how we don't need the special calling conventions anymore and we can actually say "popcnt .." and gcc selects registers.
The include files hackery is kinda nasty but I had to do it because I needed to be able to use static_cpu_has() in a header and including asm/cpufeature.h pulls in all kinds of nasty dependencies. I'm certainly open for better ideas...
---
From: Borislav Petkov <[email protected]>
Date: Wed, 4 May 2016 18:52:09 +0200
Subject: [PATCH] x86/hweight: Get rid of the special calling convention
People complained about ARCH_HWEIGHT_CFLAGS and how it throws a wrench into kcov, lto, etc, experimentation.
And its not like we absolutely need it so let's get rid of it and streamline it a bit. I had to do some carving out of facilities so that the include hell doesn't swallow me but other than that, the new __arch_hweight*() versions look much more palatable and gcc is more free to select registers than us hardcoding them in the insn bytes.
--- arch/x86/Kconfig | 5 -- arch/x86/include/asm/arch_hweight.h | 43 ++++--------- arch/x86/include/asm/cpufeature.h | 112 +------------------------------- arch/x86/include/asm/cpuinfo.h | 65 +++++++++++++++++++ arch/x86/include/asm/processor.h | 63 +----------------- arch/x86/include/asm/static_cpu_has.h | 116 ++++++++++++++++++++++++++++++++++ lib/Makefile | 5 -- 7 files changed, 197 insertions(+), 212 deletions(-) create mode 100644 arch/x86/include/asm/cpuinfo.h create mode 100644 arch/x86/include/asm/static_cpu_has.h
arch/x86/Kconfig +0 -5
@@ -292,11 +292,6 @@ config X86_32_LAZY_GS def_bool y depends on X86_32 && !CC_STACKPROTECTOR -config ARCH_HWEIGHT_CFLAGS - string - default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 - default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 - config ARCH_SUPPORTS_UPROBES def_bool y
arch/x86/include/asm/arch_hweight.h +13 -30
62 lines not on this page · raw message
arch/x86/include/asm/cpufeature.h +2 -110
136 lines not on this page · raw message
arch/x86/include/asm/cpuinfo.h new file +65 -0
65 lines not on this page · raw message
arch/x86/include/asm/processor.h +1 -62
81 lines not on this page · raw message
arch/x86/include/asm/static_cpu_has.h new file +116 -0
116 lines not on this page · raw message
lib/Makefile +0 -5
@@ -15,9 +15,6 @@ KCOV_INSTRUMENT_rbtree.o := n KCOV_INSTRUMENT_list_debug.o := n KCOV_INSTRUMENT_debugobjects.o := n KCOV_INSTRUMENT_dynamic_debug.o := n -# Kernel does not boot if we instrument this file as it uses custom calling -# convention (see CONFIG_ARCH_HWEIGHT_CFLAGS). -KCOV_INSTRUMENT_hweight.o := n lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o timerqueue.o\
@@ -72,8 +69,6 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o -GCOV_PROFILE_hweight.o := n -CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_BTREE) += btree.o
Signature · 4 lines
2.7.3 SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg) --
Re: [RFC PATCH] x86/hweight: Get rid of the special calling convention
Quoted 98 lines · Borislav Petkov
Quoted 9 lines · Borislav Petkov
I guess we can do something like this:
if (likely(static_cpu_has(X86_FEATURE_POPCNT))) asm volatile(POPCNT32 : "="REG_OUT (res) : REG_IN (w)); else res = __sw_hweight32(w);Quoted 4 lines
and get rid of the custom calling convention.
Along with some numbers showing that the change doesn't cause any noticeable slowdown...
Ok, here's something which seems to build and boot in kvm.
I like how we don't need the special calling conventions anymore and we can actually say "popcnt .." and gcc selects registers.
The include files hackery is kinda nasty but I had to do it because I needed to be able to use
static_cpu_has()in a header and includingasm/cpufeature.hpulls in all kinds of nasty dependencies. I'm certainly open for better ideas...---
From: Borislav Petkov <[email protected]>
Date: Wed, 4 May 2016 18:52:09 +0200
Subject: [PATCH] x86/hweight: Get rid of the special calling conventionPeople complained about
ARCH_HWEIGHT_CFLAGSand how it throws a wrench into kcov, lto, etc, experimentation.And its not like we absolutely need it so let's get rid of it and streamline it a bit. I had to do some carving out of facilities so that the include hell doesn't swallow me but other than that, the new __arch_hweight*() versions look much more palatable and gcc is more free to select registers than us hardcoding them in the insn bytes.
Signed-off-by Borislav Petkov <[email protected]>--- arch/x86/Kconfig | 5 -- arch/x86/include/asm/arch_hweight.h | 43 ++++--------- arch/x86/include/asm/cpufeature.h | 112 +------------------------------- arch/x86/include/asm/cpuinfo.h | 65 +++++++++++++++++++ arch/x86/include/asm/processor.h | 63 +----------------- arch/x86/include/asm/static_cpu_has.h | 116 ++++++++++++++++++++++++++++++++++ lib/Makefile | 5 -- 7 files changed, 197 insertions(+), 212 deletions(-) create mode 100644 arch/x86/include/asm/cpuinfo.h create mode 100644 arch/x86/include/asm/static_cpu_has.harch/x86/Kconfig +0
-5@@ -292,11 +292,6 @@ config X86_32_LAZY_GS def_bool y depends on X86_32 && !CC_STACKPROTECTOR -config ARCH_HWEIGHT_CFLAGS - string - default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 - default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 - config ARCH_SUPPORTS_UPROBES def_bool yarch/x86/include/asm/arch_hweight.h +1
-20@@ -2,36 +2,18 @@#define _ASM_X86_HWEIGHT_H#include <asm/cpufeatures.h> +#include <asm/static_cpu_has.h> -#ifdef CONFIG_64BIT -/* popcnt %edi, %eax -- redundant REX prefix for alignment */ -#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" -/* popcnt %rdi, %rax */ -#define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7" -#define REG_IN "D" -#define REG_OUT "a" -#else -/* popcnt %eax, %eax */ -#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc0" -#define REG_IN "a" -#define REG_OUT "a" -#endif - -/* -* __sw_hweightXX are called from within the alternatives below -* and callee-clobbered registers need to be taken care of. See -* ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective -* compiler switches. -*/
arch/x86/include/asm/arch_hweight.h line 12
Quoted 10 lines
arch/x86/include/asm/arch_hweight.h +3
-4static __always_inline unsigned int __arch_hweight32(unsigned int w) { -unsigned int res =0 ; +unsigned int res; - asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); +if (likely (static_cpu_has (X86_FEATURE_POPCNT ))) { + asmvolatile ("popcnt %[w], %[res]" : [res]"=r" (res) : [w]"r" (w));
Do all supported versions of the assembler know of the popcnt instruction? That's why is was open coded before. The problem is Intel and AMD are constantly adding new instructions and it's a long cycle for the user's assembler to get updated.
--
Brian Gerst
H. Peter Anvin
reviewerRe: [RFC PATCH] x86/hweight: Get rid of the special calling convention
Quoted 7 lines · Brian Gerst
arch/x86/include/asm/arch_hweight.h line 12
Quoted 6 lines
arch/x86/include/asm/arch_hweight.h +2
-3- asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); +if (likely (static_cpu_has (X86_FEATURE_POPCNT ))) { + asmvolatile ("popcnt %[w], %[res]" : [res]"=r" (res) : [w]"r" (w));
Quoted 5 lines
Do all supported versions of the assembler know of the popcnt instruction? That's why is was open coded before. The problem is Intel and AMD are constantly adding new instructions and it's a long cycle for the user's assembler to get updated.
Most likely not. It would be nice to have some more uniform solution to that. I'm wondering if we could use the -Wa option to load some kind of macro package.
-hpa
Re: [RFC PATCH] x86/hweight: Get rid of the special calling convention
Quoted 3 lines · H. Peter Anvin
Most likely not. It would be nice to have some more uniform solution to that. I'm wondering if we could use the -Wa option to load some kind of macro package.
Lemme try out some old compilers first, I'm guessing 3.2 won't know about popcnt...
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- H. Peter Anvin
reviewerRe: [RFC PATCH] x86/hweight: Get rid of the special calling convention
Quoted 8 lines · Borislav Petkov
Quoted 3 lines · H. Peter Anvin
Most likely not. It would be nice to have some more uniform solution to that. I'm wondering if we could use the -Wa option to load some kind of macro package.
Lemme try out some old compilers first, I'm guessing 3.2 won't know about popcnt...
Sigh. Doesn't look like -Wa is going to help due to the lack of the equivalent of an -include option in gas.
-hpa
Re: [RFC PATCH] x86/hweight: Get rid of the special calling convention
Quoted 2 lines · H. Peter Anvin
Sigh. Doesn't look like -Wa is going to help due to the lack of the equivalent of an -include option in gas.
So much for the register "freedom" - I'll resurrect the hardcoded insn bytes. :-\
Unless my gcc friends have some other ideas...
sarge:~# gcc --version gcc (GCC) 3.3.5 (Debian 1:3.3.5-13) Copyright (C) 2003 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
sarge:~# cat popcnt.c
int main(void)
{
int a, b; asm volatile("popcnt %0, %1" : "=r" (a) : "r" (b));
return 0;
}
sarge:~# gcc -Wall -o popcnt{,.c}
/tmp/ccHmmgjH.s: Assembler messages:
/tmp/ccHmmgjH.s:14: Error: no such instruction: `popcnt %eax,%eax'
sarge:~#Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- H. Peter Anvin
reviewerRe: [RFC PATCH] x86/hweight: Get rid of the special calling convention
Quoted 8 lines · Borislav Petkov
Quoted 2 lines · H. Peter Anvin
Sigh. Doesn't look like -Wa is going to help due to the lack of the equivalent of an -include option in gas.
So much for the register "freedom" - I'll resurrect the hardcoded insn bytes. :-\
Unless my gcc friends have some other ideas...
There is the option of looking for assembler support for popcnt and only hard-code the register if not supported. This is where being able to insert a macro package would help...
-hpa
Re: [RFC PATCH] x86/hweight: Get rid of the special calling convention
In reply to Borislav PetkovQuoted 8 lines · Borislav Petkov
Quoted 2 lines · H. Peter Anvin
Sigh. Doesn't look like -Wa is going to help due to the lack of the equivalent of an -include option in gas.
So much for the register "freedom" - I'll resurrect the hardcoded insn bytes. :-\
Unless my gcc friends have some other ideas...
You can probe the assembler in the Makefile and pass a define, like it is done by the dwarf code. When the define is not set use the hard coded registers
Not very scalable, but may work in this case.
Longer term would probably need compiler probes at Kconfig time (this would be useful for a lot of things)
-Andi
Signature · 1 line
[email protected] -- Speaking for myself only.
Re: [RFC PATCH] x86/hweight: Get rid of the special calling convention
In reply to Borislav PetkovQuoted 20 lines · Borislav Petkov
Quoted 2 lines · H. Peter Anvin
Sigh. Doesn't look like -Wa is going to help due to the lack of the equivalent of an -include option in gas.
So much for the register "freedom" - I'll resurrect the hardcoded insn bytes. :-\
Unless my gcc friends have some other ideas...
sarge:~# gcc --version gcc (GCC) 3.3.5 (Debian 1:3.3.5-13) Copyright (C) 2003 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.sarge:~# cat popcnt.c int main(void) { int a, b;
Quoted 8 lines
asm volatile("popcnt %0, %1" : "=r" (a) : "r" (b));
return 0;
}
sarge:~# gcc -Wall -o popcnt{,.c}
/tmp/ccHmmgjH.s: Assembler messages:
/tmp/ccHmmgjH.s:14: Error: no such instruction: `popcnt %eax,%eax'
sarge:~#You are looking at the version of a wrong program. gcc doesn't process assembly, it generates it. as is part of binutils, not gcc. "as --version".
Re: [RFC PATCH] x86/hweight: Get rid of the special calling convention
Quoted 3 lines · Denys Vlasenko
You are looking at the version of a wrong program. gcc doesn't process assembly, it generates it. as is part of binutils, not gcc. "as --version".
I know. It doesn't matter a whole lot in this case if there's a subset of gas versions which simply don't know about POPCNT and we do use those in the kernel build.
Pending a better solution, I'll simply revert to the old, spelled POPCNT bytes and don't bother with versions. Especially if someone tries to build the kernel with some other compiler...
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- PATCH 1/1 x86/hweight: Get rid of the special calling convention
From: Borislav Petkov <[email protected]>
Date: Wed, 4 May 2016 18:52:09 +0200
Subject: [PATCH -v2] x86/hweight: Get rid of the special calling convention
People complained about ARCH_HWEIGHT_CFLAGS and how it throws a wrench into kcov, lto, etc, experimentation.
And its not like we absolutely need it so let's get rid of it and streamline it a bit. I had to do some carving out of facilities so that the include hell doesn't swallow me.
We still need to hardcode POPCNT and register operands as some old gas versions which we support, do not know about POPCNT.
---
-v2: Revert to the old spelled-out POPCNT insn bytes.
arch/x86/Kconfig | 5 -- arch/x86/include/asm/arch_hweight.h | 38 +++++------ arch/x86/include/asm/cpufeature.h | 112 +------------------------------- arch/x86/include/asm/cpuinfo.h | 65 +++++++++++++++++++ arch/x86/include/asm/processor.h | 63 +----------------- arch/x86/include/asm/static_cpu_has.h | 116 ++++++++++++++++++++++++++++++++++ lib/Makefile | 5 -- 7 files changed, 204 insertions(+), 200 deletions(-) create mode 100644 arch/x86/include/asm/cpuinfo.h create mode 100644 arch/x86/include/asm/static_cpu_has.h
arch/x86/Kconfig +0 -5
@@ -292,11 +292,6 @@ config X86_32_LAZY_GS def_bool y depends on X86_32 && !CC_STACKPROTECTOR -config ARCH_HWEIGHT_CFLAGS - string - default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 - default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 - config ARCH_SUPPORTS_UPROBES def_bool y
arch/x86/include/asm/arch_hweight.h +20 -18
@@ -2,10 +2,11 @@#define _ASM_X86_HWEIGHT_H#include <asm/cpufeatures.h> +#include <asm/static_cpu_has.h> #ifdef CONFIG_64BIT -/* popcnt %edi, %eax -- redundant REX prefix for alignment */ -#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" +/* popcnt %edi, %eax */ +#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc7"/* popcnt %rdi, %rax */ #define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"#define REG_IN "D"
@@ -17,21 +18,19 @@#define REG_OUT "a"#endif -/* -* __sw_hweightXX are called from within the alternatives below -* and callee-clobbered registers need to be taken care of. See -* ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective -* compiler switches. -*/ static __always_inline unsigned int __arch_hweight32(unsigned int w) { -unsigned int res =0 ; +unsigned int res; - asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); +if (likely (static_cpu_has (X86_FEATURE_POPCNT ))) { +/* popcnt %eax, %eax */ + asm volatile(POPCNT32 + : "="REG_OUT (res) + : REG_IN (w)); -return res; +return res; + } +return __sw_hweight32 (w); }static inline unsigned int __arch_hweight16 (unsigned int w)
@@ -53,13 +52,16 @@ static inline unsigned long __arch_hweight64(__u64 w)#else static __always_inline unsigned long __arch_hweight64 (__u64 w) { -unsigned long res =0 ; +unsigned long res; - asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); +if (likely (static_cpu_has (X86_FEATURE_POPCNT ))) { + asm volatile(POPCNT64 + : "="REG_OUT (res) + : REG_IN (w)); -return res; +return res; + } +return __sw_hweight64 (w); }#endif /* CONFIG_X86_32 */
arch/x86/include/asm/cpufeature.h +2 -110
136 lines not on this page · raw message
arch/x86/include/asm/cpuinfo.h new file +65 -0
65 lines not on this page · raw message
arch/x86/include/asm/processor.h +1 -62
81 lines not on this page · raw message
arch/x86/include/asm/static_cpu_has.h new file +116 -0
116 lines not on this page · raw message
lib/Makefile +0 -5
@@ -15,9 +15,6 @@ KCOV_INSTRUMENT_rbtree.o := n KCOV_INSTRUMENT_list_debug.o := n KCOV_INSTRUMENT_debugobjects.o := n KCOV_INSTRUMENT_dynamic_debug.o := n -# Kernel does not boot if we instrument this file as it uses custom calling -# convention (see CONFIG_ARCH_HWEIGHT_CFLAGS). -KCOV_INSTRUMENT_hweight.o := n lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o timerqueue.o\
@@ -72,8 +69,6 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o -GCOV_PROFILE_hweight.o := n -CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_BTREE) += btree.o
Signature · 1 line
2.7.3
Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 9 lines · Borislav Petkov
static
__always_inlineunsigned int__arch_hweight32(unsigned int w){arch/x86/include/asm/arch_hweight.h +2
-4-unsigned int res =0 ; +unsigned int res; - asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); +if (likely (static_cpu_has (X86_FEATURE_POPCNT ))) {
arch/x86/include/asm/arch_hweight.h line 34
Quoted 10 lines
arch/x86/include/asm/arch_hweight.h +7
-1+/* popcnt %eax, %eax */ + asm volatile(POPCNT32 + : "="REG_OUT (res) + : REG_IN (w)); -return res; +return res; + } +return __sw_hweight32 (w); }
So what was wrong with using the normal thunk_*.S wrappers for the calls? That would allow you to use the alternative() stuff which does generate smaller code.
Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 3 lines · Peter Zijlstra
So what was wrong with using the normal thunk_*.S wrappers for the calls? That would allow you to use the
alternative()stuff which does generate smaller code.
Yeah, so a full allyesconfig vmlinux gives ~22K .text size increase:
text data bss dec hex filename
85391772 105899159 70717440 262008371 f9dee33 vmlinux before 85413991 105899223 70746112 262059326 f9eb53e vmlinux after
--------
22219
I guess I better try the thunk stuff, might make it smaller.
Also, in the next version I'll split out the static_cpu_has() move into a separate patch, as you requested on IRC.
Thanks.
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- H. Peter Anvin
reviewerRe: [PATCH -v2] x86/hweight: Get rid of the special calling convention
In reply to Peter ZijlstraQuoted 16 lines · Peter Zijlstra
arch/x86/include/asm/arch_hweight.h
Quoted 6 lines · Borislav Petkov
static
__always_inlineunsigned int__arch_hweight32(unsigned int w){arch/x86/include/asm/arch_hweight.h +1
-2-unsigned int res =0 ; +unsigned int res; - asm (ALTERNATIVE("call __sw_hweight32", POPCNT32,
X86_FEATURE_POPCNT)Quoted 8 lines
arch/x86/include/asm/arch_hweight.h +5
-2- : "="REG_OUT (res) - : REG_IN (w)); +if (likely (static_cpu_has (X86_FEATURE_POPCNT ))) { +/* popcnt %eax, %eax */ + asm volatile(POPCNT32 + : "="REG_OUT (res) + : REG_IN (w));
Quoted 9 lines
arch/x86/include/asm/arch_hweight.h line 34
Quoted 5 lines
arch/x86/include/asm/arch_hweight.h +3
-1-return res; +return res; + } +return __sw_hweight32 (w); }So what was wrong with using the normal thunk_*.S wrappers for the calls? That would allow you to use the
alternative()stuff which does generate smaller code.
Also, to be fair... if the problem is with these being in C then we could just do it in assembly easily enough.
Signature · 1 line
Sent from my Android device with K-9 Mail. Please excuse brevity and formatting.
Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 2 lines · H. Peter Anvin
Also, to be fair... if the problem is with these being in C then we could just do it in assembly easily enough.
I thought about converting the __sw_hweight* variants to asm but __sw_hweight32, for example, is 55 bytes here and that's a lot.
Or do you have a better idea?
peterz's sounds ok to me: we call a thunk which then calls __sw_hweight* after having saved regs properly - problem solved.
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- H. Peter Anvin
reviewerRe: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 4 lines · Borislav Petkov
Quoted 2 lines · H. Peter Anvin
Also, to be fair... if the problem is with these being in C then we could just do it in assembly easily enough.
Quoted 8 lines
I thought about converting the __sw_hweight* variants to asm but
__sw_hweight32, for example, is 55 bytes here and that's a lot.Or do you have a better idea?
peterz's sounds ok to me: we call a thunk which then calls __sw_hweight* after having saved regs properly - problem solved.
I didn't mean inline assembly.
-hpa
Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 1 line · H. Peter Anvin
I didn't mean inline assembly.
How does that matter?
The problem is having as less insn bytes as possible and the minimal size we can do is issuing POPCNT everywhere which is 4 or 5 bytes. The alternatives then replace that with a CALL which is also 5 bytes.
The way I did it now, it adds 22K more to allyesconfig vmlinux due to the static_cpu_has doubled alternatives sections and the JMPs. The thunks will keep those 5 bytes *and* get rid of the calling convention without the growth.
Or?
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 9 lines · Borislav Petkov
Quoted 1 line · H. Peter Anvin
I didn't mean inline assembly.
How does that matter?
The problem is having as less insn bytes as possible and the minimal size we can do is issuing POPCNT everywhere which is 4 or 5 bytes. The alternatives then replace that with a CALL which is also 5 bytes.
Quoted 6 lines
The way I did it now, it adds 22K more to allyesconfig vmlinux due to the
static_cpu_hasdoubled alternatives sections and the JMPs. The thunks will keep those 5 bytes *and* get rid of the calling convention without the growth.Or?
I think he meant the out of line version would be asm, so you could control what registers were clobbered.
--
Brian Gerst
Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 2 lines · Brian Gerst
I think he meant the out of line version would be asm, so you could control what registers were clobbered.
Yeah, it might save a few cycles on the call, but given that most machines should have popcnt these days is it worth the hassle/cost of duplicating the lib/hweight.c magic in asm (and remember, twice, once for 32bit and once for 64bit) ?
Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 4 lines · Peter Zijlstra
Yeah, it might save a few cycles on the call, but given that most machines should have popcnt these days is it worth the hassle/cost of duplicating the
lib/hweight.cmagic in asm (and remember, twice, once for 32bit and once for 64bit) ?
Makes sense to me - we can do the funky cool stuff but considering the fact that we have all the required bits already, I think we should do the thunking game and be done with it.
I guess we're older, lazy and more realists now...
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- H. Peter Anvin
reviewerRe: [PATCH -v2] x86/hweight: Get rid of the special calling convention
In reply to Peter ZijlstraQuoted 9 lines · Peter Zijlstra
Quoted 2 lines · Brian Gerst
I think he meant the out of line version would be asm, so you could control what registers were clobbered.
Yeah, it might save a few cycles on the call, but given that most machines should have popcnt these days is it worth the hassle/cost of duplicating the
lib/hweight.cmagic in asm (and remember, twice, once for 32bit and once for 64bit) ?
I was thinking it isn't really very complex code even in assembly as it is super-regular; you can even crib the gcc-generated code if you wish.
Signature · 1 line
Sent from my Android device with K-9 Mail. Please excuse brevity and formatting.
Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 3 lines · H. Peter Anvin
I was thinking it isn't really very complex code even in assembly as it is super-regular; you can even crib the gcc-generated code if you wish.
Do I wanna do experiments in asm? Always! :-)
Ok, so I did steal gcc -m32 -O3 output because there it uses only one additional register. So how about this (only __sw_hweight32 today):
#ifdef CONFIG_X86_32
# define PUSH_DX "pushl %%edx\n\t" # define POP_DX "popl %%edx\n\t" #else # define PUSH_DX "pushq %%rdx\n\t" # define POP_DX "popq %%rdx\n\t" #endif
unsigned int __sw_hweight32(unsigned int w)
{
asm volatile(PUSH_DX
"movl %[w], %%edx\n\t" /* w -> t */
"shrl %%edx\n\t" /* t >> 1 */
"andl $0x55555555, %%edx\n\t" /* t & 0x55555555 */
"subl %%edx, %[w]\n" /* w -= t */
"\n\t"
"movl %[w], %%edx\n\t" /* w -> t */
"shrl $2, %[w]\n\t" /* w_tmp >> 2 */
"andl $0x33333333, %%edx\n\t" /* t & 0x33333333 */
"andl $0x33333333, %[w]\n\t" /* w_tmp & 0x33333333 */
"addl %%edx, %[w]\n" /* w = w_tmp + t */
"\n\t"
"movl %[w], %%edx\n\t" /* w -> t */
"shrl $4, %%edx\n\t" /* t >> 4 */
"addl %%edx, %[w]\n\t" /* w_tmp += t */
"andl $0x0f0f0f0f, %[w]\n\t" /* w_tmp &= 0x0f0f0f0f */
"imull $0x01010101, %[w], %[w]\n\t" /* w_tmp *= 0x01010101 */
"shrl $24, %[w]\n\t" /* w = w_tmp >> 24 */
POP_DX
: [w] "+r" (w));
return w;
}I've chosen rDX as a temp because gcc takes that one but it doesn't matter which - we're stashing it.
And then we rely on gcc to figure out which reg to use for w. It ends up using rAX as that is the return reg which fits nicely with our intention of returning POPCNT values in rAX.
I'm guessing we can just as well write %%rax in the asm because we're returning that value and that's ABI.
Generated asm looks ok, only on 64-bit it does one
movl %edi, %eax # w, w
before the inline asm in order to stick w in rAX.
Complaints?
Full diff:
---
arch/x86/Kconfig +0 -5
@@ -292,11 +292,6 @@ config X86_32_LAZY_GS def_bool y depends on X86_32 && !CC_STACKPROTECTOR -config ARCH_HWEIGHT_CFLAGS - string - default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 - default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 - config ARCH_SUPPORTS_UPROBES def_bool y
arch/x86/include/asm/arch_hweight.h +16 -16
@@ -2,10 +2,11 @@#define _ASM_X86_HWEIGHT_H#include <asm/cpufeatures.h> +#include <asm/static_cpu_has.h> #ifdef CONFIG_64BIT -/* popcnt %edi, %eax -- redundant REX prefix for alignment */ -#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" +/* popcnt %edi, %eax */ +#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc7"/* popcnt %rdi, %rax */ #define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"#define REG_IN "D"
@@ -17,19 +18,15 @@#define REG_OUT "a"#endif -/* -* __sw_hweightXX are called from within the alternatives below -* and callee-clobbered registers need to be taken care of. See -* ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective -* compiler switches. -*/ +#define __HAVE_ARCH_SW_HWEIGHT + static __always_inline unsigned int __arch_hweight32(unsigned int w) { -unsigned int res =0 ; +unsigned int res; asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); + : "="REG_OUT (res) + : REG_IN (w));return res; }
@@ -53,13 +50,16 @@ static inline unsigned long __arch_hweight64(__u64 w)#else static __always_inline unsigned long __arch_hweight64 (__u64 w) { -unsigned long res =0 ; +unsigned long res; - asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); +if (likely (static_cpu_has (X86_FEATURE_POPCNT ))) { + asm volatile(POPCNT64 + : "="REG_OUT (res) + : REG_IN (w)); -return res; +return res; + } +return __sw_hweight64 (w); }#endif /* CONFIG_X86_32 */
arch/x86/include/asm/cpufeature.h +2 -110
136 lines not on this page · raw message
arch/x86/include/asm/cpuinfo.h new file +65 -0
65 lines not on this page · raw message
arch/x86/include/asm/processor.h +1 -62
81 lines not on this page · raw message
arch/x86/include/asm/static_cpu_has.h new file +116 -0
116 lines not on this page · raw message
arch/x86/lib/Makefile +1 -1
@@ -25,7 +25,7 @@ lib-y += memcpy_$(BITS).o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o -obj-y += msr.o msr-reg.o msr-reg-export.o +obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o ifeq ($(CONFIG_X86_32),y) obj-y += atomic64_32.o
arch/x86/lib/hweight.c new file +37 -0
@@ -0,0 +1,37 @@ +#include <linux/export.h> +#include <linux/compiler.h> + +#ifdef CONFIG_X86_32 +# define PUSH_DX "pushl %%edx\n\t" +# define POP_DX "popl %%edx\n\t" +#else +# define PUSH_DX "pushq %%rdx\n\t" +# define POP_DX "popq %%rdx\n\t" +#endif + +unsigned int __sw_hweight32 (unsigned int w) +{ + asmvolatile (PUSH_DX +"movl %[w], %%edx\n\t" /* w -> t */ +"shrl %%edx\n\t" /* t >> 1 */ +"andl $0x55555555, %%edx\n\t" /* t & 0x55555555 */ +"subl %%edx, %[w]\n" /* w -= t */ +"\n\t" +"movl %[w], %%edx\n\t" /* w -> t */ +"shrl $2, %[w]\n\t" /* w_tmp >> 2 */ +"andl $0x33333333, %%edx\n\t" /* t & 0x33333333 */ +"andl $0x33333333, %[w]\n\t" /* w_tmp & 0x33333333 */ +"addl %%edx, %[w]\n" /* w = w_tmp + t */ +"\n\t" +"movl %[w], %%edx\n\t" /* w -> t */ +"shrl $4, %%edx\n\t" /* t >> 4 */ +"addl %%edx, %[w]\n\t" /* w_tmp += t */ +"andl $0x0f0f0f0f, %[w]\n\t" /* w_tmp &= 0x0f0f0f0f */ +"imull $0x01010101, %[w], %[w]\n\t" /* w_tmp *= 0x01010101 */ +"shrl $24, %[w]\n\t" /* w = w_tmp >> 24 */ +POP_DX + : [w]"+r" (w)); + +return w; +} +EXPORT_SYMBOL (__sw_hweight32);
lib/Makefile +0 -5
@@ -15,9 +15,6 @@ KCOV_INSTRUMENT_rbtree.o := n KCOV_INSTRUMENT_list_debug.o := n KCOV_INSTRUMENT_debugobjects.o := n KCOV_INSTRUMENT_dynamic_debug.o := n -# Kernel does not boot if we instrument this file as it uses custom calling -# convention (see CONFIG_ARCH_HWEIGHT_CFLAGS). -KCOV_INSTRUMENT_hweight.o := n lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o timerqueue.o\
@@ -72,8 +69,6 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o -GCOV_PROFILE_hweight.o := n -CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_BTREE) += btree.o
lib/hweight.c +2 -0
@@ -9,6 +9,7 @@* The Hamming Weight of a number is the total number of bits set in it. */ +#ifndef __HAVE_ARCH_SW_HWEIGHTunsigned int __sw_hweight32 (unsigned int w) {#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
@@ -25,6 +26,7 @@ unsigned int __sw_hweight32(unsigned int w) #endif }EXPORT_SYMBOL (__sw_hweight32); +#endif unsigned int __sw_hweight16 (unsigned int w) {
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 25 lines · Borislav Petkov
#ifdef
CONFIG_X86_32# define PUSH_DX "pushl %%edx\n\t" # define POP_DX "popl %%edx\n\t" #else # define PUSH_DX "pushq %%rdx\n\t" # define POP_DX "popq %%rdx\n\t" #endifunsigned int
__sw_hweight32(unsigned int w){ asm volatile(PUSH_DX "movl %[w], %%edx\n\t" /* w -> t */ "shrl %%edx\n\t" /* t >> 1 */ "andl $0x55555555, %%edx\n\t" /* t & 0x55555555 */ "subl %%edx, %[w]\n" /* w -= t */ "\n\t" "movl %[w], %%edx\n\t" /* w -> t */ "shrl $2, %[w]\n\t" /* w_tmp >> 2 */ "andl $0x33333333, %%edx\n\t" /* t & 0x33333333 */ "andl $0x33333333, %[w]\n\t" /* w_tmp & 0x33333333 */ "addl %%edx, %[w]\n" /* w = w_tmp + t */ "\n\t" "movl %[w], %%edx\n\t" /* w -> t */ "shrl $4, %%edx\n\t" /* t >> 4 */ "addl %%edx, %[w]\n\t" /* w_tmp += t */
Quoted 8 lines
"andl $0x0f0f0f0f, %[w]\n\t" /* w_tmp &= 0x0f0f0f0f */
"imull $0x01010101, %[w], %[w]\n\t" /* w_tmp *= 0x01010101 */
"shrl $24, %[w]\n\t" /* w = w_tmp >> 24 */
POP_DX
: [w] "+r" (w));
return w;
}But this is a C function, with C calling convention. You're now assuming GCC doesn't clobber anything with its prologue/epilogue.
I think hpa meant to put it in an .S file and avoid all that.
Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 4 lines · Peter Zijlstra
But this is a C function, with C calling convention. You're now assuming GCC doesn't clobber anything with its prologue/epilogue.
I think hpa meant to put it in an .S file and avoid all that.
I wanted to have gcc use %[w] and this way not hardcode the reg but the ABI kinda hardcodes it to rAX. And you're right about tracing funkyness adding glue so we're probably better off doing the .S thing directly and making it more robust this way.
Signature · 5 lines
Regards/Gruss,
Boris.
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)
-- Re: [PATCH -v2] x86/hweight: Get rid of the special calling convention
Quoted 4 lines · Borislav Petkov
I wanted to have gcc use %[w] and this way not hardcode the reg but the ABI kinda hardcodes it to rAX. And you're right about tracing funkyness adding glue so we're probably better off doing the .S thing directly and making it more robust this way.
Ok, here's a new version. Let me know what do you think before I hammer on it more seriously. But booting in kvm with "-popcnt" and without seems to work, no splats, corruptions or whatnot.
I've also been running POPCNT vs the asm versions in userspace and comparing results, looks good too, seems to work correctly. :)
Thanks.
---
From: Borislav Petkov <[email protected]>
Date: Wed, 4 May 2016 18:52:09 +0200
Subject: [PATCH] x86/hweight: Get rid of the special calling convention
People complained about ARCH_HWEIGHT_CFLAGS and how it throws a wrench into kcov, lto, etc, experimentation. Add asm versions for __sw_hweight{32,64}() and do explicitly saving and restoring of clobbered registers. This gets rid of the special calling convention.
We still need to hardcode POPCNT and register operands as some old gas versions which we support, do not know about POPCNT.
Btw, remove redundant REX prefix from 32-bit POPCNT because alternatives can do padding now.
--- arch/x86/Kconfig | 5 --- arch/x86/include/asm/arch_hweight.h | 24 +++++------- arch/x86/kernel/i386_ksyms_32.c | 2 + arch/x86/kernel/x8664_ksyms_64.c | 3 ++ arch/x86/lib/Makefile | 2 +- arch/x86/lib/hweight.S | 77 +++++++++++++++++++++++++++++++++++++ lib/Makefile | 5 --- lib/hweight.c | 4 ++ 8 files changed, 97 insertions(+), 25 deletions(-) create mode 100644 arch/x86/lib/hweight.S
arch/x86/Kconfig +0 -5
@@ -296,11 +296,6 @@ config X86_32_LAZY_GS def_bool y depends on X86_32 && !CC_STACKPROTECTOR -config ARCH_HWEIGHT_CFLAGS - string - default "-fcall-saved-ecx -fcall-saved-edx" if X86_32 - default "-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" if X86_64 - config ARCH_SUPPORTS_UPROBES def_bool y
arch/x86/include/asm/arch_hweight.h +10 -14
@@ -4,8 +4,8 @@#include <asm/cpufeatures.h> #ifdef CONFIG_64BIT -/* popcnt %edi, %eax -- redundant REX prefix for alignment */ -#define POPCNT32 ".byte 0xf3,0x40,0x0f,0xb8,0xc7" +/* popcnt %edi, %eax */ +#define POPCNT32 ".byte 0xf3,0x0f,0xb8,0xc7"/* popcnt %rdi, %rax */ #define POPCNT64 ".byte 0xf3,0x48,0x0f,0xb8,0xc7"#define REG_IN "D"
@@ -17,19 +17,15 @@#define REG_OUT "a"#endif -/* -* __sw_hweightXX are called from within the alternatives below -* and callee-clobbered registers need to be taken care of. See -* ARCH_HWEIGHT_CFLAGS in <arch/x86/Kconfig> for the respective -* compiler switches. -*/ +#define __HAVE_ARCH_SW_HWEIGHT + static __always_inline unsigned int __arch_hweight32(unsigned int w) { -unsigned int res =0 ; +unsigned int res; asm (ALTERNATIVE("call __sw_hweight32", POPCNT32, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); + : "="REG_OUT (res) + : REG_IN (w));return res; }
@@ -53,11 +49,11 @@ static inline unsigned long __arch_hweight64(__u64 w)#else static __always_inline unsigned long __arch_hweight64 (__u64 w) { -unsigned long res =0 ; +unsigned long res; asm (ALTERNATIVE("call __sw_hweight64", POPCNT64, X86_FEATURE_POPCNT) - : "="REG_OUT (res) - : REG_IN (w)); + : "="REG_OUT (res) + : REG_IN (w));return res; }
arch/x86/kernel/i386_ksyms_32.c +2 -0
@@ -42,3 +42,5 @@ EXPORT_SYMBOL(empty_zero_page);EXPORT_SYMBOL (___preempt_schedule);EXPORT_SYMBOL (___preempt_schedule_notrace);#endif + +EXPORT_SYMBOL (__sw_hweight32);
arch/x86/kernel/x8664_ksyms_64.c +3 -0
@@ -44,6 +44,9 @@ EXPORT_SYMBOL(clear_page);EXPORT_SYMBOL (csum_partial); +EXPORT_SYMBOL (__sw_hweight32); +EXPORT_SYMBOL (__sw_hweight64); +/* * Export string functions. We normally rely on gcc builtin for most of these, * but gcc sometimes decides not to inline them.
arch/x86/lib/Makefile +1 -1
@@ -25,7 +25,7 @@ lib-y += memcpy_$(BITS).o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_INSTRUCTION_DECODER) += insn.o inat.o -obj-y += msr.o msr-reg.o msr-reg-export.o +obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o ifeq ($(CONFIG_X86_32),y) obj-y += atomic64_32.o
arch/x86/lib/hweight.S new file +77 -0
77 lines not on this page · raw message
lib/Makefile +0 -5
@@ -15,9 +15,6 @@ KCOV_INSTRUMENT_rbtree.o := n KCOV_INSTRUMENT_list_debug.o := n KCOV_INSTRUMENT_debugobjects.o := n KCOV_INSTRUMENT_dynamic_debug.o := n -# Kernel does not boot if we instrument this file as it uses custom calling -# convention (see CONFIG_ARCH_HWEIGHT_CFLAGS). -KCOV_INSTRUMENT_hweight.o := n lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o timerqueue.o\
@@ -72,8 +69,6 @@ obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o -GCOV_PROFILE_hweight.o := n -CFLAGS_hweight.o = $(subst $(quote),,$(CONFIG_ARCH_HWEIGHT_CFLAGS)) obj-$(CONFIG_GENERIC_HWEIGHT) += hweight.o obj-$(CONFIG_BTREE) += btree.o
lib/hweight.c +4 -0
@@ -9,6 +9,7 @@* The Hamming Weight of a number is the total number of bits set in it. */ +#ifndef __HAVE_ARCH_SW_HWEIGHTunsigned int __sw_hweight32 (unsigned int w) {#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
@@ -25,6 +26,7 @@ unsigned int __sw_hweight32(unsigned int w) #endif }EXPORT_SYMBOL (__sw_hweight32); +#endif unsigned int __sw_hweight16 (unsigned int w) {
@@ -43,6 +45,7 @@ unsigned int __sw_hweight8(unsigned int w) }EXPORT_SYMBOL (__sw_hweight8); +#ifndef __HAVE_ARCH_SW_HWEIGHTunsigned long __sw_hweight64 (__u64 w) {#if BITS_PER_LONG ==32
@@ -65,3 +68,4 @@ unsigned long __sw_hweight64(__u64 w) #endif }EXPORT_SYMBOL (__sw_hweight64); +#endif
Signature · 4 lines
2.7.3 SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg) --
Re: [PATCH v2 10/30] Add x86-specific parity functions
In reply to Andi KleenQuoted 8 lines · On Wed, 06 Apr 2016 12:45:27 -0700 Andi Kleen <[email protected]> wrote:
Quoted 3 lines · [email protected] writes:
From: Zhaoxiu Zeng <[email protected]>
Use alternatives, lifted from
arch_hweightIs there actually anything performance critical in the kernel that uses parity?
On very low end devices some of the flash, but the implementation here is ironically pretty much worst-case for such x86 devices 8)
Alan
PATCH v2 11/30 sunrpc: use parity8
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- net/sunrpc/auth_gss/gss_krb5_keys.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
net/sunrpc/auth_gss/gss_krb5_keys.c +1 -5
@@ -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]); } }
Signature · 1 line
2.5.0
PATCH v2 12/30 mips: use parity functions in cerr-sb1.c
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- arch/mips/mm/cerr-sb1.c | 67 +++++++++++++------------------------------------ 1 file changed, 17 insertions(+), 50 deletions(-)
arch/mips/mm/cerr-sb1.c +17 -50
@@ -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; }
Signature · 1 line
2.5.0
PATCH v2 13/30 bch: use parity32
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- lib/bch.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-)
lib/bch.c +1 -13
@@ -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 ; }
Signature · 1 line
2.5.0
PATCH v2 14/30 media: use parity8 in vivid-vbi-gen.c
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/media/platform/vivid/vivid-vbi-gen.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/media/platform/vivid/vivid-vbi-gen.c +2 -7
@@ -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)
Signature · 1 line
2.5.0
PATCH v2 15/30 media: use parity functions in saa7115
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/media/i2c/saa7115.c | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-)
drivers/media/i2c/saa7115.c +2 -15
@@ -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 ;
Signature · 1 line
2.5.0
PATCH v2 16/30 input: use parity32 in grip_mp
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/input/joystick/grip_mp.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-)
drivers/input/joystick/grip_mp.c +1 -15
@@ -112,20 +112,6 @@ static const int axis_map[] = { 5, 9, 1, 5, 6, 10, 2, 6, 4, 8, 0, 4, 5, 9, 1, 5static 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 */
Signature · 1 line
2.5.0
PATCH v2 17/30 input: use parity64 in sidewinder
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/input/joystick/sidewinder.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-)
drivers/input/joystick/sidewinder.c +4 -20
@@ -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 ];
Signature · 1 line
2.5.0
PATCH v2 18/30 input: use parity16 in ams_delta_serio
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/input/serio/ams_delta_serio.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/input/serio/ams_delta_serio.c +2 -6
@@ -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);
Signature · 1 line
2.5.0
PATCH v2 19/30 scsi: use parity32 in isci's phy
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/scsi/isci/phy.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-)
drivers/scsi/isci/phy.c +1 -14
@@ -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 ;
@@ -225,18 +223,7 @@ 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. */ - 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 ) - phy_cap.parity =1 ; + phy_cap.parity =parity32 (phy_cap.all);writel (phy_cap.all, &llr->phy_capabilities);
Signature · 1 line
2.5.0
PATCH v2 20/30 mtd: use parity16 in ssfdc
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
The original get_parity return even parity of the input number. So hweight of "block_address & 0x7ff" must be odd if block_address is valid.
This patch use parity16, and rearrange the code.
--- drivers/mtd/ssfdc.c | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-)
drivers/mtd/ssfdc.c +8 -23
@@ -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,18 +201,17 @@ 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) { -pr_debug ("SSFDC_RO: logical address field%d" -"parity error(0x%04X)\n" , j+1 , - block_address); - }else { - ok =1 ; + ok =parity16 (block_address); +if (ok) { + block_address >>=1 ;break ; } + +pr_debug ("SSFDC_RO: logical address field%d" +"parity error(0x%04X)\n" , j+1 , + block_address); } }
Signature · 1 line
2.5.0
PATCH v2 21/30 mtd: use parity functions in inftlcore
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/mtd/inftlcore.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-)
drivers/mtd/inftlcore.c +4 -13
@@ -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);
Signature · 1 line
2.5.0
PATCH v2 22/30 crypto: use parity functions in qat_hal
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/crypto/qat/qat_common/qat_hal.c | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-)
drivers/crypto/qat/qat_common/qat_hal.c +10 -22
@@ -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); }
Signature · 1 line
2.5.0
PATCH v2 23/30 mtd: use parity16 in sm_ftl
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/mtd/sm_ftl.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/mtd/sm_ftl.c +2 -3
@@ -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,8 +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 ) - tmp[1 ] |=1 ; + tmp[1 ] |=parity16 (*(uint16_t *)tmp); oob->lba_copy1[0 ] = oob->lba_copy2[0 ] = tmp[0 ]; oob->lba_copy1[1 ] = oob->lba_copy2[1 ] = tmp[1 ];
Signature · 1 line
2.5.0
PATCH v2 24/30 ethernet: use parity8 in sun/niu.c
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/net/ethernet/sun/niu.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
drivers/net/ethernet/sun/niu.c +2 -8
@@ -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 ;
Signature · 1 line
2.5.0
PATCH v2 25/30 input: use parity8 in pcips2
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/input/serio/pcips2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/serio/pcips2.c +1 -1
@@ -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);
Signature · 1 line
2.5.0
PATCH v2 26/30 input: use parity8 in sa1111ps2
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/input/serio/sa1111ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/input/serio/sa1111ps2.c +1 -1
@@ -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);
Signature · 1 line
2.5.0
PATCH v2 27/30 iio: use parity32 in adxrs450
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/iio/gyro/adxrs450.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/gyro/adxrs450.c +2 -2
@@ -109,7 +109,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 )) +if (!parity32 (tx)) tx |=ADXRS450_P ; st->tx =cpu_to_be32 (tx);
@@ -145,7 +145,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 )) +if (!parity32 (tx)) tx |=ADXRS450_P ; st->tx =cpu_to_be32 (tx);
Signature · 1 line
2.5.0
Re: [PATCH v2 27/30] iio: use parity32 in adxrs450
Quoted 3 lines · On 06/04/16 11:16, [email protected] wrote:
From: Zhaoxiu Zeng <[email protected]>
Signed-off-by Zhaoxiu Zeng <[email protected]>
Applied to the togreg branch of iio.git as you seem to have addressed Lars' comments.
Thanks,
Jonathan
Quoted 27 lines
--- drivers/iio/gyro/adxrs450.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)drivers/iio/gyro/adxrs450.c +2
-2@@ -109,7 +109,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 )) +if (!parity32 (tx)) tx |=ADXRS450_P ; st->tx =cpu_to_be32 (tx);@@ -145,7 +145,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 )) +if (!parity32 (tx)) tx |=ADXRS450_P ; st->tx =cpu_to_be32 (tx);
Re: [PATCH v2 27/30] iio: use parity32 in adxrs450
Quoted 6 lines · Jonathan Cameron
Quoted 3 lines · On 06/04/16 11:16, [email protected] wrote:
From: Zhaoxiu Zeng <[email protected]>
Signed-off-by Zhaoxiu Zeng <[email protected]>Applied to the togreg branch of iio.git as you seem to have addressed Lars' comments.
The whole series needs to go through the same tree since the new functions are introduced in the beginning.
Re: [PATCH v2 27/30] iio: use parity32 in adxrs450
Quoted 10 lines · Lars-Peter Clausen
Quoted 6 lines · Jonathan Cameron
Quoted 3 lines · On 06/04/16 11:16, [email protected] wrote:
From: Zhaoxiu Zeng <[email protected]>
Signed-off-by Zhaoxiu Zeng <[email protected]>Applied to the togreg branch of iio.git as you seem to have addressed Lars' comments.
The whole series needs to go through the same tree since the new functions are introduced in the beginning.
Yeah, I just realized that when my build test failed!
Quoted 6 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Jonathan Cameron
maintainerRe: [PATCH v2 27/30] iio: use parity32 in adxrs450
Quoted 6 lines · Jonathan Cameron
Quoted 5 lines · Lars-Peter Clausen
Quoted 4 lines · Jonathan Cameron
Quoted 3 lines · On 06/04/16 11:16, [email protected] wrote:
From: Zhaoxiu Zeng <[email protected]>
Signed-off-by Zhaoxiu Zeng <[email protected]>
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Applied to the togreg branch of iio.git as you seem to have addressed Lars' comments.
The whole series needs to go through the same tree since the new functions are introduced in the beginning.
Yeah, I just realized that when my build test failed!
Acked-by Jonathan Cameron <[email protected]>
Backed out of the togreg branch of iio.git...
oops and thanks Lars!
Quoted 12 lines
Quoted 6 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html--
To unsubscribe from this list: send the line "unsubscribe linux-iio" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 28/30 serial: use parity32 in max3100
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/tty/serial/max3100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/tty/serial/max3100.c +1 -1
@@ -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; }
Signature · 1 line
2.5.0
Greg KH
maintainerRe: [PATCH v2 28/30] serial: use parity32 in max3100
Quoted 6 lines · On Wed, Apr 06, 2016 at 06:18:42PM +0800, [email protected] wrote:
From: Zhaoxiu Zeng <[email protected]>
Signed-off-by Zhaoxiu Zeng <[email protected]>--- drivers/tty/serial/max3100.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
I can't take patches without any changelog text :(
PATCH v2 29/30 input: use parity8 in elantech
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
Remove even parity table, use parity8 instead.
--- drivers/input/mouse/elantech.c | 10 +++------- drivers/input/mouse/elantech.h | 1 - 2 files changed, 3 insertions(+), 8 deletions(-)
drivers/input/mouse/elantech.c +3 -7
@@ -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 */
drivers/input/mouse/elantech.h +0 -1
@@ -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); };
Signature · 1 line
2.5.0
PATCH v2 30/30 ethernet: use parity8 in broadcom/tg3.c
In reply to Zeng ZhaoxiuFrom: Zhaoxiu Zeng <[email protected]>
--- drivers/net/ethernet/broadcom/tg3.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
drivers/net/ethernet/broadcom/tg3.c +1 -5
@@ -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 ;
Signature · 1 line
2.5.0