[Neon] Absolute Value fns (#877)
This commit is contained in:
parent
b93f41cbb3
commit
ce4277d977
2 changed files with 175 additions and 0 deletions
|
|
@ -71,6 +71,14 @@ pub struct poly8x16x4_t(
|
|||
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
// absolute value
|
||||
#[link_name = "llvm.aarch64.neon.abs.i64"]
|
||||
fn vabsd_s64_(a: i64) -> i64;
|
||||
#[link_name = "llvm.aarch64.neon.abs.v1i64"]
|
||||
fn vabs_s64_(a: int64x1_t) -> int64x1_t;
|
||||
#[link_name = "llvm.aarch64.neon.abs.v2i64"]
|
||||
fn vabsq_s64_(a: int64x2_t) -> int64x2_t;
|
||||
|
||||
#[link_name = "llvm.aarch64.neon.pmull64"]
|
||||
fn vmull_p64_(a: i64, b: i64) -> int8x16_t;
|
||||
|
||||
|
|
@ -246,6 +254,28 @@ extern "C" {
|
|||
) -> int8x16_t;
|
||||
}
|
||||
|
||||
/// Absolute Value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(abs))]
|
||||
pub unsafe fn vabsd_s64(a: i64) -> i64 {
|
||||
vabsd_s64_(a)
|
||||
}
|
||||
/// Absolute Value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(abs))]
|
||||
pub unsafe fn vabs_s64(a: int64x1_t) -> int64x1_t {
|
||||
vabs_s64_(a)
|
||||
}
|
||||
/// Absolute Value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(abs))]
|
||||
pub unsafe fn vabsq_s64(a: int64x2_t) -> int64x2_t {
|
||||
vabsq_s64_(a)
|
||||
}
|
||||
|
||||
/// Add pairwise
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
|
|
@ -2503,6 +2533,33 @@ mod tests {
|
|||
unsafe fn test_vsubq_f64() {
|
||||
testq_ari_f64(|i, j| vsubq_f64(i, j), |a: f64, b: f64| -> f64 { a - b });
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabsd_s64() {
|
||||
assert_eq!(vabsd_s64(-1), 1);
|
||||
assert_eq!(vabsd_s64(0), 0);
|
||||
assert_eq!(vabsd_s64(1), 1);
|
||||
assert_eq!(vabsd_s64(i64::MIN), i64::MIN);
|
||||
assert_eq!(vabsd_s64(i64::MIN + 1), i64::MAX);
|
||||
}
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabs_s64() {
|
||||
let a = i64x1::new(i64::MIN);
|
||||
let r: i64x1 = transmute(vabs_s64(transmute(a)));
|
||||
let e = i64x1::new(i64::MIN);
|
||||
assert_eq!(r, e);
|
||||
let a = i64x1::new(i64::MIN + 1);
|
||||
let r: i64x1 = transmute(vabs_s64(transmute(a)));
|
||||
let e = i64x1::new(i64::MAX);
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabsq_s64() {
|
||||
let a = i64x2::new(i64::MIN, i64::MIN + 1);
|
||||
let r: i64x2 = transmute(vabsq_s64(transmute(a)));
|
||||
let e = i64x2::new(i64::MIN, i64::MAX);
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
|
|
@ -102,6 +102,27 @@ pub struct poly8x8x4_t(pub poly8x8_t, pub poly8x8_t, pub poly8x8_t, pub poly8x8_
|
|||
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
// absolute value (64-bit)
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vabs.v8i8")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.abs.v8i8")]
|
||||
fn vabs_s8_(a: int8x8_t) -> int8x8_t;
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vabs.v4i16")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.abs.v4i16")]
|
||||
fn vabs_s16_(a: int16x4_t) -> int16x4_t;
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vabs.v2i32")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.abs.v2i32")]
|
||||
fn vabs_s32_(a: int32x2_t) -> int32x2_t;
|
||||
// absolute value (128-bit)
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vabs.v16i8")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.abs.v16i8")]
|
||||
fn vabsq_s8_(a: int8x16_t) -> int8x16_t;
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vabs.v8i16")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.abs.v8i16")]
|
||||
fn vabsq_s16_(a: int16x8_t) -> int16x8_t;
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vabs.v4i32")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.abs.v4i32")]
|
||||
fn vabsq_s32_(a: int32x4_t) -> int32x4_t;
|
||||
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vrsqrte.v2f32")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.frsqrte.v2f32")]
|
||||
fn frsqrte_v2f32(a: float32x2_t) -> float32x2_t;
|
||||
|
|
@ -185,6 +206,61 @@ extern "C" {
|
|||
) -> int8x8_t;
|
||||
}
|
||||
|
||||
/// Absolute value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(abs))]
|
||||
pub unsafe fn vabs_s8(a: int8x8_t) -> int8x8_t {
|
||||
vabs_s8_(a)
|
||||
}
|
||||
/// Absolute value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(abs))]
|
||||
pub unsafe fn vabs_s16(a: int16x4_t) -> int16x4_t {
|
||||
vabs_s16_(a)
|
||||
}
|
||||
/// Absolute value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(abs))]
|
||||
pub unsafe fn vabs_s32(a: int32x2_t) -> int32x2_t {
|
||||
vabs_s32_(a)
|
||||
}
|
||||
/// Absolute value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(abs))]
|
||||
pub unsafe fn vabsq_s8(a: int8x16_t) -> int8x16_t {
|
||||
vabsq_s8_(a)
|
||||
}
|
||||
/// Absolute value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(abs))]
|
||||
pub unsafe fn vabsq_s16(a: int16x8_t) -> int16x8_t {
|
||||
vabsq_s16_(a)
|
||||
}
|
||||
/// Absolute value (wrapping).
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vabs))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(abs))]
|
||||
pub unsafe fn vabsq_s32(a: int32x4_t) -> int32x4_t {
|
||||
vabsq_s32_(a)
|
||||
}
|
||||
|
||||
/// Unsigned saturating extract narrow.
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
|
|
@ -3945,6 +4021,48 @@ mod tests {
|
|||
let e = i8x16::new(-1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
|
||||
assert_eq!(r, e)
|
||||
}
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabs_s8() {
|
||||
let a = i8x8::new(-1, 0, 1, -2, 0, 2, -128, 127);
|
||||
let r: i8x8 = transmute(vabs_s8(transmute(a)));
|
||||
let e = i8x8::new(1, 0, 1, 2, 0, 2, -128, 127);
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabsq_s8() {
|
||||
let a = i8x16::new(-1, 0, 1, -2, 0, 2, -128, 127, -1, 0, 1, -2, 0, 2, -128, 127);
|
||||
let r: i8x16 = transmute(vabsq_s8(transmute(a)));
|
||||
let e = i8x16::new(1, 0, 1, 2, 0, 2, -128, 127, 1, 0, 1, 2, 0, 2, -128, 127);
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabs_s16() {
|
||||
let a = i16x4::new(-1, 0, i16::MIN, i16::MAX);
|
||||
let r: i16x4 = transmute(vabs_s16(transmute(a)));
|
||||
let e = i16x4::new(1, 0, i16::MIN, i16::MAX);
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabsq_s16() {
|
||||
let a = i16x8::new(-1, 0, i16::MIN, i16::MAX, -1, 0, i16::MIN, i16::MAX);
|
||||
let r: i16x8 = transmute(vabsq_s16(transmute(a)));
|
||||
let e = i16x8::new(1, 0, i16::MIN, i16::MAX, 1, 0, i16::MIN, i16::MAX);
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabs_s32() {
|
||||
let a = i32x2::new(i32::MIN, i32::MIN + 1);
|
||||
let r: i32x2 = transmute(vabs_s32(transmute(a)));
|
||||
let e = i32x2::new(i32::MIN, i32::MAX);
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vabsq_s32() {
|
||||
let a = i32x4::new(i32::MIN, i32::MIN + 1, 0, -1);
|
||||
let r: i32x4 = transmute(vabsq_s32(transmute(a)));
|
||||
let e = i32x4::new(i32::MIN, i32::MAX, 0, 1);
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue