aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/embind/shell.html2
-rw-r--r--tests/hello_world_worker.cpp10
-rw-r--r--tests/pthread/specific.c8
-rw-r--r--tests/pthread/specific.c.txt2
-rw-r--r--tests/sdl_canvas_size.html2
-rw-r--r--tests/sdl_joystick.c4
-rw-r--r--tests/test_browser.py21
-rw-r--r--tests/test_core.py517
-rw-r--r--tests/test_other.py62
9 files changed, 608 insertions, 20 deletions
diff --git a/tests/embind/shell.html b/tests/embind/shell.html
index f0ee10f8..7a3b0a07 100644
--- a/tests/embind/shell.html
+++ b/tests/embind/shell.html
@@ -48,7 +48,7 @@
//text = text.replace(/>/g, ">");
//text = text.replace('\n', '<br>', 'g');
element.value += text + "\n";
- element.scrollTop = 99999; // focus on bottom
+ element.scrollTop = element.scrollHeight; // focus on bottom
};
})(),
printErr: function(text) {
diff --git a/tests/hello_world_worker.cpp b/tests/hello_world_worker.cpp
index 5ea26d91..5b673df8 100644
--- a/tests/hello_world_worker.cpp
+++ b/tests/hello_world_worker.cpp
@@ -1,9 +1,17 @@
+#include <string.h>
#include <stdio.h>
#include <emscripten.h>
int main()
{
printf("you should not see this text when in a worker!\n"); // this should not crash, but also should not show up anywhere if you are in a worker
- emscripten_run_script("if (typeof postMessage !== 'undefined') { postMessage('hello from worker!') }");
+ FILE *f = fopen("file.dat", "r");
+ char buffer[100];
+ memset(buffer, 0, 100);
+ buffer[0] = 0;
+ fread(buffer, 10, 1, f);
+ char buffer2[100];
+ sprintf(buffer2, "if (typeof postMessage !== 'undefined') { postMessage('hello from worker, and |%s|') }", buffer);
+ emscripten_run_script(buffer2);
}
diff --git a/tests/pthread/specific.c b/tests/pthread/specific.c
index 914884e7..631baf8c 100644
--- a/tests/pthread/specific.c
+++ b/tests/pthread/specific.c
@@ -33,6 +33,14 @@ int main(void)
printf("pthread_getspecific = %d\n", *data2);
assert(*data2 == 123);
+ rv = pthread_setspecific(key, NULL);
+ printf("valid pthread_setspecific for value NULL = %d\n", rv);
+ assert(rv == 0);
+
+ data2 = pthread_getspecific(key);
+ assert(data2 == NULL);
+ printf("pthread_getspecific = %p\n", data2);
+
rv = pthread_key_create(&key, &destr_function);
data2 = pthread_getspecific(key);
printf("pthread_getspecific after key recreate = %p\n", data2);
diff --git a/tests/pthread/specific.c.txt b/tests/pthread/specific.c.txt
index ad122b3d..ce7bef3d 100644
--- a/tests/pthread/specific.c.txt
+++ b/tests/pthread/specific.c.txt
@@ -1,6 +1,8 @@
pthread_key_create = 0
pthread_setspecific = 0
pthread_getspecific = 123
+valid pthread_setspecific for value NULL = 0
+pthread_getspecific = (nil)
pthread_getspecific after key recreate = (nil)
pthread_key_delete = 0
pthread_key_delete repeated = 22
diff --git a/tests/sdl_canvas_size.html b/tests/sdl_canvas_size.html
index 50495049..37e3818f 100644
--- a/tests/sdl_canvas_size.html
+++ b/tests/sdl_canvas_size.html
@@ -51,7 +51,7 @@
//text = text.replace(/>/g, "&gt;");
//text = text.replace('\n', '<br>', 'g');
element.value += text + "\n";
- element.scrollTop = 99999; // focus on bottom
+ element.scrollTop = element.scrollHeight; // focus on bottom
};
})(),
printErr: function(text) {
diff --git a/tests/sdl_joystick.c b/tests/sdl_joystick.c
index 50802c31..bdb621ab 100644
--- a/tests/sdl_joystick.c
+++ b/tests/sdl_joystick.c
@@ -72,6 +72,10 @@ void main_2(void* arg) {
assert(SDL_JoystickNumAxes(pad1) == 4);
assert(SDL_JoystickNumButtons(pad1) == 16);
+ // By default, SDL will automatically process events. Test this behavior, and then disable it.
+ assert(SDL_JoystickEventState(SDL_QUERY) == SDL_ENABLE);
+ SDL_JoystickEventState(SDL_DISABLE);
+ assert(SDL_JoystickEventState(SDL_QUERY) == SDL_DISABLE);
// Button events.
emscripten_run_script("window.simulateGamepadButtonDown(0, 1)");
// We didn't tell SDL to automatically update this joystick's state.
diff --git a/tests/test_browser.py b/tests/test_browser.py
index 128820b3..d0618af8 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -183,7 +183,7 @@ If manually bisecting:
//text = text.replace(/>/g, "&gt;");
//text = text.replace('\\n', '<br>', 'g');
element.value += text + "\\n";
- element.scrollTop = 99999; // focus on bottom
+ element.scrollTop = element.scrollHeight; // focus on bottom
};
})(),
printErr: function(text) {
@@ -274,7 +274,7 @@ If manually bisecting:
//text = text.replace(/>/g, "&gt;");
//text = text.replace('\\n', '<br>', 'g');
element.value += text + "\\n";
- element.scrollTop = 99999; // focus on bottom
+ element.scrollTop = element.scrollHeight; // focus on bottom
};
})(),
printErr: function(text) {
@@ -898,7 +898,7 @@ keydown(100);keyup(100); // trigger the end
return function(text) {
text = Array.prototype.slice.call(arguments).join(' ');
element.value += text + "\\n";
- element.scrollTop = 99999; // focus on bottom
+ element.scrollTop = element.scrollHeight; // focus on bottom
};
})()
};
@@ -1218,10 +1218,7 @@ keydown(100);keyup(100); // trigger the end
def test_worker(self):
# Test running in a web worker
- output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'], stdout=PIPE, stderr=PIPE).communicate()
- assert len(output[0]) == 0, output[0]
- assert os.path.exists('worker.js'), output
- self.assertContained('you should not see this text when in a worker!', run_js('worker.js')) # code should run standalone
+ open('file.dat', 'w').write('data for worker')
html_file = open('main.html', 'w')
html_file.write('''
<html>
@@ -1240,7 +1237,15 @@ keydown(100);keyup(100); // trigger the end
</html>
''')
html_file.close()
- self.run_browser('main.html', 'You should see that the worker was called, and said "hello from worker!"', '/report_result?hello%20from%20worker!')
+
+ # no file data
+ for file_data in [0, 1]:
+ print 'file data', file_data
+ output = Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world_worker.cpp'), '-o', 'worker.js'] + (['--preload-file', 'file.dat'] if file_data else []) , stdout=PIPE, stderr=PIPE).communicate()
+ assert len(output[0]) == 0, output[0]
+ assert os.path.exists('worker.js'), output
+ if not file_data: self.assertContained('you should not see this text when in a worker!', run_js('worker.js')) # code should run standalone
+ self.run_browser('main.html', '', '/report_result?hello%20from%20worker,%20and%20|' + ('data%20for%20w' if file_data else '') + '|')
def test_chunked_synchronous_xhr(self):
main = 'chunked_sync_xhr.html'
diff --git a/tests/test_core.py b/tests/test_core.py
index 1803c926..69abfc0e 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -3865,6 +3865,25 @@ Exiting setjmp function, level: 0, prev_jmp: -1
process.communicate()
assert process.returncode is 0, 'float.h should agree with our system'
+ def test_llvm_used(self):
+ src = r'''
+ #include <stdio.h>
+ #include <emscripten.h>
+
+ extern "C" {
+ EMSCRIPTEN_KEEPALIVE void foobar(int x) {
+ printf("Worked! %d\n", x);
+ }
+ }
+
+ int main() {
+ emscripten_run_script("Module['_foobar'](10)");
+ return 0;
+ }'''
+
+ Building.LLVM_OPTS = 3
+ self.do_run(src, 'Worked! 10\n')
+
def test_emscripten_api(self):
#if Settings.MICRO_OPTS or Settings.RELOOP or Building.LLVM_OPTS: return self.skip('FIXME')
@@ -8730,6 +8749,8 @@ void*:16
self.do_run(path_from_root('tests', 'cubescript'), '*\nTemp is 33\n9\n5\nhello, everyone\n*', main_file='command.cpp')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('skipping extra parts in fastcomp')
+
assert 'asm2g' in test_modes
if self.run_name == 'asm2g':
results = {}
@@ -8792,20 +8813,20 @@ int main(int argc, char **argv) {
printf("zeros %d, %d, %d, %d\n", (int)c[0], (int)c[1], (int)c[2], (int)c[3]);
}
{
- uint32x4 *a = (uint32x4*)&data[0];
- uint32x4 *b = (uint32x4*)&data[4];
- uint32x4 c, d, e, f;
+ int32x4 *a = (int32x4*)&data[0];
+ int32x4 *b = (int32x4*)&data[4];
+ int32x4 c, d, e, f;
c = *a;
d = *b;
- printf("4uints! %d, %d, %d, %d %d, %d, %d, %d\n", c[0], c[1], c[2], c[3], d[0], d[1], d[2], d[3]);
+ printf("4ints! %d, %d, %d, %d %d, %d, %d, %d\n", c[0], c[1], c[2], c[3], d[0], d[1], d[2], d[3]);
e = c+d;
f = c-d;
- printf("5uints! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]);
+ printf("5ints! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]);
e = c&d;
f = c|d;
e = ~c&d;
f = c^d;
- printf("5uintops! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]);
+ printf("5intops! %d, %d, %d, %d %d, %d, %d, %d\n", e[0], e[1], e[2], e[3], f[0], f[1], f[2], f[3]);
}
{
float32x4 c, d, e, f;
@@ -8823,9 +8844,9 @@ int main(int argc, char **argv) {
2floats! 48, 68, 92, 120 42, 56, 72, 90
3floats! 48, 68, 92, 120 2016, 3808, 6624, 10800
zeros 0, 0, 0, 0
-4uints! 1086324736, 1094713344, 1101004800, 1106247680 1109917696, 1113587712, 1116733440, 1119092736
-5uints! -2098724864, -2086666240, -2077229056, -2069626880 -23592960, -18874368, -15728640, -12845056
-5uintops! 36175872, 35651584, 34603008, 33816576 48758784, 52428800, 53477376, 54788096
+4ints! 1086324736, 1094713344, 1101004800, 1106247680 1109917696, 1113587712, 1116733440, 1119092736
+5ints! -2098724864, -2086666240, -2077229056, -2069626880 -23592960, -18874368, -15728640, -12845056
+5intops! 36175872, 35651584, 34603008, 33816576 48758784, 52428800, 53477376, 54788096
6floats! -9, 0, 4, 9 -2, -12, 14, 10
''')
@@ -8876,6 +8897,484 @@ zeros 0, 0, 0, 0
16.000000
''')
+ def test_simd3(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('needs ta2')
+ if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate
+ src = r'''
+ #include <iostream>
+ #include <emmintrin.h>
+ #include <assert.h>
+ #include <stdint.h>
+ #include <bitset>
+
+ using namespace std;
+
+ void testSetPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v = _mm_set_ps(1.0, 2.0, 3.0, 4.0);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 4.0);
+ assert(ar[1] == 3.0);
+ assert(ar[2] == 2.0);
+ assert(ar[3] == 1.0);
+ }
+
+ void testSet1Ps() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v = _mm_set1_ps(5.5);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 5.5);
+ assert(ar[1] == 5.5);
+ assert(ar[2] == 5.5);
+ assert(ar[3] == 5.5);
+ }
+
+ void testSetZeroPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v = _mm_setzero_ps();
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 0);
+ assert(ar[1] == 0);
+ assert(ar[2] == 0);
+ assert(ar[3] == 0);
+ }
+
+ void testSetEpi32() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v = _mm_set_epi32(5, 7, 126, 381);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == 381);
+ assert(ar[1] == 126);
+ assert(ar[2] == 7);
+ assert(ar[3] == 5);
+ v = _mm_set_epi32(0x55555555, 0xaaaaaaaa, 0xffffffff, 0x12345678);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == 0x12345678);
+ assert(ar[1] == 0xffffffff);
+ assert(ar[2] == 0xaaaaaaaa);
+ assert(ar[3] == 0x55555555);
+ }
+
+ void testSet1Epi32() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v = _mm_set1_epi32(-5);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == -5);
+ assert(ar[1] == -5);
+ assert(ar[2] == -5);
+ assert(ar[3] == -5);
+ }
+
+ void testSetZeroSi128() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v = _mm_setzero_si128();
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == 0);
+ assert(ar[1] == 0);
+ assert(ar[2] == 0);
+ assert(ar[3] == 0);
+ }
+
+ void testBitCasts() {
+ int32_t __attribute__((__aligned__(16))) ar1[4];
+ float __attribute__((__aligned__(16))) ar2[4];
+ __m128i v1 = _mm_set_epi32(0x3f800000, 0x40000000, 0x40400000, 0x40800000);
+ __m128 v2 = _mm_castsi128_ps(v1);
+ _mm_store_ps(ar2, v2);
+ assert(ar2[0] == 4.0);
+ assert(ar2[1] == 3.0);
+ assert(ar2[2] == 2.0);
+ assert(ar2[3] == 1.0);
+ v2 = _mm_set_ps(5.0, 6.0, 7.0, 8.0);
+ v1 = _mm_castps_si128(v2);
+ _mm_store_si128((__m128i *)ar1, v1);
+ assert(ar1[0] == 0x41000000);
+ assert(ar1[1] == 0x40e00000);
+ assert(ar1[2] == 0x40c00000);
+ assert(ar1[3] == 0x40a00000);
+ float w = 0;
+ float z = -278.3;
+ float y = 5.2;
+ float x = -987654321;
+ v1 = _mm_castps_si128(_mm_set_ps(w, z, y, x));
+ _mm_store_ps(ar2, _mm_castsi128_ps(v1));
+ assert(ar2[0] == x);
+ assert(ar2[1] == y);
+ assert(ar2[2] == z);
+ assert(ar2[3] == w);
+ /*
+ std::bitset<sizeof(float)*CHAR_BIT> bits1x(*reinterpret_cast<unsigned long*>(&(ar2[0])));
+ std::bitset<sizeof(float)*CHAR_BIT> bits1y(*reinterpret_cast<unsigned long*>(&(ar2[1])));
+ std::bitset<sizeof(float)*CHAR_BIT> bits1z(*reinterpret_cast<unsigned long*>(&(ar2[2])));
+ std::bitset<sizeof(float)*CHAR_BIT> bits1w(*reinterpret_cast<unsigned long*>(&(ar2[3])));
+ std::bitset<sizeof(float)*CHAR_BIT> bits2x(*reinterpret_cast<unsigned long*>(&x));
+ std::bitset<sizeof(float)*CHAR_BIT> bits2y(*reinterpret_cast<unsigned long*>(&y));
+ std::bitset<sizeof(float)*CHAR_BIT> bits2z(*reinterpret_cast<unsigned long*>(&z));
+ std::bitset<sizeof(float)*CHAR_BIT> bits2w(*reinterpret_cast<unsigned long*>(&w));
+ assert(bits1x == bits2x);
+ assert(bits1y == bits2y);
+ assert(bits1z == bits2z);
+ assert(bits1w == bits2w);
+ */
+ v2 = _mm_castsi128_ps(_mm_set_epi32(0xffffffff, 0, 0x5555cccc, 0xaaaaaaaa));
+ _mm_store_si128((__m128i *)ar1, _mm_castps_si128(v2));
+ assert(ar1[0] == 0xaaaaaaaa);
+ assert(ar1[1] == 0x5555cccc);
+ assert(ar1[2] == 0);
+ assert(ar1[3] == 0xffffffff);
+ }
+
+ void testConversions() {
+ int32_t __attribute__((__aligned__(16))) ar1[4];
+ float __attribute__((__aligned__(16))) ar2[4];
+ __m128i v1 = _mm_set_epi32(0, -3, -517, 256);
+ __m128 v2 = _mm_cvtepi32_ps(v1);
+ _mm_store_ps(ar2, v2);
+ assert(ar2[0] == 256.0);
+ assert(ar2[1] == -517.0);
+ assert(ar2[2] == -3.0);
+ assert(ar2[3] == 0);
+ v2 = _mm_set_ps(5.0, 6.0, 7.45, -8.0);
+ v1 = _mm_cvtps_epi32(v2);
+ _mm_store_si128((__m128i *)ar1, v1);
+ assert(ar1[0] == -8);
+ assert(ar1[1] == 7);
+ assert(ar1[2] == 6);
+ assert(ar1[3] == 5);
+ }
+
+ void testMoveMaskPs() {
+ __m128 v = _mm_castsi128_ps(_mm_set_epi32(0xffffffff, 0xffffffff, 0, 0xffffffff));
+ int mask = _mm_movemask_ps(v);
+ assert(mask == 13);
+ }
+
+ void testAddPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(4.0, 3.0, 2.0, 1.0);
+ __m128 v2 = _mm_set_ps(10.0, 20.0, 30.0, 40.0);
+ __m128 v = _mm_add_ps(v1, v2);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 41.0);
+ assert(ar[1] == 32.0);
+ assert(ar[2] == 23.0);
+ assert(ar[3] == 14.0);
+ }
+
+ void testSubPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(4.0, 3.0, 2.0, 1.0);
+ __m128 v2 = _mm_set_ps(10.0, 20.0, 30.0, 40.0);
+ __m128 v = _mm_sub_ps(v1, v2);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == -39.0);
+ assert(ar[1] == -28.0);
+ assert(ar[2] == -17.0);
+ assert(ar[3] == -6.0);
+ }
+
+ void testMulPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(4.0, 3.0, 2.0, 1.0);
+ __m128 v2 = _mm_set_ps(10.0, 20.0, 30.0, 40.0);
+ __m128 v = _mm_mul_ps(v1, v2);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 40.0);
+ assert(ar[1] == 60.0);
+ assert(ar[2] == 60.0);
+ assert(ar[3] == 40.0);
+ }
+
+ void testDivPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(4.0, 9.0, 8.0, 1.0);
+ __m128 v2 = _mm_set_ps(2.0, 3.0, 1.0, 0.5);
+ __m128 v = _mm_div_ps(v1, v2);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 2.0);
+ assert(ar[1] == 8.0);
+ assert(ar[2] == 3.0);
+ assert(ar[3] == 2.0);
+ }
+
+ void testMinPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(-20.0, 10.0, 30.0, 0.5);
+ __m128 v2 = _mm_set_ps(2.0, 1.0, 50.0, 0.0);
+ __m128 v = _mm_min_ps(v1, v2);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 0.0);
+ assert(ar[1] == 30.0);
+ assert(ar[2] == 1.0);
+ assert(ar[3] == -20.0);
+ }
+
+ void testMaxPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(-20.0, 10.0, 30.0, 0.5);
+ __m128 v2 = _mm_set_ps(2.5, 5.0, 55.0, 1.0);
+ __m128 v = _mm_max_ps(v1, v2);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 1.0);
+ assert(ar[1] == 55.0);
+ assert(ar[2] == 10.0);
+ assert(ar[3] == 2.5);
+ }
+
+ void testSqrtPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(16.0, 9.0, 4.0, 1.0);
+ __m128 v = _mm_sqrt_ps(v1);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 1.0);
+ assert(ar[1] == 2.0);
+ assert(ar[2] == 3.0);
+ assert(ar[3] == 4.0);
+ }
+
+ void testCmpLtPs() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(1.0, 2.0, 0.1, 0.001);
+ __m128 v2 = _mm_set_ps(2.0, 2.0, 0.001, 0.1);
+ __m128 v = _mm_cmplt_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar, _mm_castps_si128(v));
+ assert(ar[0] == 0xffffffff);
+ assert(ar[1] == 0);
+ assert(ar[2] == 0);
+ assert(ar[3] == 0xffffffff);
+ assert(_mm_movemask_ps(v) == 9);
+ }
+
+ void testCmpLePs() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(1.0, 2.0, 0.1, 0.001);
+ __m128 v2 = _mm_set_ps(2.0, 2.0, 0.001, 0.1);
+ __m128 v = _mm_cmple_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar, _mm_castps_si128(v));
+ assert(ar[0] == 0xffffffff);
+ assert(ar[1] == 0);
+ assert(ar[2] == 0xffffffff);
+ assert(ar[3] == 0xffffffff);
+ assert(_mm_movemask_ps(v) == 13);
+ }
+
+ void testCmpEqPs() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(1.0, 2.0, 0.1, 0.001);
+ __m128 v2 = _mm_set_ps(2.0, 2.0, 0.001, 0.1);
+ __m128 v = _mm_cmpeq_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar, _mm_castps_si128(v));
+ assert(ar[0] == 0);
+ assert(ar[1] == 0);
+ assert(ar[2] == 0xffffffff);
+ assert(ar[3] == 0);
+ assert(_mm_movemask_ps(v) == 4);
+ }
+
+ void testCmpGePs() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(1.0, 2.0, 0.1, 0.001);
+ __m128 v2 = _mm_set_ps(2.0, 2.0, 0.001, 0.1);
+ __m128 v = _mm_cmpge_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar, _mm_castps_si128(v));
+ assert(ar[0] == 0);
+ assert(ar[1] == 0xffffffff);
+ assert(ar[2] == 0xffffffff);
+ assert(ar[3] == 0);
+ assert(_mm_movemask_ps(v) == 6);
+ }
+
+ void testCmpGtPs() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(1.0, 2.0, 0.1, 0.001);
+ __m128 v2 = _mm_set_ps(2.0, 2.0, 0.001, 0.1);
+ __m128 v = _mm_cmpgt_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar, _mm_castps_si128(v));
+ assert(ar[0] == 0);
+ assert(ar[1] == 0xffffffff);
+ assert(ar[2] == 0);
+ assert(ar[3] == 0);
+ assert(_mm_movemask_ps(v) == 2);
+ }
+
+ void testAndPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(425, -501, -32, 68);
+ __m128 v2 = _mm_castsi128_ps(_mm_set_epi32(0xffffffff, 0xffffffff, 0, 0xffffffff));
+ __m128 v = _mm_and_ps(v1, v2);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 68);
+ assert(ar[1] == 0);
+ assert(ar[2] == -501);
+ assert(ar[3] == 425);
+ int32_t __attribute__((__aligned__(16))) ar2[4];
+ v1 = _mm_castsi128_ps(_mm_set_epi32(0xaaaaaaaa, 0xaaaaaaaa, -1431655766, 0xaaaaaaaa));
+ v2 = _mm_castsi128_ps(_mm_set_epi32(0x55555555, 0x55555555, 0x55555555, 0x55555555));
+ v = _mm_and_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar2, _mm_castps_si128(v));
+ assert(ar2[0] == 0);
+ assert(ar2[1] == 0);
+ assert(ar2[2] == 0);
+ assert(ar2[3] == 0);
+ }
+
+ void testAndNotPs() {
+ float __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_set_ps(425, -501, -32, 68);
+ __m128 v2 = _mm_castsi128_ps(_mm_set_epi32(0xffffffff, 0xffffffff, 0, 0xffffffff));
+ __m128 v = _mm_andnot_ps(v2, v1);
+ _mm_store_ps(ar, v);
+ assert(ar[0] == 0);
+ assert(ar[1] == -32);
+ assert(ar[2] == 0);
+ assert(ar[3] == 0);
+ int32_t __attribute__((__aligned__(16))) ar2[4];
+ v1 = _mm_castsi128_ps(_mm_set_epi32(0xaaaaaaaa, 0xaaaaaaaa, -1431655766, 0xaaaaaaaa));
+ v2 = _mm_castsi128_ps(_mm_set_epi32(0x55555555, 0x55555555, 0x55555555, 0x55555555));
+ v = _mm_andnot_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar2, _mm_castps_si128(v));
+ assert(ar2[0] == 0x55555555);
+ assert(ar2[1] == 0x55555555);
+ assert(ar2[2] == 0x55555555);
+ assert(ar2[3] == 0x55555555);
+ }
+
+ void testOrPs() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_castsi128_ps(_mm_set_epi32(0xaaaaaaaa, 0xaaaaaaaa, 0xffffffff, 0));
+ __m128 v2 = _mm_castsi128_ps(_mm_set_epi32(0x55555555, 0x55555555, 0x55555555, 0x55555555));
+ __m128 v = _mm_or_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar, _mm_castps_si128(v));
+ assert(ar[0] == 0x55555555);
+ assert(ar[1] == 0xffffffff);
+ assert(ar[2] == 0xffffffff);
+ assert(ar[3] == 0xffffffff);
+ }
+
+ void testXorPs() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128 v1 = _mm_castsi128_ps(_mm_set_epi32(0xaaaaaaaa, 0xaaaaaaaa, 0xffffffff, 0));
+ __m128 v2 = _mm_castsi128_ps(_mm_set_epi32(0x55555555, 0x55555555, 0x55555555, 0x55555555));
+ __m128 v = _mm_xor_ps(v1, v2);
+ _mm_store_si128((__m128i *)ar, _mm_castps_si128(v));
+ assert(ar[0] == 0x55555555);
+ assert(ar[1] == 0xaaaaaaaa);
+ assert(ar[2] == 0xffffffff);
+ assert(ar[3] == 0xffffffff);
+ }
+
+ void testAndSi128() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v1 = _mm_set_epi32(0xaaaaaaaa, 0xaaaaaaaa, -1431655766, 0xaaaaaaaa);
+ __m128i v2 = _mm_set_epi32(0x55555555, 0x55555555, 0x55555555, 0x55555555);
+ __m128i v = _mm_and_si128(v1, v2);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == 0);
+ assert(ar[1] == 0);
+ assert(ar[2] == 0);
+ assert(ar[3] == 0);
+ }
+
+ void testAndNotSi128() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v1 = _mm_set_epi32(0xaaaaaaaa, 0xaaaaaaaa, -1431655766, 0xaaaaaaaa);
+ __m128i v2 = _mm_set_epi32(0x55555555, 0x55555555, 0x55555555, 0x55555555);
+ __m128i v = _mm_andnot_si128(v1, v2);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == 0x55555555);
+ assert(ar[1] == 0x55555555);
+ assert(ar[2] == 0x55555555);
+ assert(ar[3] == 0x55555555);
+ }
+
+ void testOrSi128() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v1 = _mm_set_epi32(0xaaaaaaaa, 0xaaaaaaaa, 0xffffffff, 0);
+ __m128i v2 = _mm_set_epi32(0x55555555, 0x55555555, 0x55555555, 0x55555555);
+ __m128i v = _mm_or_si128(v1, v2);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == 0x55555555);
+ assert(ar[1] == 0xffffffff);
+ assert(ar[2] == 0xffffffff);
+ assert(ar[3] == 0xffffffff);
+ }
+
+ void testXorSi128() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v1 = _mm_set_epi32(0xaaaaaaaa, 0xaaaaaaaa, 0xffffffff, 0);
+ __m128i v2 = _mm_set_epi32(0x55555555, 0x55555555, 0x55555555, 0x55555555);
+ __m128i v = _mm_xor_si128(v1, v2);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == 0x55555555);
+ assert(ar[1] == 0xaaaaaaaa);
+ assert(ar[2] == 0xffffffff);
+ assert(ar[3] == 0xffffffff);
+ }
+
+ void testAddEpi32() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v1 = _mm_set_epi32(4, 3, 2, 1);
+ __m128i v2 = _mm_set_epi32(10, 20, 30, 40);
+ __m128i v = _mm_add_epi32(v1, v2);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == 41);
+ assert(ar[1] == 32);
+ assert(ar[2] == 23);
+ assert(ar[3] == 14);
+ }
+
+ void testSubEpi32() {
+ int32_t __attribute__((__aligned__(16))) ar[4];
+ __m128i v1 = _mm_set_epi32(4, 3, 2, 1);
+ __m128i v2 = _mm_set_epi32(10, 20, 30, 40);
+ __m128i v = _mm_sub_epi32(v1, v2);
+ _mm_store_si128((__m128i *)ar, v);
+ assert(ar[0] == -39);
+ assert(ar[1] == -28);
+ assert(ar[2] == -17);
+ assert(ar[3] == -6);
+ }
+
+ int main(int argc, char ** argv) {
+ testSetPs();
+ testSet1Ps();
+ testSetZeroPs();
+ testSetEpi32();
+ testSet1Epi32();
+ testSetZeroSi128();
+ testBitCasts();
+ testConversions();
+ testMoveMaskPs();
+ testAddPs();
+ testSubPs();
+ testMulPs();
+ testDivPs();
+ testMaxPs();
+ testMinPs();
+ testSqrtPs();
+ testCmpLtPs();
+ testCmpLePs();
+ testCmpEqPs();
+ testCmpGePs();
+ testCmpGtPs();
+ testAndPs();
+ testAndNotPs();
+ testOrPs();
+ testXorPs();
+ testAndSi128();
+ testAndNotSi128();
+ testOrSi128();
+ testXorSi128();
+ testAddEpi32();
+ testSubEpi32();
+ printf("DONE");
+ return 0;
+ }
+ '''
+
+ self.do_run(src, 'DONE')
+
+
def test_gcc_unmangler(self):
Settings.NAMED_GLOBALS = 1 # test coverage for this
diff --git a/tests/test_other.py b/tests/test_other.py
index 0dd0bd12..5100db72 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -371,6 +371,11 @@ f.close()
process.communicate()
assert process.returncode is 0, 'User should be able to specify custom -std= on the command line!'
+ def test_cap_suffixes(self):
+ shutil.copyfile(path_from_root('tests', 'hello_world.cpp'), 'test.CPP')
+ Popen([PYTHON, EMCC, os.path.join(self.get_dir(), 'test.CPP')]).communicate()
+ self.assertContained('hello, world!', run_js(os.path.join(self.get_dir(), 'a.out.js')))
+
def test_catch_undef(self):
open(os.path.join(self.get_dir(), 'test.cpp'), 'w').write(r'''
#include <vector>
@@ -686,6 +691,38 @@ f.close()
}
''', ['hello through side\n'])
+ # js library call
+ open('lib.js', 'w').write(r'''
+ mergeInto(LibraryManager.library, {
+ test_lib_func: function(x) {
+ return x + 17.2;
+ }
+ });
+ ''')
+ test('js-lib', 'extern "C" { extern double test_lib_func(int input); }', r'''
+ #include <stdio.h>
+ #include "header.h"
+ extern double sidey();
+ int main2() { return 11; }
+ int main() {
+ int input = sidey();
+ double temp = test_lib_func(input);
+ printf("other says %.2f\n", temp);
+ printf("more: %.5f, %d\n", temp, input);
+ return 0;
+ }
+ ''', r'''
+ #include <stdio.h>
+ #include "header.h"
+ extern int main2();
+ double sidey() {
+ int temp = main2();
+ printf("main2 sed: %d\n", temp);
+ printf("main2 sed: %u, %c\n", temp, temp/2);
+ return test_lib_func(temp);
+ }
+ ''', 'other says 45.2', ['--js-library', 'lib.js'])
+
# libc usage in one modules. must force libc inclusion in the main module if that isn't the one using mallinfo()
try:
os.environ['EMCC_FORCE_STDLIBS'] = 'libc'
@@ -2074,3 +2111,28 @@ int main()
Popen([PYTHON, EMCC, path_from_root('tests', 'linpack.c'), '-O2', '-DSP', '--llvm-opts', '''['-O3', '-vectorize', '-vectorize-loops', '-bb-vectorize-vector-bits=128', '-force-vector-width=4']''']).communicate()
self.assertContained('Unrolled Single Precision', run_js('a.out.js'))
+ def test_dependency_file(self):
+ # Issue 1732: -MMD (and friends) create dependency files that need to be
+ # copied from the temporary directory.
+
+ open(os.path.join(self.get_dir(), 'test.cpp'), 'w').write(r'''
+ #include "test.hpp"
+
+ void my_function()
+ {
+ }
+ ''')
+ open(os.path.join(self.get_dir(), 'test.hpp'), 'w').write(r'''
+ void my_function();
+ ''')
+
+ Popen([PYTHON, EMCC, '-MMD', '-c', os.path.join(self.get_dir(), 'test.cpp'), '-o',
+ os.path.join(self.get_dir(), 'test.o')]).communicate()
+
+ assert os.path.exists(os.path.join(self.get_dir(), 'test.d')), 'No dependency file generated'
+ deps = open(os.path.join(self.get_dir(), 'test.d')).read()
+ # Look for ': ' instead of just ':' to not confuse C:\path\ notation with make "target: deps" rule. Not perfect, but good enough for this test.
+ head, tail = deps.split(': ', 2)
+ assert 'test.o' in head, 'Invalid dependency target'
+ assert 'test.cpp' in tail and 'test.hpp' in tail, 'Invalid dependencies generated'
+