summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.tests/arch/arch.cpp162
-rwxr-xr-xconfig.tests/unix/arch.test16
-rwxr-xr-xconfigure18
-rw-r--r--tools/configure/configureapp.cpp59
4 files changed, 229 insertions, 26 deletions
diff --git a/config.tests/arch/arch.cpp b/config.tests/arch/arch.cpp
index ed772f70a0..da0fe1c1b7 100644
--- a/config.tests/arch/arch.cpp
+++ b/config.tests/arch/arch.cpp
@@ -76,7 +76,169 @@ const char msg[] = "==Qt=magic=Qt== Architecture:"
#endif
;
+extern const char msg2[];
+const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
+ // This is the list of features found in GCC or MSVC
+ // We don't use all of them, but this is ready for future expansion
+
+// -- x86 --
+#ifdef __3dNOW__
+// 3dNow!, introduced with the AMD K6-2, discontinued after 2010
+" 3dnow"
+#endif
+#ifdef __3dNOW_A__
+// Athlon
+" 3dnow-a"
+#endif
+#ifdef __ABM__
+// Advanced Bit Manipulation, AMD Barcelona (family 10h)
+" abm"
+#endif
+#ifdef __AES__
+// AES New Instructions, Intel Core-i7 second generation ("Sandy Bridge")
+" aes"
+#endif
+#ifdef __AVX__
+// Advanced Vector Extensions, Intel Core-i7 second generation ("Sandy Bridge")
+" avx"
+#endif
+#ifdef __AVX2__
+// AVX 2, Intel codename "Haswell"
+" avx2"
+#endif
+#ifdef __BMI__
+// Bit Manipulation Instructions 1, Intel codename "Haswell", AMD "Bulldozer 2"
+" bmi"
+#endif
+#ifdef __BMI2__
+// Bit Manipulation Instructions 2, Intel codename "Haswell"
+" bmi2"
+#endif
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
+// cmpxchg16b instruction, Intel Pentium 4 64-bit ("Nocona"), AMD Barcelona (family 10h)
+// Notably, this instruction is missing on earlier AMD Athlon 64
+" cx16"
+#endif
+#ifdef __F16C__
+// 16-bit floating point conversion, Intel codename "Ivy Bridge"
+" f16c"
+#endif
+#ifdef __FMA__
+// Fused Multiply-Add with 3 arguments, Intel codename "Haswell", AMD "Bulldozer 2"
+// a.k.a. "FMA3"
+" fma"
+#endif
+#ifdef __FMA4__
+// Fused Multiply-Add with 4 arguments, AMD "Bulldozer"
+" fma4"
+#endif
+#ifdef __FSGSBASE__
+// rdfsgsbase, wrfsgsbase, Intel codename "Ivy Bridge"
+" fsgsbase"
+#endif
+#ifdef __LWP__
+// LWP instructions, AMD "Bulldozer"
+" lwp"
+#endif
+#ifdef __LZCNT__
+// Leading-Zero bit count, Intel codename "Haswell"
+" lzcnt"
+#endif
+#ifdef __MMX__
+// Multimedia Extensions, Pentium MMX, AMD K6-2
+" mmx"
+#endif
+#ifdef __MOVBE__
+// Move Big Endian, Intel Atom & "Haswell"
+" movbe"
+#endif
+#ifdef __NO_SAHF__
+// missing SAHF instruction in 64-bit, up to Intel Pentium 4 64-bit ("Nocona"), AMD Athlon FX
+// Note: the macro is not defined, so this will never show up
+" no-sahf"
+#endif
+#ifdef __PCLMUL__
+// (Packed) Carry-less multiplication, Intel Core-i7 second generation ("Sandy Bridge")
+" pclmul"
+#endif
+#ifdef __POPCNT__
+// Population Count (count of set bits), Intel Core-i7 second generation ("Sandy Bridge")
+" popcnt"
+#endif
+#ifdef __RDRND__
+// Random number generator, Intel codename "Ivy Bridge"
+" rdrnd"
+#endif
+#if defined(__SSE__) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1) || defined(_M_X64)
+// Streaming SIMD Extensions, Intel Pentium III, AMD Athlon
+" sse"
+#endif
+#if defined(__SSE2__) || (defined(_M_IX86_FP) && _M_IX86_FP >= 2) || defined(_M_X64)
+// SSE2, Intel Pentium-M, Intel Pentium 4, AMD Opteron and Athlon 64
+" sse2"
+#endif
+#ifdef __SSE3__
+// SSE3, Intel Pentium 4 "Prescott", AMD Athlon 64 rev E
+" sse3"
+#endif
+#ifdef __SSSE3__
+// Supplemental SSE3, Intel Core 2, AMD "Bulldozer"
+" ssse3"
+#endif
+#ifdef __SSE4A__
+// SSE4a, AMD Barcelona
+" sse4a"
+#endif
+#ifdef __SSE4_1__
+// SSE 4.1, Intel Core-i7 ("Nehalem"), AMD "Bulldozer"
+" sse4.1"
+#endif
+#ifdef __SSE4_2__
+// SSE 4.2, Intel Core-i7 ("Nehalem"), AMD "Bulldozer"
+" sse4.2"
+// Since no processor supports SSE4.2 without 4.1 and since no Intel processor
+// supports SSE4a, define "sse4" to indicate SSE4"
+" sse4"
+#endif
+#ifdef __TBM__
+// TBM, AMD "Bulldozer"
+" tbm"
+#endif
+#ifdef __XOP__
+// XOP, AMD "Bulldozer"
+" xop"
+#endif
+
+// -- ARM --
+#ifdef __ARM_NEON__
+" neon"
+#endif
+#ifdef __IWMMXT__
+" iwmmxt"
+#endif
+
+// -- SPARC --
+#ifdef __VIS__
+" vis"
+# if __VIS__ >= 0x200
+" vis2"
+# endif
+# if __VIS__ >= 0x300
+" vis3"
+# endif
+#endif
+
+// -- MIPS --
+// Wikipedia says there are extensions, but GCC installs no headers
+
+// -- POWER, PowerPC --
+#ifdef __ALTIVEC__
+" altivec"
+#endif
+ "";
+
int main()
{
puts(msg);
+ puts(msg2);
}
diff --git a/config.tests/unix/arch.test b/config.tests/unix/arch.test
index 2a6e12de56..939b49cea0 100755
--- a/config.tests/unix/arch.test
+++ b/config.tests/unix/arch.test
@@ -5,6 +5,7 @@ VERBOSE=$2
SRCDIR=$3
OUTDIR=$4
RESULTFILE=$5
+VARPREFIX=$6
# debuggery
[ "$VERBOSE" = "yes" ] && echo "Determining architecture... ($*)"
@@ -28,14 +29,15 @@ else
exit 2
fi
-ARCH=`strings - $binary 2>/dev/null | awk -F: '/==Qt=magic=Qt==/ { print $2 }'` ||
-{
+if strings - $binary 2>/dev/null | \
+ awk -F: '/==Qt=magic=Qt== Architecture/ { print "'$VARPREFIX'_ARCH=\"" $2 "\"" }
+ /==Qt=magic=Qt== Sub-architecture/ { print "'$VARPREFIX'_CPUFEATURES=\"" $2 "\"" }' > "$RESULTFILE"
+then
+ [ "$VERBOSE" = "yes" ] && echo " Found architecture in binary" && \
+ cat "$RESULTFILE"
+else
[ "$VERBOSE" = "yes" ] && echo "Unable to determine architecture!"
exit 2
-}
+fi
$MAKE distclean >/dev/null 2>&1
-
-[ "$VERBOSE" = "yes" ] && echo " Found '$ARCH' in binary"
-
-echo "$ARCH" > $5
diff --git a/configure b/configure
index 52413f12fe..c8f615888c 100755
--- a/configure
+++ b/configure
@@ -708,8 +708,10 @@ CFG_PKGCONFIG=auto
# Target architecture
CFG_ARCH=
+CFG_CPUFEATURES=
# Host architecture, same as CFG_ARCH when not cross-compiling
CFG_HOST_ARCH=
+CFG_HOST_CPUFEATURES=
# Set when the -arch or -host-arch arguments are used
OPT_OBSOLETE_HOST_ARG=no
@@ -3668,9 +3670,9 @@ fi
# Use config.tests/arch/arch.pro to has the compiler tell us what the target architecture is
OUTFILE=$outpath/arch.result
-"$unixtests/arch.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "$OUTFILE"
+"$unixtests/arch.test" "$XQMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "$OUTFILE" "CFG"
if [ $? -eq 0 ]; then
- CFG_ARCH=`cat "$OUTFILE"`
+ eval `cat "$OUTFILE"`
else
echo
echo "Could not determine the target architecture!"
@@ -3681,9 +3683,9 @@ rm -f "$OUTFILE" 2>/dev/null
if [ "$QMAKESPEC" != "$XQMAKESPEC" ]; then
# Do the same test again, using the host compiler
- SYSROOT_FLAG= "$unixtests/arch.test" "$QMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "$OUTFILE"
+ SYSROOT_FLAG= "$unixtests/arch.test" "$QMAKESPEC" $OPT_VERBOSE "$relpath" "$outpath" "$OUTFILE" "CFG_HOST"
if [ $? -eq 0 ]; then
- CFG_HOST_ARCH=`cat "$OUTFILE"`
+ eval `cat "$OUTFILE"`
else
echo
echo "Could not determine the host architecture!"
@@ -3694,6 +3696,7 @@ if [ "$QMAKESPEC" != "$XQMAKESPEC" ]; then
else
# not cross compiling, host == target
CFG_HOST_ARCH="$CFG_ARCH"
+ CFG_HOST_CPUFEATURES="$CFG_CPUFEATURES"
fi
unset OUTFILE
@@ -5719,6 +5722,8 @@ cat >>"$QTCONFIG.tmp" <<EOF
CONFIG += $QTCONFIG_CONFIG
QT_ARCH = $CFG_ARCH
QT_HOST_ARCH = $CFG_HOST_ARCH
+QT_CPU_FEATURES = $CFG_CPUFEATURES
+QT_HOST_CPU_FEATURES = $CFG_HOST_CPUFEATURES
QT_EDITION = $Edition
QT_CONFIG += $QT_CONFIG
@@ -5882,8 +5887,9 @@ else
echo "Building for: $XPLATFORM"
fi
-echo "Architecture: $CFG_ARCH"
-echo "Host architecture: $CFG_HOST_ARCH"
+# the missing space before $CFG_FEATURES is intentional
+echo "Architecture: $CFG_ARCH, features:$CFG_CPUFEATURES"
+echo "Host architecture: $CFG_HOST_ARCH, features:$CFG_HOST_CPUFEATURES"
if [ -n "$PLATFORM_NOTES" ]; then
echo "Platform notes:"
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index 1059f0f83b..3e6613f066 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -2531,6 +2531,17 @@ void Configure::generateCachefile()
}
}
+struct ArchData {
+ const char *qmakespec;
+ const char *key;
+ const char *subarchKey;
+ const char *type;
+ ArchData() {}
+ ArchData(const char *t, const char *qm, const char *k, const char *sak)
+ : qmakespec(qm), key(k), subarchKey(sak), type(t)
+ {}
+};
+
/*
Runs qmake on config.tests/arch/arch.pro, which will detect the target arch
for the compiler we are using
@@ -2551,15 +2562,16 @@ void Configure::detectArch()
return;
}
- QList<QPair<QString, QString> > qmakespecs;
+ QVector<ArchData> qmakespecs;
if (dictionary.contains("XQMAKESPEC"))
- qmakespecs << qMakePair(QString("XQMAKESPEC"), QString("QT_ARCH"));
- qmakespecs << qMakePair(QString("QMAKESPEC"), QString("QT_HOST_ARCH"));
+ qmakespecs << ArchData("target", "XQMAKESPEC", "QT_ARCH", "QT_CPU_FEATURES");
+ qmakespecs << ArchData("host", "QMAKESPEC", "QT_HOST_ARCH", "QT_HOST_CPU_FEATURES");
for (int i = 0; i < qmakespecs.count(); ++i) {
- const QPair<QString, QString> &pair = qmakespecs.at(i);
- QString qmakespec = dictionary.value(pair.first);
- QString key = pair.second;
+ const ArchData &data = qmakespecs.at(i);
+ QString qmakespec = dictionary.value(data.qmakespec);
+ QString key = data.key;
+ QString subarchKey = data.subarchKey;
// run qmake
QString command =
@@ -2584,10 +2596,11 @@ void Configure::detectArch()
QByteArray exeContents = exe.readAll();
exe.close();
- static const char magic[] = "==Qt=magic=Qt== Architecture:";
- int magicPos = exeContents.indexOf(magic);
+ static const char archMagic[] = "==Qt=magic=Qt== Architecture:";
+ int magicPos = exeContents.indexOf(archMagic);
if (magicPos == -1) {
- cout << "Internal error, could not find the architecture of the executable" << endl;
+ cout << "Internal error, could not find the architecture of the "
+ << data.type << " executable" << endl;
dictionary["DONE"] = "error";
return;
}
@@ -2595,10 +2608,24 @@ void Configure::detectArch()
// the conversion from QByteArray will stop at the ending NUL anyway
QString arch = QString::fromLatin1(exeContents.constData() + magicPos
- + sizeof(magic) - 1);
+ + sizeof(archMagic) - 1);
dictionary[key] = arch;
+ static const char subarchMagic[] = "==Qt=magic=Qt== Sub-architecture:";
+ magicPos = exeContents.indexOf(subarchMagic);
+ if (magicPos == -1) {
+ cout << "Internal error, could not find the sub-architecture of the "
+ << data.type << " executable" << endl;
+ dictionary["DONE"] = "error";
+ return;
+ }
+
+ QString subarch = QString::fromLatin1(exeContents.constData() + magicPos
+ + sizeof(subarchMagic) - 1);
+ dictionary[subarchKey] = subarch;
+
//cout << "Detected arch '" << qPrintable(arch) << "'\n";
+ //cout << "Detected sub-arch '" << qPrintable(subarch) << "'\n";
// clean up
Environment::execute(command + " distclean");
@@ -2606,8 +2633,10 @@ void Configure::detectArch()
if (!dictionary.contains("QT_HOST_ARCH"))
dictionary["QT_HOST_ARCH"] = "unknown";
- if (!dictionary.contains("QT_ARCH"))
+ if (!dictionary.contains("QT_ARCH")) {
dictionary["QT_ARCH"] = dictionary["QT_HOST_ARCH"];
+ dictionary["QT_CPU_FEATURES"] = dictionary["QT_HOST_CPU_FEATURES"];
+ }
QDir::setCurrent(oldpwd);
}
@@ -2650,6 +2679,8 @@ void Configure::generateQConfigPri()
configStream << endl;
configStream << "QT_ARCH = " << dictionary["QT_ARCH"] << endl;
configStream << "QT_HOST_ARCH = " << dictionary["QT_HOST_ARCH"] << endl;
+ configStream << "QT_CPU_FEATURES = " << dictionary["QT_CPU_FEATURES"] << endl;
+ configStream << "QT_HOST_CPU_FEATURES = " << dictionary["QT_HOST_CPU_FEATURES"] << endl;
if (dictionary["QT_EDITION"].contains("OPENSOURCE"))
configStream << "QT_EDITION = " << QLatin1String("OpenSource") << endl;
else
@@ -3037,8 +3068,10 @@ void Configure::displayConfig()
sout << "QMAKESPEC..................." << dictionary[ "XQMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
else
sout << "QMAKESPEC..................." << dictionary[ "QMAKESPEC" ] << " (" << dictionary["QMAKESPEC_FROM"] << ")" << endl;
- sout << "Architecture................" << dictionary["QT_ARCH"] << endl;
- sout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"] << endl;
+ sout << "Architecture................" << dictionary["QT_ARCH"]
+ << ", features:" << dictionary["QT_CPU_FEATURES"] << endl;
+ sout << "Host Architecture..........." << dictionary["QT_HOST_ARCH"]
+ << ", features:" << dictionary["QT_HOST_CPU_FEATURES"] << endl;
sout << "Maketool...................." << dictionary[ "MAKE" ] << endl;
sout << "Debug symbols..............." << (dictionary[ "BUILD" ] == "debug" ? "yes" : "no") << endl;
sout << "Link Time Code Generation..." << dictionary[ "LTCG" ] << endl;