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_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 d) {
51   kmp_uint32 old_value, new_value;
52 
53   old_value = TCR_4(*p);
54   new_value = old_value | d;
55 
56   while (!__kmp_compare_and_store32((volatile kmp_int32 *)p, old_value,
57                                     new_value)) {
58     KMP_CPU_PAUSE();
59     old_value = TCR_4(*p);
60     new_value = old_value | d;
61   }
62   return old_value;
63 }
64 
65 kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 d) {
66   kmp_uint32 old_value, new_value;
67 
68   old_value = TCR_4(*p);
69   new_value = old_value & d;
70 
71   while (!__kmp_compare_and_store32((volatile kmp_int32 *)p, old_value,
72                                     new_value)) {
73     KMP_CPU_PAUSE();
74     old_value = TCR_4(*p);
75     new_value = old_value & d;
76   }
77   return old_value;
78 }
79 
80 kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 d) {
81   kmp_int64 old_value, new_value;
82 
83   old_value = TCR_1(*p);
84   new_value = old_value + d;
85   while (!__kmp_compare_and_store8(p, old_value, new_value)) {
86     KMP_CPU_PAUSE();
87     old_value = TCR_1(*p);
88     new_value = old_value + d;
89   }
90   return old_value;
91 }
92 
93 #if KMP_ARCH_X86
94 kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 d) {
95   kmp_int64 old_value, new_value;
96 
97   old_value = TCR_8(*p);
98   new_value = old_value + d;
99   while (!__kmp_compare_and_store64(p, old_value, new_value)) {
100     KMP_CPU_PAUSE();
101     old_value = TCR_8(*p);
102     new_value = old_value + d;
103   }
104   return old_value;
105 }
106 #endif /* KMP_ARCH_X86 */
107 
108 kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 d) {
109   kmp_uint64 old_value, new_value;
110 
111   old_value = TCR_8(*p);
112   new_value = old_value | d;
113   while (!__kmp_compare_and_store64((volatile kmp_int64 *)p, old_value,
114                                     new_value)) {
115     KMP_CPU_PAUSE();
116     old_value = TCR_8(*p);
117     new_value = old_value | d;
118   }
119 
120   return old_value;
121 }
122 
123 kmp_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 d) {
124   kmp_uint64 old_value, new_value;
125 
126   old_value = TCR_8(*p);
127   new_value = old_value & d;
128   while (!__kmp_compare_and_store64((volatile kmp_int64 *)p, old_value,
129                                     new_value)) {
130     KMP_CPU_PAUSE();
131     old_value = TCR_8(*p);
132     new_value = old_value & d;
133   }
134 
135   return old_value;
136 }
137 
138 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
139