diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c index d4c936612ab..34e327eedb7 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c @@ -894,6 +894,46 @@ void CDECL _vcomp_atomic_sub_r8(double *dest, double val) while (interlocked_cmpxchg64((LONG64 *)dest, new, old) != old); } +static void CDECL _vcomp_atomic_bool_and_r8(double *dest, double val) +{ + LONG64 old, new; + do + { + old = *(LONG64 *)dest; + *(double *)&new = (*(double *)&old != 0.0) ? (val != 0.0) : 0.0; + } + while (interlocked_cmpxchg64((LONG64 *)dest, new, old) != old); +} + +static void CDECL _vcomp_atomic_bool_or_r8(double *dest, double val) +{ + LONG64 old, new; + do + { + old = *(LONG64 *)dest; + *(double *)&new = (*(double *)&old != 0.0) ? *(double *)&old : (val != 0.0); + } + while (interlocked_cmpxchg64((LONG64 *)dest, new, old) != old); +} + +void CDECL _vcomp_reduction_r8(unsigned int flags, double *dest, double val) +{ + static void (CDECL * const funcs[])(double *, double) = + { + _vcomp_atomic_add_r8, + _vcomp_atomic_add_r8, + _vcomp_atomic_mul_r8, + _vcomp_atomic_bool_or_r8, + _vcomp_atomic_bool_or_r8, + _vcomp_atomic_bool_or_r8, + _vcomp_atomic_bool_and_r8, + _vcomp_atomic_bool_or_r8, + }; + unsigned int op = (flags >> 8) & 0xf; + op = min(op, sizeof(funcs)/sizeof(funcs[0]) - 1); + funcs[op](dest, val); +} + int CDECL omp_get_dynamic(void) { TRACE("stub\n"); diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c index 15fc473a704..96a3d9c20a8 100644 --- a/dlls/vcomp/tests/vcomp.c +++ b/dlls/vcomp/tests/vcomp.c @@ -108,6 +108,7 @@ static void (CDECL *p_vcomp_reduction_i2)(unsigned int flags, short *dest, sh static void (CDECL *p_vcomp_reduction_i4)(unsigned int flags, int *dest, int val); static void (CDECL *p_vcomp_reduction_i8)(unsigned int flags, LONG64 *dest, LONG64 val); static void (CDECL *p_vcomp_reduction_r4)(unsigned int flags, float *dest, float val); +static void (CDECL *p_vcomp_reduction_r8)(unsigned int flags, double *dest, double val); static void (CDECL *p_vcomp_reduction_u1)(unsigned int flags, unsigned char *dest, unsigned char 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); @@ -358,6 +359,7 @@ static BOOL init_vcomp(void) VCOMP_GET_PROC(_vcomp_reduction_i4); VCOMP_GET_PROC(_vcomp_reduction_i8); VCOMP_GET_PROC(_vcomp_reduction_r4); + VCOMP_GET_PROC(_vcomp_reduction_r8); VCOMP_GET_PROC(_vcomp_reduction_u1); VCOMP_GET_PROC(_vcomp_reduction_u2); VCOMP_GET_PROC(_vcomp_reduction_u4); @@ -2110,7 +2112,7 @@ static void test_reduction_integer64(void) } } -static void test_reduction_float(void) +static void test_reduction_float_double(void) { static const struct { @@ -2161,6 +2163,13 @@ static void test_reduction_float(void) ok(tests[i].expected - 0.001 < val && val < tests[i].expected + 0.001, "test %d: expected val == %f, got %f\n", i, tests[i].expected, val); } + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) + { + double val = tests[i].v1; + p_vcomp_reduction_r8(tests[i].flags, &val, tests[i].v2); + ok(tests[i].expected - 0.001 < val && val < tests[i].expected + 0.001, + "test %d: expected val == %f, got %f\n", i, tests[i].expected, val); + } } START_TEST(vcomp) @@ -2191,7 +2200,7 @@ START_TEST(vcomp) test_reduction_integer16(); test_reduction_integer32(); test_reduction_integer64(); - test_reduction_float(); + test_reduction_float_double(); release_vcomp(); } diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec index 22f06cb50a1..f2231c0de24 100644 --- a/dlls/vcomp/vcomp.spec +++ b/dlls/vcomp/vcomp.spec @@ -78,7 +78,7 @@ @ cdecl _vcomp_reduction_i4(long ptr long) @ cdecl _vcomp_reduction_i8(long ptr int64) @ cdecl _vcomp_reduction_r4(long ptr float) -@ stub _vcomp_reduction_r8 +@ cdecl _vcomp_reduction_r8(long ptr double) @ cdecl _vcomp_reduction_u1(long ptr long) _vcomp_reduction_i1 @ cdecl _vcomp_reduction_u2(long ptr long) _vcomp_reduction_i2 @ cdecl _vcomp_reduction_u4(long ptr long) _vcomp_reduction_i4 diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec index b87bd8b29fd..afea2f2af65 100644 --- a/dlls/vcomp100/vcomp100.spec +++ b/dlls/vcomp100/vcomp100.spec @@ -78,7 +78,7 @@ @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ cdecl _vcomp_reduction_i8(long ptr int64) vcomp._vcomp_reduction_i8 @ cdecl _vcomp_reduction_r4(long ptr float) vcomp._vcomp_reduction_r4 -@ stub _vcomp_reduction_r8 +@ cdecl _vcomp_reduction_r8(long ptr double) vcomp._vcomp_reduction_r8 @ cdecl _vcomp_reduction_u1(long ptr long) vcomp._vcomp_reduction_u1 @ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 diff --git a/dlls/vcomp110/vcomp110.spec b/dlls/vcomp110/vcomp110.spec index e86d50b8ef4..cec1c99a7f2 100644 --- a/dlls/vcomp110/vcomp110.spec +++ b/dlls/vcomp110/vcomp110.spec @@ -79,7 +79,7 @@ @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ cdecl _vcomp_reduction_i8(long ptr int64) vcomp._vcomp_reduction_i8 @ cdecl _vcomp_reduction_r4(long ptr float) vcomp._vcomp_reduction_r4 -@ stub _vcomp_reduction_r8 +@ cdecl _vcomp_reduction_r8(long ptr double) vcomp._vcomp_reduction_r8 @ cdecl _vcomp_reduction_u1(long ptr long) vcomp._vcomp_reduction_u1 @ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 diff --git a/dlls/vcomp120/vcomp120.spec b/dlls/vcomp120/vcomp120.spec index e86d50b8ef4..cec1c99a7f2 100644 --- a/dlls/vcomp120/vcomp120.spec +++ b/dlls/vcomp120/vcomp120.spec @@ -79,7 +79,7 @@ @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ cdecl _vcomp_reduction_i8(long ptr int64) vcomp._vcomp_reduction_i8 @ cdecl _vcomp_reduction_r4(long ptr float) vcomp._vcomp_reduction_r4 -@ stub _vcomp_reduction_r8 +@ cdecl _vcomp_reduction_r8(long ptr double) vcomp._vcomp_reduction_r8 @ cdecl _vcomp_reduction_u1(long ptr long) vcomp._vcomp_reduction_u1 @ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 diff --git a/dlls/vcomp140/vcomp140.spec b/dlls/vcomp140/vcomp140.spec index e86d50b8ef4..cec1c99a7f2 100644 --- a/dlls/vcomp140/vcomp140.spec +++ b/dlls/vcomp140/vcomp140.spec @@ -79,7 +79,7 @@ @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ cdecl _vcomp_reduction_i8(long ptr int64) vcomp._vcomp_reduction_i8 @ cdecl _vcomp_reduction_r4(long ptr float) vcomp._vcomp_reduction_r4 -@ stub _vcomp_reduction_r8 +@ cdecl _vcomp_reduction_r8(long ptr double) vcomp._vcomp_reduction_r8 @ cdecl _vcomp_reduction_u1(long ptr long) vcomp._vcomp_reduction_u1 @ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4 diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec index b87bd8b29fd..afea2f2af65 100644 --- a/dlls/vcomp90/vcomp90.spec +++ b/dlls/vcomp90/vcomp90.spec @@ -78,7 +78,7 @@ @ cdecl _vcomp_reduction_i4(long ptr long) vcomp._vcomp_reduction_i4 @ cdecl _vcomp_reduction_i8(long ptr int64) vcomp._vcomp_reduction_i8 @ cdecl _vcomp_reduction_r4(long ptr float) vcomp._vcomp_reduction_r4 -@ stub _vcomp_reduction_r8 +@ cdecl _vcomp_reduction_r8(long ptr double) vcomp._vcomp_reduction_r8 @ cdecl _vcomp_reduction_u1(long ptr long) vcomp._vcomp_reduction_u1 @ cdecl _vcomp_reduction_u2(long ptr long) vcomp._vcomp_reduction_u2 @ cdecl _vcomp_reduction_u4(long ptr long) vcomp._vcomp_reduction_u4