Skip to content

Commit

Permalink
Update to stabilized s390x asm
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Nov 11, 2024
1 parent c9b0810 commit c9d7286
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 536 deletions.
8 changes: 3 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,9 @@ jobs:
# - rust: nightly
# target: riscv64gc-unknown-linux-gnu
# flags: -Z codegen-backend=cranelift
- rust: nightly-2023-08-24 # Rust 1.74, LLVM 17 (oldest version we can use asm_experimental_arch on this target)
target: s390x-unknown-linux-gnu
- rust: nightly-2024-01-04 # Rust 1.77, LLVM 17 (last version that does not support reg_addr register class)
target: s390x-unknown-linux-gnu
- rust: nightly-2024-01-05 # Rust 1.77, LLVM 17 (oldest version that supports reg_addr register class)
# - rust: '1.84' # LLVM 19 (oldest stable version we can use asm on this target)
# target: s390x-unknown-linux-gnu
- rust: nightly-2024-01-05 # Rust 1.77, LLVM 17 (oldest version we can use asm_experimental_arch on this target)
target: s390x-unknown-linux-gnu
- rust: nightly
target: s390x-unknown-linux-gnu
Expand Down
71 changes: 36 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,42 @@ This crate provides a way to soundly perform such operations.

## Platform Support

Currently, x86, x86_64, Arm, AArch64, RISC-V, LoongArch64, MIPS32, MIPS64, PowerPC, s390x, MSP430, Arm64EC, AVR, SPARC, Hexagon, M68k, and Xtensa are supported.

| target_arch | primitives | load/store | swap/CAS |
| -------------------------------- | --------------------------------------------------- |:----------:|:--------:|
| x86 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| x86_64 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| x86_64 (+cmpxchg16b) \[5] | i128,u128 |||
| arm (v6+ or Linux/Android) | isize,usize,i8,u8,i16,u16,i32,u32 ||\[1] |
| arm (except for M-profile) \[2] | i64,u64 |||
| aarch64 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 |||
| riscv32 | isize,usize,i8,u8,i16,u16,i32,u32 ||\[1] |
| riscv64 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 ||\[1] |
| loongarch64 \[3] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| mips / mips32r6 \[4] | isize,usize,i8,u8,i16,u16,i32,u32 |||
| mips64 / mips64r6 \[4] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| powerpc \[4] | isize,usize,i8,u8,i16,u16,i32,u32 |||
| powerpc64 \[4] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| powerpc64 (pwr8+) \[4] \[6] | i128,u128 |||
| s390x \[4] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 |||
| arm64ec \[4] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 |||
| msp430 \[4] (experimental) | isize,usize,i8,u8,i16,u16 |||
| avr \[4] (experimental) | isize,usize,i8,u8,i16,u16 |||
| sparc \[4] \[7] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 |||
| sparc64 \[4] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| hexagon \[4] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| m68k \[4] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 ||\[1] |
| xtensa \[4] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 ||\[1] |

\[1] Arm's atomic RMW operations are not available on v6-m (thumbv6m). RISC-V's atomic RMW operations are not available on targets without the A (or G which means IMAFD) extension such as riscv32i, riscv32imc, etc. M68k's atomic RMW operations requires M68020+ (Linux is M68020+ by default). Xtensa's atomic RMW operations are not available on esp32s2.<br>
\[2] Armv6+ or Linux/Android, except for M-profile architecture such as thumbv6m, thumbv7m, etc.<br>
\[3] Requires Rust 1.72+.<br>
\[4] Requires nightly due to `#![feature(asm_experimental_arch)]`.<br>
\[5] Requires cmpxchg16b target feature (enabled by default on Apple and Windows (except Windows 7) targets).<br>
\[6] Requires target-cpu pwr8+ (powerpc64le is pwr8 by default).<br>
\[7] Requires CAS instruction support.<br>
Currently, x86, x86_64, Arm, AArch64, RISC-V, LoongArch64, s390x, Arm64EC, MIPS, PowerPC, MSP430, AVR, SPARC, Hexagon, M68k, and Xtensa are supported.

| target_arch | primitives | load/store | swap/CAS |
| ------------------------------- | --------------------------------------------------- |:----------:|:--------:|
| x86 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| x86_64 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| x86_64 (+cmpxchg16b) \[2] | i128,u128 |||
| arm (v6+ or Linux/Android) | isize,usize,i8,u8,i16,u16,i32,u32 ||\[1] |
| arm (except for M-profile) \[3] | i64,u64 |||
| aarch64 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 |||
| riscv32 | isize,usize,i8,u8,i16,u16,i32,u32 ||\[1] |
| riscv64 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 ||\[1] |
| loongarch64 \[6] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| s390x \[7] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 |||
| arm64ec \[8] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 |||
| mips / mips32r6 \[8] | isize,usize,i8,u8,i16,u16,i32,u32 |||
| mips64 / mips64r6 \[8] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| powerpc \[8] | isize,usize,i8,u8,i16,u16,i32,u32 |||
| powerpc64 \[8] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| powerpc64 (pwr8+) \[4] \[8] | i128,u128 |||
| msp430 \[8] (experimental) | isize,usize,i8,u8,i16,u16 |||
| avr \[8] (experimental) | isize,usize,i8,u8,i16,u16 |||
| sparc \[5] \[8] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 |||
| sparc64 \[8] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| hexagon \[8] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 |||
| m68k \[8] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 ||\[1] |
| xtensa \[8] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 ||\[1] |

\[1] Arm's atomic RMW operations are not available on v6-m (thumbv6m). RISC-V's atomic RMW operations are not available on targets without the A (or G which means IMAFD) extension such as riscv32i, riscv32imc, etc. M68k's atomic RMW operations requires target-cpu M68020+ (Linux is M68020 by default). Xtensa's atomic RMW operations are not available on esp32s2.<br>
\[2] Requires `cmpxchg16b` target feature (enabled by default on Apple and Windows (except Windows 7) targets).<br>
\[3] Armv6+ or Linux/Android, except for M-profile architecture such as thumbv6m, thumbv7m, etc.<br>
\[4] Requires `quadword-atomics` target feature (enabled by default on powerpc64le).<br>
\[5] Requires `v9` or `leoncasa` target feature (enabled by default on Linux).<br>
\[6] Requires Rust 1.72+.<br>
\[7] Requires Rust 1.84+.<br>
\[8] Requires nightly due to `#![feature(asm_experimental_arch)]`.<br>

Feel free to submit an issue if your target is not supported yet.

