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