summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-11-18 10:57:44 +0100
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-12-01 12:51:04 +0000
commit4e8f07cd0f2f24926badc82f1592ed91ba3a79e0 (patch)
tree8f0b09a6d81e8fb33137a39399cad3cc79891ae2 /src/corelib/tools
parentbf7ce1ff84a735056b64958349a8a831eafe4684 (diff)
Use __builtin_clz/ctz when available.
Nicely ask the compiler if it has a built-in for clz/ctz before resorting to CPU specific brute force measurements. Change-Id: Ifa992267ec4528219d7da14524af738316ceeaea Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r--src/corelib/tools/qsimd_p.h18
1 files changed, 17 insertions, 1 deletions
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 96b9d376b7..dedee06e38 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -431,7 +431,23 @@ static inline quint64 qCpuFeatures()
#define qCpuHasFeature(feature) ((qCompilerCpuFeatures & (Q_UINT64_C(1) << CpuFeature ## feature)) \
|| (qCpuFeatures() & (Q_UINT64_C(1) << CpuFeature ## feature)))
-#ifdef Q_PROCESSOR_X86
+#if QT_HAS_BUILTIN(__builtin_clz) && QT_HAS_BUILTIN(__builtin_ctz) && defined(Q_CC_CLANG) && !defined(Q_CC_INTEL)
+static Q_ALWAYS_INLINE unsigned _bit_scan_reverse(unsigned val)
+{
+ Q_ASSERT(val != 0); // if val==0, the result is undefined.
+ unsigned result = static_cast<unsigned>(__builtin_clz(val)); // Count Leading Zeros
+ // Now Invert the result: clz will count *down* from the msb to the lsb, so the msb index is 31
+ // and the lsb inde is 0. The result for _bit_scan_reverse is expected to be the index when
+ // counting up: msb index is 0 (because it starts there), and the lsb index is 31.
+ result ^= sizeof(unsigned) * 8 - 1;
+ return result;
+}
+static Q_ALWAYS_INLINE unsigned _bit_scan_forward(unsigned val)
+{
+ Q_ASSERT(val != 0); // if val==0, the result is undefined.
+ return static_cast<unsigned>(__builtin_ctz(val)); // Count Trailing Zeros
+}
+#elif defined(Q_PROCESSOR_X86)
// Bit scan functions for x86
# if defined(Q_CC_MSVC) && !defined(Q_OS_WINCE)
// MSVC calls it _BitScanReverse and returns the carry flag, which we don't need