diff options
| author | Folkert de Vries <folkert@folkertdev.nl> | 2025-07-12 21:54:23 +0200 |
|---|---|---|
| committer | Folkert de Vries <folkert@folkertdev.nl> | 2025-07-15 01:36:20 +0200 |
| commit | 48c33b774825c92c9aa3a3d01424ed62e62c3174 (patch) | |
| tree | 1096b69e5d18ce9de4e9cc774f2fbd2c4071a3a2 /library/stdarch | |
| parent | 42bcb0668ec27b7ee2af17649c185f09f0491872 (diff) | |
| download | rust-48c33b774825c92c9aa3a3d01424ed62e62c3174.tar.gz rust-48c33b774825c92c9aa3a3d01424ed62e62c3174.zip | |
`aarch64`: implement `vabs` using `instrinsics::simd`
Diffstat (limited to 'library/stdarch')
| -rw-r--r-- | library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs | 36 | ||||
| -rw-r--r-- | library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml | 35 |
2 files changed, 44 insertions, 27 deletions
diff --git a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs index 9595b30789e..319cef2b1a1 100644 --- a/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs +++ b/library/stdarch/crates/core_arch/src/aarch64/neon/generated.rs @@ -298,46 +298,40 @@ pub fn vabsq_f64(a: float64x2_t) -> float64x2_t { #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(abs))] pub fn vabs_s64(a: int64x1_t) -> int64x1_t { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.abs.v1i64" - )] - fn _vabs_s64(a: int64x1_t) -> int64x1_t; + unsafe { + let neg: int64x1_t = simd_neg(a); + let mask: int64x1_t = simd_ge(a, neg); + simd_select(mask, a, neg) } - unsafe { _vabs_s64(a) } } #[doc = "Absolute Value (wrapping)."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsd_s64)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_s64)"] #[inline] #[target_feature(enable = "neon")] #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(abs))] -pub fn vabsd_s64(a: i64) -> i64 { - unsafe extern "unadjusted" { - #[cfg_attr( - any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.abs.i64" - )] - fn _vabsd_s64(a: i64) -> i64; +pub fn vabsq_s64(a: int64x2_t) -> int64x2_t { + unsafe { + let neg: int64x2_t = simd_neg(a); + let mask: int64x2_t = simd_ge(a, neg); + simd_select(mask, a, neg) } - unsafe { _vabsd_s64(a) } } #[doc = "Absolute Value (wrapping)."] -#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsq_s64)"] +#[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vabsd_s64)"] #[inline] #[target_feature(enable = "neon")] #[stable(feature = "neon_intrinsics", since = "1.59.0")] #[cfg_attr(test, assert_instr(abs))] -pub fn vabsq_s64(a: int64x2_t) -> int64x2_t { +pub fn vabsd_s64(a: i64) -> i64 { unsafe extern "unadjusted" { #[cfg_attr( any(target_arch = "aarch64", target_arch = "arm64ec"), - link_name = "llvm.aarch64.neon.abs.v2i64" + link_name = "llvm.aarch64.neon.abs.i64" )] - fn _vabsq_s64(a: int64x2_t) -> int64x2_t; + fn _vabsd_s64(a: i64) -> i64; } - unsafe { _vabsq_s64(a) } + unsafe { _vabsd_s64(a) } } #[doc = "Add"] #[doc = "[Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaddd_s64)"] diff --git a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml index 2b5aab3e7f5..8fa33e5bb33 100644 --- a/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml +++ b/library/stdarch/crates/stdarch-gen-arm/spec/neon/aarch64.spec.yml @@ -13023,6 +13023,26 @@ intrinsics: - link: "llvm.aarch64.crc32cx" arch: aarch64,arm64ec + - name: "vabsd_s64" + doc: "Absolute Value (wrapping)." + arguments: ["a: {type[1]}"] + return_type: "{type[1]}" + attr: + - *neon-stable + assert_instr: [abs] + safety: safe + types: + - [i64, i64] + compose: + # This is behaviorally equivalent to `i64::wrapping_abs`, but keeps the value in a SIMD + # register. That can be beneficial when combined with other instructions. This LLVM + # issue provides some extra context https://github.com/llvm/llvm-project/issues/148388. + - LLVMLink: + name: "vabsd_s64" + links: + - link: "llvm.aarch64.neon.abs.i64" + arch: aarch64,arm64ec + - name: "{type[0]}" doc: "Absolute Value (wrapping)." arguments: ["a: {type[1]}"] @@ -13032,15 +13052,18 @@ intrinsics: assert_instr: [abs] safety: safe types: - - ['vabsd_s64', i64, i64] - ['vabs_s64', int64x1_t, v1i64] - ['vabsq_s64', int64x2_t, v2i64] compose: - - LLVMLink: - name: "{type[0]}" - links: - - link: "llvm.aarch64.neon.abs.{type[2]}" - arch: aarch64,arm64ec + - Let: + - neg + - "{type[1]}" + - FnCall: [simd_neg, [a]] + - Let: + - mask + - "{type[1]}" + - FnCall: [simd_ge, [a, neg]] + - FnCall: [simd_select, [mask, a, neg]] - name: "vuqadd{neon_type[0].no}" doc: "Signed saturating Accumulate of Unsigned value." |
