webkit  2cdf99a9e3038c7e01b3c37e8ad903ecbe5eecf1
https://github.com/WebKit/webkit
atomicops_internals_power.h
Go to the documentation of this file.
1 // Copyright 2014 Bloomberg Finance LP. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 // * Neither the name of Bloomberg Finance LP. nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 // This file is an internal atomic implementation, use atomicops.h instead.
30 
31 #ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_AIX_H_
32 #define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_AIX_H_
33 
34 namespace google {
35 namespace protobuf {
36 namespace internal {
37 
38 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
39  Atomic32 old_value,
40  Atomic32 new_value) {
42 
43  asm volatile (
44  "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
45  " cmpw %[cmp], %[res] \n\t" // compare values
46  " bne- 2f \n\t"
47  " stwcx. %[val], %[zero], %[obj] \n\t" // store new value
48  " bne- 1b \n\t"
49  "2: \n\t"
50  : [res] "=&b" (result)
51  : [obj] "b" (ptr),
52  [cmp] "b" (old_value),
53  [val] "b" (new_value),
54  [zero] "i" (0)
55  : "cr0", "ctr");
56 
57  return result;
58 }
59 
60 inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
61  Atomic32 new_value) {
63 
64  asm volatile (
65  "1: lwarx %[res], %[zero], %[obj] \n\t"
66  " stwcx. %[val], %[zero], %[obj] \n\t"
67  " bne- 1b \n\t"
68  : [res] "=&b" (result)
69  : [obj] "b" (ptr),
70  [val] "b" (new_value),
71  [zero] "i" (0)
72  : "cr0", "ctr");
73 
74  return result;
75 }
76 
77 inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
78  Atomic32 increment) {
80 
81  asm volatile (
82  "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
83  " add %[res], %[val], %[res] \n\t" // add the operand
84  " stwcx. %[res], %[zero], %[obj] \n\t" // store old value
85  // if still reserved
86  " bne- 1b \n\t"
87  : [res] "=&b" (result)
88  : [obj] "b" (ptr),
89  [val] "b" (increment),
90  [zero] "i" (0)
91  : "cr0", "ctr");
92 
93  return result;
94 }
95 
96 inline void MemoryBarrier(void) {
97  asm volatile (
98  " lwsync \n\t"
99  " isync \n\t"
100  :
101  :
102  : "memory");
103 }
104 
105 inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
106  Atomic32 increment) {
108 
109  asm volatile (
110  " lwsync \n\t"
111 
112  "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
113  " add %[res], %[val], %[res] \n\t" // add the operand
114  " stwcx. %[res], %[zero], %[obj] \n\t" // store old value
115  // if still reserved
116  " bne- 1b \n\t"
117  " isync \n\t"
118  : [res] "=&b" (result)
119  : [obj] "b" (ptr),
120  [val] "b" (increment),
121  [zero] "i" (0)
122  : "cr0", "ctr");
123 
124  return result;
125 }
126 
127 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
128  Atomic32 old_value,
129  Atomic32 new_value) {
131 
132  asm volatile (
133  "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
134  " cmpw %[cmp], %[res] \n\t" // compare values
135  " bne- 2f \n\t"
136  " stwcx. %[val], %[zero], %[obj] \n\t" // store new value
137  " bne- 1b \n\t"
138 
139  " isync \n\t"
140  "2: \n\t"
141  : [res] "=&b" (result)
142  : [obj] "b" (ptr),
143  [cmp] "b" (old_value),
144  [val] "b" (new_value),
145  [zero] "i" (0)
146  : "cr0", "ctr");
147 
148  return result;
149 }
150 
151 inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
152  Atomic32 old_value,
153  Atomic32 new_value) {
155 
156  asm volatile (
157  " lwsync \n\t"
158 
159  "1: lwarx %[res], %[zero], %[obj] \n\t" // load and reserve
160  " cmpw %[cmp], %[res] \n\t" // compare values
161  " bne- 2f \n\t"
162  " stwcx. %[val], %[zero], %[obj] \n\t" // store new value
163  " bne- 1b \n\t"
164 
165  "2: \n\t"
166  : [res] "=&b" (result)
167  : [obj] "b" (ptr),
168  [cmp] "b" (old_value),
169  [val] "b" (new_value),
170  [zero] "i" (0)
171  : "cr0", "ctr");
172 
173  return result;
174 }
175 
176 inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
177  *ptr = value;
178 }
179 
180 inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
181  asm volatile (
182  " stw %[val], %[obj] \n\t"
183  " isync \n\t"
184  : [obj] "=m" (*ptr)
185  : [val] "b" (value));
186 }
187 
188 inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
189  asm volatile (
190  " lwsync \n\t"
191  " stw %[val], %[obj] \n\t"
192  : [obj] "=m" (*ptr)
193  : [val] "b" (value));
194 }
195 
196 inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
197  return *ptr;
198 }
199 
200 inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
202 
203  asm volatile (
204  "1: lwz %[res], %[obj] \n\t"
205  " cmpw %[res], %[res] \n\t" // create data
206  // dependency for
207  // load/load ordering
208  " bne- 1b \n\t" // never taken
209 
210  " isync \n\t"
211  : [res] "=b" (result)
212  : [obj] "m" (*ptr),
213  [zero] "i" (0)
214  : "cr0", "ctr");
215 
216  return result;
217 }
218 
219 inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
221 
222  asm volatile (
223  " lwsync \n\t"
224 
225  "1: lwz %[res], %[obj] \n\t"
226  " cmpw %[res], %[res] \n\t" // create data
227  // dependency for
228  // load/load ordering
229  " bne- 1b \n\t" // never taken
230  : [res] "=b" (result)
231  : [obj] "m" (*ptr),
232  [zero] "i" (0)
233  : "cr0", "ctr");
234 
235  return result;
236 }
237 
238 #ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
239 inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
240  Atomic64 old_value,
241  Atomic64 new_value) {
242  Atomic64 result;
243 
244  asm volatile (
245  "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
246  " cmpd %[cmp], %[res] \n\t" // compare values
247  " bne- 2f \n\t"
248 
249  " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value
250  " bne- 1b \n\t"
251  "2: \n\t"
252  : [res] "=&b" (result)
253  : [obj] "b" (ptr),
254  [cmp] "b" (old_value),
255  [val] "b" (new_value),
256  [zero] "i" (0)
257  : "cr0", "ctr");
258 
259  return result;
260 }
261 
262 inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
263  Atomic64 new_value) {
264  Atomic64 result;
265 
266  asm volatile (
267  "1: ldarx %[res], %[zero], %[obj] \n\t"
268  " stdcx. %[val], %[zero], %[obj] \n\t"
269  " bne- 1b \n\t"
270  : [res] "=&b" (result)
271  : [obj] "b" (ptr),
272  [val] "b" (new_value),
273  [zero] "i" (0)
274  : "cr0", "ctr");
275 
276  return result;
277 }
278 
279 inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
280  Atomic64 increment) {
281  Atomic64 result;
282 
283  asm volatile (
284  "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
285  " add %[res], %[res], %[val] \n\t" // add the operand
286  " stdcx. %[res], %[zero], %[obj] \n\t" // store old value if
287  // still reserved
288 
289  " bne- 1b \n\t"
290  : [res] "=&b" (result)
291  : [obj] "b" (ptr),
292  [val] "b" (increment),
293  [zero] "i" (0)
294  : "cr0", "ctr");
295 
296  return result;
297 }
298 
299 inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr,
300  Atomic64 increment) {
301 
302  Atomic64 result;
303 
304  asm volatile (
305  " lwsync \n\t"
306 
307  "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
308  " add %[res], %[res], %[val] \n\t" // add the operand
309  " stdcx. %[res], %[zero], %[obj] \n\t" // store old value if
310  // still reserved
311 
312  " bne- 1b \n\t"
313 
314  " isync \n\t"
315  : [res] "=&b" (result)
316  : [obj] "b" (ptr),
317  [val] "b" (increment),
318  [zero] "i" (0)
319  : "cr0", "ctr");
320 
321  return result;
322 }
323 
324 inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
325  Atomic64 old_value,
326  Atomic64 new_value) {
327  Atomic64 result;
328 
329  asm volatile (
330  "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
331  " cmpd %[cmp], %[res] \n\t" // compare values
332  " bne- 2f \n\t"
333 
334  " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value
335  " bne- 1b \n\t"
336  " isync \n\t"
337  "2: \n\t"
338  : [res] "=&b" (result)
339  : [obj] "b" (ptr),
340  [cmp] "b" (old_value),
341  [val] "b" (new_value),
342  [zero] "i" (0)
343  : "cr0", "ctr");
344 
345  return result;
346 }
347 
348 inline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
349  Atomic64 old_value,
350  Atomic64 new_value) {
351  Atomic64 result;
352 
353  asm volatile (
354  " lwsync \n\t"
355 
356  "1: ldarx %[res], %[zero], %[obj] \n\t" // load and reserve
357  " cmpd %[cmp], %[res] \n\t" // compare values
358  " bne- 2f \n\t"
359 
360  " stdcx. %[val], %[zero], %[obj] \n\t" // store the new value
361  " bne- 1b \n\t"
362  "2: \n\t"
363  : [res] "=&b" (result)
364  : [obj] "b" (ptr),
365  [cmp] "b" (old_value),
366  [val] "b" (new_value),
367  [zero] "i" (0)
368  : "cr0", "ctr");
369 
370  return result;
371 }
372 
373 inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
374  *ptr = value;
375 }
376 
377 inline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
378  asm volatile (
379  " std %[val], %[obj] \n\t"
380  " isync \n\t"
381  : [obj] "=m" (*ptr)
382  : [val] "b" (value));
383 }
384 
385 inline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
386  asm volatile (
387  " lwsync \n\t"
388  " std %[val], %[obj] \n\t"
389  : [obj] "=m" (*ptr)
390  : [val] "b" (value));
391 }
392 
393 inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
394  return *ptr;
395 }
396 
397 inline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
398  Atomic64 result;
399 
400  asm volatile (
401  "1: ld %[res], %[obj] \n\t"
402  " cmpd %[res], %[res] \n\t" // create data
403  // dependency for
404  // load/load ordering
405  " bne- 1b \n\t" // never taken
406 
407  " isync \n\t"
408  : [res] "=b" (result)
409  : [obj] "m" (*ptr),
410  [zero] "i" (0)
411  : "cr0", "ctr");
412 
413  return result;
414 }
415 
416 inline Atomic64 Release_Load(volatile const Atomic64* ptr) {
417  Atomic64 result;
418 
419  asm volatile (
420  " lwsync \n\t"
421 
422  "1: ld %[res], %[obj] \n\t"
423  " cmpd %[res], %[res] \n\t" // create data
424  // dependency for
425  // load/load ordering
426  " bne- 1b \n\t" // never taken
427  : [res] "=b" (result)
428  : [obj] "m" (*ptr),
429  [zero] "i" (0)
430  : "cr0", "ctr");
431 
432  return result;
433 }
434 #endif
435 
436 } // namespace internal
437 } // namespace protobuf
438 } // namespace google
439 
440 #endif // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
Atomic32 Acquire_Load(volatile const Atomic32 *ptr)
Definition: atomicops_internals_arm64_gcc.h:167
void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value)
Definition: atomicops_internals_arm64_gcc.h:149
Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr, Atomic32 old_value, Atomic32 new_value)
Definition: atomicops_internals_arm64_gcc.h:52
OPENSSL_EXPORT const ASN1_OBJECT * obj
Definition: x509.h:1053
const FieldDescriptor const OneofDescriptor value
Definition: descriptor.h:1717
void Release_Store(volatile Atomic32 *ptr, Atomic32 value)
Definition: atomicops_internals_arm64_gcc.h:154
EGLAttrib * value
Definition: eglext.h:120
Definition: __init__.py:1
Atomic32 Release_Load(volatile const Atomic32 *ptr)
Definition: atomicops_internals_arm64_gcc.h:180
Definition: document.h:393
result
Definition: target-blank-opener-post-window.php:5
Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr, Atomic32 old_value, Atomic32 new_value)
Definition: atomicops_internals_arm64_gcc.h:136
Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr, Atomic32 increment)
Definition: atomicops_internals_arm64_gcc.h:118
Definition: gflags_completions.h:115
Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr, Atomic32 increment)
Definition: atomicops_internals_arm64_gcc.h:97
int32 Atomic32
Definition: atomicops.h:75
res
Definition: harness.py:111
GLuint GLsizei GLsizei GLfloat * val
Definition: gl2ext.h:3301
Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr, Atomic32 new_value)
Definition: atomicops_internals_arm64_gcc.h:77
void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value)
Definition: atomicops_internals_arm64_gcc.h:145
Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr)
Definition: atomicops_internals_arm64_gcc.h:163
Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr, Atomic32 old_value, Atomic32 new_value)
Definition: atomicops_internals_arm64_gcc.h:127
void MemoryBarrier()
Definition: atomicops_internals_arm64_gcc.h:40