From da234bfdea528bb71a4bdea98184e42a46df51a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Tue, 26 Aug 2025 01:58:44 +0300 Subject: [PATCH 1/3] Try out how a bigendian suite could work out. --- test/test_core.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/test_core.py b/test/test_core.py index 608fedd2febfa..0d24de9886d48 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -9973,5 +9973,27 @@ def setUp(self): minimal0 = make_run('minimal0', cflags=['-g'], settings={'MINIMAL_RUNTIME': 1}) llvmlibc = make_run('llvmlibc', cflags=['-lllvmlibc']) +# To run the big endian test suite on a little endian Linux host: +# 1. sudo apt install -y qemu-user libc6-s390x-cross libstdc++6-s390x-cross +# 2. wget https://nodejs.org/dist/v22.16.0/node-v22.16.0-linux-s390x.tar.xz +# 3. tar xJf node-v22.14.0-linux-s390x.tar.xz +# 4. run a little endian emsdk install, e.g. `emsdk install sdk-main-64bit` +# 5. activate little endian emsdk install, e.g. `emsdk activate sdk-main-64bit` +# 6. modify the generated emsdk install: edit file .emscripten under emsdk/ root directory, and change the line +# NODE_JS = emsdk_path + '/node/22.16.0_64bit/bin/node' +# to point to big endian node: +# NODE_JS = ['qemu-s390x', '-L', '/usr/s390x-linux-gnu/', '/home/user/node-v22.16.0-linux-s390x/bin/node'] +# 7. enter emsdk environment in current terminal with `source ./emsdk_env.sh` +# 8. modify EMSDK_NODE environment variable to also point to the big endian node: +# export EMSDK_NODE="qemu-s390x -L /usr/s390x-linux-gnu/ /home/user/node-v22.16.0-linux-s390x/bin/node" +# 9. run some tests in big endian mode: in Emscripten root directory, run +# `test/runner bigendian` to run all tests, or a single test with +# `test/runner bigendian.test_jslib_i64_params` + +# The above test scheme has a small quirk that it will also use the Big Endian version of node.js for internal +# Emscripten compilation. At a quick test, this actually worked, so maybe this would be fine for this test harness. +# Alternatively, we would want to find a way to separate compiler node from runtime node somehow in the harness. +bigendian = make_run('bigendian', cflags=['-O0'], settings={'SUPPORT_BIG_ENDIAN': 1}) + # TestCoreBase is just a shape for the specific subclasses, we don't test it itself del TestCoreBase # noqa From 46a2cdf75f78839cec47a3010e24cf02894826bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Tue, 26 Aug 2025 14:00:52 +0300 Subject: [PATCH 2/3] Add a mechanism to skip tests that do not work in big endian mode. --- test/test_core.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/test_core.py b/test/test_core.py index 0d24de9886d48..5c196b805eac1 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -399,6 +399,7 @@ def decorated(self, textdecoder, *args, **kwargs): no_minimal_runtime = make_no_decorator_for_setting('MINIMAL_RUNTIME') no_safe_heap = make_no_decorator_for_setting('SAFE_HEAP') no_strict = make_no_decorator_for_setting('STRICT') +no_big_endian = make_no_decorator_for_setting('SUPPORT_BIG_ENDIAN') def is_sanitizing(args): @@ -6575,6 +6576,7 @@ def test_neon_wasm_simd(self): '': ([],), 'nontrapping': (['-mnontrapping-fptoint'],), }) + @no_big_endian('SIMD support is currently not compatible with big endian') def test_sse1(self, args): src = test_file('sse/test_sse1.cpp') self.run_process([shared.CLANG_CXX, src, '-msse', '-o', 'test_sse1', '-D_CRT_SECURE_NO_WARNINGS=1'] + clang_native.get_clang_native_args(), stdout=PIPE) @@ -6597,6 +6599,7 @@ def test_sse1(self, args): '': ([],), 'nontrapping': (['-mnontrapping-fptoint'],), }) + @no_big_endian('SIMD support is currently not compatible with big endian') def test_sse2(self, args): src = test_file('sse/test_sse2.cpp') self.run_process([shared.CLANG_CXX, src, '-msse2', '-Wno-argument-outside-range', '-o', 'test_sse2', '-D_CRT_SECURE_NO_WARNINGS=1'] + clang_native.get_clang_native_args(), stdout=PIPE) @@ -6610,6 +6613,7 @@ def test_sse2(self, args): @wasm_simd @requires_native_clang @requires_x64_cpu + @no_big_endian('SIMD support is currently not compatible with big endian') def test_sse3(self): src = test_file('sse/test_sse3.cpp') self.run_process([shared.CLANG_CXX, src, '-msse3', '-Wno-argument-outside-range', '-o', 'test_sse3', '-D_CRT_SECURE_NO_WARNINGS=1'] + clang_native.get_clang_native_args(), stdout=PIPE) @@ -6623,6 +6627,7 @@ def test_sse3(self): @wasm_simd @requires_native_clang @requires_x64_cpu + @no_big_endian('SIMD support is currently not compatible with big endian') def test_ssse3(self): src = test_file('sse/test_ssse3.cpp') self.run_process([shared.CLANG_CXX, src, '-mssse3', '-Wno-argument-outside-range', '-o', 'test_ssse3', '-D_CRT_SECURE_NO_WARNINGS=1'] + clang_native.get_clang_native_args(), stdout=PIPE) @@ -6638,6 +6643,7 @@ def test_ssse3(self): @requires_native_clang @requires_x64_cpu @is_slow_test + @no_big_endian('SIMD support is currently not compatible with big endian') def test_sse4_1(self): src = test_file('sse/test_sse4_1.cpp') # Run with inlining disabled to avoid slow LLVM behavior with lots of macro expanded loops inside a function body. @@ -6656,6 +6662,7 @@ def test_sse4_1(self): '': (False,), '2': (True,), }) + @no_big_endian('SIMD support is currently not compatible with big endian') def test_sse4(self, use_4_2): msse4 = '-msse4.2' if use_4_2 else '-msse4' src = test_file('sse/test_sse4_2.cpp') @@ -6677,6 +6684,7 @@ def test_sse4(self, use_4_2): '': ([],), 'nontrapping': (['-mnontrapping-fptoint'],), }) + @no_big_endian('SIMD support is currently not compatible with big endian') def test_avx(self, args): src = test_file('sse/test_avx.cpp') self.run_process([shared.CLANG_CXX, src, '-mavx', '-Wno-argument-outside-range', '-Wpedantic', '-o', 'test_avx', '-D_CRT_SECURE_NO_WARNINGS=1'] + clang_native.get_clang_native_args(), stdout=PIPE) @@ -6697,6 +6705,7 @@ def test_avx(self, args): '': ([],), 'nontrapping': (['-mnontrapping-fptoint'],), }) + @no_big_endian('SIMD support is currently not compatible with big endian') def test_avx2(self, args): src = test_file('sse/test_avx2.cpp') self.run_process([shared.CLANG_CXX, src, '-mavx2', '-Wno-argument-outside-range', '-Wpedantic', '-o', 'test_avx2', '-D_CRT_SECURE_NO_WARNINGS=1'] + clang_native.get_clang_native_args(), stdout=PIPE) From 93cb3defd6ac4f6dc5c760343f4e9f8beed5ec37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jukka=20Jyl=C3=A4nki?= Date: Wed, 27 Aug 2025 17:18:57 +0300 Subject: [PATCH 3/3] bigendian0 --- test/test_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_core.py b/test/test_core.py index 5c196b805eac1..75d902ff8924f 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -10002,7 +10002,7 @@ def setUp(self): # The above test scheme has a small quirk that it will also use the Big Endian version of node.js for internal # Emscripten compilation. At a quick test, this actually worked, so maybe this would be fine for this test harness. # Alternatively, we would want to find a way to separate compiler node from runtime node somehow in the harness. -bigendian = make_run('bigendian', cflags=['-O0'], settings={'SUPPORT_BIG_ENDIAN': 1}) +bigendian0 = make_run('bigendian0', cflags=['-O0'], settings={'SUPPORT_BIG_ENDIAN': 1}) # TestCoreBase is just a shape for the specific subclasses, we don't test it itself del TestCoreBase # noqa