diff --git a/src/imp/atomic128/README.md b/src/imp/atomic128/README.md
index 3657add5..00a467e8 100644
--- a/src/imp/atomic128/README.md
+++ b/src/imp/atomic128/README.md
@@ -6,8 +6,8 @@ Here is the table of targets that support 128-bit atomics and the instructions u
| target_arch | load | store | CAS | RMW | note |
| ----------- | ---- | ----- | --- | --- | ---- |
-| x86_64 | cmpxchg16b or vmovdqa | cmpxchg16b or vmovdqa | cmpxchg16b | cmpxchg16b | cmpxchg16b target feature required. vmovdqa requires Intel or AMD CPU with AVX.
Both compile-time and run-time detection are supported for cmpxchg16b. vmovdqa is currently run-time detection only.
Requires rustc 1.59+ when cmpxchg16b target feature is enabled at compile-time, otherwise requires rustc 1.69+ |
-| aarch64 | ldxp/stxp or casp or ldp/ldiapp | ldxp/stxp or casp or stp/stilp/swpp | ldxp/stxp or casp | ldxp/stxp or casp/swpp/ldclrp/ldsetp | casp requires lse target feature, ldp/stp requires lse2 target feature, ldiapp/stilp requires lse2 and rcpc3 target features, swpp/ldclrp/ldsetp requires lse128 target feature.
Both compile-time and run-time detection are supported for lse. Others are currently compile-time detection only.
Requires rustc 1.59+ |
+| x86_64 | cmpxchg16b or vmovdqa | cmpxchg16b or vmovdqa | cmpxchg16b | cmpxchg16b | cmpxchg16b target feature required. vmovdqa requires Intel or AMD CPU with AVX.
Both compile-time and run-time detection are supported for cmpxchg16b. vmovdqa is currently run-time detection only.
Requires rustc 1.59+ when cmpxchg16b target feature is enabled at compile-time, otherwise requires rustc 1.69+ |
+| aarch64 | ldxp/stxp or casp or ldp/ldiapp | ldxp/stxp or casp or stp/stilp/swpp | ldxp/stxp or casp | ldxp/stxp or casp/swpp/ldclrp/ldsetp | casp requires lse target feature, ldp/stp requires lse2 target feature, ldiapp/stilp requires lse2 and rcpc3 target features, swpp/ldclrp/ldsetp requires lse128 target feature.
Both compile-time and run-time detection are supported for lse and lse2. Others are currently compile-time detection only.
Requires rustc 1.59+ |
| powerpc64 | lq | stq | lqarx/stqcx. | lqarx/stqcx. | Requires target-cpu pwr8+ (powerpc64le is pwr8 by default). Both compile-time and run-time detection are supported (run-time detection is currently disabled by default).
Requires nightly |
| s390x | lpq | stpq | cdsg | cdsg | Requires nightly |
diff --git a/src/imp/atomic128/aarch64.rs b/src/imp/atomic128/aarch64.rs
index 27cc8ed3..00dfca5e 100644
--- a/src/imp/atomic128/aarch64.rs
+++ b/src/imp/atomic128/aarch64.rs
@@ -68,7 +68,13 @@ include!("macros.rs");
// On musl with static linking, it seems that getauxval is not always available.
// See detect/auxv.rs for more.
#[cfg(not(portable_atomic_no_outline_atomics))]
-#[cfg(any(test, not(any(target_feature = "lse", portable_atomic_target_feature = "lse"))))]
+#[cfg(any(
+ test,
+ not(all(
+ any(target_feature = "lse2", portable_atomic_target_feature = "lse2"),
+ any(target_feature = "lse", portable_atomic_target_feature = "lse"),
+ )),
+))]
#[cfg(any(
all(
target_os = "linux",
@@ -84,7 +90,13 @@ include!("macros.rs");
#[path = "detect/auxv.rs"]
mod detect;
#[cfg(not(portable_atomic_no_outline_atomics))]
-#[cfg(any(test, not(any(target_feature = "lse", portable_atomic_target_feature = "lse"))))]
+#[cfg(any(
+ test,
+ not(all(
+ any(target_feature = "lse2", portable_atomic_target_feature = "lse2"),
+ any(target_feature = "lse", portable_atomic_target_feature = "lse"),
+ )),
+))]
#[cfg(any(target_os = "netbsd", target_os = "openbsd"))]
#[path = "detect/aarch64_aa64reg.rs"]
mod detect;
@@ -154,6 +166,43 @@ macro_rules! debug_assert_lse {
}
};
}
+#[rustfmt::skip]
+#[cfg(any(
+ target_feature = "lse2",
+ portable_atomic_target_feature = "lse2",
+ not(portable_atomic_no_outline_atomics),
+))]
+macro_rules! debug_assert_lse2 {
+ () => {
+ #[cfg(all(
+ not(portable_atomic_no_outline_atomics),
+ any(
+ all(
+ target_os = "linux",
+ any(
+ target_env = "gnu",
+ all(
+ any(target_env = "musl", target_env = "ohos"),
+ not(target_feature = "crt-static"),
+ ),
+ portable_atomic_outline_atomics,
+ ),
+ ),
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ // These don't support detection of FEAT_LSE2.
+ // target_os = "fuchsia",
+ // target_os = "windows",
+ ),
+ ))]
+ #[cfg(not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")))]
+ {
+ debug_assert!(detect::detect().has_lse2());
+ }
+ };
+}
// Refs: https://developer.arm.com/documentation/100067/0612/armclang-Integrated-Assembler/AArch32-Target-selection-directives?lang=en
//
@@ -230,29 +279,141 @@ macro_rules! atomic_rmw {
// cfg guarantee that the CPU supports FEAT_LSE2.
#[cfg(any(target_feature = "lse2", portable_atomic_target_feature = "lse2"))]
-use atomic_load_ldp as atomic_load;
+use _atomic_load_ldp as atomic_load;
#[cfg(not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")))]
#[inline]
unsafe fn atomic_load(src: *mut u128, order: Ordering) -> u128 {
- #[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))]
- // SAFETY: the caller must uphold the safety contract.
- // cfg guarantee that the CPU supports FEAT_LSE.
- unsafe {
- _atomic_load_casp(src, order)
+ #[inline]
+ unsafe fn atomic_load_no_lse2(src: *mut u128, order: Ordering) -> u128 {
+ #[cfg(any(target_feature = "lse", portable_atomic_target_feature = "lse"))]
+ // SAFETY: the caller must uphold the safety contract.
+ // cfg guarantee that the CPU supports FEAT_LSE.
+ unsafe {
+ _atomic_load_casp(src, order)
+ }
+ #[cfg(not(any(target_feature = "lse", portable_atomic_target_feature = "lse")))]
+ // SAFETY: the caller must uphold the safety contract.
+ unsafe {
+ _atomic_load_ldxp_stxp(src, order)
+ }
}
- #[cfg(not(any(target_feature = "lse", portable_atomic_target_feature = "lse")))]
+ #[cfg(not(all(
+ not(portable_atomic_no_outline_atomics),
+ any(
+ all(
+ target_os = "linux",
+ any(
+ target_env = "gnu",
+ all(
+ any(target_env = "musl", target_env = "ohos"),
+ not(target_feature = "crt-static"),
+ ),
+ portable_atomic_outline_atomics,
+ ),
+ ),
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ // These don't support detection of FEAT_LSE2.
+ // target_os = "fuchsia",
+ // target_os = "windows",
+ ),
+ )))]
// SAFETY: the caller must uphold the safety contract.
unsafe {
- _atomic_load_ldxp_stxp(src, order)
+ atomic_load_no_lse2(src, order)
+ }
+ #[cfg(all(
+ not(portable_atomic_no_outline_atomics),
+ any(
+ all(
+ target_os = "linux",
+ any(
+ target_env = "gnu",
+ all(
+ any(target_env = "musl", target_env = "ohos"),
+ not(target_feature = "crt-static"),
+ ),
+ portable_atomic_outline_atomics,
+ ),
+ ),
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ // These don't support detection of FEAT_LSE2.
+ // target_os = "fuchsia",
+ // target_os = "windows",
+ ),
+ ))]
+ {
+ fn_alias! {
+ // inline(never) is just a hint and also not strictly necessary
+ // because we use ifunc helper macro, but used for clarity.
+ #[inline(never)]
+ unsafe fn(src: *mut u128) -> u128;
+ atomic_load_lse2_relaxed = _atomic_load_ldp(Ordering::Relaxed);
+ atomic_load_lse2_acquire = _atomic_load_ldp(Ordering::Acquire);
+ atomic_load_lse2_seqcst = _atomic_load_ldp(Ordering::SeqCst);
+ }
+ fn_alias! {
+ unsafe fn(src: *mut u128) -> u128;
+ atomic_load_no_lse2_relaxed = atomic_load_no_lse2(Ordering::Relaxed);
+ atomic_load_no_lse2_acquire = atomic_load_no_lse2(Ordering::Acquire);
+ atomic_load_no_lse2_seqcst = atomic_load_no_lse2(Ordering::SeqCst);
+ }
+ // SAFETY: the caller must uphold the safety contract.
+ // and we've checked if FEAT_LSE2 is available.
+ unsafe {
+ match order {
+ Ordering::Relaxed => {
+ ifunc!(unsafe fn(src: *mut u128) -> u128 {
+ let cpuinfo = detect::detect();
+ if cpuinfo.has_lse2() {
+ atomic_load_lse2_relaxed
+ } else {
+ atomic_load_no_lse2_relaxed
+ }
+ })
+ }
+ Ordering::Acquire => {
+ ifunc!(unsafe fn(src: *mut u128) -> u128 {
+ let cpuinfo = detect::detect();
+ if cpuinfo.has_lse2() {
+ atomic_load_lse2_acquire
+ } else {
+ atomic_load_no_lse2_acquire
+ }
+ })
+ }
+ Ordering::SeqCst => {
+ ifunc!(unsafe fn(src: *mut u128) -> u128 {
+ let cpuinfo = detect::detect();
+ if cpuinfo.has_lse2() {
+ atomic_load_lse2_seqcst
+ } else {
+ atomic_load_no_lse2_seqcst
+ }
+ })
+ }
+ _ => unreachable!("{:?}", order),
+ }
+ }
}
}
// If CPU supports FEAT_LSE2, LDP/LDIAPP is single-copy atomic reads,
// otherwise it is two single-copy atomic reads.
// Refs: B2.2.1 of the Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile
-#[cfg(any(target_feature = "lse2", portable_atomic_target_feature = "lse2"))]
+#[cfg(any(
+ target_feature = "lse2",
+ portable_atomic_target_feature = "lse2",
+ not(portable_atomic_no_outline_atomics),
+))]
#[inline]
-unsafe fn atomic_load_ldp(src: *mut u128, order: Ordering) -> u128 {
+unsafe fn _atomic_load_ldp(src: *mut u128, order: Ordering) -> u128 {
debug_assert!(src as usize % 16 == 0);
+ debug_assert_lse2!();
// SAFETY: the caller must guarantee that `dst` is valid for reads,
// 16-byte aligned, that there are no concurrent non-atomic operations.
@@ -384,37 +545,149 @@ unsafe fn _atomic_load_ldxp_stxp(src: *mut u128, order: Ordering) -> u128 {
// cfg guarantee that the CPU supports FEAT_LSE2.
#[cfg(any(target_feature = "lse2", portable_atomic_target_feature = "lse2"))]
-use atomic_store_stp as atomic_store;
+use _atomic_store_stp as atomic_store;
#[cfg(not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2")))]
#[inline]
unsafe fn atomic_store(dst: *mut u128, val: u128, order: Ordering) {
- // If FEAT_LSE is available at compile-time and portable_atomic_ll_sc_rmw cfg is not set,
- // we use CAS-based atomic RMW.
- #[cfg(all(
- any(target_feature = "lse", portable_atomic_target_feature = "lse"),
- not(portable_atomic_ll_sc_rmw),
- ))]
- // SAFETY: the caller must uphold the safety contract.
- // cfg guarantee that the CPU supports FEAT_LSE.
- unsafe {
- _atomic_swap_casp(dst, val, order);
+ #[inline]
+ unsafe fn atomic_store_no_lse2(dst: *mut u128, val: u128, order: Ordering) {
+ // If FEAT_LSE is available at compile-time and portable_atomic_ll_sc_rmw cfg is not set,
+ // we use CAS-based atomic RMW.
+ #[cfg(all(
+ any(target_feature = "lse", portable_atomic_target_feature = "lse"),
+ not(portable_atomic_ll_sc_rmw),
+ ))]
+ // SAFETY: the caller must uphold the safety contract.
+ // cfg guarantee that the CPU supports FEAT_LSE.
+ unsafe {
+ _atomic_swap_casp(dst, val, order);
+ }
+ #[cfg(not(all(
+ any(target_feature = "lse", portable_atomic_target_feature = "lse"),
+ not(portable_atomic_ll_sc_rmw),
+ )))]
+ // SAFETY: the caller must uphold the safety contract.
+ unsafe {
+ _atomic_store_ldxp_stxp(dst, val, order);
+ }
}
#[cfg(not(all(
- any(target_feature = "lse", portable_atomic_target_feature = "lse"),
- not(portable_atomic_ll_sc_rmw),
+ not(portable_atomic_no_outline_atomics),
+ any(
+ all(
+ target_os = "linux",
+ any(
+ target_env = "gnu",
+ all(
+ any(target_env = "musl", target_env = "ohos"),
+ not(target_feature = "crt-static"),
+ ),
+ portable_atomic_outline_atomics,
+ ),
+ ),
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ // These don't support detection of FEAT_LSE2.
+ // target_os = "fuchsia",
+ // target_os = "windows",
+ ),
)))]
// SAFETY: the caller must uphold the safety contract.
unsafe {
- _atomic_store_ldxp_stxp(dst, val, order);
+ atomic_store_no_lse2(dst, val, order);
+ }
+ #[cfg(all(
+ not(portable_atomic_no_outline_atomics),
+ any(
+ all(
+ target_os = "linux",
+ any(
+ target_env = "gnu",
+ all(
+ any(target_env = "musl", target_env = "ohos"),
+ not(target_feature = "crt-static"),
+ ),
+ portable_atomic_outline_atomics,
+ ),
+ ),
+ target_os = "android",
+ target_os = "freebsd",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ // These don't support detection of FEAT_LSE2.
+ // target_os = "fuchsia",
+ // target_os = "windows",
+ ),
+ ))]
+ {
+ fn_alias! {
+ // inline(never) is just a hint and also not strictly necessary
+ // because we use ifunc helper macro, but used for clarity.
+ #[inline(never)]
+ unsafe fn(dst: *mut u128, val: u128);
+ atomic_store_lse2_relaxed = _atomic_store_stp(Ordering::Relaxed);
+ atomic_store_lse2_release = _atomic_store_stp(Ordering::Release);
+ atomic_store_lse2_seqcst = _atomic_store_stp(Ordering::SeqCst);
+ }
+ fn_alias! {
+ unsafe fn(dst: *mut u128, val: u128);
+ atomic_store_no_lse2_relaxed = atomic_store_no_lse2(Ordering::Relaxed);
+ atomic_store_no_lse2_release = atomic_store_no_lse2(Ordering::Release);
+ atomic_store_no_lse2_seqcst = atomic_store_no_lse2(Ordering::SeqCst);
+ }
+ // SAFETY: the caller must uphold the safety contract.
+ // and we've checked if FEAT_LSE2 is available.
+ unsafe {
+ match order {
+ Ordering::Relaxed => {
+ ifunc!(unsafe fn(dst: *mut u128, val: u128) {
+ let cpuinfo = detect::detect();
+ if cpuinfo.has_lse2() {
+ atomic_store_lse2_relaxed
+ } else {
+ atomic_store_no_lse2_relaxed
+ }
+ });
+ }
+ Ordering::Release => {
+ ifunc!(unsafe fn(dst: *mut u128, val: u128) {
+ let cpuinfo = detect::detect();
+ if cpuinfo.has_lse2() {
+ atomic_store_lse2_release
+ } else {
+ atomic_store_no_lse2_release
+ }
+ });
+ }
+ Ordering::SeqCst => {
+ ifunc!(unsafe fn(dst: *mut u128, val: u128) {
+ let cpuinfo = detect::detect();
+ if cpuinfo.has_lse2() {
+ atomic_store_lse2_seqcst
+ } else {
+ atomic_store_no_lse2_seqcst
+ }
+ });
+ }
+ _ => unreachable!("{:?}", order),
+ }
+ }
}
}
// If CPU supports FEAT_LSE2, STP/STILP is single-copy atomic writes,
// otherwise it is two single-copy atomic writes.
// Refs: B2.2.1 of the Arm Architecture Reference Manual Armv8, for Armv8-A architecture profile
-#[cfg(any(target_feature = "lse2", portable_atomic_target_feature = "lse2"))]
+#[cfg(any(
+ target_feature = "lse2",
+ portable_atomic_target_feature = "lse2",
+ not(portable_atomic_no_outline_atomics),
+))]
#[inline]
-unsafe fn atomic_store_stp(dst: *mut u128, val: u128, order: Ordering) {
+unsafe fn _atomic_store_stp(dst: *mut u128, val: u128, order: Ordering) {
debug_assert!(dst as usize % 16 == 0);
+ debug_assert_lse2!();
// SAFETY: the caller must guarantee that `dst` is valid for writes,
// 16-byte aligned, that there are no concurrent non-atomic operations.
diff --git a/src/imp/atomic128/detect/aarch64_aa64reg.rs b/src/imp/atomic128/detect/aarch64_aa64reg.rs
index f800f5af..35923179 100644
--- a/src/imp/atomic128/detect/aarch64_aa64reg.rs
+++ b/src/imp/atomic128/detect/aarch64_aa64reg.rs
@@ -37,7 +37,6 @@ struct AA64Reg {
aa64isar0: u64,
#[cfg(test)]
aa64isar1: u64,
- #[cfg(test)]
aa64mmfr2: u64,
}
@@ -47,7 +46,6 @@ fn _detect(info: &mut CpuInfo) {
aa64isar0,
#[cfg(test)]
aa64isar1,
- #[cfg(test)]
aa64mmfr2,
} = imp::aa64reg();
@@ -56,7 +54,7 @@ fn _detect(info: &mut CpuInfo) {
let atomic = extract(aa64isar0, 23, 20);
if atomic >= 2 {
info.set(CpuInfo::HAS_LSE);
- // we currently only use FEAT_LSE in outline-atomics.
+ // we currently only use FEAT_LSE and FEAT_LSE2 in outline-atomics.
#[cfg(test)]
{
if atomic >= 3 {
@@ -64,7 +62,7 @@ fn _detect(info: &mut CpuInfo) {
}
}
}
- // we currently only use FEAT_LSE in outline-atomics.
+ // we currently only use FEAT_LSE and FEAT_LSE2 in outline-atomics.
#[cfg(test)]
{
// ID_AA64ISAR1_EL1, Instruction Set Attribute Register 1
@@ -72,11 +70,11 @@ fn _detect(info: &mut CpuInfo) {
if extract(aa64isar1, 23, 20) >= 3 {
info.set(CpuInfo::HAS_RCPC3);
}
- // ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2
- // https://developer.arm.com/documentation/ddi0601/2023-06/AArch64-Registers/ID-AA64MMFR2-EL1--AArch64-Memory-Model-Feature-Register-2?lang=en
- if extract(aa64mmfr2, 35, 32) >= 1 {
- info.set(CpuInfo::HAS_LSE2);
- }
+ }
+ // ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2
+ // https://developer.arm.com/documentation/ddi0601/2023-06/AArch64-Registers/ID-AA64MMFR2-EL1--AArch64-Memory-Model-Feature-Register-2?lang=en
+ if extract(aa64mmfr2, 35, 32) >= 1 {
+ info.set(CpuInfo::HAS_LSE2);
}
}
@@ -114,21 +112,16 @@ mod imp {
options(pure, nomem, nostack, preserves_flags)
);
}
- #[cfg(test)]
let aa64mmfr2: u64;
- #[cfg(test)]
- {
- asm!(
- "mrs {0}, ID_AA64MMFR2_EL1",
- out(reg) aa64mmfr2,
- options(pure, nomem, nostack, preserves_flags)
- );
- }
+ asm!(
+ "mrs {0}, ID_AA64MMFR2_EL1",
+ out(reg) aa64mmfr2,
+ options(pure, nomem, nostack, preserves_flags)
+ );
AA64Reg {
aa64isar0,
#[cfg(test)]
aa64isar1,
- #[cfg(test)]
aa64mmfr2,
}
}
@@ -225,7 +218,6 @@ mod imp {
aa64isar0: buf.aa64isar0,
#[cfg(test)]
aa64isar1: buf.aa64isar1,
- #[cfg(test)]
aa64mmfr2: buf.aa64mmfr2,
})
}
@@ -244,7 +236,6 @@ mod imp {
aa64isar0: 0,
#[cfg(test)]
aa64isar1: 0,
- #[cfg(test)]
aa64mmfr2: 0,
},
}
@@ -273,7 +264,6 @@ mod imp {
pub(crate) const CPU_ID_AA64ISAR0: c_int = 2;
#[cfg(test)]
pub(crate) const CPU_ID_AA64ISAR1: c_int = 3;
- #[cfg(test)]
pub(crate) const CPU_ID_AA64MMFR2: c_int = 7;
extern "C" {
@@ -302,13 +292,11 @@ mod imp {
let aa64isar0 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64ISAR0]).unwrap_or(0);
#[cfg(test)]
let aa64isar1 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64ISAR1]).unwrap_or(0);
- #[cfg(test)]
let aa64mmfr2 = sysctl64(&[ffi::CTL_MACHDEP, ffi::CPU_ID_AA64MMFR2]).unwrap_or(0);
AA64Reg {
aa64isar0,
#[cfg(test)]
aa64isar1,
- #[cfg(test)]
aa64mmfr2,
}
}
diff --git a/src/imp/atomic128/detect/aarch64_macos.rs b/src/imp/atomic128/detect/aarch64_macos.rs
index 2ed63664..d6bf9d00 100644
--- a/src/imp/atomic128/detect/aarch64_macos.rs
+++ b/src/imp/atomic128/detect/aarch64_macos.rs
@@ -6,7 +6,7 @@
// https://github.com/llvm/llvm-project/blob/llvmorg-17.0.0-rc2/llvm/include/llvm/TargetParser/AArch64TargetParser.h#L494
//
// If macOS supporting Armv9.4-a becomes popular in the future, this module will
-// be used to support outline atomics for FEAT_LSE128/FEAT_LRCPC3.
+// be used to support outline-atomics for FEAT_LSE128/FEAT_LRCPC3.
//
// Refs: https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics
//
@@ -79,13 +79,13 @@ fn _detect(info: &mut CpuInfo) {
} {
info.set(CpuInfo::HAS_LSE);
}
- // we currently only use FEAT_LSE in outline-atomics.
+ // SAFETY: we passed a valid C string.
+ if unsafe { sysctlbyname32(b"hw.optional.arm.FEAT_LSE2\0").unwrap_or(0) != 0 } {
+ info.set(CpuInfo::HAS_LSE2);
+ }
+ // we currently only use FEAT_LSE and FEAT_LSE2 in outline-atomics.
#[cfg(test)]
{
- // SAFETY: we passed a valid C string.
- if unsafe { sysctlbyname32(b"hw.optional.arm.FEAT_LSE2\0").unwrap_or(0) != 0 } {
- info.set(CpuInfo::HAS_LSE2);
- }
// SAFETY: we passed a valid C string.
if unsafe { sysctlbyname32(b"hw.optional.arm.FEAT_LSE128\0").unwrap_or(0) != 0 } {
info.set(CpuInfo::HAS_LSE128);
diff --git a/src/imp/atomic128/detect/auxv.rs b/src/imp/atomic128/detect/auxv.rs
index c13e5f8c..42415fc8 100644
--- a/src/imp/atomic128/detect/auxv.rs
+++ b/src/imp/atomic128/detect/auxv.rs
@@ -187,7 +187,6 @@ mod arch {
// https://github.com/freebsd/freebsd-src/blob/release/13.0.0/sys/arm64/include/elf.h
// https://github.com/freebsd/freebsd-src/blob/release/12.2.0/sys/arm64/include/elf.h
pub(super) const HWCAP_ATOMICS: ffi::c_ulong = 1 << 8;
- #[cfg(test)]
pub(super) const HWCAP_USCAT: ffi::c_ulong = 1 << 25;
#[cold]
@@ -197,12 +196,8 @@ mod arch {
if hwcap & HWCAP_ATOMICS != 0 {
info.set(CpuInfo::HAS_LSE);
}
- // we currently only use FEAT_LSE in outline-atomics.
- #[cfg(test)]
- {
- if hwcap & HWCAP_USCAT != 0 {
- info.set(CpuInfo::HAS_LSE2);
- }
+ if hwcap & HWCAP_USCAT != 0 {
+ info.set(CpuInfo::HAS_LSE2);
}
}
}
@@ -676,12 +671,16 @@ mod tests {
_elf_aux_info = libc::elf_aux_info;
_elf_aux_info = sys::elf_aux_info;
}
+ #[cfg(not(target_os = "freebsd"))]
+ type AtType = ffi::c_ulong;
+ #[cfg(target_os = "freebsd")]
+ type AtType = ffi::c_int;
#[cfg(not(target_os = "freebsd"))] // libc doesn't have this on FreeBSD
static_assert!(ffi::AT_HWCAP == libc::AT_HWCAP);
- static_assert!(ffi::AT_HWCAP == sys::AT_HWCAP as _);
+ static_assert!(ffi::AT_HWCAP == sys::AT_HWCAP as AtType);
#[cfg(not(target_os = "freebsd"))] // libc doesn't have this on FreeBSD
static_assert!(ffi::AT_HWCAP2 == libc::AT_HWCAP2);
- static_assert!(ffi::AT_HWCAP2 == sys::AT_HWCAP2 as _);
+ static_assert!(ffi::AT_HWCAP2 == sys::AT_HWCAP2 as AtType);
#[cfg(target_arch = "aarch64")]
{
// static_assert!(arch::HWCAP_ATOMICS == libc::HWCAP_ATOMICS); // libc doesn't have this
diff --git a/src/imp/atomic128/detect/common.rs b/src/imp/atomic128/detect/common.rs
index dbe0a567..b87caa35 100644
--- a/src/imp/atomic128/detect/common.rs
+++ b/src/imp/atomic128/detect/common.rs
@@ -50,8 +50,7 @@ impl CpuInfo {
/// Whether FEAT_LSE is available
const HAS_LSE: u32 = 1;
/// Whether FEAT_LSE2 is available
- // This is currently only used in tests.
- #[cfg(test)]
+ #[cfg_attr(not(test), allow(dead_code))]
const HAS_LSE2: u32 = 2;
/// Whether FEAT_LSE128 is available
// This is currently only used in tests.
@@ -67,7 +66,8 @@ impl CpuInfo {
pub(crate) fn has_lse(self) -> bool {
self.test(CpuInfo::HAS_LSE)
}
- #[cfg(test)]
+ #[cfg_attr(not(test), allow(dead_code))]
+ #[cfg(any(test, not(any(target_feature = "lse2", portable_atomic_target_feature = "lse2"))))]
#[inline]
pub(crate) fn has_lse2(self) -> bool {
self.test(CpuInfo::HAS_LSE2)