Add configure-time checking for the SSE and AVX features on Windows
Modify configure.exe to run some configure-time tests and check if the SSE and AVX compiler features are supported. The tests themselves required a bit of changes to compile with MSVC. The include in sse4_2.cpp was wrong. And for whatever reason, it didn't like the volatile variables, which GCC, Clang and ICC have been happy with. This should produce no effect in compilation, though: even dead code must be syntactically correct. We're not running the output. Change-Id: Ibe5d0904a378a7efed853c7215f88a2ddcefb1b3 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@nokia.com>
This commit is contained in:
parent
f9c9d8aaa6
commit
b4525b3407
@ -43,9 +43,9 @@
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
volatile __m256d a = _mm256_setzero_pd();
|
||||
volatile __m256d b = _mm256_set1_pd(42.42);
|
||||
volatile __m256d result = _mm256_add_pd(a, b);
|
||||
__m256d a = _mm256_setzero_pd();
|
||||
__m256d b = _mm256_set1_pd(42.42);
|
||||
__m256d result = _mm256_add_pd(a, b);
|
||||
(void)result;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
SOURCES = avx.cpp
|
||||
CONFIG -= x11 qt
|
||||
CONFIG -= qt dylib release debug_and_release
|
||||
CONFIG += debug console
|
||||
mac:CONFIG -= app_bundle
|
||||
isEmpty(QMAKE_CFLAGS_AVX):error("This compiler does not support AVX")
|
||||
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX
|
||||
|
@ -45,11 +45,11 @@ int main(int, char**)
|
||||
{
|
||||
/* AVX */
|
||||
_mm256_zeroall();
|
||||
volatile __m256i a = _mm256_setzero_si256();
|
||||
__m256i a = _mm256_setzero_si256();
|
||||
|
||||
/* AVX2 */
|
||||
volatile __m256i b = _mm256_and_si256(a, a);
|
||||
volatile __m256i result = _mm256_add_epi8(a, b);
|
||||
__m256i b = _mm256_and_si256(a, a);
|
||||
__m256i result = _mm256_add_epi8(a, b);
|
||||
(void)result;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
SOURCES = avx2.cpp
|
||||
CONFIG -= x11 qt
|
||||
CONFIG -= qt dylib release debug_and_release
|
||||
CONFIG += debug console
|
||||
mac:CONFIG -= app_bundle
|
||||
isEmpty(QMAKE_CFLAGS_AVX2):error("This compiler does not support AVX2")
|
||||
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_AVX2
|
||||
|
@ -1,5 +1,6 @@
|
||||
SOURCES = sse2.cpp
|
||||
CONFIG -= x11 qt
|
||||
CONFIG -= qt dylib release debug_and_release
|
||||
CONFIG += debug console
|
||||
mac:CONFIG -= app_bundle
|
||||
isEmpty(QMAKE_CFLAGS_SSE2):error("This compiler does not support SSE2")
|
||||
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE2
|
||||
|
@ -43,9 +43,9 @@
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
volatile __m128d a = _mm_set1_pd(6.28);
|
||||
volatile __m128d b = _mm_set1_pd(3.14);
|
||||
volatile __m128d result = _mm_addsub_pd(a, b);
|
||||
__m128d a = _mm_set1_pd(6.28);
|
||||
__m128d b = _mm_set1_pd(3.14);
|
||||
__m128d result = _mm_addsub_pd(a, b);
|
||||
result = _mm_movedup_pd(result);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
SOURCES = sse3.cpp
|
||||
CONFIG -= x11 qt
|
||||
CONFIG -= qt dylib release debug_and_release
|
||||
CONFIG += debug console
|
||||
mac:CONFIG -= app_bundle
|
||||
isEmpty(QMAKE_CFLAGS_SSE3):error("This compiler does not support SSE3")
|
||||
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE3
|
||||
|
@ -43,9 +43,9 @@
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
volatile __m128 a = _mm_setzero_ps();
|
||||
__m128 a = _mm_setzero_ps();
|
||||
_mm_ceil_ps(a);
|
||||
volatile __m128i result = _mm_mullo_epi32(_mm_set1_epi32(42), _mm_set1_epi32(64));
|
||||
__m128i result = _mm_mullo_epi32(_mm_set1_epi32(42), _mm_set1_epi32(64));
|
||||
(void)result;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
SOURCES = sse4_1.cpp
|
||||
CONFIG -= x11 qt
|
||||
CONFIG -= qt dylib release debug_and_release
|
||||
CONFIG += debug console
|
||||
mac:CONFIG -= app_bundle
|
||||
isEmpty(QMAKE_CFLAGS_SSE4_1):error("This compiler does not support SSE4.1")
|
||||
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_1
|
||||
|
@ -39,13 +39,13 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <smmintrin.h>
|
||||
#include <nmmintrin.h>
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
volatile __m128i a = _mm_setzero_si128();
|
||||
volatile __m128i b = _mm_set1_epi32(42);
|
||||
volatile __m128i result = _mm_cmpestrm(a, 16, b, 16, 0);
|
||||
__m128i a = _mm_setzero_si128();
|
||||
__m128i b = _mm_set1_epi32(42);
|
||||
__m128i result = _mm_cmpestrm(a, 16, b, 16, 0);
|
||||
(void)result;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
SOURCES = sse4_2.cpp
|
||||
CONFIG -= x11 qt
|
||||
CONFIG -= qt dylib release debug_and_release
|
||||
CONFIG += debug console
|
||||
mac:CONFIG -= app_bundle
|
||||
isEmpty(QMAKE_CFLAGS_SSE4_2):error("This compiler does not support SSE4.2")
|
||||
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSE4_2
|
||||
|
@ -43,9 +43,9 @@
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
volatile __m128i a = _mm_set1_epi32(42);
|
||||
__m128i a = _mm_set1_epi32(42);
|
||||
_mm_abs_epi8(a);
|
||||
volatile __m128i result = _mm_sign_epi16(a, _mm_set1_epi32(64));
|
||||
__m128i result = _mm_sign_epi16(a, _mm_set1_epi32(64));
|
||||
(void)result;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
SOURCES = ssse3.cpp
|
||||
CONFIG -= x11 qt
|
||||
CONFIG -= qt dylib release debug_and_release
|
||||
CONFIG += debug console
|
||||
mac:CONFIG -= app_bundle
|
||||
isEmpty(QMAKE_CFLAGS_SSSE3):error("This compiler does not support SSSE3")
|
||||
else:QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_SSSE3
|
||||
|
@ -212,6 +212,12 @@ Configure::Configure(int& argc, char** argv)
|
||||
dictionary[ "WIDGETS" ] = "yes";
|
||||
dictionary[ "RTTI" ] = "yes";
|
||||
dictionary[ "SSE2" ] = "auto";
|
||||
dictionary[ "SSE3" ] = "auto";
|
||||
dictionary[ "SSSE3" ] = "auto";
|
||||
dictionary[ "SSE4_1" ] = "auto";
|
||||
dictionary[ "SSE4_2" ] = "auto";
|
||||
dictionary[ "AVX" ] = "auto";
|
||||
dictionary[ "AVX2" ] = "auto";
|
||||
dictionary[ "IWMMXT" ] = "auto";
|
||||
dictionary[ "SYNCQT" ] = "auto";
|
||||
dictionary[ "CE_CRT" ] = "no";
|
||||
@ -808,6 +814,30 @@ void Configure::parseCmdLine()
|
||||
dictionary[ "SSE2" ] = "no";
|
||||
else if (configCmdLine.at(i) == "-sse2")
|
||||
dictionary[ "SSE2" ] = "yes";
|
||||
else if (configCmdLine.at(i) == "-no-sse3")
|
||||
dictionary[ "SSE3" ] = "no";
|
||||
else if (configCmdLine.at(i) == "-sse3")
|
||||
dictionary[ "SSE3" ] = "yes";
|
||||
else if (configCmdLine.at(i) == "-no-ssse3")
|
||||
dictionary[ "SSSE3" ] = "no";
|
||||
else if (configCmdLine.at(i) == "-ssse3")
|
||||
dictionary[ "SSSE3" ] = "yes";
|
||||
else if (configCmdLine.at(i) == "-no-sse4.1")
|
||||
dictionary[ "SSE4_1" ] = "no";
|
||||
else if (configCmdLine.at(i) == "-sse4.1")
|
||||
dictionary[ "SSE4_1" ] = "yes";
|
||||
else if (configCmdLine.at(i) == "-no-sse4.2")
|
||||
dictionary[ "SSE4_2" ] = "no";
|
||||
else if (configCmdLine.at(i) == "-sse4.2")
|
||||
dictionary[ "SSE4_2" ] = "yes";
|
||||
else if (configCmdLine.at(i) == "-no-avx")
|
||||
dictionary[ "AVX" ] = "no";
|
||||
else if (configCmdLine.at(i) == "-avx")
|
||||
dictionary[ "AVX" ] = "yes";
|
||||
else if (configCmdLine.at(i) == "-no-avx2")
|
||||
dictionary[ "AVX2" ] = "no";
|
||||
else if (configCmdLine.at(i) == "-avx2")
|
||||
dictionary[ "AVX2" ] = "yes";
|
||||
else if (configCmdLine.at(i) == "-no-iwmmxt")
|
||||
dictionary[ "IWMMXT" ] = "no";
|
||||
else if (configCmdLine.at(i) == "-iwmmxt")
|
||||
@ -1380,6 +1410,12 @@ void Configure::applySpecSpecifics()
|
||||
dictionary[ "OPENSSL" ] = "no";
|
||||
dictionary[ "RTTI" ] = "no";
|
||||
dictionary[ "SSE2" ] = "no";
|
||||
dictionary[ "SSE3" ] = "no";
|
||||
dictionary[ "SSSE3" ] = "no";
|
||||
dictionary[ "SSE4_1" ] = "no";
|
||||
dictionary[ "SSE4_2" ] = "no";
|
||||
dictionary[ "AVX" ] = "no";
|
||||
dictionary[ "AVX2" ] = "no";
|
||||
dictionary[ "IWMMXT" ] = "no";
|
||||
dictionary[ "CE_CRT" ] = "yes";
|
||||
dictionary[ "DIRECTSHOW" ] = "no";
|
||||
@ -1468,7 +1504,10 @@ bool Configure::displayHelp()
|
||||
"[-qt-zlib] [-system-zlib] [-qt-pcre] [-system-pcre] [-no-gif]\n"
|
||||
"[-no-libpng] [-qt-libpng] [-system-libpng]\n"
|
||||
"[-no-libjpeg] [-qt-libjpeg] [-system-libjpeg]\n"
|
||||
"[-sse2] [-no-sse2]\n"
|
||||
"[-sse2] [-no-sse2] [-sse3] [-no-sse3]\n"
|
||||
"[-ssse3] [-no-ssse3]\n"
|
||||
"[-sse4.1] [-no-sse4.1] [-sse4.2] [-no-sse4.2]\n"
|
||||
"[-avx] [-no-avx] [-avx2] [-no-avx2]\n"
|
||||
"[-no-iwmmxt] [-iwmmxt] [-openssl] [-openssl-linked]\n"
|
||||
"[-no-openssl] [-no-dbus] [-dbus] [-dbus-linked] [-platform <spec>]\n"
|
||||
"[-qtnamespace <namespace>] [-qtlibinfix <infix>] [-no-phonon]\n"
|
||||
@ -1635,7 +1674,19 @@ bool Configure::displayHelp()
|
||||
desc("RTTI", "no", "-no-rtti", "Do not compile runtime type information.");
|
||||
desc("RTTI", "yes", "-rtti", "Compile runtime type information.\n");
|
||||
desc("SSE2", "no", "-no-sse2", "Do not compile with use of SSE2 instructions");
|
||||
desc("SSE2", "yes", "-sse2", "Compile with use of SSE2 instructions");
|
||||
desc("SSE2", "yes", "-sse2", "Compile with use of SSE2 instructions");
|
||||
desc("SSE3", "no", "-no-sse3", "Do not compile with use of SSE3 instructions");
|
||||
desc("SSE3", "yes", "-sse3", "Compile with use of SSE3 instructions");
|
||||
desc("SSSE3", "no", "-no-ssse3", "Do not compile with use of SSSE3 instructions");
|
||||
desc("SSSE3", "yes", "-ssse3", "Compile with use of SSSE3 instructions");
|
||||
desc("SSE4_1", "no", "-no-sse4.1", "Do not compile with use of SSE4.1 instructions");
|
||||
desc("SSE4_1", "yes", "-sse4.1", "Compile with use of SSE4.1 instructions");
|
||||
desc("SSE4_2", "no", "-no-sse4.2", "Do not compile with use of SSE4.2 instructions");
|
||||
desc("SSE4_2", "yes", "-sse4.2", "Compile with use of SSE4.2 instructions");
|
||||
desc("AVX", "no", "-no-avx", "Do not compile with use of AVX instructions");
|
||||
desc("AVX", "yes", "-avx", "Compile with use of AVX instructions");
|
||||
desc("AVX2", "no", "-no-avx2", "Do not compile with use of AVX2 instructions");
|
||||
desc("AVX2", "yes", "-avx2", "Compile with use of AVX2 instructions");
|
||||
desc("OPENSSL", "no", "-no-openssl", "Do not compile in OpenSSL support");
|
||||
desc("OPENSSL", "yes", "-openssl", "Compile in run-time OpenSSL support");
|
||||
desc("OPENSSL", "linked","-openssl-linked", "Compile in linked OpenSSL support");
|
||||
@ -1878,7 +1929,19 @@ bool Configure::checkAvailability(const QString &part)
|
||||
else if (part == "DIRECTSHOW")
|
||||
available = (dictionary.value("XQMAKESPEC").startsWith("wince"));
|
||||
else if (part == "SSE2")
|
||||
available = (dictionary.value("QMAKESPEC") != "win32-msvc");
|
||||
available = tryCompileProject("common/sse2");
|
||||
else if (part == "SSE3")
|
||||
available = tryCompileProject("common/sse3");
|
||||
else if (part == "SSSE3")
|
||||
available = tryCompileProject("common/ssse3");
|
||||
else if (part == "SSE4_1")
|
||||
available = tryCompileProject("common/sse4_1");
|
||||
else if (part == "SSE4_2")
|
||||
available = tryCompileProject("common/sse4_2");
|
||||
else if (part == "AVX")
|
||||
available = tryCompileProject("common/avx");
|
||||
else if (part == "AVX2")
|
||||
available = tryCompileProject("common/avx2");
|
||||
else if (part == "OPENSSL")
|
||||
available = findFile("openssl\\ssl.h");
|
||||
else if (part == "DBUS")
|
||||
@ -1989,6 +2052,18 @@ void Configure::autoDetection()
|
||||
dictionary["SQL_IBASE"] = checkAvailability("SQL_IBASE") ? defaultTo("SQL_IBASE") : "no";
|
||||
if (dictionary["SSE2"] == "auto")
|
||||
dictionary["SSE2"] = checkAvailability("SSE2") ? "yes" : "no";
|
||||
if (dictionary["SSE3"] == "auto")
|
||||
dictionary["SSE3"] = checkAvailability("SSE3") ? "yes" : "no";
|
||||
if (dictionary["SSSE3"] == "auto")
|
||||
dictionary["SSSE3"] = checkAvailability("SSSE3") ? "yes" : "no";
|
||||
if (dictionary["SSE4_1"] == "auto")
|
||||
dictionary["SSE4_1"] = checkAvailability("SSE4_1") ? "yes" : "no";
|
||||
if (dictionary["SSE4_2"] == "auto")
|
||||
dictionary["SSE4_2"] = checkAvailability("SSE4_2") ? "yes" : "no";
|
||||
if (dictionary["AVX"] == "auto")
|
||||
dictionary["AVX"] = checkAvailability("AVX") ? "yes" : "no";
|
||||
if (dictionary["AVX2"] == "auto")
|
||||
dictionary["AVX2"] = checkAvailability("AVX2") ? "yes" : "no";
|
||||
if (dictionary["IWMMXT"] == "auto")
|
||||
dictionary["IWMMXT"] = checkAvailability("IWMMXT") ? "yes" : "no";
|
||||
if (dictionary["OPENSSL"] == "auto")
|
||||
@ -2543,6 +2618,18 @@ void Configure::generateCachefile()
|
||||
moduleStream << "CONFIG += create_prl link_prl";
|
||||
if (dictionary[ "SSE2" ] == "yes")
|
||||
moduleStream << " sse2";
|
||||
if (dictionary[ "SSE3" ] == "yes")
|
||||
moduleStream << " sse3";
|
||||
if (dictionary[ "SSSE3" ] == "yes")
|
||||
moduleStream << " ssse3";
|
||||
if (dictionary[ "SSE4_1" ] == "yes")
|
||||
moduleStream << " sse4_1";
|
||||
if (dictionary[ "SSE4_2" ] == "yes")
|
||||
moduleStream << " sse4_2";
|
||||
if (dictionary[ "AVX" ] == "yes")
|
||||
moduleStream << " avx";
|
||||
if (dictionary[ "AVX2" ] == "yes")
|
||||
moduleStream << " avx2";
|
||||
if (dictionary[ "IWMMXT" ] == "yes")
|
||||
moduleStream << " iwmmxt";
|
||||
moduleStream << endl;
|
||||
@ -2665,6 +2752,47 @@ void Configure::detectArch()
|
||||
QDir::setCurrent(oldpwd);
|
||||
}
|
||||
|
||||
bool Configure::tryCompileProject(const QString &projectPath, const QString &extraOptions)
|
||||
{
|
||||
QString oldpwd = QDir::currentPath();
|
||||
|
||||
QString newpwd = fixSeparators(QString("%1/config.tests/%2").arg(buildPath, projectPath));
|
||||
if (!QDir().exists(newpwd) && !QDir().mkpath(newpwd)) {
|
||||
cout << "Failed to create directory " << qPrintable(newpwd) << endl;
|
||||
dictionary["DONE"] = "error";
|
||||
return false;
|
||||
}
|
||||
if (!QDir::setCurrent(newpwd)) {
|
||||
cout << "Failed to change working directory to " << qPrintable(newpwd) << endl;
|
||||
dictionary["DONE"] = "error";
|
||||
return false;
|
||||
}
|
||||
|
||||
// run qmake
|
||||
QString command =
|
||||
fixSeparators(QString("%1/bin/qmake.exe %2/config.tests/%3 %4 2>&1")
|
||||
.arg(buildPath, sourcePath, projectPath, extraOptions));
|
||||
int code = 0;
|
||||
QString output = Environment::execute(command, &code);
|
||||
//cout << output << endl;
|
||||
|
||||
if (code == 0) {
|
||||
// compile
|
||||
command = dictionary[ "MAKE" ];
|
||||
if (command.contains("nmake"))
|
||||
command += " /NOLOGO";
|
||||
command += " -s 2>&1";
|
||||
output = Environment::execute(command, &code);
|
||||
//cout << output << endl;
|
||||
|
||||
// clean up
|
||||
Environment::execute(command + " distclean 2>&1");
|
||||
}
|
||||
|
||||
QDir::setCurrent(oldpwd);
|
||||
return code == 0;
|
||||
}
|
||||
|
||||
void Configure::generateQConfigPri()
|
||||
{
|
||||
// Generate qconfig.pri
|
||||
@ -3108,6 +3236,12 @@ void Configure::displayConfig()
|
||||
sout << "Accessibility support......." << dictionary[ "ACCESSIBILITY" ] << endl;
|
||||
sout << "RTTI support................" << dictionary[ "RTTI" ] << endl;
|
||||
sout << "SSE2 support................" << dictionary[ "SSE2" ] << endl;
|
||||
sout << "SSE3 support................" << dictionary[ "SSE3" ] << endl;
|
||||
sout << "SSSE3 support..............." << dictionary[ "SSSE3" ] << endl;
|
||||
sout << "SSE4.1 support.............." << dictionary[ "SSE4_1" ] << endl;
|
||||
sout << "SSE4.2 support.............." << dictionary[ "SSE4_2" ] << endl;
|
||||
sout << "AVX support................." << dictionary[ "AVX" ] << endl;
|
||||
sout << "AVX2 support................" << dictionary[ "AVX2" ] << endl;
|
||||
sout << "IWMMXT support.............." << dictionary[ "IWMMXT" ] << endl;
|
||||
sout << "OpenGL support.............." << dictionary[ "OPENGL" ] << endl;
|
||||
if (dictionary.value(QStringLiteral("OPENGL_ES_2")) == QStringLiteral("yes")) {
|
||||
|
@ -169,6 +169,8 @@ private:
|
||||
void saveCmdLine();
|
||||
#endif
|
||||
|
||||
bool tryCompileProject(const QString &projectPath, const QString &extraOptions = QString());
|
||||
|
||||
void desc(const char *description, int startingAt = 0, int wrapIndent = 0);
|
||||
void desc(const char *option, const char *description, bool skipIndent = false, char fillChar = '.');
|
||||
void desc(const char *mark_option, const char *mark, const char *option, const char *description, char fillChar = '.');
|
||||
|
@ -431,7 +431,7 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv
|
||||
|
||||
Taken from qmake's system() command.
|
||||
*/
|
||||
QString Environment::execute(const QString &command)
|
||||
QString Environment::execute(const QString &command, int *returnCode)
|
||||
{
|
||||
QString output;
|
||||
FILE *proc = _popen(command.toLatin1().constData(), "r");
|
||||
@ -443,8 +443,11 @@ QString Environment::execute(const QString &command)
|
||||
buff[read_in] = '\0';
|
||||
output += buff;
|
||||
}
|
||||
if (proc)
|
||||
_pclose(proc);
|
||||
if (proc) {
|
||||
int r = _pclose(proc);
|
||||
if (returnCode)
|
||||
*returnCode = r;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ public:
|
||||
static bool detectExecutable(const QString &executable);
|
||||
|
||||
static int execute(QStringList arguments, const QStringList &additionalEnv, const QStringList &removeEnv);
|
||||
static QString execute(const QString &command);
|
||||
static QString execute(const QString &command, int *returnCode = 0);
|
||||
static bool cpdir(const QString &srcDir,
|
||||
const QString &destDir,
|
||||
const QString &includeSrcDir = QString());
|
||||
|
Loading…
Reference in New Issue
Block a user