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