* [PATCH] add rotate left/right ops to bitops.h
@ 2004-10-03 10:44 Denis Vlasenko
2004-10-03 10:56 ` YOSHIFUJI Hideaki / 吉藤英明
0 siblings, 1 reply; 4+ messages in thread
From: Denis Vlasenko @ 2004-10-03 10:44 UTC (permalink / raw)
To: jmorris, davem; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 369 bytes --]
This patch is needed for next sha512 optimization patch.
It adds these to linux/bitops.h:
extern inline u32 rol32(u32 x, int num)
extern inline u32 ror32(u32 x, int num)
extern inline u64 rol64(u64 x, int num)
extern inline u64 ror64(u64 x, int num)
Generic C version is provided.
Arches may override it by optimized ones.
64bit i386 asm version is provided.
--
vda
[-- Attachment #2: 269r3rot.diff --]
[-- Type: text/x-diff, Size: 4522 bytes --]
diff -urpN linux-2.6.9-rc3.src/include/asm-i386/bitops.h linux-2.6.9-rc3rot.src/include/asm-i386/bitops.h
--- linux-2.6.9-rc3.src/include/asm-i386/bitops.h Fri Oct 1 21:30:16 2004
+++ linux-2.6.9-rc3rot.src/include/asm-i386/bitops.h Sun Oct 3 12:48:46 2004
@@ -431,9 +431,130 @@ static inline int ffs(int x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
-#endif /* __KERNEL__ */
+/*
+ * 64bit rotations
+ * (gcc3 seems to be clever enough to do 32bit ones just fine)
+ *
+ * Why "i" and "I" constraints do not work? gcc says:
+ * "warning: asm operand 2 probably doesn't match constraints"
+ * "error: impossible constraint in 'asm'"
+ * Will use "Ic" for now. If gcc will fail to do const propagation
+ * and will try to stuff constant into ecx, shld %3,... will expand
+ * to shld %ecx,... and assembler will moan.
+ * Do not 'fix' by changing to shld %b3,...
+ *
+ * Have to stick to edx,eax pair only because
+ * gcc has limited support for 64bit asm parameters
+ */
+#define constant_rol64(v,c) \
+ ({ \
+ u64 vv = (v); \
+ if(!(c&63)) { \
+ } else if((c&63)==1) { \
+ asm ( \
+ " shldl $1,%%edx,%%eax \n" \
+ " rcll $1,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } else if((c&63)==63) { \
+ asm ( \
+ " shrdl $1,%%edx,%%eax \n" \
+ " rcrl $1,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } else if((c&63)<32) { \
+ asm ( \
+ " shldl %3,%%edx,%%eax \n" \
+ " shldl %3,%2,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv), \
+ "r" (vv), \
+ "Ic" (c&63) \
+ ); \
+ } else if((c&63)>32) { \
+ asm ( \
+ " shrdl %3,%%edx,%%eax \n" \
+ " shrdl %3,%2,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv), \
+ "r" (vv), \
+ "Ic" (64-(c&63)) \
+ ); \
+ } else /* (c&63)==32 */ { \
+ asm ( \
+ " xchgl %%edx,%%eax \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } \
+ vv; \
+ })
+#define constant_ror64(v,c) \
+ ({ \
+ u64 vv = (v); \
+ if(!(c&63)) { \
+ } else if((c&63)==1) { \
+ asm ( \
+ " shrdl $1,%%edx,%%eax \n" \
+ " rcrl $1,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } else if((c&63)==63) { \
+ asm ( \
+ " shldl $1,%%edx,%%eax \n" \
+ " rcll $1,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } else if((c&63)<32) { \
+ asm ( \
+ " shrdl %3,%%edx,%%eax \n" \
+ " shrdl %3,%2,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv), \
+ "r" (vv), \
+ "Ic" (c&63) \
+ ); \
+ } else if((c&63)>32) { \
+ asm ( \
+ " shldl %3,%%edx,%%eax \n" \
+ " shldl %3,%2,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv), \
+ "r" (vv), \
+ "Ic" (64-(c&63)) \
+ ); \
+ } else /* (c&63)==32 */ { \
+ asm ( \
+ " xchgl %%edx,%%eax \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } \
+ vv; \
+ })
+/*
+ * Unfortunately 64bit rotations with non-constant count
+ * have issues with cnt>=32. Using C code instead
+ */
+extern inline u64 rol64(u64 x,int num) {
+ if(__builtin_constant_p(num))
+ return constant_rol64(x,num);
+ /* Hmmm... shall we do cnt&=63 here? */
+ return ((x<<num) | (x>>(64-num)));
+}
+extern inline u64 ror64(u64 x,int num) {
+ if(__builtin_constant_p(num))
+ return constant_ror64(x,num);
+ return ((x>>num) | (x<<(64-num)));
+}
+
+#define ARCH_HAS_ROL64
+#define ARCH_HAS_ROR64
-#ifdef __KERNEL__
#define ext2_set_bit(nr,addr) \
__test_and_set_bit((nr),(unsigned long*)addr)
diff -urpN linux-2.6.9-rc3.src/include/linux/bitops.h linux-2.6.9-rc3rot.src/include/linux/bitops.h
--- linux-2.6.9-rc3.src/include/linux/bitops.h Sat Aug 14 13:56:23 2004
+++ linux-2.6.9-rc3rot.src/include/linux/bitops.h Sun Oct 3 12:43:51 2004
@@ -4,6 +4,38 @@
#include <asm/bitops.h>
/*
+ * bit rotations
+ */
+
+#ifndef ARCH_HAS_ROL32
+extern inline u32 rol32(u32 x, int num)
+{
+ return (x << num) | (x >> (32 - num));
+}
+#endif
+
+#ifndef ARCH_HAS_ROR32
+extern inline u32 ror32(u32 x, int num)
+{
+ return (x >> num) | (x << (32 - num));
+}
+#endif
+
+#ifndef ARCH_HAS_ROL64
+extern inline u64 rol64(u64 x, int num)
+{
+ return (x << num) | (x >> (64 - num));
+}
+#endif
+
+#ifndef ARCH_HAS_ROR64
+extern inline u64 ror64(u64 x, int num)
+{
+ return (x >> num) | (x << (64 - num));
+}
+#endif
+
+/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] add rotate left/right ops to bitops.h
2004-10-03 10:44 [PATCH] add rotate left/right ops to bitops.h Denis Vlasenko
@ 2004-10-03 10:56 ` YOSHIFUJI Hideaki / 吉藤英明
2004-10-03 10:59 ` Denis Vlasenko
0 siblings, 1 reply; 4+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-10-03 10:56 UTC (permalink / raw)
To: vda; +Cc: jmorris, davem, linux-kernel, yoshfuji
In article <200410031344.54182.vda@port.imtp.ilyichevsk.odessa.ua> (at Sun, 3 Oct 2004 13:44:54 +0300), Denis Vlasenko <vda@port.imtp.ilyichevsk.odessa.ua> says:
> extern inline u32 rol32(u32 x, int num)
:
Please do not use use extern inline; use static inline instead.
Thanks.
--
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] add rotate left/right ops to bitops.h
2004-10-03 10:56 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-10-03 10:59 ` Denis Vlasenko
2004-10-04 9:55 ` Andrew Morton
0 siblings, 1 reply; 4+ messages in thread
From: Denis Vlasenko @ 2004-10-03 10:59 UTC (permalink / raw)
To: YOSHIFUJI Hideaki / 吉藤英明
Cc: jmorris, davem, linux-kernel, yoshfuji
[-- Attachment #1: Type: text/plain, Size: 227 bytes --]
> > extern inline u32 rol32(u32 x, int num)
>
> Please do not use use extern inline; use static inline instead.
We shall fold it into #define once and for all eventually.
Meanwhile, s/extern/static/ patch is attached.
--
vda
[-- Attachment #2: 269r3rot.diff --]
[-- Type: text/x-diff, Size: 4522 bytes --]
diff -urpN linux-2.6.9-rc3.src/include/asm-i386/bitops.h linux-2.6.9-rc3rot.src/include/asm-i386/bitops.h
--- linux-2.6.9-rc3.src/include/asm-i386/bitops.h Fri Oct 1 21:30:16 2004
+++ linux-2.6.9-rc3rot.src/include/asm-i386/bitops.h Sun Oct 3 12:48:46 2004
@@ -431,9 +431,130 @@ static inline int ffs(int x)
#define hweight16(x) generic_hweight16(x)
#define hweight8(x) generic_hweight8(x)
-#endif /* __KERNEL__ */
+/*
+ * 64bit rotations
+ * (gcc3 seems to be clever enough to do 32bit ones just fine)
+ *
+ * Why "i" and "I" constraints do not work? gcc says:
+ * "warning: asm operand 2 probably doesn't match constraints"
+ * "error: impossible constraint in 'asm'"
+ * Will use "Ic" for now. If gcc will fail to do const propagation
+ * and will try to stuff constant into ecx, shld %3,... will expand
+ * to shld %ecx,... and assembler will moan.
+ * Do not 'fix' by changing to shld %b3,...
+ *
+ * Have to stick to edx,eax pair only because
+ * gcc has limited support for 64bit asm parameters
+ */
+#define constant_rol64(v,c) \
+ ({ \
+ u64 vv = (v); \
+ if(!(c&63)) { \
+ } else if((c&63)==1) { \
+ asm ( \
+ " shldl $1,%%edx,%%eax \n" \
+ " rcll $1,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } else if((c&63)==63) { \
+ asm ( \
+ " shrdl $1,%%edx,%%eax \n" \
+ " rcrl $1,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } else if((c&63)<32) { \
+ asm ( \
+ " shldl %3,%%edx,%%eax \n" \
+ " shldl %3,%2,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv), \
+ "r" (vv), \
+ "Ic" (c&63) \
+ ); \
+ } else if((c&63)>32) { \
+ asm ( \
+ " shrdl %3,%%edx,%%eax \n" \
+ " shrdl %3,%2,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv), \
+ "r" (vv), \
+ "Ic" (64-(c&63)) \
+ ); \
+ } else /* (c&63)==32 */ { \
+ asm ( \
+ " xchgl %%edx,%%eax \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } \
+ vv; \
+ })
+#define constant_ror64(v,c) \
+ ({ \
+ u64 vv = (v); \
+ if(!(c&63)) { \
+ } else if((c&63)==1) { \
+ asm ( \
+ " shrdl $1,%%edx,%%eax \n" \
+ " rcrl $1,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } else if((c&63)==63) { \
+ asm ( \
+ " shldl $1,%%edx,%%eax \n" \
+ " rcll $1,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } else if((c&63)<32) { \
+ asm ( \
+ " shrdl %3,%%edx,%%eax \n" \
+ " shrdl %3,%2,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv), \
+ "r" (vv), \
+ "Ic" (c&63) \
+ ); \
+ } else if((c&63)>32) { \
+ asm ( \
+ " shldl %3,%%edx,%%eax \n" \
+ " shldl %3,%2,%%edx \n" \
+ : "=&A" (vv) \
+ : "0" (vv), \
+ "r" (vv), \
+ "Ic" (64-(c&63)) \
+ ); \
+ } else /* (c&63)==32 */ { \
+ asm ( \
+ " xchgl %%edx,%%eax \n" \
+ : "=&A" (vv) \
+ : "0" (vv) \
+ ); \
+ } \
+ vv; \
+ })
+/*
+ * Unfortunately 64bit rotations with non-constant count
+ * have issues with cnt>=32. Using C code instead
+ */
+static inline u64 rol64(u64 x,int num) {
+ if(__builtin_constant_p(num))
+ return constant_rol64(x,num);
+ /* Hmmm... shall we do cnt&=63 here? */
+ return ((x<<num) | (x>>(64-num)));
+}
+static inline u64 ror64(u64 x,int num) {
+ if(__builtin_constant_p(num))
+ return constant_ror64(x,num);
+ return ((x>>num) | (x<<(64-num)));
+}
+
+#define ARCH_HAS_ROL64
+#define ARCH_HAS_ROR64
-#ifdef __KERNEL__
#define ext2_set_bit(nr,addr) \
__test_and_set_bit((nr),(unsigned long*)addr)
diff -urpN linux-2.6.9-rc3.src/include/linux/bitops.h linux-2.6.9-rc3rot.src/include/linux/bitops.h
--- linux-2.6.9-rc3.src/include/linux/bitops.h Sat Aug 14 13:56:23 2004
+++ linux-2.6.9-rc3rot.src/include/linux/bitops.h Sun Oct 3 12:43:51 2004
@@ -4,6 +4,38 @@
#include <asm/bitops.h>
/*
+ * bit rotations
+ */
+
+#ifndef ARCH_HAS_ROL32
+static inline u32 rol32(u32 x, int num)
+{
+ return (x << num) | (x >> (32 - num));
+}
+#endif
+
+#ifndef ARCH_HAS_ROR32
+static inline u32 ror32(u32 x, int num)
+{
+ return (x >> num) | (x << (32 - num));
+}
+#endif
+
+#ifndef ARCH_HAS_ROL64
+static inline u64 rol64(u64 x, int num)
+{
+ return (x << num) | (x >> (64 - num));
+}
+#endif
+
+#ifndef ARCH_HAS_ROR64
+static inline u64 ror64(u64 x, int num)
+{
+ return (x >> num) | (x << (64 - num));
+}
+#endif
+
+/*
* ffs: find first bit set. This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from the above ffz (man ffs).
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] add rotate left/right ops to bitops.h
2004-10-03 10:59 ` Denis Vlasenko
@ 2004-10-04 9:55 ` Andrew Morton
0 siblings, 0 replies; 4+ messages in thread
From: Andrew Morton @ 2004-10-04 9:55 UTC (permalink / raw)
To: Denis Vlasenko; +Cc: yoshfuji, jmorris, davem, linux-kernel
Denis Vlasenko <vda@port.imtp.ilyichevsk.odessa.ua> wrote:
>
> 269r3rot.diff text/x-diff (4685 bytes)
- bitops.h needs types.h for u64
- Fix ghastly coding style innovations.
Signed-off-by: Andrew Morton <akpm@osdl.org>
---
25-akpm/include/asm-i386/bitops.h | 55 ++++++++++++++++++++------------------
1 files changed, 30 insertions(+), 25 deletions(-)
diff -puN include/asm-i386/bitops.h~add-rotate-left-right-ops-to-bitopsh-build-fix include/asm-i386/bitops.h
--- 25/include/asm-i386/bitops.h~add-rotate-left-right-ops-to-bitopsh-build-fix 2004-10-03 21:18:30.801267776 -0700
+++ 25-akpm/include/asm-i386/bitops.h 2004-10-03 21:28:53.625584088 -0700
@@ -7,6 +7,7 @@
#include <linux/config.h>
#include <linux/compiler.h>
+#include <linux/types.h>
/*
* These have to be done with inline assembly: that way the bit-setting
@@ -446,25 +447,25 @@ static inline int ffs(int x)
* Have to stick to edx,eax pair only because
* gcc has limited support for 64bit asm parameters
*/
-#define constant_rol64(v,c) \
+#define constant_rol64(v, c) \
({ \
u64 vv = (v); \
- if(!(c&63)) { \
- } else if((c&63)==1) { \
+ if (!(c & 63)) { \
+ } else if ((c & 63) == 1) { \
asm ( \
" shldl $1,%%edx,%%eax \n" \
" rcll $1,%%edx \n" \
: "=&A" (vv) \
: "0" (vv) \
); \
- } else if((c&63)==63) { \
+ } else if ((c & 63) == 63) { \
asm ( \
" shrdl $1,%%edx,%%eax \n" \
" rcrl $1,%%edx \n" \
: "=&A" (vv) \
: "0" (vv) \
); \
- } else if((c&63)<32) { \
+ } else if ((c & 63) < 32) { \
asm ( \
" shldl %3,%%edx,%%eax \n" \
" shldl %3,%2,%%edx \n" \
@@ -473,16 +474,16 @@ static inline int ffs(int x)
"r" (vv), \
"Ic" (c&63) \
); \
- } else if((c&63)>32) { \
+ } else if ((c & 63) > 32) { \
asm ( \
" shrdl %3,%%edx,%%eax \n" \
" shrdl %3,%2,%%edx \n" \
: "=&A" (vv) \
: "0" (vv), \
"r" (vv), \
- "Ic" (64-(c&63)) \
+ "Ic" (64 - (c & 63)) \
); \
- } else /* (c&63)==32 */ { \
+ } else /* (c & 63) == 32 */ { \
asm ( \
" xchgl %%edx,%%eax \n" \
: "=&A" (vv) \
@@ -491,43 +492,43 @@ static inline int ffs(int x)
} \
vv; \
})
-#define constant_ror64(v,c) \
+#define constant_ror64(v, c) \
({ \
u64 vv = (v); \
- if(!(c&63)) { \
- } else if((c&63)==1) { \
+ if (!(c & 63)) { \
+ } else if ((c & 63) == 1) { \
asm ( \
" shrdl $1,%%edx,%%eax \n" \
" rcrl $1,%%edx \n" \
: "=&A" (vv) \
: "0" (vv) \
); \
- } else if((c&63)==63) { \
+ } else if ((c & 63) == 63) { \
asm ( \
" shldl $1,%%edx,%%eax \n" \
" rcll $1,%%edx \n" \
: "=&A" (vv) \
: "0" (vv) \
); \
- } else if((c&63)<32) { \
+ } else if ((c & 63) < 32) { \
asm ( \
" shrdl %3,%%edx,%%eax \n" \
" shrdl %3,%2,%%edx \n" \
: "=&A" (vv) \
: "0" (vv), \
"r" (vv), \
- "Ic" (c&63) \
+ "Ic" (c & 63) \
); \
- } else if((c&63)>32) { \
+ } else if ((c & 63) > 32) { \
asm ( \
" shldl %3,%%edx,%%eax \n" \
" shldl %3,%2,%%edx \n" \
: "=&A" (vv) \
: "0" (vv), \
"r" (vv), \
- "Ic" (64-(c&63)) \
+ "Ic" (64 - (c & 63)) \
); \
- } else /* (c&63)==32 */ { \
+ } else /* (c & 63) == 32 */ { \
asm ( \
" xchgl %%edx,%%eax \n" \
: "=&A" (vv) \
@@ -536,20 +537,24 @@ static inline int ffs(int x)
} \
vv; \
})
+
/*
* Unfortunately 64bit rotations with non-constant count
* have issues with cnt>=32. Using C code instead
*/
-static inline u64 rol64(u64 x,int num) {
- if(__builtin_constant_p(num))
- return constant_rol64(x,num);
+static inline u64 rol64(u64 x,int num)
+{
+ if (__builtin_constant_p(num))
+ return constant_rol64(x, num);
/* Hmmm... shall we do cnt&=63 here? */
- return ((x<<num) | (x>>(64-num)));
+ return ((x << num) | (x >> (64 - num)));
}
-static inline u64 ror64(u64 x,int num) {
- if(__builtin_constant_p(num))
- return constant_ror64(x,num);
- return ((x>>num) | (x<<(64-num)));
+
+static inline u64 ror64(u64 x, int num)
+{
+ if (__builtin_constant_p(num))
+ return constant_ror64(x, num);
+ return ((x >> num) | (x << (64 - num)));
}
#define ARCH_HAS_ROL64
_
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-10-04 9:58 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-10-03 10:44 [PATCH] add rotate left/right ops to bitops.h Denis Vlasenko
2004-10-03 10:56 ` YOSHIFUJI Hideaki / 吉藤英明
2004-10-03 10:59 ` Denis Vlasenko
2004-10-04 9:55 ` Andrew Morton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome