|
6 | 6 | // - portable-atomic https://github.com/taiki-e/portable-atomic
|
7 | 7 | //
|
8 | 8 | // Generated asm:
|
9 |
| -// - s390x https://godbolt.org/z/7KzrMqW9e |
| 9 | +// - s390x https://godbolt.org/z/vh6x8rTjb |
| 10 | +// - s390x (z196) https://godbolt.org/z/fve3761z3 |
10 | 11 |
|
11 | 12 | use core::{
|
12 | 13 | arch::asm,
|
@@ -66,33 +67,35 @@ macro_rules! atomic_load_store {
|
66 | 67 |
|
67 | 68 | // SAFETY: the caller must uphold the safety contract.
|
68 | 69 | unsafe {
|
69 |
| - match order { |
70 |
| - // Relaxed and Release stores are equivalent. |
71 |
| - Ordering::Relaxed | Ordering::Release => { |
72 |
| - asm!( |
73 |
| - // load from val to r0 |
74 |
| - concat!("l", $asm_suffix, " %r0, 0({val})"), |
75 |
| - // (atomic) store r0 to dst |
76 |
| - concat!("st", $st_suffix, " %r0, 0({dst})"), |
77 |
| - dst = in(reg) dst, |
78 |
| - val = in(reg) val, |
79 |
| - out("r0") _, |
80 |
| - options(nostack, preserves_flags), |
81 |
| - ); |
82 |
| - } |
83 |
| - Ordering::SeqCst => { |
| 70 | + macro_rules! atomic_store { |
| 71 | + ($fence:tt) => { |
84 | 72 | asm!(
|
85 | 73 | // load from val to r0
|
86 | 74 | concat!("l", $asm_suffix, " %r0, 0({val})"),
|
87 | 75 | // (atomic) store r0 to dst
|
88 | 76 | concat!("st", $st_suffix, " %r0, 0({dst})"),
|
89 |
| - "bcr 15, %r0", |
| 77 | + $fence, |
90 | 78 | dst = in(reg) dst,
|
91 | 79 | val = in(reg) val,
|
92 | 80 | out("r0") _,
|
93 | 81 | options(nostack, preserves_flags),
|
94 |
| - ); |
95 |
| - }, |
| 82 | + ) |
| 83 | + }; |
| 84 | + } |
| 85 | + match order { |
| 86 | + // Relaxed and Release stores are equivalent. |
| 87 | + Ordering::Relaxed | Ordering::Release => atomic_store!(""), |
| 88 | + // bcr 14,0 (fast-BCR-serialization) requires z196 or later. |
| 89 | + #[cfg(any( |
| 90 | + target_feature = "fast-serialization", |
| 91 | + atomic_maybe_uninit_target_feature = "fast-serialization", |
| 92 | + ))] |
| 93 | + Ordering::SeqCst => atomic_store!("bcr 14, 0"), |
| 94 | + #[cfg(not(any( |
| 95 | + target_feature = "fast-serialization", |
| 96 | + atomic_maybe_uninit_target_feature = "fast-serialization", |
| 97 | + )))] |
| 98 | + Ordering::SeqCst => atomic_store!("bcr 15, 0"), |
96 | 99 | _ => unreachable!("{:?}", order),
|
97 | 100 | }
|
98 | 101 | }
|
@@ -465,39 +468,38 @@ macro_rules! atomic128 {
|
465 | 468 |
|
466 | 469 | // SAFETY: the caller must uphold the safety contract.
|
467 | 470 | unsafe {
|
468 |
| - match order { |
469 |
| - // Relaxed and Release stores are equivalent. |
470 |
| - Ordering::Relaxed | Ordering::Release => { |
| 471 | + macro_rules! atomic_store { |
| 472 | + ($fence:tt) => { |
471 | 473 | asm!(
|
472 | 474 | // load from val to r0-r1 pair
|
473 | 475 | "lg %r1, 8({val})",
|
474 | 476 | "lg %r0, 0({val})",
|
475 | 477 | // (atomic) store r0-r1 pair to dst
|
476 | 478 | "stpq %r0, 0({dst})",
|
| 479 | + $fence, |
477 | 480 | dst = in(reg) dst,
|
478 | 481 | val = in(reg) val,
|
479 | 482 | // Quadword atomic instructions work with even/odd pair of specified register and subsequent register.
|
480 | 483 | out("r0") _,
|
481 | 484 | out("r1") _,
|
482 | 485 | options(nostack, preserves_flags),
|
483 |
| - ); |
484 |
| - } |
485 |
| - Ordering::SeqCst => { |
486 |
| - asm!( |
487 |
| - // load from val to r0-r1 pair |
488 |
| - "lg %r1, 8({val})", |
489 |
| - "lg %r0, 0({val})", |
490 |
| - // (atomic) store r0-r1 pair to dst |
491 |
| - "stpq %r0, 0({dst})", |
492 |
| - "bcr 15, %r0", |
493 |
| - dst = in(reg) dst, |
494 |
| - val = in(reg) val, |
495 |
| - // Quadword atomic instructions work with even/odd pair of specified register and subsequent register. |
496 |
| - out("r0") _, |
497 |
| - out("r1") _, |
498 |
| - options(nostack, preserves_flags), |
499 |
| - ); |
500 |
| - } |
| 486 | + ) |
| 487 | + }; |
| 488 | + } |
| 489 | + match order { |
| 490 | + // Relaxed and Release stores are equivalent. |
| 491 | + Ordering::Relaxed | Ordering::Release => atomic_store!(""), |
| 492 | + // bcr 14,0 (fast-BCR-serialization) requires z196 or later. |
| 493 | + #[cfg(any( |
| 494 | + target_feature = "fast-serialization", |
| 495 | + atomic_maybe_uninit_target_feature = "fast-serialization", |
| 496 | + ))] |
| 497 | + Ordering::SeqCst => atomic_store!("bcr 14, 0"), |
| 498 | + #[cfg(not(any( |
| 499 | + target_feature = "fast-serialization", |
| 500 | + atomic_maybe_uninit_target_feature = "fast-serialization", |
| 501 | + )))] |
| 502 | + Ordering::SeqCst => atomic_store!("bcr 15, 0"), |
501 | 503 | _ => unreachable!("{:?}", order),
|
502 | 504 | }
|
503 | 505 | }
|
|
0 commit comments