Module: wine Branch: master Commit: 86dea350eac15f7dd8a276d937e3c087a8f6bfc9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=86dea350eac15f7dd8a276d937...
Author: Sebastian Lackner sebastian@fds-team.de Date: Wed Sep 7 10:56:08 2016 +0200
vcomp: Implement _vcomp_reduction_{u,i}2 and add tests.
Signed-off-by: Sebastian Lackner sebastian@fds-team.de Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/vcomp/main.c | 30 +++++++++++++++++++++++++++ dlls/vcomp/tests/vcomp.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ dlls/vcomp/vcomp.spec | 4 ++-- dlls/vcomp100/vcomp100.spec | 4 ++-- dlls/vcomp110/vcomp110.spec | 4 ++-- dlls/vcomp120/vcomp120.spec | 4 ++-- dlls/vcomp140/vcomp140.spec | 4 ++-- dlls/vcomp90/vcomp90.spec | 4 ++-- 8 files changed, 91 insertions(+), 12 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c index 53ad28a..a3a29db 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c @@ -516,6 +516,36 @@ void CDECL _vcomp_atomic_xor_i2(short *dest, short val) do old = *dest; while (interlocked_cmpxchg16(dest, old ^ val, old) != old); }
+static void CDECL _vcomp_atomic_bool_and_i2(short *dest, short val) +{ + short old; + do old = *dest; while (interlocked_cmpxchg16(dest, old && val, old) != old); +} + +static void CDECL _vcomp_atomic_bool_or_i2(short *dest, short val) +{ + short old; + do old = *dest; while (interlocked_cmpxchg16(dest, old ? old : (val != 0), old) != old); +} + +void CDECL _vcomp_reduction_i2(unsigned int flags, short *dest, short val) +{ + static void (CDECL * const funcs[])(short *, short) = + { + _vcomp_atomic_add_i2, + _vcomp_atomic_add_i2, + _vcomp_atomic_mul_i2, + _vcomp_atomic_and_i2, + _vcomp_atomic_or_i2, + _vcomp_atomic_xor_i2, + _vcomp_atomic_bool_and_i2, + _vcomp_atomic_bool_or_i2, + }; + unsigned int op = (flags >> 8) & 0xf; + op = min(op, sizeof(funcs)/sizeof(funcs[0]) - 1); + funcs[op](dest, val); +} + void CDECL _vcomp_atomic_add_i4(int *dest, int val) { interlocked_xchg_add(dest, val); diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c index dc84f98..5911601 100644 --- a/dlls/vcomp/tests/vcomp.c +++ b/dlls/vcomp/tests/vcomp.c @@ -103,7 +103,9 @@ static int (CDECL *p_vcomp_get_thread_num)(void); static void (CDECL *p_vcomp_leave_critsect)(CRITICAL_SECTION *critsect); static int (CDECL *p_vcomp_master_begin)(void); static void (CDECL *p_vcomp_master_end)(void); +static void (CDECL *p_vcomp_reduction_i2)(unsigned int flags, short *dest, short val); static void (CDECL *p_vcomp_reduction_i4)(unsigned int flags, int *dest, int val); +static void (CDECL *p_vcomp_reduction_u2)(unsigned int flags, unsigned short *dest, unsigned short val); static void (CDECL *p_vcomp_reduction_u4)(unsigned int flags, unsigned int *dest, unsigned int val); static void (CDECL *p_vcomp_sections_init)(int n); static int (CDECL *p_vcomp_sections_next)(void); @@ -346,7 +348,9 @@ static BOOL init_vcomp(void) VCOMP_GET_PROC(_vcomp_leave_critsect); VCOMP_GET_PROC(_vcomp_master_begin); VCOMP_GET_PROC(_vcomp_master_end); + VCOMP_GET_PROC(_vcomp_reduction_i2); VCOMP_GET_PROC(_vcomp_reduction_i4); + VCOMP_GET_PROC(_vcomp_reduction_u2); VCOMP_GET_PROC(_vcomp_reduction_u4); VCOMP_GET_PROC(_vcomp_sections_init); VCOMP_GET_PROC(_vcomp_sections_next); @@ -1883,6 +1887,50 @@ static void test_atomic_double(void) } }
+static void test_reduction_integer16(void) +{ + struct + { + unsigned int flags; + short v1, v2, expected; + } + tests[] = + { + { 0x000, 0x1122, 0x7766, -0x7778 }, + { VCOMP_REDUCTION_FLAGS_ADD, 0x1122, 0x7766, -0x7778 }, + { VCOMP_REDUCTION_FLAGS_MUL, 0x1122, 0x7766, -0x5e74 }, + { VCOMP_REDUCTION_FLAGS_MUL, 0x1122, -0x7766, 0x5e74 }, + { VCOMP_REDUCTION_FLAGS_AND, 0x1122, 0x7766, 0x1122 }, + { VCOMP_REDUCTION_FLAGS_OR, 0x1122, 0x7766, 0x7766 }, + { VCOMP_REDUCTION_FLAGS_XOR, 0x1122, 0x7766, 0x6644 }, + { VCOMP_REDUCTION_FLAGS_BOOL_AND, 1, 2, 1 }, + { VCOMP_REDUCTION_FLAGS_BOOL_OR, 0, 2, 1 }, + { 0x800, 0, 2, 1 }, + { 0x900, 0, 2, 1 }, + { 0xa00, 0, 2, 1 }, + { 0xb00, 0, 2, 1 }, + { 0xc00, 0, 2, 1 }, + { 0xd00, 0, 2, 1 }, + { 0xe00, 0, 2, 1 }, + { 0xf00, 0, 2, 1 }, + }; + int i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + short val = tests[i].v1; + p_vcomp_reduction_i2(tests[i].flags, &val, tests[i].v2); + ok(val == tests[i].expected, "test %d: expected val == %d, got %d\n", i, tests[i].expected, val); + } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + unsigned short val = tests[i].v1; + p_vcomp_reduction_u2(tests[i].flags, &val, tests[i].v2); + ok(val == (unsigned short)tests[i].expected, + "test %d: expected val == %u, got %u\n", i, (unsigned short)tests[i].expected, val); + } +} + static void CDECL reduction_cb(int *a, int *b) { p_vcomp_reduction_i4(VCOMP_REDUCTION_FLAGS_ADD, a, 1); @@ -1989,6 +2037,7 @@ START_TEST(vcomp) test_atomic_integer64(); test_atomic_float(); test_atomic_double(); + test_reduction_integer16(); test_reduction_integer32();
release_vcomp(); diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec index ddb35b8..85df49e 100644 --- a/dlls/vcomp/vcomp.spec +++ b/dlls/vcomp/vcomp.spec @@ -74,13 +74,13 @@ @ stub _vcomp_ordered_end @ stub _vcomp_ordered_loop_end @ stub _vcomp_reduction_i1 -@ stub _vcomp_reduction_i2 +@ cdecl _vcomp_reduction_i2(long ptr long) @ cdecl _vcomp_reduction_i4(long ptr long) @ stub _vcomp_reduction_i8 @ stub _vcomp_reduction_r4 @ stub _vcomp_reduction_r8 @ stub _vcomp_reduction_u1 -@ stub _vcomp_reduction_u2 +@ cdecl _vcomp_reduction_u2(long ptr long) _vcomp_reduction_i2 @ cdecl _vcomp_reduction_u4(long ptr long) _vcomp_reduction_i4 @ stub _vcomp_reduction_u8 @ cdecl _vcomp_sections_init(long) diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec index 92f6a9d..49f5a1b 100644 --- a/dlls/vcomp100/vcomp100.spec +++ b/dlls/vcomp100/vcomp100.spec @@ -74,13 +74,13 @@ @ stub _vcomp_ordered_end @ stub _vcomp_ordered_loop_end @ stub _vcomp_reduction_i1 -@ stub _vcomp_reduction_i2 +@ cdecl _vcomp_reduction_i2(long ptr long) vcomp._vcomp_reduction_i2 @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ stub _vcomp_reduction_i8 @ stub _vcomp_reduction_r4 @ stub _vcomp_reduction_r8 @ stub _vcomp_reduction_u1 -@ stub _vcomp_reduction_u2 +@ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 @ stub _vcomp_reduction_u8 @ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init diff --git a/dlls/vcomp110/vcomp110.spec b/dlls/vcomp110/vcomp110.spec index cb2a21d..dd9537a 100644 --- a/dlls/vcomp110/vcomp110.spec +++ b/dlls/vcomp110/vcomp110.spec @@ -75,13 +75,13 @@ @ stub _vcomp_ordered_end @ stub _vcomp_ordered_loop_end @ stub _vcomp_reduction_i1 -@ stub _vcomp_reduction_i2 +@ cdecl _vcomp_reduction_i2(long ptr long) vcomp._vcomp_reduction_i2 @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ stub _vcomp_reduction_i8 @ stub _vcomp_reduction_r4 @ stub _vcomp_reduction_r8 @ stub _vcomp_reduction_u1 -@ stub _vcomp_reduction_u2 +@ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 @ stub _vcomp_reduction_u8 @ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init diff --git a/dlls/vcomp120/vcomp120.spec b/dlls/vcomp120/vcomp120.spec index cb2a21d..dd9537a 100644 --- a/dlls/vcomp120/vcomp120.spec +++ b/dlls/vcomp120/vcomp120.spec @@ -75,13 +75,13 @@ @ stub _vcomp_ordered_end @ stub _vcomp_ordered_loop_end @ stub _vcomp_reduction_i1 -@ stub _vcomp_reduction_i2 +@ cdecl _vcomp_reduction_i2(long ptr long) vcomp._vcomp_reduction_i2 @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ stub _vcomp_reduction_i8 @ stub _vcomp_reduction_r4 @ stub _vcomp_reduction_r8 @ stub _vcomp_reduction_u1 -@ stub _vcomp_reduction_u2 +@ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 @ stub _vcomp_reduction_u8 @ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init diff --git a/dlls/vcomp140/vcomp140.spec b/dlls/vcomp140/vcomp140.spec index cb2a21d..dd9537a 100644 --- a/dlls/vcomp140/vcomp140.spec +++ b/dlls/vcomp140/vcomp140.spec @@ -75,13 +75,13 @@ @ stub _vcomp_ordered_end @ stub _vcomp_ordered_loop_end @ stub _vcomp_reduction_i1 -@ stub _vcomp_reduction_i2 +@ cdecl _vcomp_reduction_i2(long ptr long) vcomp._vcomp_reduction_i2 @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ stub _vcomp_reduction_i8 @ stub _vcomp_reduction_r4 @ stub _vcomp_reduction_r8 @ stub _vcomp_reduction_u1 -@ stub _vcomp_reduction_u2 +@ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 @ stub _vcomp_reduction_u8 @ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec index 92f6a9d..49f5a1b 100644 --- a/dlls/vcomp90/vcomp90.spec +++ b/dlls/vcomp90/vcomp90.spec @@ -74,13 +74,13 @@ @ stub _vcomp_ordered_end @ stub _vcomp_ordered_loop_end @ stub _vcomp_reduction_i1 -@ stub _vcomp_reduction_i2 +@ cdecl _vcomp_reduction_i2(long ptr long) vcomp._vcomp_reduction_i2 @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ stub _vcomp_reduction_i8 @ stub _vcomp_reduction_r4 @ stub _vcomp_reduction_r8 @ stub _vcomp_reduction_u1 -@ stub _vcomp_reduction_u2 +@ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 @ stub _vcomp_reduction_u8 @ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init