summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qsimd.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@nokia.com>2010-08-24 11:00:33 (GMT)
committerThiago Macieira <thiago.macieira@nokia.com>2010-08-24 13:01:10 (GMT)
commit5070c3ae331faf18f6997535356853cc61ef0ad7 (patch)
tree548970ab87fcfe86abd5d0866d70e9038c43c250 /src/corelib/tools/qsimd.cpp
parentdb1a70b33ce03197111556344542e931e9345839 (diff)
downloadQt-5070c3ae331faf18f6997535356853cc61ef0ad7.zip
Qt-5070c3ae331faf18f6997535356853cc61ef0ad7.tar.gz
Qt-5070c3ae331faf18f6997535356853cc61ef0ad7.tar.bz2
Detect CPU features on ARM by reading the ELF auxvec.
Reviewed-by: Benjamin Poulain
Diffstat (limited to 'src/corelib/tools/qsimd.cpp')
-rw-r--r--src/corelib/tools/qsimd.cpp45
1 files changed, 43 insertions, 2 deletions
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
index d6e6c03..a5ec3c5 100644
--- a/src/corelib/tools/qsimd.cpp
+++ b/src/corelib/tools/qsimd.cpp
@@ -50,6 +50,13 @@
#include <intrin.h>
#endif
+#if defined(Q_OS_LINUX) && defined(__arm__)
+#include "private/qcore_unix_p.h"
+
+#include <asm/hwcap.h>
+#include <linux/auxvec.h>
+#endif
+
QT_BEGIN_NAMESPACE
#if defined (Q_OS_WINCE)
@@ -81,16 +88,50 @@ static inline uint detectProcessorFeatures()
{
uint features = 0;
+#if defined(Q_OS_LINUX)
+ int auxv = ::qt_safe_open("/proc/self/auxv", O_RDONLY);
+ if (auxv != -1) {
+ unsigned long vector[64];
+ int nread;
+ while (features == 0) {
+ nread = ::qt_safe_read(auxv, (char *)vector, sizeof vector);
+ if (nread <= 0) {
+ // EOF or error
+ break;
+ }
+
+ int max = nread / (sizeof vector[0]);
+ for (int i = 0; i < max; i += 2)
+ if (vector[i] == AT_HWCAP) {
+ if (vector[i+1] & HWCAP_IWMMXT)
+ features |= IWMMXT;
+ if (vector[i+1] & HWCAP_NEON)
+ features |= NEON;
+ break;
+ }
+ }
+
+ if (qgetenv("QT_NO_IWMMXT").toInt())
+ features ^= IWMMXT;
+ if (qgetenv("QT_NO_NEON").toInt())
+ features ^= NEON;
+
+ ::qt_safe_close(auxv);
+ return features;
+ }
+ // fall back if /proc/self/auxv wasn't found
+#endif
+
#if defined(QT_HAVE_IWMMXT)
// runtime detection only available when running as a previlegied process
static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();
features = doIWMMXT ? IWMMXT : 0;
- return features;
#elif defined(QT_HAVE_NEON)
static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();
features = doNEON ? NEON : 0;
- return features;
#endif
+
+ return features;
}
#elif defined(__i386__) || defined(_M_IX86)