Expand Down
37 changes: 21 additions & 16 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ fn main() {
// Custom cfgs set by build script. Not public API.
// grep -F 'cargo:rustc-cfg=' build.rs | grep -Ev '^ *//' | sed -E 's/^.*cargo:rustc-cfg=//; s/(=\\)?".*$//' | LC_ALL=C sort -u | tr '\n' ',' | sed -E 's/,$/\n/'
println!(
"cargo:rustc-check-cfg=cfg(atomic_maybe_uninit_no_asm_maybe_uninit,atomic_maybe_uninit_no_const_fn_trait_bound,atomic_maybe_uninit_no_const_mut_refs,atomic_maybe_uninit_no_loongarch64_asm,atomic_maybe_uninit_s390x_no_reg_addr,atomic_maybe_uninit_target_feature,atomic_maybe_uninit_unstable_asm_experimental_arch,portable_atomic_pre_llvm_20)"
"cargo:rustc-check-cfg=cfg(atomic_maybe_uninit_no_asm,atomic_maybe_uninit_no_asm_maybe_uninit,atomic_maybe_uninit_no_const_fn_trait_bound,atomic_maybe_uninit_no_const_mut_refs,atomic_maybe_uninit_target_feature,atomic_maybe_uninit_unstable_asm_experimental_arch,portable_atomic_pre_llvm_20)"
);
// TODO: handle multi-line target_feature_fallback
// grep -F 'target_feature_fallback("' build.rs | grep -Ev '^ *//' | sed -E 's/^.*target_feature_fallback\(//; s/",.*$/"/' | LC_ALL=C sort -u | tr '\n' ',' | sed -E 's/,$/\n/'
Expand Down Expand Up @@ -84,8 +84,26 @@ fn main() {

match target_arch {
"loongarch64" => {
// asm! on LoongArch64 stabilized in Rust 1.72
if version.minor < 72 {
println!("cargo:rustc-cfg=atomic_maybe_uninit_no_loongarch64_asm");
println!("cargo:rustc-cfg=atomic_maybe_uninit_no_asm");
}
}
"s390x" => {
// asm! on s390x stabilized in Rust 1.84 (nightly-2024-11-11): /~https://github.com/rust-lang/rust/pull/131258
if !version.probe(84, 2024, 11, 10) {
if version.nightly
&& version.probe(77, 2024, 1, 4)
&& is_allowed_feature("asm_experimental_arch")
{
// /~https://github.com/rust-lang/rust/pull/119431 merged in Rust 1.77 (nightly-2024-01-05).
// The part of this feature we use has not been changed since nightly-2024-01-05
// until it was stabilized in nightly-2024-11-11, so it can be safely enabled in
// nightly, which is older than nightly-2024-11-11.
println!("cargo:rustc-cfg=atomic_maybe_uninit_unstable_asm_experimental_arch");
} else {
println!("cargo:rustc-cfg=atomic_maybe_uninit_no_asm");
}
}
}
"arm64ec" | "avr" | "hexagon" | "m68k" | "mips" | "mips32r6" | "mips64" | "mips64r6"
Expand All @@ -94,21 +112,8 @@ fn main() {
println!("cargo:rustc-cfg=atomic_maybe_uninit_unstable_asm_experimental_arch");
}
}
// /~https://github.com/rust-lang/rust/pull/111331 merged in Rust 1.71 (nightly-2023-05-09).
"s390x" => {
if version.nightly
&& version.probe(71, 2023, 5, 8)
&& is_allowed_feature("asm_experimental_arch")
{
// /~https://github.com/rust-lang/rust/pull/119431 merged in Rust 1.77 (nightly-2024-01-05).
if !version.probe(77, 2024, 1, 4) {
println!("cargo:rustc-cfg=atomic_maybe_uninit_s390x_no_reg_addr");
}
println!("cargo:rustc-cfg=atomic_maybe_uninit_unstable_asm_experimental_arch");
}
}
// /~https://github.com/rust-lang/rust/pull/132472 merged in Rust 1.84 (nightly-2024-11-08).
"sparc" | "sparc64" => {
// /~https://github.com/rust-lang/rust/pull/132472 merged in Rust 1.84 (nightly-2024-11-08).
if version.nightly
&& version.probe(84, 2024, 11, 7)
&& is_allowed_feature("asm_experimental_arch")
Expand Down
5 changes: 2 additions & 3 deletions src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
target_arch = "riscv32",
target_arch = "riscv64",
target_arch = "loongarch64",
all(target_arch = "s390x", not(atomic_maybe_uninit_no_asm)),
all(
any(
target_arch = "arm64ec",
Expand All @@ -38,7 +39,6 @@
target_arch = "msp430",
target_arch = "powerpc",
target_arch = "powerpc64",
target_arch = "s390x",
all(
target_arch = "sparc",
any(
Expand Down Expand Up @@ -115,8 +115,7 @@ mod powerpc;
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
mod riscv;
#[cfg(target_arch = "s390x")]
#[cfg(atomic_maybe_uninit_unstable_asm_experimental_arch)]
#[cfg_attr(atomic_maybe_uninit_s390x_no_reg_addr, path = "s390x_no_reg_addr.rs")]
#[cfg(not(atomic_maybe_uninit_no_asm))]
mod s390x;
#[cfg(any(
all(
Expand Down
Loading

0 comments on commit c9d7286

Please sign in to comment.