Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ unexpected_cfgs = { level = "warn", check-cfg = [
'cfg(target_feature,values("lse2","lse128","rcpc3"))', # 1.82+ https://github.com/rust-lang/rust/pull/128192
'cfg(target_feature,values("partword-atomics","quadword-atomics"))', # 1.83+ https://github.com/rust-lang/rust/pull/130873
'cfg(target_feature,values("zaamo","zabha","zalrsc"))', # 1.83+ https://github.com/rust-lang/rust/pull/130877
'cfg(target_feature,values("leoncasa","v9"))', # 1.84+ https://github.com/rust-lang/rust/pull/132552
'cfg(target_feature,values("leoncasa","v8plus","v9"))', # 1.84+ https://github.com/rust-lang/rust/pull/132552
Comment thread
taiki-e marked this conversation as resolved.
'cfg(target_feature,values("x87"))', # 1.85+ https://github.com/rust-lang/rust/pull/133099
'cfg(target_feature,values("isa-68020"))', # 1.85+ https://github.com/rust-lang/rust/pull/134329
'cfg(target_feature,values("zacas"))', # 1.87+ https://github.com/rust-lang/rust/pull/137417
Expand Down
54 changes: 29 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ This crate provides a way to soundly perform such operations.

## Platform Support

Currently, all CPU architectures supported by Rust (x86, x86_64, Arm, AArch64, RISC-V, LoongArch, Arm64EC, s390x, MIPS, PowerPC, MSP430, AVR, SPARC, Hexagon, M68k, C-SKY, and Xtensa) are supported.
(You can use `cfg_{has,no}_*` macros to write code based on whether or not which size of primitives is available.)
Currently, all CPU architectures supported by Rust (x86, x86_64, Arm, AArch64, Arm64EC, RISC-V, LoongArch, s390x, PowerPC, MIPS, SPARC, AVR, MSP430, Hexagon, M68k, C-SKY, and Xtensa) are supported.
(You can use `cfg_{has,no}_*` macros to write code based on which primitive sizes are available for the current target and Rust version.)

| target_arch | primitives | load/store | swap/CAS |
| ------------------------------------------- | --------------------------------------------------- |:----------:|:--------:|
Expand All @@ -30,39 +30,43 @@ Currently, all CPU architectures supported by Rust (x86, x86_64, Arm, AArch64, R
| 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 | ✓ | ✓ |
| arm64ec \[10] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 | ✓ | ✓ |
| riscv32 | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |
| riscv32 (+zacas) \[4] | i64,u64 | ✓ | ✓ |
| riscv64 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓\[1] |
| riscv64 (+zacas) \[4] | i128,u128 | ✓ | ✓ |
| loongarch64 | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| loongarch32 \[8] | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓ |
| arm64ec \[7] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 | ✓ | ✓ |
| s390x \[7] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 | ✓ | ✓ |
| powerpc \[9] | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓ |
| powerpc64 \[9] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| powerpc64 (+quadword-atomics) \[5] \[9] | i128,u128 | ✓ | ✓ |
| mips / mips32r6 \[10] | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓ |
| mips64 / mips64r6 \[10] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| msp430 \[10] (experimental) | isize,usize,i8,u8,i16,u16 | ✓ | ✓ |
| avr \[10] (experimental) | isize,usize,i8,u8,i16,u16 | ✓ | ✓ |
| sparc \[10] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |
| sparc64 \[10] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| hexagon \[10] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| m68k \[10] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |
| m68k (+isa-68020) \[6] \[10] (experimental) | i64,u64 | ✓ | ✓ |
| csky \[10] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |
| xtensa \[10] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |
| loongarch32 \[11] | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓ |
| s390x \[10] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64,i128,u128 | ✓ | ✓ |
| powerpc \[12] | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓ |
| powerpc64 \[12] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| powerpc64 (+quadword-atomics) \[6] \[12] | i128,u128 | ✓ | ✓ |
| mips / mips32r6 \[13] | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓ |
| mips64 / mips64r6 \[13] | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| sparc \[13] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |
| sparc (+v8plus) \[8] \[13] (experimental) | i64,u64 | ✓ | ✓ |
| sparc64 \[13] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| avr \[13] (experimental) | isize,usize,i8,u8,i16,u16 | ✓ | ✓ |
| msp430 \[13] (experimental) | isize,usize,i8,u8,i16,u16 | ✓ | ✓ |
| hexagon \[13] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32,i64,u64 | ✓ | ✓ |
| m68k \[13] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |
| m68k (+isa-68020) \[9] \[13] (experimental) | i64,u64 | ✓ | ✓ |
| csky \[13] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |
| xtensa \[13] (experimental) | isize,usize,i8,u8,i16,u16,i32,u32 | ✓ | ✓\[1] |

\[1] Arm's RMW operations are not available on Armv6-M (thumbv6m). RISC-V's RMW operations are not available on targets without the A (or G which means IMAFD) or Zalrsc or Zacas extension, such as riscv32i, riscv32imc, etc. 32-bit SPARC's RMW operations requires `v9` or `leoncasa` target feature (enabled by default on Linux). M68k's atomic RMW operations requires target-cpu M68020+ (enabled by default on Linux). C-SKY's atomic RMW operations requires target-cpu ck860\* or c860\* (enabled by default on the hard-float target). Xtensa's atomic RMW operations are not available on esp32s2.<br>
\[2] Requires `cmpxchg16b` target feature (enabled by default on Apple, Windows (except Windows 7), and Fuchsia targets).<br>
\[3] Armv6+ or Linux/Android, except for M-profile architecture such as thumbv6m, thumbv7m, etc.<br>
\[4] Requires `zacas` target feature.<br>
\[5] Requires `quadword-atomics` target feature (enabled by default on powerpc64le).<br>
\[6] Requires target-cpu M68020+ (enabled by default on Linux).<br>
\[7] Requires Rust 1.84+.<br>
\[8] Requires Rust 1.91+.<br>
\[9] Requires Rust 1.95+.<br>
\[10] Requires nightly due to `#![feature(asm_experimental_arch)]`.<br>
\[6] Requires `quadword-atomics` target feature (enabled by default on powerpc64le).<br>
\[8] Requires `v9` and `v8plus` target features (both enabled by default on Linux).<br>
\[9] Requires target-cpu M68020+ (enabled by default on Linux).<br>
\[10] Requires Rust 1.84+.<br>
\[11] Requires Rust 1.91+.<br>
\[12] Requires Rust 1.95+.<br>
\[13] Requires nightly due to `#![feature(asm_experimental_arch)]`.<br>
<!-- loongarch64: \[5] Requires `scq` target feature.<br> -->
<!-- mips32r6/mips64r6: \[7] Requires Release 6 Paired LL/SC family of instructions.<br> -->

See also [Atomic operation overview by architecture](https://github.com/taiki-e/atomic-maybe-uninit/blob/HEAD/src/arch/README.md)
for more information about atomic operations in these architectures.
Expand Down
13 changes: 9 additions & 4 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ fn main() {
// 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/'
println!(
r#"cargo:rustc-check-cfg=cfg(atomic_maybe_uninit_target_feature,values("a","fast-serialization","isa-68020","leoncasa","lowbytefirst","lse128","lse2","mclass","msync","partword-atomics","quadword-atomics","rcpc3","rmw","thumb-mode","thumb2","tinyencoding","v5te","v6","v7","v8","v8m","v9","x87","zaamo","zabha","zacas","zalrsc"))"#
r#"cargo:rustc-check-cfg=cfg(atomic_maybe_uninit_target_feature,values("a","fast-serialization","isa-68020","leoncasa","lowbytefirst","lse128","lse2","mclass","msync","partword-atomics","quadword-atomics","rcpc3","rmw","thumb-mode","thumb2","tinyencoding","v5te","v6","v7","v8","v8m","v8plus","v9","x87","zaamo","zabha","zacas","zalrsc"))"#
);
}

Expand Down Expand Up @@ -442,6 +442,7 @@ fn main() {
let mut leoncasa = false;
let mut v9 = false;
let mut v7 = false;
let is_linux_or_solaris = target_os == "linux" || target_os == "solaris";
if let Some(cpu) = target_cpu() {
// https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/llvm/lib/Target/Sparc/Sparc.td#L143
match &*cpu {
Expand All @@ -450,21 +451,25 @@ fn main() {
| "ma2480" | "ma2485" | "ma2x8x" | "gr712rc" | "leon4" | "gr740" => {
leoncasa = true;
}
// v8plus is ABI feature so not associated with -C target-cpu.
"v9" | "ultrasparc" | "ultrasparc3" | "niagara" | "niagara2" | "niagara3"
| "niagara4" => v9 = true,
"v7" => v7 = true,
_ => {}
}
} else {
// https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0-rc1/clang/lib/Driver/ToolChains/Arch/Sparc.cpp#L136
// https://github.com/rust-lang/rust/blob/1.90.0/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs#L19
v9 = target_os == "linux" || target_os == "solaris";
// https://github.com/rust-lang/rust/blob/1.94.0/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs#L19
// https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0/clang/lib/Driver/ToolChains/Arch/Sparc.cpp#L169
v9 = is_linux_or_solaris;
}
// target_feature "leoncasa"/"v9" is unstable and available on rustc side since nightly-2024-11-11: https://github.com/rust-lang/rust/pull/132552
// Note: nightly-2024-11-10 is unavailable: https://github.com/rust-lang/rust/issues/132838
if !version.probe(84, 2024, 11, 10) || needs_target_feature_fallback(&version, None) {
target_feature_fallback("leoncasa", leoncasa);
target_feature_fallback("v9", v9);
// https://github.com/rust-lang/rust/blob/1.94.0/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs#L18
// https://github.com/llvm/llvm-project/blob/llvmorg-22.1.0/clang/lib/Driver/ToolChains/Arch/Sparc.cpp#L170
target_feature_fallback("v8plus", is_linux_or_solaris);
}
if v7 {
// SPARC-V7 has no STBAR.
Expand Down
Loading
Loading