]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/atomic/detail/extra_ops_gcc_ppc.hpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / boost / atomic / detail / extra_ops_gcc_ppc.hpp
1 /*
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * Copyright (c) 2017 - 2018 Andrey Semashev
7 */
8 /*!
9 * \file atomic/detail/extra_ops_gcc_ppc.hpp
10 *
11 * This header contains implementation of the extra atomic operations for PowerPC.
12 */
13
14 #ifndef BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_PPC_HPP_INCLUDED_
16
17 #include <cstddef>
18 #include <boost/memory_order.hpp>
19 #include <boost/atomic/detail/config.hpp>
20 #include <boost/atomic/detail/storage_traits.hpp>
21 #include <boost/atomic/detail/extra_operations_fwd.hpp>
22 #include <boost/atomic/detail/extra_ops_generic.hpp>
23 #include <boost/atomic/detail/ops_gcc_ppc_common.hpp>
24 #include <boost/atomic/detail/capabilities.hpp>
25 #include <boost/atomic/detail/header.hpp>
26
27 #ifdef BOOST_HAS_PRAGMA_ONCE
28 #pragma once
29 #endif
30
31 namespace boost {
32 namespace atomics {
33 namespace detail {
34
35 template< typename Base >
36 struct extra_operations_gcc_ppc_common :
37 public Base
38 {
39 typedef Base base_type;
40 typedef typename base_type::storage_type storage_type;
41
42 static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
43 {
44 base_type::fetch_negate(storage, order);
45 }
46
47 static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
48 {
49 base_type::fetch_complement(storage, order);
50 }
51
52 static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
53 {
54 return !!base_type::negate(storage, order);
55 }
56
57 static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
58 {
59 return !!base_type::add(storage, v, order);
60 }
61
62 static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
63 {
64 return !!base_type::sub(storage, v, order);
65 }
66
67 static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
68 {
69 return !!base_type::bitwise_and(storage, v, order);
70 }
71
72 static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
73 {
74 return !!base_type::bitwise_or(storage, v, order);
75 }
76
77 static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
78 {
79 return !!base_type::bitwise_xor(storage, v, order);
80 }
81
82 static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
83 {
84 return !!base_type::bitwise_complement(storage, order);
85 }
86 };
87
88 template< typename Base, std::size_t Size, bool Signed >
89 struct extra_operations_gcc_ppc;
90
91 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
92
93 template< typename Base, bool Signed >
94 struct extra_operations_gcc_ppc< Base, 1u, Signed > :
95 public extra_operations_generic< Base, 1u, Signed >
96 {
97 typedef extra_operations_generic< Base, 1u, Signed > base_type;
98 typedef typename base_type::storage_type storage_type;
99
100 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
101 {
102 core_arch_operations_gcc_ppc_base::fence_before(order);
103 storage_type original, result;
104 __asm__ __volatile__
105 (
106 "1:\n\t"
107 "lbarx %0,%y2\n\t"
108 "neg %1,%0\n\t"
109 "stbcx. %1,%y2\n\t"
110 "bne- 1b\n\t"
111 : "=&b" (original), "=&b" (result), "+Z" (storage)
112 :
113 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
114 );
115 core_arch_operations_gcc_ppc_base::fence_after(order);
116 return original;
117 }
118
119 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
120 {
121 core_arch_operations_gcc_ppc_base::fence_before(order);
122 storage_type original, result;
123 __asm__ __volatile__
124 (
125 "1:\n\t"
126 "lbarx %0,%y2\n\t"
127 "neg %1,%0\n\t"
128 "stbcx. %1,%y2\n\t"
129 "bne- 1b\n\t"
130 : "=&b" (original), "=&b" (result), "+Z" (storage)
131 :
132 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
133 );
134 core_arch_operations_gcc_ppc_base::fence_after(order);
135 return result;
136 }
137
138 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
139 {
140 storage_type original, result;
141 core_arch_operations_gcc_ppc_base::fence_before(order);
142 __asm__ __volatile__
143 (
144 "1:\n\t"
145 "lbarx %0,%y2\n\t"
146 "add %1,%0,%3\n\t"
147 "stbcx. %1,%y2\n\t"
148 "bne- 1b\n\t"
149 : "=&b" (original), "=&b" (result), "+Z" (storage)
150 : "b" (v)
151 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
152 );
153 core_arch_operations_gcc_ppc_base::fence_after(order);
154 return result;
155 }
156
157 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
158 {
159 storage_type original, result;
160 core_arch_operations_gcc_ppc_base::fence_before(order);
161 __asm__ __volatile__
162 (
163 "1:\n\t"
164 "lbarx %0,%y2\n\t"
165 "sub %1,%0,%3\n\t"
166 "stbcx. %1,%y2\n\t"
167 "bne- 1b\n\t"
168 : "=&b" (original), "=&b" (result), "+Z" (storage)
169 : "b" (v)
170 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
171 );
172 core_arch_operations_gcc_ppc_base::fence_after(order);
173 return result;
174 }
175
176 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
177 {
178 storage_type original, result;
179 core_arch_operations_gcc_ppc_base::fence_before(order);
180 __asm__ __volatile__
181 (
182 "1:\n\t"
183 "lbarx %0,%y2\n\t"
184 "and %1,%0,%3\n\t"
185 "stbcx. %1,%y2\n\t"
186 "bne- 1b\n\t"
187 : "=&b" (original), "=&b" (result), "+Z" (storage)
188 : "b" (v)
189 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
190 );
191 core_arch_operations_gcc_ppc_base::fence_after(order);
192 return result;
193 }
194
195 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
196 {
197 storage_type original, result;
198 core_arch_operations_gcc_ppc_base::fence_before(order);
199 __asm__ __volatile__
200 (
201 "1:\n\t"
202 "lbarx %0,%y2\n\t"
203 "or %1,%0,%3\n\t"
204 "stbcx. %1,%y2\n\t"
205 "bne- 1b\n\t"
206 : "=&b" (original), "=&b" (result), "+Z" (storage)
207 : "b" (v)
208 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
209 );
210 core_arch_operations_gcc_ppc_base::fence_after(order);
211 return result;
212 }
213
214 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
215 {
216 storage_type original, result;
217 core_arch_operations_gcc_ppc_base::fence_before(order);
218 __asm__ __volatile__
219 (
220 "1:\n\t"
221 "lbarx %0,%y2\n\t"
222 "xor %1,%0,%3\n\t"
223 "stbcx. %1,%y2\n\t"
224 "bne- 1b\n\t"
225 : "=&b" (original), "=&b" (result), "+Z" (storage)
226 : "b" (v)
227 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
228 );
229 core_arch_operations_gcc_ppc_base::fence_after(order);
230 return result;
231 }
232
233 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
234 {
235 core_arch_operations_gcc_ppc_base::fence_before(order);
236 storage_type original, result;
237 __asm__ __volatile__
238 (
239 "1:\n\t"
240 "lbarx %0,%y2\n\t"
241 "nor %1,%0,%0\n\t"
242 "stbcx. %1,%y2\n\t"
243 "bne- 1b\n\t"
244 : "=&b" (original), "=&b" (result), "+Z" (storage)
245 :
246 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
247 );
248 core_arch_operations_gcc_ppc_base::fence_after(order);
249 return original;
250 }
251
252 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
253 {
254 core_arch_operations_gcc_ppc_base::fence_before(order);
255 storage_type original, result;
256 __asm__ __volatile__
257 (
258 "1:\n\t"
259 "lbarx %0,%y2\n\t"
260 "nor %1,%0,%0\n\t"
261 "stbcx. %1,%y2\n\t"
262 "bne- 1b\n\t"
263 : "=&b" (original), "=&b" (result), "+Z" (storage)
264 :
265 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
266 );
267 core_arch_operations_gcc_ppc_base::fence_after(order);
268 return result;
269 }
270 };
271
272 template< typename Base, bool Signed >
273 struct extra_operations< Base, 1u, Signed, true > :
274 public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 1u, Signed > >
275 {
276 };
277
278 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
279
280 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
281
282 template< typename Base, bool Signed >
283 struct extra_operations_gcc_ppc< Base, 2u, Signed > :
284 public extra_operations_generic< Base, 2u, Signed >
285 {
286 typedef extra_operations_generic< Base, 2u, Signed > base_type;
287 typedef typename base_type::storage_type storage_type;
288
289 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
290 {
291 core_arch_operations_gcc_ppc_base::fence_before(order);
292 storage_type original, result;
293 __asm__ __volatile__
294 (
295 "1:\n\t"
296 "lharx %0,%y2\n\t"
297 "neg %1,%0\n\t"
298 "sthcx. %1,%y2\n\t"
299 "bne- 1b\n\t"
300 : "=&b" (original), "=&b" (result), "+Z" (storage)
301 :
302 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
303 );
304 core_arch_operations_gcc_ppc_base::fence_after(order);
305 return original;
306 }
307
308 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
309 {
310 core_arch_operations_gcc_ppc_base::fence_before(order);
311 storage_type original, result;
312 __asm__ __volatile__
313 (
314 "1:\n\t"
315 "lharx %0,%y2\n\t"
316 "neg %1,%0\n\t"
317 "sthcx. %1,%y2\n\t"
318 "bne- 1b\n\t"
319 : "=&b" (original), "=&b" (result), "+Z" (storage)
320 :
321 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
322 );
323 core_arch_operations_gcc_ppc_base::fence_after(order);
324 return result;
325 }
326
327 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
328 {
329 storage_type original, result;
330 core_arch_operations_gcc_ppc_base::fence_before(order);
331 __asm__ __volatile__
332 (
333 "1:\n\t"
334 "lharx %0,%y2\n\t"
335 "add %1,%0,%3\n\t"
336 "sthcx. %1,%y2\n\t"
337 "bne- 1b\n\t"
338 : "=&b" (original), "=&b" (result), "+Z" (storage)
339 : "b" (v)
340 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
341 );
342 core_arch_operations_gcc_ppc_base::fence_after(order);
343 return result;
344 }
345
346 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
347 {
348 storage_type original, result;
349 core_arch_operations_gcc_ppc_base::fence_before(order);
350 __asm__ __volatile__
351 (
352 "1:\n\t"
353 "lharx %0,%y2\n\t"
354 "sub %1,%0,%3\n\t"
355 "sthcx. %1,%y2\n\t"
356 "bne- 1b\n\t"
357 : "=&b" (original), "=&b" (result), "+Z" (storage)
358 : "b" (v)
359 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
360 );
361 core_arch_operations_gcc_ppc_base::fence_after(order);
362 return result;
363 }
364
365 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
366 {
367 storage_type original, result;
368 core_arch_operations_gcc_ppc_base::fence_before(order);
369 __asm__ __volatile__
370 (
371 "1:\n\t"
372 "lharx %0,%y2\n\t"
373 "and %1,%0,%3\n\t"
374 "sthcx. %1,%y2\n\t"
375 "bne- 1b\n\t"
376 : "=&b" (original), "=&b" (result), "+Z" (storage)
377 : "b" (v)
378 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
379 );
380 core_arch_operations_gcc_ppc_base::fence_after(order);
381 return result;
382 }
383
384 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
385 {
386 storage_type original, result;
387 core_arch_operations_gcc_ppc_base::fence_before(order);
388 __asm__ __volatile__
389 (
390 "1:\n\t"
391 "lharx %0,%y2\n\t"
392 "or %1,%0,%3\n\t"
393 "sthcx. %1,%y2\n\t"
394 "bne- 1b\n\t"
395 : "=&b" (original), "=&b" (result), "+Z" (storage)
396 : "b" (v)
397 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
398 );
399 core_arch_operations_gcc_ppc_base::fence_after(order);
400 return result;
401 }
402
403 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
404 {
405 storage_type original, result;
406 core_arch_operations_gcc_ppc_base::fence_before(order);
407 __asm__ __volatile__
408 (
409 "1:\n\t"
410 "lharx %0,%y2\n\t"
411 "xor %1,%0,%3\n\t"
412 "sthcx. %1,%y2\n\t"
413 "bne- 1b\n\t"
414 : "=&b" (original), "=&b" (result), "+Z" (storage)
415 : "b" (v)
416 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
417 );
418 core_arch_operations_gcc_ppc_base::fence_after(order);
419 return result;
420 }
421
422 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
423 {
424 core_arch_operations_gcc_ppc_base::fence_before(order);
425 storage_type original, result;
426 __asm__ __volatile__
427 (
428 "1:\n\t"
429 "lharx %0,%y2\n\t"
430 "nor %1,%0,%0\n\t"
431 "sthcx. %1,%y2\n\t"
432 "bne- 1b\n\t"
433 : "=&b" (original), "=&b" (result), "+Z" (storage)
434 :
435 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
436 );
437 core_arch_operations_gcc_ppc_base::fence_after(order);
438 return original;
439 }
440
441 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
442 {
443 core_arch_operations_gcc_ppc_base::fence_before(order);
444 storage_type original, result;
445 __asm__ __volatile__
446 (
447 "1:\n\t"
448 "lharx %0,%y2\n\t"
449 "nor %1,%0,%0\n\t"
450 "sthcx. %1,%y2\n\t"
451 "bne- 1b\n\t"
452 : "=&b" (original), "=&b" (result), "+Z" (storage)
453 :
454 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
455 );
456 core_arch_operations_gcc_ppc_base::fence_after(order);
457 return result;
458 }
459 };
460
461 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
462
463 template< typename Base, bool Signed >
464 struct extra_operations_gcc_ppc< Base, 4u, Signed > :
465 public extra_operations_generic< Base, 4u, Signed >
466 {
467 typedef extra_operations_generic< Base, 4u, Signed > base_type;
468 typedef typename base_type::storage_type storage_type;
469
470 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
471 {
472 core_arch_operations_gcc_ppc_base::fence_before(order);
473 storage_type original, result;
474 __asm__ __volatile__
475 (
476 "1:\n\t"
477 "lwarx %0,%y2\n\t"
478 "neg %1,%0\n\t"
479 "stwcx. %1,%y2\n\t"
480 "bne- 1b\n\t"
481 : "=&b" (original), "=&b" (result), "+Z" (storage)
482 :
483 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
484 );
485 core_arch_operations_gcc_ppc_base::fence_after(order);
486 return original;
487 }
488
489 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
490 {
491 core_arch_operations_gcc_ppc_base::fence_before(order);
492 storage_type original, result;
493 __asm__ __volatile__
494 (
495 "1:\n\t"
496 "lwarx %0,%y2\n\t"
497 "neg %1,%0\n\t"
498 "stwcx. %1,%y2\n\t"
499 "bne- 1b\n\t"
500 : "=&b" (original), "=&b" (result), "+Z" (storage)
501 :
502 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
503 );
504 core_arch_operations_gcc_ppc_base::fence_after(order);
505 return result;
506 }
507
508 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
509 {
510 storage_type original, result;
511 core_arch_operations_gcc_ppc_base::fence_before(order);
512 __asm__ __volatile__
513 (
514 "1:\n\t"
515 "lwarx %0,%y2\n\t"
516 "add %1,%0,%3\n\t"
517 "stwcx. %1,%y2\n\t"
518 "bne- 1b\n\t"
519 : "=&b" (original), "=&b" (result), "+Z" (storage)
520 : "b" (v)
521 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
522 );
523 core_arch_operations_gcc_ppc_base::fence_after(order);
524 return result;
525 }
526
527 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
528 {
529 storage_type original, result;
530 core_arch_operations_gcc_ppc_base::fence_before(order);
531 __asm__ __volatile__
532 (
533 "1:\n\t"
534 "lwarx %0,%y2\n\t"
535 "sub %1,%0,%3\n\t"
536 "stwcx. %1,%y2\n\t"
537 "bne- 1b\n\t"
538 : "=&b" (original), "=&b" (result), "+Z" (storage)
539 : "b" (v)
540 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
541 );
542 core_arch_operations_gcc_ppc_base::fence_after(order);
543 return result;
544 }
545
546 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
547 {
548 storage_type original, result;
549 core_arch_operations_gcc_ppc_base::fence_before(order);
550 __asm__ __volatile__
551 (
552 "1:\n\t"
553 "lwarx %0,%y2\n\t"
554 "and %1,%0,%3\n\t"
555 "stwcx. %1,%y2\n\t"
556 "bne- 1b\n\t"
557 : "=&b" (original), "=&b" (result), "+Z" (storage)
558 : "b" (v)
559 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
560 );
561 core_arch_operations_gcc_ppc_base::fence_after(order);
562 return result;
563 }
564
565 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
566 {
567 storage_type original, result;
568 core_arch_operations_gcc_ppc_base::fence_before(order);
569 __asm__ __volatile__
570 (
571 "1:\n\t"
572 "lwarx %0,%y2\n\t"
573 "or %1,%0,%3\n\t"
574 "stwcx. %1,%y2\n\t"
575 "bne- 1b\n\t"
576 : "=&b" (original), "=&b" (result), "+Z" (storage)
577 : "b" (v)
578 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
579 );
580 core_arch_operations_gcc_ppc_base::fence_after(order);
581 return result;
582 }
583
584 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
585 {
586 storage_type original, result;
587 core_arch_operations_gcc_ppc_base::fence_before(order);
588 __asm__ __volatile__
589 (
590 "1:\n\t"
591 "lwarx %0,%y2\n\t"
592 "xor %1,%0,%3\n\t"
593 "stwcx. %1,%y2\n\t"
594 "bne- 1b\n\t"
595 : "=&b" (original), "=&b" (result), "+Z" (storage)
596 : "b" (v)
597 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
598 );
599 core_arch_operations_gcc_ppc_base::fence_after(order);
600 return result;
601 }
602
603 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
604 {
605 core_arch_operations_gcc_ppc_base::fence_before(order);
606 storage_type original, result;
607 __asm__ __volatile__
608 (
609 "1:\n\t"
610 "lwarx %0,%y2\n\t"
611 "nor %1,%0,%0\n\t"
612 "stwcx. %1,%y2\n\t"
613 "bne- 1b\n\t"
614 : "=&b" (original), "=&b" (result), "+Z" (storage)
615 :
616 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
617 );
618 core_arch_operations_gcc_ppc_base::fence_after(order);
619 return original;
620 }
621
622 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
623 {
624 core_arch_operations_gcc_ppc_base::fence_before(order);
625 storage_type original, result;
626 __asm__ __volatile__
627 (
628 "1:\n\t"
629 "lwarx %0,%y2\n\t"
630 "nor %1,%0,%0\n\t"
631 "stwcx. %1,%y2\n\t"
632 "bne- 1b\n\t"
633 : "=&b" (original), "=&b" (result), "+Z" (storage)
634 :
635 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
636 );
637 core_arch_operations_gcc_ppc_base::fence_after(order);
638 return result;
639 }
640 };
641
642 template< typename Base, bool Signed >
643 struct extra_operations< Base, 4u, Signed, true > :
644 public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 4u, Signed > >
645 {
646 };
647
648 #if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
649
650 template< typename Base, bool Signed >
651 struct extra_operations_gcc_ppc< Base, 8u, Signed > :
652 public extra_operations_generic< Base, 8u, Signed >
653 {
654 typedef extra_operations_generic< Base, 8u, Signed > base_type;
655 typedef typename base_type::storage_type storage_type;
656
657 static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
658 {
659 core_arch_operations_gcc_ppc_base::fence_before(order);
660 storage_type original, result;
661 __asm__ __volatile__
662 (
663 "1:\n\t"
664 "ldarx %0,%y2\n\t"
665 "neg %1,%0\n\t"
666 "stdcx. %1,%y2\n\t"
667 "bne- 1b\n\t"
668 : "=&b" (original), "=&b" (result), "+Z" (storage)
669 :
670 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
671 );
672 core_arch_operations_gcc_ppc_base::fence_after(order);
673 return original;
674 }
675
676 static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
677 {
678 core_arch_operations_gcc_ppc_base::fence_before(order);
679 storage_type original, result;
680 __asm__ __volatile__
681 (
682 "1:\n\t"
683 "ldarx %0,%y2\n\t"
684 "neg %1,%0\n\t"
685 "stdcx. %1,%y2\n\t"
686 "bne- 1b\n\t"
687 : "=&b" (original), "=&b" (result), "+Z" (storage)
688 :
689 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
690 );
691 core_arch_operations_gcc_ppc_base::fence_after(order);
692 return result;
693 }
694
695 static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
696 {
697 storage_type original, result;
698 core_arch_operations_gcc_ppc_base::fence_before(order);
699 __asm__ __volatile__
700 (
701 "1:\n\t"
702 "ldarx %0,%y2\n\t"
703 "add %1,%0,%3\n\t"
704 "stdcx. %1,%y2\n\t"
705 "bne- 1b\n\t"
706 : "=&b" (original), "=&b" (result), "+Z" (storage)
707 : "b" (v)
708 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
709 );
710 core_arch_operations_gcc_ppc_base::fence_after(order);
711 return result;
712 }
713
714 static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
715 {
716 storage_type original, result;
717 core_arch_operations_gcc_ppc_base::fence_before(order);
718 __asm__ __volatile__
719 (
720 "1:\n\t"
721 "ldarx %0,%y2\n\t"
722 "sub %1,%0,%3\n\t"
723 "stdcx. %1,%y2\n\t"
724 "bne- 1b\n\t"
725 : "=&b" (original), "=&b" (result), "+Z" (storage)
726 : "b" (v)
727 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
728 );
729 core_arch_operations_gcc_ppc_base::fence_after(order);
730 return result;
731 }
732
733 static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
734 {
735 storage_type original, result;
736 core_arch_operations_gcc_ppc_base::fence_before(order);
737 __asm__ __volatile__
738 (
739 "1:\n\t"
740 "ldarx %0,%y2\n\t"
741 "and %1,%0,%3\n\t"
742 "stdcx. %1,%y2\n\t"
743 "bne- 1b\n\t"
744 : "=&b" (original), "=&b" (result), "+Z" (storage)
745 : "b" (v)
746 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
747 );
748 core_arch_operations_gcc_ppc_base::fence_after(order);
749 return result;
750 }
751
752 static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
753 {
754 storage_type original, result;
755 core_arch_operations_gcc_ppc_base::fence_before(order);
756 __asm__ __volatile__
757 (
758 "1:\n\t"
759 "ldarx %0,%y2\n\t"
760 "or %1,%0,%3\n\t"
761 "stdcx. %1,%y2\n\t"
762 "bne- 1b\n\t"
763 : "=&b" (original), "=&b" (result), "+Z" (storage)
764 : "b" (v)
765 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
766 );
767 core_arch_operations_gcc_ppc_base::fence_after(order);
768 return result;
769 }
770
771 static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
772 {
773 storage_type original, result;
774 core_arch_operations_gcc_ppc_base::fence_before(order);
775 __asm__ __volatile__
776 (
777 "1:\n\t"
778 "ldarx %0,%y2\n\t"
779 "xor %1,%0,%3\n\t"
780 "stdcx. %1,%y2\n\t"
781 "bne- 1b\n\t"
782 : "=&b" (original), "=&b" (result), "+Z" (storage)
783 : "b" (v)
784 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
785 );
786 core_arch_operations_gcc_ppc_base::fence_after(order);
787 return result;
788 }
789
790 static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
791 {
792 core_arch_operations_gcc_ppc_base::fence_before(order);
793 storage_type original, result;
794 __asm__ __volatile__
795 (
796 "1:\n\t"
797 "ldarx %0,%y2\n\t"
798 "nor %1,%0,%0\n\t"
799 "stdcx. %1,%y2\n\t"
800 "bne- 1b\n\t"
801 : "=&b" (original), "=&b" (result), "+Z" (storage)
802 :
803 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
804 );
805 core_arch_operations_gcc_ppc_base::fence_after(order);
806 return original;
807 }
808
809 static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
810 {
811 core_arch_operations_gcc_ppc_base::fence_before(order);
812 storage_type original, result;
813 __asm__ __volatile__
814 (
815 "1:\n\t"
816 "ldarx %0,%y2\n\t"
817 "nor %1,%0,%0\n\t"
818 "stdcx. %1,%y2\n\t"
819 "bne- 1b\n\t"
820 : "=&b" (original), "=&b" (result), "+Z" (storage)
821 :
822 : BOOST_ATOMIC_DETAIL_ASM_CLOBBER_CC
823 );
824 core_arch_operations_gcc_ppc_base::fence_after(order);
825 return result;
826 }
827 };
828
829 template< typename Base, bool Signed >
830 struct extra_operations< Base, 8u, Signed, true > :
831 public extra_operations_gcc_ppc_common< extra_operations_gcc_ppc< Base, 8u, Signed > >
832 {
833 };
834
835 #endif // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
836
837 } // namespace detail
838 } // namespace atomics
839 } // namespace boost
840
841 #include <boost/atomic/detail/footer.hpp>
842
843 #endif // BOOST_ATOMIC_DETAIL_EXTRA_OPS_GCC_ARM_PPC_INCLUDED_