On Fri, 11 Mar 2011, Mike Belopuhov wrote:
> recent commit to pirofti made me wonder why don't we take an advantage
> of the 64 bit bswap instruction on amd64?
Here's a revised diff with two changes from Mike's:
1) use %0 instead of %1, as the %N operands are zero-based. (I dare
anyone to find a clear specification for the behavior of gcc for %N
when then 'N' is the exact number of operands provided, like %1 in
the current asm)
2) include __statement to suppress warnings when compiled with -pedantic
oks?
Philip Guenther
Index: endian.h
===================================================================
RCS file: /cvs/src/sys/arch/amd64/include/endian.h,v
retrieving revision 1.4
diff -u -p -r1.4 endian.h
--- endian.h 11 Mar 2011 15:17:08 -0000 1.4
+++ endian.h 11 Mar 2011 22:12:14 -0000
@@ -29,25 +29,24 @@
#ifdef __GNUC__
-#define __swap32md(x) ({
\
+#define __swap32md(x) __statement({
\
u_int32_t __swap32md_x = (x); \
\
- __asm ("bswap %1" : "+r" (__swap32md_x)); \
+ __asm ("bswap %0" : "+r" (__swap32md_x)); \
__swap32md_x; \
})
-/* XXX - I'm sure there is a better way on this cpu. */
-#define __swap64md(x) ({
\
+#define __swap64md(x) __statement({
\
u_int64_t __swap64md_x = (x); \
\
- (u_int64_t)__swap32md(__swap64md_x >> 32) | \
- (u_int64_t)__swap32md(__swap64md_x & 0xffffffff) << 32; \
+ __asm ("bswapq %0" : "+r" (__swap64md_x)); \
+ __swap64md_x; \
})
-#define __swap16md(x) ({
\
+#define __swap16md(x) __statement({
\
u_int16_t __swap16md_x = (x); \
\
- __asm ("rorw $8, %w1" : "+r" (__swap16md_x)); \
+ __asm ("rorw $8, %w0" : "+r" (__swap16md_x)); \
__swap16md_x; \
})