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