This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
PATCH: Use __builtin_bswap32/64 for GCC >= 4.2
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: GNU C Library <libc-alpha at sourceware dot org>
- Date: Thu, 5 Apr 2012 13:08:40 -0700
- Subject: PATCH: Use __builtin_bswap32/64 for GCC >= 4.2
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
sysdeps/x86_64/bits/byteswap.h has
#if defined __GNUC__ && __GNUC__ >= 2
..
#else
# define __bswap_32(x) \
(__extension__
\
({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
#endif
It doesn't work for compilers without GCC __extension__
support.
This patch uses __builtin_bswap32/64 for GCC >= 4.2.
I used inline function instead of __extension__ to avoid
the __builtin_bswap32/64 return type issue:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37743
Tested on Linux/ia32 and Linux/x86-64. OK to install?
Thanks.
H.J.
--
2012-04-05 H.J. Lu <hongjiu.lu@intel.com>
* sysdeps/i386/bits/byteswap.h: (__bswap_32): Use
__builtin_bswap32 for GCC >= 4.2.
(__bswap_64): Use __builtin_bswap64 for GCC >= 4.2.
* sysdeps/x86_64/bits/byteswap.h: Likewise.
diff --git a/sysdeps/i386/bits/byteswap.h b/sysdeps/i386/bits/byteswap.h
index fb0a827..751e10d 100644
--- a/sysdeps/i386/bits/byteswap.h
+++ b/sysdeps/i386/bits/byteswap.h
@@ -60,52 +60,18 @@ __bswap_16 (unsigned short int __bsx)
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
-#ifdef __GNUC__
-# if __GNUC__ >= 2
-/* To swap the bytes in a word the i486 processors and up provide the
- `bswap' opcode. On i386 we have to use three instructions. */
-# if !defined __i486__ && !defined __pentium__ && !defined __pentiumpro__ \
- && !defined __pentium4__ && !defined __k8__ && !defined __athlon__ \
- && !defined __k6__ && !defined __nocona__ && !defined __core2__ \
- && !defined __geode__ && !defined __amdfam10__
-# define __bswap_32(x) \
- (__extension__ \
- ({ register unsigned int __v, __x = (x); \
- if (__builtin_constant_p (__x)) \
- __v = __bswap_constant_32 (__x); \
- else \
- __asm__ ("rorw $8, %w0;" \
- "rorl $16, %0;" \
- "rorw $8, %w0" \
- : "=r" (__v) \
- : "0" (__x) \
- : "cc"); \
- __v; }))
-# else
-# define __bswap_32(x) \
- (__extension__ \
- ({ register unsigned int __v, __x = (x); \
- if (__builtin_constant_p (__x)) \
- __v = __bswap_constant_32 (__x); \
- else \
- __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
- __v; }))
-# endif
-# else
-# define __bswap_32(x) \
- (__extension__ \
- ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
-# endif
-#else
static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
+#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
+ return __builtin_bswap32 (__bsx);
+#else
return __bswap_constant_32 (__bsx);
-}
#endif
+}
-#if defined __GNUC__ && __GNUC__ >= 2
+#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
/* Swap bytes in 64 bit value. */
# define __bswap_constant_64(x) \
(__extension__ ((((x) & 0xff00000000000000ull) >> 56) \
@@ -117,19 +83,11 @@ __bswap_32 (unsigned int __bsx)
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56)))
-# define __bswap_64(x) \
- (__extension__ \
- ({ union { __extension__ unsigned long long int __ll; \
- unsigned long int __l[2]; } __w, __r; \
- if (__builtin_constant_p (x)) \
- __r.__ll = __bswap_constant_64 (x); \
- else \
- { \
- __w.__ll = (x); \
- __r.__l[0] = __bswap_32 (__w.__l[1]); \
- __r.__l[1] = __bswap_32 (__w.__l[0]); \
- } \
- __r.__ll; }))
+static __inline unsigned long long int
+__bswap_64 (unsigned long long int __bsx)
+{
+ return __builtin_bswap64 (__bsx);
+}
#elif __GLIBC_HAVE_LONG_LONG
# define __bswap_constant_64(x) \
((((x) & 0xff00000000000000ull) >> 56) \
diff --git a/sysdeps/x86_64/bits/byteswap.h b/sysdeps/x86_64/bits/byteswap.h
index 472281f..38c42c8 100644
--- a/sysdeps/x86_64/bits/byteswap.h
+++ b/sysdeps/x86_64/bits/byteswap.h
@@ -23,8 +23,6 @@
#ifndef _BITS_BYTESWAP_H
#define _BITS_BYTESWAP_H 1
-#include <bits/wordsize.h>
-
/* Swap bytes in 16 bit value. */
#define __bswap_constant_16(x) \
((unsigned short int) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8)))
@@ -55,46 +53,18 @@
((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
-#if defined __GNUC__ && __GNUC__ >= 2
-# if __WORDSIZE == 64 || (defined __i486__ || defined __pentium__ \
- || defined __pentiumpro__ || defined __pentium4__ \
- || defined __k8__ || defined __athlon__ \
- || defined __k6__ || defined __nocona__ \
- || defined __core2__ || defined __geode__ \
- || defined __amdfam10__)
-/* To swap the bytes in a word the i486 processors and up provide the
- `bswap' opcode. On i386 we have to use three instructions. */
-# define __bswap_32(x) \
- (__extension__ \
- ({ register unsigned int __v, __x = (x); \
- if (__builtin_constant_p (__x)) \
- __v = __bswap_constant_32 (__x); \
- else \
- __asm__ ("bswap %0" : "=r" (__v) : "0" (__x)); \
- __v; }))
-# else
-# define __bswap_32(x) \
- (__extension__ \
- ({ register unsigned int __v, __x = (x); \
- if (__builtin_constant_p (__x)) \
- __v = __bswap_constant_32 (__x); \
- else \
- __asm__ ("rorw $8, %w0;" \
- "rorl $16, %0;" \
- "rorw $8, %w0" \
- : "=r" (__v) \
- : "0" (__x) \
- : "cc"); \
- __v; }))
-# endif
+static __inline unsigned int
+__bswap_32 (unsigned int __bsx)
+{
+#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
+ return __builtin_bswap32 (__bsx);
#else
-# define __bswap_32(x) \
- (__extension__ \
- ({ register unsigned int __x = (x); __bswap_constant_32 (__x); }))
+ return __bswap_constant_32 (__bsx);
#endif
+}
-#if defined __GNUC__ && __GNUC__ >= 2
+#if defined __GNUC__ && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
/* Swap bytes in 64 bit value. */
# define __bswap_constant_64(x) \
(__extension__ ((((x) & 0xff00000000000000ull) >> 56) \
@@ -106,30 +76,11 @@
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56)))
-# if __WORDSIZE == 64
-# define __bswap_64(x) \
- (__extension__ \
- ({ register unsigned long __v, __x = (x); \
- if (__builtin_constant_p (__x)) \
- __v = __bswap_constant_64 (__x); \
- else \
- __asm__ ("bswap %q0" : "=r" (__v) : "0" (__x)); \
- __v; }))
-# else
-# define __bswap_64(x) \
- (__extension__ \
- ({ union { __extension__ unsigned long long int __ll; \
- unsigned int __l[2]; } __w, __r; \
- if (__builtin_constant_p (x)) \
- __r.__ll = __bswap_constant_64 (x); \
- else \
- { \
- __w.__ll = (x); \
- __r.__l[0] = __bswap_32 (__w.__l[1]); \
- __r.__l[1] = __bswap_32 (__w.__l[0]); \
- } \
- __r.__ll; }))
-# endif
+static __inline unsigned long long int
+__bswap_64 (unsigned long long int __bsx)
+{
+ return __builtin_bswap64 (__bsx);
+}
#elif __GLIBC_HAVE_LONG_LONG
# define __bswap_constant_64(x) \
((((x) & 0xff00000000000000ull) >> 56) \