wasm: add simd support

Emscripten only supports
SSE1, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, and 128-bit AVX instruction
sets at this time.
https://emscripten.org/docs/porting/simd.html

Browsers might need to enable simd support in the advanced
configurations
about: config or chrome:flags

Enable by configuring Qt with -sse2

Pick-to: 6.2
Fixes: QTBUG-63924
Change-Id: Ifeafae20e199dee0d19689802ad20fd0bd424ca7
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
This commit is contained in:
Lorn Potter 2021-04-16 15:34:57 +10:00
parent ef623fd16f
commit 0e100a4d89
8 changed files with 36 additions and 3 deletions

View File

@ -199,4 +199,7 @@ if(WASM)
set(QT_CFLAGS_OPTIMIZE_FULL "-O3")
set(QT_CFLAGS_OPTIMIZE_SIZE "-Os")
set(QT_CFLAGS_OPTIMIZE_DEBUG "-g2")
set(QT_CFLAGS_SSE2 -O2 -msimd128 -msse -msse2)
endif()

View File

@ -177,6 +177,10 @@ if(UIKIT)
qt_internal_apply_bitcode_flags(PlatformCommonInternal)
endif()
if(WASM AND QT_FEATURE_sse2)
target_compile_definitions(PlatformCommonInternal INTERFACE QT_COMPILER_SUPPORTS_SSE2)
endif()
# Taken from mkspecs/common/msvc-version.conf and mkspecs/common/msvc-desktop.conf
if (MSVC)
if (MSVC_VERSION GREATER_EQUAL 1799)

View File

@ -19,6 +19,11 @@ function (qt_internal_setup_wasm_target_properties wasmTarget)
target_compile_options("${wasmTarget}" INTERFACE --bind)
#simd
if (QT_FEATURE_sse2)
target_compile_options("${wasmTarget}" INTERFACE -O2 -msimd128 -msse -msse2)
endif()
# Hardcode wasm memory size. Emscripten does not currently support memory growth
# (ALLOW_MEMORY_GROWTH) in pthreads mode, and requires specifying the memory size
# at build time. Further, browsers limit the maximum initial memory size to 1GB.

View File

@ -4,3 +4,7 @@ project(arch LANGUAGES CXX)
add_executable(architecture_test)
set_property(TARGET architecture_test PROPERTY MACOSX_BUNDLE FALSE)
target_sources(architecture_test PRIVATE arch.cpp)
if(EMSCRIPTEN)
target_compile_options(architecture_test PRIVATE -O2 -msimd128 -msse -msse2)
endif()

View File

@ -659,7 +659,9 @@ qt_feature("signaling_nan" PUBLIC
)
qt_feature("sse2" PRIVATE
LABEL "SSE2"
CONDITION ( ( ( TEST_architecture_arch STREQUAL i386 ) OR ( TEST_architecture_arch STREQUAL x86_64 ) ) AND TEST_subarch_sse2 ) OR QT_FORCE_FEATURE_sse2 # special case
CONDITION ( ( ( TEST_architecture_arch STREQUAL i386 )
OR ( TEST_architecture_arch STREQUAL x86_64 ) ) AND TEST_subarch_sse2 ) OR QT_FORCE_FEATURE_sse2 OR WASM
AUTODETECT NOT WASM
)
qt_feature_definition("sse2" "QT_COMPILER_SUPPORTS_SSE2" VALUE "1")
qt_feature_config("sse2" QMAKE_PRIVATE_CONFIG)
@ -1017,7 +1019,7 @@ qt_configure_add_summary_entry(
TYPE "featureList"
ARGS "sse2 sse3 ssse3 sse4_1 sse4_2"
MESSAGE "SSE"
CONDITION ( ( TEST_architecture_arch STREQUAL i386 ) OR ( TEST_architecture_arch STREQUAL x86_64 ) )
CONDITION ( ( TEST_architecture_arch STREQUAL i386 ) OR ( TEST_architecture_arch STREQUAL x86_64 ) OR ( TEST_architecture_arch STREQUAL wasm ) )
)
qt_configure_add_summary_entry(
TYPE "featureList"

View File

@ -36,6 +36,14 @@ exists($$QMAKE_QT_CONFIG) {
message("Setting INITIAL_MEMORY to" $$INITIAL_MEMORY)
EMCC_THREAD_LFLAGS += -s INITIAL_MEMORY=$$INITIAL_MEMORY
}
qtConfig(sse2) {
QMAKE_CFLAGS += -O2 -msimd128 -msse -msse2
QMAKE_CXXFLAGS += -O2 -msimd128 -msse -msse2
QMAKE_LFLAGS += -msimd128 -msse -msse2
QMAKE_LFLAGS_DEBUG += -msimd128 -msse -msse2
}
QMAKE_LFLAGS += $$EMCC_THREAD_LFLAGS
QMAKE_LFLAGS_DEBUG += $$EMCC_THREAD_LFLAGS
QMAKE_CFLAGS += $$EMCC_THREAD_LFLAGS

View File

@ -340,6 +340,10 @@
# define Q_PROCESSOR_WASM
# define Q_BYTE_ORDER Q_LITTLE_ENDIAN
# define Q_PROCESSOR_WORDSIZE 8
#ifdef QT_COMPILER_SUPPORTS_SSE2
# define Q_PROCESSOR_X86 6 // enables SIMD support
#endif
#endif
/*

View File

@ -190,10 +190,13 @@
# define __SSE__ 1
# endif
# if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
# if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_OS_WASM)
// GCC 4.4 and Clang 2.8 added a few more intrinsics there
# include <x86intrin.h>
# endif
#ifdef Q_OS_WASM
# include <immintrin.h>
# endif
# if defined(__SSE4_2__) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS) && (defined(Q_CC_INTEL) || defined(Q_CC_MSVC))
// POPCNT instructions: