Remove dependency on SSE instructions
mozconfig.linux32: global flags, remove sse2 flags and target i686 instead of pentium-m.
blink: DenormalDisabler: Disable denormal to zero flush that use stmxcsr instruction (SSE) (Software flush is done instead).
angle: moz.build.common: build gfx/angle without SSE2 (no intrinsics used).
mozbuild: emitter.py: change the order of UNIFIED_SOURCES and SOURCES to make non SSE object files before SSE specific ones when linking libxul.so. Else, the linker might prefer to link in a function defined in a header that use SSE2 instructions over one without SSE2 instructions. This the case with gfxImageSurface::GetSize defined in gfx/thebes/gfxImageSurface.h and also included in gfxAlphaRecoverySSE2.cpp. This means gfxImageSurface::GetSize() is defined in a header and is built multiple time, so this happens:
-
Unified sources build one without SSE2 flags, so the definition doesn't have SSE2 instructions. The definition is put in a Unified_xxxx.o file.
-
SSE2 specific file gfxAlphaRecoverySSE2.o is built with SSE2 flags, and contains a definition of gfxImageSurface::GetSize that uses automatically generated SSE2 instruction by g++.
-
Previously, sources were linked before unified sources when linking libxul.so, which I suppose is why the SSE2 version of gfxImageSurface::GetSize is used.
-
Reversing the order of SOURCES and UNIFIED_SOURCES makes gcc's linker to use the non-SSE2 version of gfxImageSurface::GetSize.
libwebrtc: moz.build: remove global SSE2 gcc flags (sse2 specific libraries are still built using SSE2 flags to allow runtime detection) aec3: disable the compilation of SSE2 functions to be able to build aec3 without SSE2. SSE2 specific function are not placed in a specific SSE2 dedicated source file, so we need to disable them entierly to prevent any SSE2 instructions in non-SSE2 code paths.
pffft: modified moz.build to set PFFFT_SIMD_DISABLE define on x86.
A better fix for webrtc would be to move aec3 SSE / NEON functions in a a dedicated source file, the same way other SSE functions are made in libwebrtc. But this requires more file changes.
I've tested it using:
- Real hardware with AMD Athlon XP 2600+ processor (supports only SSE but not SSE2)
- qemu using
qemu-system-i386 -cpu pentium2,check -m 1G -device ac97 -vga std -display gtk -drive file=harddisk.img,format=raw,index=0,media=disk -netdev user,id=net1,hostfwd=::11023-:22 -device e1000,netdev=net1 -usbdevice tablet
Note that enabling SSE on qemu will also enable SSE2 (even if absent from cpuid, there is no illegal instruction errors). Using -cpu pentium2 will produce Illegal Instruction on any SSE instruction.
To update this patch:
In third_party/libwebrtc:
-
replace in [all moz.build files except ones in folders containing '_sse' or '_avx'] any occurence of CXXFLAGS += [ -msse2 ] with nothing or CXXFLAGS += []. Example: any previously modified moz.build file in third_party/libwebrtc.
-
Search for all occurence of WEBRTC_ARCH_X86_FAMILY in any files Check for definitions of SSE functions inside a file whose name doesn't have 'sse' or 'avx'. In these files, replace WEBRTC_ARCH_X86_FAMILY with WEBRTC_ARCH_X86_64. Example: any modified source files in third_party/libwebrtc.
In any moz.build files, search for SSE2_FLAGS. Remove any occurence that doesn't apply to files whose name contains 'sse' or 'avx'.
To check the resulting build, you can use this:
Check that only .o files with 'sse' in their name are returned by these commands:
-
Check for 'movq' instructions: find . -type f -name '*.o' | xargs -I% sh -c 'xxd -p "%" | grep -q -e '660fd600' && echo %'
-
Check for 'stmxcsr' instructions: find . -type f -name '*.o' | xargs -I% sh -c 'xxd -p "%" | grep -q -e '0fae1d' && echo %'
Closes: #961663, #1002600
This is a rebase of !6 (closed) on esr102/debian-hacks.