diff --git a/library/stdarch/crates/core_arch/src/aarch64/crc.rs b/library/stdarch/crates/core_arch/src/aarch64/crc.rs deleted file mode 100644 index 35940e0db80a..000000000000 --- a/library/stdarch/crates/core_arch/src/aarch64/crc.rs +++ /dev/null @@ -1,51 +0,0 @@ -extern "unadjusted" { - #[link_name = "llvm.aarch64.crc32x"] - fn crc32x_(crc: u32, data: u64) -> u32; - - #[link_name = "llvm.aarch64.crc32cx"] - fn crc32cx_(crc: u32, data: u64) -> u32; -} - -#[cfg(test)] -use stdarch_test::assert_instr; - -/// CRC32 single round checksum for quad words (64 bits). -/// -/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d) -#[inline] -#[target_feature(enable = "crc")] -#[cfg_attr(test, assert_instr(crc32x))] -#[unstable(feature = "stdarch_arm_crc32", issue = "117215")] -pub unsafe fn __crc32d(crc: u32, data: u64) -> u32 { - crc32x_(crc, data) -} - -/// CRC32-C single round checksum for quad words (64 bits). -/// -/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd) -#[inline] -#[target_feature(enable = "crc")] -#[cfg_attr(test, assert_instr(crc32cx))] -#[unstable(feature = "stdarch_arm_crc32", issue = "117215")] -pub unsafe fn __crc32cd(crc: u32, data: u64) -> u32 { - crc32cx_(crc, data) -} - -#[cfg(test)] -mod tests { - use crate::core_arch::{aarch64::*, simd::*}; - use std::mem; - use stdarch_test::simd_test; - - #[simd_test(enable = "crc")] - unsafe fn test_crc32d() { - assert_eq!(__crc32d(0, 0), 0); - assert_eq!(__crc32d(0, 18446744073709551615), 1147535477); - } - - #[simd_test(enable = "crc")] - unsafe fn test_crc32cd() { - assert_eq!(__crc32cd(0, 0), 0); - assert_eq!(__crc32cd(0, 18446744073709551615), 3293575501); - } -} diff --git a/library/stdarch/crates/core_arch/src/aarch64/mod.rs b/library/stdarch/crates/core_arch/src/aarch64/mod.rs index fefd2f4780c2..ebd7a3178108 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/mod.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/mod.rs @@ -17,10 +17,6 @@ mod tme; #[unstable(feature = "stdarch_aarch64_tme", issue = "117216")] pub use self::tme::*; -mod crc; -#[unstable(feature = "stdarch_arm_crc32", issue = "117215")] -pub use self::crc::*; - mod prefetch; #[unstable(feature = "stdarch_aarch64_prefetch", issue = "117217")] pub use self::prefetch::*; diff --git a/library/stdarch/crates/core_arch/src/arm_shared/crc.rs b/library/stdarch/crates/core_arch/src/arm_shared/crc.rs index b1f716e1aa92..8eedd21696f2 100644 --- a/library/stdarch/crates/core_arch/src/arm_shared/crc.rs +++ b/library/stdarch/crates/core_arch/src/arm_shared/crc.rs @@ -18,6 +18,10 @@ extern "unadjusted" { #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32cw")] #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.crc32cw")] fn crc32cw_(crc: u32, data: u32) -> u32; + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32x")] + fn crc32x_(crc: u32, data: u64) -> u32; + #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.crc32cx")] + fn crc32cx_(crc: u32, data: u64) -> u32; } #[cfg(test)] @@ -95,12 +99,82 @@ pub unsafe fn __crc32cw(crc: u32, data: u32) -> u32 { crc32cw_(crc, data) } +/// CRC32 single round checksum for quad words (64 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d) +#[inline] +#[target_feature(enable = "crc")] +#[cfg(target_arch = "aarch64")] +#[cfg_attr(test, assert_instr(crc32x))] +#[unstable(feature = "stdarch_arm_crc32", issue = "117215")] +pub unsafe fn __crc32d(crc: u32, data: u64) -> u32 { + crc32x_(crc, data) +} + +/// CRC32 single round checksum for quad words (64 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32d) +#[inline] +#[target_feature(enable = "crc")] +#[cfg(target_arch = "arm")] +#[cfg_attr(test, assert_instr(crc32w))] +#[unstable(feature = "stdarch_arm_crc32", issue = "117215")] +pub unsafe fn __crc32d(crc: u32, data: u64) -> u32 { + // On 32-bit ARM this intrinsic emits a chain of two `crc32_w` instructions + // and truncates the data to 32 bits in both clang and gcc + crc32w_( + crc32w_(crc, (data & 0xffffffff) as u32), + (data >> 32) as u32, + ) +} + +/// CRC32 single round checksum for quad words (64 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd) +#[inline] +#[target_feature(enable = "crc")] +#[cfg(target_arch = "aarch64")] +#[cfg_attr(test, assert_instr(crc32cx))] +#[unstable(feature = "stdarch_arm_crc32", issue = "117215")] +pub unsafe fn __crc32cd(crc: u32, data: u64) -> u32 { + crc32cx_(crc, data) +} + +/// CRC32 single round checksum for quad words (64 bits). +/// +/// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/__crc32cd) +#[inline] +#[target_feature(enable = "crc")] +#[cfg(target_arch = "arm")] +#[cfg_attr(test, assert_instr(crc32cw))] +#[unstable(feature = "stdarch_arm_crc32", issue = "117215")] +pub unsafe fn __crc32cd(crc: u32, data: u64) -> u32 { + // On 32-bit ARM this intrinsic emits a chain of two `crc32_cw` instructions + // and truncates the data to 32 bits in both clang and gcc + crc32cw_( + crc32cw_(crc, (data & 0xffffffff) as u32), + (data >> 32) as u32, + ) +} + #[cfg(test)] mod tests { use crate::core_arch::{arm_shared::*, simd::*}; use std::mem; use stdarch_test::simd_test; + #[simd_test(enable = "crc")] + unsafe fn test_crc32d() { + assert_eq!(__crc32d(0, 0), 0); + assert_eq!(__crc32d(0, 18446744073709551615), 1147535477); + } + + #[simd_test(enable = "crc")] + unsafe fn test_crc32cd() { + assert_eq!(__crc32cd(0, 0), 0); + assert_eq!(__crc32cd(0, 18446744073709551615), 3293575501); + } + #[simd_test(enable = "crc")] unsafe fn test_crc32b() { assert_eq!(__crc32b(0, 0), 0); diff --git a/library/stdarch/crates/intrinsic-test/missing_arm.txt b/library/stdarch/crates/intrinsic-test/missing_arm.txt index 7439cd6e6644..0ea4cec406fa 100644 --- a/library/stdarch/crates/intrinsic-test/missing_arm.txt +++ b/library/stdarch/crates/intrinsic-test/missing_arm.txt @@ -14,8 +14,6 @@ vbfmlaltq_laneq_f32 vbfmmlaq_f32 # Implemented in Clang and stdarch for A64 only even though CSV claims A32 support -__crc32d -__crc32cd vaddq_p64 vbsl_p64 vbslq_p64