1 /*
2 * z_Windows_NT-586_util.cpp -- platform specific routines.
3 */
4
5 //===----------------------------------------------------------------------===//
6 //
7 // The LLVM Compiler Infrastructure
8 //
9 // This file is dual licensed under the MIT and the University of Illinois Open
10 // Source Licenses. See LICENSE.txt for details.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "kmp.h"
15
16 #if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
17 /* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to
18 use compare_and_store for these routines */
19
__kmp_test_then_or8(volatile kmp_int8 * p,kmp_int8 d)20 kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 d) {
21 kmp_int8 old_value, new_value;
22
23 old_value = TCR_1(*p);
24 new_value = old_value | d;
25
26 while (!__kmp_compare_and_store8(p, old_value, new_value)) {
27 KMP_CPU_PAUSE();
28 old_value = TCR_1(*p);
29 new_value = old_value | d;
30 }
31 return old_value;
32 }
33
__kmp_test_then_and8(volatile kmp_int8 * p,kmp_int8 d)34 kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 d) {
35 kmp_int8 old_value, new_value;
36
37 old_value = TCR_1(*p);
38 new_value = old_value & d;
39
40 while (!__kmp_compare_and_store8(p, old_value, new_value)) {
41 KMP_CPU_PAUSE();
42 old_value = TCR_1(*p);
43 new_value = old_value & d;
44 }
45 return old_value;
46 }
47
__kmp_test_then_or32(volatile kmp_uint32 * p,kmp_uint32 d)48 kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 d) {
49 kmp_uint32 old_value, new_value;
50
51 old_value = TCR_4(*p);
52 new_value = old_value | d;
53
54 while (!__kmp_compare_and_store32((volatile kmp_int32 *)p, old_value,
55 new_value)) {
56 KMP_CPU_PAUSE();
57 old_value = TCR_4(*p);
58 new_value = old_value | d;
59 }
60 return old_value;
61 }
62
__kmp_test_then_and32(volatile kmp_uint32 * p,kmp_uint32 d)63 kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 d) {
64 kmp_uint32 old_value, new_value;
65
66 old_value = TCR_4(*p);
67 new_value = old_value & d;
68
69 while (!__kmp_compare_and_store32((volatile kmp_int32 *)p, old_value,
70 new_value)) {
71 KMP_CPU_PAUSE();
72 old_value = TCR_4(*p);
73 new_value = old_value & d;
74 }
75 return old_value;
76 }
77
__kmp_test_then_add8(volatile kmp_int8 * p,kmp_int8 d)78 kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 d) {
79 kmp_int64 old_value, new_value;
80
81 old_value = TCR_1(*p);
82 new_value = old_value + d;
83 while (!__kmp_compare_and_store8(p, old_value, new_value)) {
84 KMP_CPU_PAUSE();
85 old_value = TCR_1(*p);
86 new_value = old_value + d;
87 }
88 return old_value;
89 }
90
91 #if KMP_ARCH_X86
__kmp_test_then_add64(volatile kmp_int64 * p,kmp_int64 d)92 kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 d) {
93 kmp_int64 old_value, new_value;
94
95 old_value = TCR_8(*p);
96 new_value = old_value + d;
97 while (!__kmp_compare_and_store64(p, old_value, new_value)) {
98 KMP_CPU_PAUSE();
99 old_value = TCR_8(*p);
100 new_value = old_value + d;
101 }
102 return old_value;
103 }
104 #endif /* KMP_ARCH_X86 */
105
__kmp_test_then_or64(volatile kmp_uint64 * p,kmp_uint64 d)106 kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 d) {
107 kmp_uint64 old_value, new_value;
108
109 old_value = TCR_8(*p);
110 new_value = old_value | d;
111 while (!__kmp_compare_and_store64((volatile kmp_int64 *)p, old_value,
112 new_value)) {
113 KMP_CPU_PAUSE();
114 old_value = TCR_8(*p);
115 new_value = old_value | d;
116 }
117
118 return old_value;
119 }
120
__kmp_test_then_and64(volatile kmp_uint64 * p,kmp_uint64 d)121 kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 d) {
122 kmp_uint64 old_value, new_value;
123
124 old_value = TCR_8(*p);
125 new_value = old_value & d;
126 while (!__kmp_compare_and_store64((volatile kmp_int64 *)p, old_value,
127 new_value)) {
128 KMP_CPU_PAUSE();
129 old_value = TCR_8(*p);
130 new_value = old_value & d;
131 }
132
133 return old_value;
134 }
135
136 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
137