diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2014-12-03 14:11:47 -0800 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2014-12-20 01:41:00 +0100 |
commit | a31b75b766b87d0210ed174f587aee33ad639f9b (patch) | |
tree | fb8d188277a7fa47c433d9ace6593837e2954430 | |
parent | c70658d301e274c3aaa1fb6cebe2a5e56db12779 (diff) | |
download | qtbase-a31b75b766b87d0210ed174f587aee33ad639f9b.tar.gz |
Use the GCC and Clang __builtin_bswap intrinsics in qbswap
Glibc will use the intrinsics for 32- and 64-bit, but didn't for 16-bit
(probably because GCC didn't document it until version 4.8), so this
commit will make us access the intrinsics directly the intrisincs for
all type sizes.
Additionally, this will get us access to the compiler intrisics even
without Glibc, such as when building against uclibc or Bionic.
Another benefit is that both Clang and ICC will use the MOVBE
instruction on Atom and Haswell architectures.
Change-Id: I39d1891f479887d719d69ebe4ac92ac9bfeda8af
Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@theqtcompany.com>
-rw-r--r-- | mkspecs/features/qt_common.prf | 3 | ||||
-rw-r--r-- | src/corelib/global/qendian.h | 26 |
2 files changed, 13 insertions, 16 deletions
diff --git a/mkspecs/features/qt_common.prf b/mkspecs/features/qt_common.prf index af9d6cae67..eb65e73079 100644 --- a/mkspecs/features/qt_common.prf +++ b/mkspecs/features/qt_common.prf @@ -50,9 +50,6 @@ warnings_are_errors:warning_clean { reg_ver = $${QT_CLANG_MAJOR_VERSION}.$${QT_CLANG_MINOR_VERSION} contains(apple_ver, "4\\.[012]|5\\.[01]")|contains(reg_ver, "3\\.[34]") { QMAKE_CXXFLAGS_WARN_ON += -Werror -Wno-error=\\$${LITERAL_HASH}warnings -Wno-error=deprecated-declarations $$WERROR - - # glibc's bswap_XX macros use the "register" keyword - linux:equals(reg_ver, "3.4"): QMAKE_CXXFLAGS_WARN_ON += -Wno-error=deprecated-register } } else:intel_icc:linux { # Intel CC 13.0 - 15.0, on Linux only diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index 136581167c..7c643f7592 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -40,10 +40,6 @@ #include <stdlib.h> #include <string.h> -#ifdef __GLIBC__ -#include <byteswap.h> -#endif - QT_BEGIN_NAMESPACE @@ -276,18 +272,16 @@ template <> inline qint8 qFromBigEndian<qint8>(const uchar *src) */ template <typename T> T qbswap(T source); -#ifdef __GLIBC__ +// GCC 4.3 implemented all the intrinsics, but the 16-bit one only got implemented in 4.8; +// Clang 2.6 implemented the 32- and 64-bit but waited until 3.2 to implement the 16-bit one +#if (defined(Q_CC_GNU) && Q_CC_GNU >= 403) || (defined(Q_CC_CLANG) && Q_CC_CLANG >= 206) template <> inline quint64 qbswap<quint64>(quint64 source) { - return bswap_64(source); + return __builtin_bswap64(source); } template <> inline quint32 qbswap<quint32>(quint32 source) { - return bswap_32(source); -} -template <> inline quint16 qbswap<quint16>(quint16 source) -{ - return bswap_16(source); + return __builtin_bswap32(source); } #else template <> inline quint64 qbswap<quint64>(quint64 source) @@ -311,14 +305,20 @@ template <> inline quint32 qbswap<quint32>(quint32 source) | ((source & 0x00ff0000) >> 8) | ((source & 0xff000000) >> 24); } - +#endif // GCC & Clang intrinsics +#if (defined(Q_CC_GNU) && Q_CC_GNU >= 408) || (defined(Q_CC_CLANG) && Q_CC_CLANG >= 302) +template <> inline quint16 qbswap<quint16>(quint16 source) +{ + return __builtin_bswap16(source); +} +#else template <> inline quint16 qbswap<quint16>(quint16 source) { return quint16( 0 | ((source & 0x00ff) << 8) | ((source & 0xff00) >> 8) ); } -#endif // __GLIBC__ +#endif // GCC & Clang intrinsics // signed specializations template <> inline qint64 qbswap<qint64>(qint64 source) |