1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
/*
* z_Windows_NT-586_util.c -- platform specific routines.
*/
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.txt for details.
//
//===----------------------------------------------------------------------===//
#include "kmp.h"
#if (KMP_ARCH_X86 || KMP_ARCH_X86_64)
/* Only 32-bit "add-exchange" instruction on IA-32 architecture causes us to
* use compare_and_store for these routines
*/
kmp_int8
__kmp_test_then_or8( volatile kmp_int8 *p, kmp_int8 d )
{
kmp_int8 old_value, new_value;
old_value = TCR_1( *p );
new_value = old_value | d;
while ( ! __kmp_compare_and_store8 ( p, old_value, new_value ) )
{
KMP_CPU_PAUSE();
old_value = TCR_1( *p );
new_value = old_value | d;
}
return old_value;
}
kmp_int8
__kmp_test_then_and8( volatile kmp_int8 *p, kmp_int8 d )
{
kmp_int8 old_value, new_value;
old_value = TCR_1( *p );
new_value = old_value & d;
while ( ! __kmp_compare_and_store8 ( p, old_value, new_value ) )
{
KMP_CPU_PAUSE();
old_value = TCR_1( *p );
new_value = old_value & d;
}
return old_value;
}
kmp_int32
__kmp_test_then_or32( volatile kmp_int32 *p, kmp_int32 d )
{
kmp_int32 old_value, new_value;
old_value = TCR_4( *p );
new_value = old_value | d;
while ( ! __kmp_compare_and_store32 ( p, old_value, new_value ) )
{
KMP_CPU_PAUSE();
old_value = TCR_4( *p );
new_value = old_value | d;
}
return old_value;
}
kmp_int32
__kmp_test_then_and32( volatile kmp_int32 *p, kmp_int32 d )
{
kmp_int32 old_value, new_value;
old_value = TCR_4( *p );
new_value = old_value & d;
while ( ! __kmp_compare_and_store32 ( p, old_value, new_value ) )
{
KMP_CPU_PAUSE();
old_value = TCR_4( *p );
new_value = old_value & d;
}
return old_value;
}
kmp_int8
__kmp_test_then_add8( volatile kmp_int8 *p, kmp_int8 d )
{
kmp_int64 old_value, new_value;
old_value = TCR_1( *p );
new_value = old_value + d;
while ( ! __kmp_compare_and_store8 ( p, old_value, new_value ) )
{
KMP_CPU_PAUSE();
old_value = TCR_1( *p );
new_value = old_value + d;
}
return old_value;
}
#if KMP_ARCH_X86
kmp_int64
__kmp_test_then_add64( volatile kmp_int64 *p, kmp_int64 d )
{
kmp_int64 old_value, new_value;
old_value = TCR_8( *p );
new_value = old_value + d;
while ( ! __kmp_compare_and_store64 ( p, old_value, new_value ) )
{
KMP_CPU_PAUSE();
old_value = TCR_8( *p );
new_value = old_value + d;
}
return old_value;
}
#endif /* KMP_ARCH_X86 */
kmp_int64
__kmp_test_then_or64( volatile kmp_int64 *p, kmp_int64 d )
{
kmp_int64 old_value, new_value;
old_value = TCR_8( *p );
new_value = old_value | d;
while ( ! __kmp_compare_and_store64 ( p, old_value, new_value ) )
{
KMP_CPU_PAUSE();
old_value = TCR_8( *p );
new_value = old_value | d;
}
return old_value;
}
kmp_int64
__kmp_test_then_and64( volatile kmp_int64 *p, kmp_int64 d )
{
kmp_int64 old_value, new_value;
old_value = TCR_8( *p );
new_value = old_value & d;
while ( ! __kmp_compare_and_store64 ( p, old_value, new_value ) )
{
KMP_CPU_PAUSE();
old_value = TCR_8( *p );
new_value = old_value & d;
}
return old_value;
}
#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
/* ------------------------------------------------------------------------ */
/* ------------------------------------------------------------------------ */
|