LLVM OpenMP* Runtime Library
z_Windows_NT-586_util.cpp
1 /*
2  * z_Windows_NT-586_util.cpp -- platform specific routines.
3  */
4 
5 //===----------------------------------------------------------------------===//
6 //
7 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8 // See https://llvm.org/LICENSE.txt for license information.
9 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "kmp.h"
14 
15 #if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
16 /* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to
17  use compare_and_store for these routines */
18 
19 kmp_int8 __kmp_test_then_or8(volatile kmp_int8 *p, kmp_int8 d) {
20  kmp_int8 old_value, new_value;
21 
22  old_value = TCR_1(*p);
23  new_value = old_value | d;
24 
25  while (!__kmp_compare_and_store8(p, old_value, new_value)) {
26  KMP_CPU_PAUSE();
27  old_value = TCR_1(*p);
28  new_value = old_value | d;
29  }
30  return old_value;
31 }
32 
33 kmp_int8 __kmp_test_then_and8(volatile kmp_int8 *p, kmp_int8 d) {
34  kmp_int8 old_value, new_value;
35 
36  old_value = TCR_1(*p);
37  new_value = old_value & d;
38 
39  while (!__kmp_compare_and_store8(p, old_value, new_value)) {
40  KMP_CPU_PAUSE();
41  old_value = TCR_1(*p);
42  new_value = old_value & d;
43  }
44  return old_value;
45 }
46 
47 kmp_uint32 __kmp_test_then_or32(volatile kmp_uint32 *p, kmp_uint32 d) {
48  kmp_uint32 old_value, new_value;
49 
50  old_value = TCR_4(*p);
51  new_value = old_value | d;
52 
53  while (!__kmp_compare_and_store32((volatile kmp_int32 *)p, old_value,
54  new_value)) {
55  KMP_CPU_PAUSE();
56  old_value = TCR_4(*p);
57  new_value = old_value | d;
58  }
59  return old_value;
60 }
61 
62 kmp_uint32 __kmp_test_then_and32(volatile kmp_uint32 *p, kmp_uint32 d) {
63  kmp_uint32 old_value, new_value;
64 
65  old_value = TCR_4(*p);
66  new_value = old_value & d;
67 
68  while (!__kmp_compare_and_store32((volatile kmp_int32 *)p, old_value,
69  new_value)) {
70  KMP_CPU_PAUSE();
71  old_value = TCR_4(*p);
72  new_value = old_value & d;
73  }
74  return old_value;
75 }
76 
77 kmp_int8 __kmp_test_then_add8(volatile kmp_int8 *p, kmp_int8 d) {
78  kmp_int64 old_value, new_value;
79 
80  old_value = TCR_1(*p);
81  new_value = old_value + d;
82  while (!__kmp_compare_and_store8(p, old_value, new_value)) {
83  KMP_CPU_PAUSE();
84  old_value = TCR_1(*p);
85  new_value = old_value + d;
86  }
87  return old_value;
88 }
89 
90 #if KMP_ARCH_X86
91 kmp_int64 __kmp_test_then_add64(volatile kmp_int64 *p, kmp_int64 d) {
92  kmp_int64 old_value, new_value;
93 
94  old_value = TCR_8(*p);
95  new_value = old_value + d;
96  while (!__kmp_compare_and_store64(p, old_value, new_value)) {
97  KMP_CPU_PAUSE();
98  old_value = TCR_8(*p);
99  new_value = old_value + d;
100  }
101  return old_value;
102 }
103 #endif /* KMP_ARCH_X86 */
104 
105 kmp_uint64 __kmp_test_then_or64(volatile kmp_uint64 *p, kmp_uint64 d) {
106  kmp_uint64 old_value, new_value;
107 
108  old_value = TCR_8(*p);
109  new_value = old_value | d;
110  while (!__kmp_compare_and_store64((volatile kmp_int64 *)p, old_value,
111  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_uint64 __kmp_test_then_and64(volatile kmp_uint64 *p, kmp_uint64 d) {
121  kmp_uint64 old_value, new_value;
122 
123  old_value = TCR_8(*p);
124  new_value = old_value & d;
125  while (!__kmp_compare_and_store64((volatile kmp_int64 *)p, old_value,
126  new_value)) {
127  KMP_CPU_PAUSE();
128  old_value = TCR_8(*p);
129  new_value = old_value & d;
130  }
131 
132  return old_value;
133 }
134 
135 #endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */