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 // 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 
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 
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 
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 
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 
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_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 
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 */