Add vqmovn neon instructions (#1163)
This commit is contained in:
parent
604ed7ebbf
commit
4a21f4db0e
4 changed files with 593 additions and 23 deletions
|
|
@ -5895,6 +5895,150 @@ pub unsafe fn vqdmulhs_laneq_s32<const N: i32>(a: i32, b: int32x4_t) -> i32 {
|
|||
vqdmulhs_s32(a, b)
|
||||
}
|
||||
|
||||
/// Saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtn))]
|
||||
pub unsafe fn vqmovnh_s16(a: i16) -> i8 {
|
||||
simd_extract(vqmovn_s16(vdupq_n_s16(a)), 0)
|
||||
}
|
||||
|
||||
/// Saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtn))]
|
||||
pub unsafe fn vqmovns_s32(a: i32) -> i16 {
|
||||
simd_extract(vqmovn_s32(vdupq_n_s32(a)), 0)
|
||||
}
|
||||
|
||||
/// Saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtn))]
|
||||
pub unsafe fn vqmovnd_s64(a: i64) -> i32 {
|
||||
simd_extract(vqmovn_s64(vdupq_n_s64(a)), 0)
|
||||
}
|
||||
|
||||
/// Saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(uqxtn))]
|
||||
pub unsafe fn vqmovnh_u16(a: u16) -> u8 {
|
||||
simd_extract(vqmovn_u16(vdupq_n_u16(a)), 0)
|
||||
}
|
||||
|
||||
/// Saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(uqxtn))]
|
||||
pub unsafe fn vqmovns_u32(a: u32) -> u16 {
|
||||
simd_extract(vqmovn_u32(vdupq_n_u32(a)), 0)
|
||||
}
|
||||
|
||||
/// Saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(uqxtn))]
|
||||
pub unsafe fn vqmovnd_u64(a: u64) -> u32 {
|
||||
simd_extract(vqmovn_u64(vdupq_n_u64(a)), 0)
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtn2))]
|
||||
pub unsafe fn vqmovn_high_s16(a: int8x8_t, b: int16x8_t) -> int8x16_t {
|
||||
simd_shuffle16!(a, vqmovn_s16(b), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtn2))]
|
||||
pub unsafe fn vqmovn_high_s32(a: int16x4_t, b: int32x4_t) -> int16x8_t {
|
||||
simd_shuffle8!(a, vqmovn_s32(b), [0, 1, 2, 3, 4, 5, 6, 7])
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtn2))]
|
||||
pub unsafe fn vqmovn_high_s64(a: int32x2_t, b: int64x2_t) -> int32x4_t {
|
||||
simd_shuffle4!(a, vqmovn_s64(b), [0, 1, 2, 3])
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(uqxtn2))]
|
||||
pub unsafe fn vqmovn_high_u16(a: uint8x8_t, b: uint16x8_t) -> uint8x16_t {
|
||||
simd_shuffle16!(a, vqmovn_u16(b), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(uqxtn2))]
|
||||
pub unsafe fn vqmovn_high_u32(a: uint16x4_t, b: uint32x4_t) -> uint16x8_t {
|
||||
simd_shuffle8!(a, vqmovn_u32(b), [0, 1, 2, 3, 4, 5, 6, 7])
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(uqxtn2))]
|
||||
pub unsafe fn vqmovn_high_u64(a: uint32x2_t, b: uint64x2_t) -> uint32x4_t {
|
||||
simd_shuffle4!(a, vqmovn_u64(b), [0, 1, 2, 3])
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtun))]
|
||||
pub unsafe fn vqmovunh_s16(a: i16) -> u8 {
|
||||
simd_extract(vqmovun_s16(vdupq_n_s16(a)), 0)
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtun))]
|
||||
pub unsafe fn vqmovuns_s32(a: i32) -> u16 {
|
||||
simd_extract(vqmovun_s32(vdupq_n_s32(a)), 0)
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtun))]
|
||||
pub unsafe fn vqmovund_s64(a: i64) -> u32 {
|
||||
simd_extract(vqmovun_s64(vdupq_n_s64(a)), 0)
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtun2))]
|
||||
pub unsafe fn vqmovun_high_s16(a: uint8x8_t, b: int16x8_t) -> uint8x16_t {
|
||||
simd_shuffle16!(a, vqmovun_s16(b), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtun2))]
|
||||
pub unsafe fn vqmovun_high_s32(a: uint16x4_t, b: int32x4_t) -> uint16x8_t {
|
||||
simd_shuffle8!(a, vqmovun_s32(b), [0, 1, 2, 3, 4, 5, 6, 7])
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(test, assert_instr(sqxtun2))]
|
||||
pub unsafe fn vqmovun_high_s64(a: uint32x2_t, b: int64x2_t) -> uint32x4_t {
|
||||
simd_shuffle4!(a, vqmovun_s64(b), [0, 1, 2, 3])
|
||||
}
|
||||
|
||||
/// Signed saturating rounding doubling multiply returning high half
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
|
|
@ -13537,6 +13681,159 @@ mod test {
|
|||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovnh_s16() {
|
||||
let a: i16 = 1;
|
||||
let e: i8 = 1;
|
||||
let r: i8 = transmute(vqmovnh_s16(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovns_s32() {
|
||||
let a: i32 = 1;
|
||||
let e: i16 = 1;
|
||||
let r: i16 = transmute(vqmovns_s32(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovnd_s64() {
|
||||
let a: i64 = 1;
|
||||
let e: i32 = 1;
|
||||
let r: i32 = transmute(vqmovnd_s64(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovnh_u16() {
|
||||
let a: u16 = 1;
|
||||
let e: u8 = 1;
|
||||
let r: u8 = transmute(vqmovnh_u16(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovns_u32() {
|
||||
let a: u32 = 1;
|
||||
let e: u16 = 1;
|
||||
let r: u16 = transmute(vqmovns_u32(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovnd_u64() {
|
||||
let a: u64 = 1;
|
||||
let e: u32 = 1;
|
||||
let r: u32 = transmute(vqmovnd_u64(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_high_s16() {
|
||||
let a: i8x8 = i8x8::new(0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F);
|
||||
let b: i16x8 = i16x8::new(0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF);
|
||||
let e: i8x16 = i8x16::new(0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F);
|
||||
let r: i8x16 = transmute(vqmovn_high_s16(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_high_s32() {
|
||||
let a: i16x4 = i16x4::new(0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF);
|
||||
let b: i32x4 = i32x4::new(0x7F_FF_FF_FF, 0x7F_FF_FF_FF, 0x7F_FF_FF_FF, 0x7F_FF_FF_FF);
|
||||
let e: i16x8 = i16x8::new(0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF);
|
||||
let r: i16x8 = transmute(vqmovn_high_s32(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_high_s64() {
|
||||
let a: i32x2 = i32x2::new(0x7F_FF_FF_FF, 0x7F_FF_FF_FF);
|
||||
let b: i64x2 = i64x2::new(0x7F_FF_FF_FF_FF_FF_FF_FF, 0x7F_FF_FF_FF_FF_FF_FF_FF);
|
||||
let e: i32x4 = i32x4::new(0x7F_FF_FF_FF, 0x7F_FF_FF_FF, 0x7F_FF_FF_FF, 0x7F_FF_FF_FF);
|
||||
let r: i32x4 = transmute(vqmovn_high_s64(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_high_u16() {
|
||||
let a: u8x8 = u8x8::new(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
let b: u16x8 = u16x8::new(0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF);
|
||||
let e: u8x16 = u8x16::new(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
let r: u8x16 = transmute(vqmovn_high_u16(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_high_u32() {
|
||||
let a: u16x4 = u16x4::new(0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF);
|
||||
let b: u32x4 = u32x4::new(0xFF_FF_FF_FF, 0xFF_FF_FF_FF, 0xFF_FF_FF_FF, 0xFF_FF_FF_FF);
|
||||
let e: u16x8 = u16x8::new(0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF);
|
||||
let r: u16x8 = transmute(vqmovn_high_u32(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_high_u64() {
|
||||
let a: u32x2 = u32x2::new(0xFF_FF_FF_FF, 0xFF_FF_FF_FF);
|
||||
let b: u64x2 = u64x2::new(0xFF_FF_FF_FF_FF_FF_FF_FF, 0xFF_FF_FF_FF_FF_FF_FF_FF);
|
||||
let e: u32x4 = u32x4::new(0xFF_FF_FF_FF, 0xFF_FF_FF_FF, 0xFF_FF_FF_FF, 0xFF_FF_FF_FF);
|
||||
let r: u32x4 = transmute(vqmovn_high_u64(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovunh_s16() {
|
||||
let a: i16 = 1;
|
||||
let e: u8 = 1;
|
||||
let r: u8 = transmute(vqmovunh_s16(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovuns_s32() {
|
||||
let a: i32 = 1;
|
||||
let e: u16 = 1;
|
||||
let r: u16 = transmute(vqmovuns_s32(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovund_s64() {
|
||||
let a: i64 = 1;
|
||||
let e: u32 = 1;
|
||||
let r: u32 = transmute(vqmovund_s64(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovun_high_s16() {
|
||||
let a: u8x8 = u8x8::new(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
let b: i16x8 = i16x8::new(-1, -1, -1, -1, -1, -1, -1, -1);
|
||||
let e: u8x16 = u8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
let r: u8x16 = transmute(vqmovun_high_s16(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovun_high_s32() {
|
||||
let a: u16x4 = u16x4::new(0, 0, 0, 0);
|
||||
let b: i32x4 = i32x4::new(-1, -1, -1, -1);
|
||||
let e: u16x8 = u16x8::new(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
let r: u16x8 = transmute(vqmovun_high_s32(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovun_high_s64() {
|
||||
let a: u32x2 = u32x2::new(0, 0);
|
||||
let b: i64x2 = i64x2::new(-1, -1);
|
||||
let e: u32x4 = u32x4::new(0, 0, 0, 0);
|
||||
let r: u32x4 = transmute(vqmovun_high_s64(transmute(a), transmute(b)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqrdmulhh_s16() {
|
||||
let a: i16 = 1;
|
||||
|
|
|
|||
|
|
@ -8110,6 +8110,150 @@ pub unsafe fn vqdmulhq_nq_s32(a: int32x4_t, b: i32) -> int32x4_t {
|
|||
vqdmulhq_s32(a, b)
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sqxtn))]
|
||||
pub unsafe fn vqmovn_s16(a: int16x8_t) -> int8x8_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovns.v8i8")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.sqxtn.v8i8")]
|
||||
fn vqmovn_s16_(a: int16x8_t) -> int8x8_t;
|
||||
}
|
||||
vqmovn_s16_(a)
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sqxtn))]
|
||||
pub unsafe fn vqmovn_s32(a: int32x4_t) -> int16x4_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovns.v4i16")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.sqxtn.v4i16")]
|
||||
fn vqmovn_s32_(a: int32x4_t) -> int16x4_t;
|
||||
}
|
||||
vqmovn_s32_(a)
|
||||
}
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sqxtn))]
|
||||
pub unsafe fn vqmovn_s64(a: int64x2_t) -> int32x2_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovns.v2i32")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.sqxtn.v2i32")]
|
||||
fn vqmovn_s64_(a: int64x2_t) -> int32x2_t;
|
||||
}
|
||||
vqmovn_s64_(a)
|
||||
}
|
||||
|
||||
/// Unsigned saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(uqxtn))]
|
||||
pub unsafe fn vqmovn_u16(a: uint16x8_t) -> uint8x8_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovnu.v8i8")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.uqxtn.v8i8")]
|
||||
fn vqmovn_u16_(a: uint16x8_t) -> uint8x8_t;
|
||||
}
|
||||
vqmovn_u16_(a)
|
||||
}
|
||||
|
||||
/// Unsigned saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(uqxtn))]
|
||||
pub unsafe fn vqmovn_u32(a: uint32x4_t) -> uint16x4_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovnu.v4i16")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.uqxtn.v4i16")]
|
||||
fn vqmovn_u32_(a: uint32x4_t) -> uint16x4_t;
|
||||
}
|
||||
vqmovn_u32_(a)
|
||||
}
|
||||
|
||||
/// Unsigned saturating extract narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(uqxtn))]
|
||||
pub unsafe fn vqmovn_u64(a: uint64x2_t) -> uint32x2_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovnu.v2i32")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.uqxtn.v2i32")]
|
||||
fn vqmovn_u64_(a: uint64x2_t) -> uint32x2_t;
|
||||
}
|
||||
vqmovn_u64_(a)
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovun))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sqxtun))]
|
||||
pub unsafe fn vqmovun_s16(a: int16x8_t) -> uint8x8_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovnsu.v8i8")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.sqxtun.v8i8")]
|
||||
fn vqmovun_s16_(a: int16x8_t) -> uint8x8_t;
|
||||
}
|
||||
vqmovun_s16_(a)
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovun))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sqxtun))]
|
||||
pub unsafe fn vqmovun_s32(a: int32x4_t) -> uint16x4_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovnsu.v4i16")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.sqxtun.v4i16")]
|
||||
fn vqmovun_s32_(a: int32x4_t) -> uint16x4_t;
|
||||
}
|
||||
vqmovun_s32_(a)
|
||||
}
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovun))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(sqxtun))]
|
||||
pub unsafe fn vqmovun_s64(a: int64x2_t) -> uint32x2_t {
|
||||
#[allow(improper_ctypes)]
|
||||
extern "C" {
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovnsu.v2i32")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.sqxtun.v2i32")]
|
||||
fn vqmovun_s64_(a: int64x2_t) -> uint32x2_t;
|
||||
}
|
||||
vqmovun_s64_(a)
|
||||
}
|
||||
|
||||
/// Signed saturating rounding doubling multiply returning high half
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
|
|
@ -20404,6 +20548,78 @@ mod test {
|
|||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_s16() {
|
||||
let a: i16x8 = i16x8::new(0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF);
|
||||
let e: i8x8 = i8x8::new(0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F);
|
||||
let r: i8x8 = transmute(vqmovn_s16(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_s32() {
|
||||
let a: i32x4 = i32x4::new(0x7F_FF_FF_FF, 0x7F_FF_FF_FF, 0x7F_FF_FF_FF, 0x7F_FF_FF_FF);
|
||||
let e: i16x4 = i16x4::new(0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF);
|
||||
let r: i16x4 = transmute(vqmovn_s32(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_s64() {
|
||||
let a: i64x2 = i64x2::new(0x7F_FF_FF_FF_FF_FF_FF_FF, 0x7F_FF_FF_FF_FF_FF_FF_FF);
|
||||
let e: i32x2 = i32x2::new(0x7F_FF_FF_FF, 0x7F_FF_FF_FF);
|
||||
let r: i32x2 = transmute(vqmovn_s64(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_u16() {
|
||||
let a: u16x8 = u16x8::new(0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF);
|
||||
let e: u8x8 = u8x8::new(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
let r: u8x8 = transmute(vqmovn_u16(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_u32() {
|
||||
let a: u32x4 = u32x4::new(0xFF_FF_FF_FF, 0xFF_FF_FF_FF, 0xFF_FF_FF_FF, 0xFF_FF_FF_FF);
|
||||
let e: u16x4 = u16x4::new(0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF);
|
||||
let r: u16x4 = transmute(vqmovn_u32(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_u64() {
|
||||
let a: u64x2 = u64x2::new(0xFF_FF_FF_FF_FF_FF_FF_FF, 0xFF_FF_FF_FF_FF_FF_FF_FF);
|
||||
let e: u32x2 = u32x2::new(0xFF_FF_FF_FF, 0xFF_FF_FF_FF);
|
||||
let r: u32x2 = transmute(vqmovn_u64(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovun_s16() {
|
||||
let a: i16x8 = i16x8::new(-1, -1, -1, -1, -1, -1, -1, -1);
|
||||
let e: u8x8 = u8x8::new(0, 0, 0, 0, 0, 0, 0, 0);
|
||||
let r: u8x8 = transmute(vqmovun_s16(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovun_s32() {
|
||||
let a: i32x4 = i32x4::new(-1, -1, -1, -1);
|
||||
let e: u16x4 = u16x4::new(0, 0, 0, 0);
|
||||
let r: u16x4 = transmute(vqmovun_s32(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovun_s64() {
|
||||
let a: i64x2 = i64x2::new(-1, -1);
|
||||
let e: u32x2 = u32x2::new(0, 0);
|
||||
let r: u32x2 = transmute(vqmovun_s64(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqrdmulh_s16() {
|
||||
let a: i16x4 = i16x4::new(0x7F_FF, 0x7F_FF, 0x7F_FF, 0x7F_FF);
|
||||
|
|
|
|||
|
|
@ -135,11 +135,6 @@ extern "C" {
|
|||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.abs.v4i32")]
|
||||
fn vabsq_s32_(a: int32x4_t) -> int32x4_t;
|
||||
|
||||
//uint32x2_t vqmovn_u64 (uint64x2_t a)
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vqmovnu.v2i32")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.uqxtn.v2i32")]
|
||||
fn vqmovn_u64_(a: uint64x2_t) -> uint32x2_t;
|
||||
|
||||
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vpmins.v8i8")]
|
||||
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.sminp.v8i8")]
|
||||
fn vpmins_v8i8(a: int8x8_t, b: int8x8_t) -> int8x8_t;
|
||||
|
|
@ -1035,16 +1030,6 @@ pub unsafe fn vpadd_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
|
|||
transmute(vpadd_s8_(transmute(a), transmute(b)))
|
||||
}
|
||||
|
||||
/// Unsigned saturating extract narrow.
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
|
||||
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vqmovn.u64))]
|
||||
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(uqxtn))]
|
||||
pub unsafe fn vqmovn_u64(a: uint64x2_t) -> uint32x2_t {
|
||||
vqmovn_u64_(a)
|
||||
}
|
||||
|
||||
/// Vector add.
|
||||
#[inline]
|
||||
#[target_feature(enable = "neon")]
|
||||
|
|
@ -4715,14 +4700,6 @@ mod tests {
|
|||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vqmovn_u64() {
|
||||
let a = u64x2::new(1, 2);
|
||||
let e = u32x2::new(1, 2);
|
||||
let r: u32x2 = transmute(vqmovn_u64(transmute(a)));
|
||||
assert_eq!(r, e);
|
||||
}
|
||||
|
||||
#[simd_test(enable = "neon")]
|
||||
unsafe fn test_vget_high_s8() {
|
||||
let a = i8x16::new(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
|
||||
|
|
|
|||
|
|
@ -3351,6 +3351,86 @@ validate 1
|
|||
aarch64 = sqdmulh
|
||||
generate i32:int32x2_t:i32, i32:int32x4_t:i32
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
name = vqmovn
|
||||
no-q
|
||||
a = MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX
|
||||
validate MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX
|
||||
|
||||
aarch64 = sqxtn
|
||||
link-aarch64 = sqxtn._EXT2_
|
||||
arm = vqmovn
|
||||
link-arm = vqmovns._EXT2_
|
||||
generate int16x8_t:int8x8_t, int32x4_t:int16x4_t, int64x2_t:int32x2_t
|
||||
|
||||
/// Unsigned saturating extract narrow
|
||||
name = vqmovn
|
||||
no-q
|
||||
a = MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX
|
||||
validate MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX
|
||||
|
||||
aarch64 = uqxtn
|
||||
link-aarch64 = uqxtn._EXT2_
|
||||
arm = vqmovn
|
||||
link-arm = vqmovnu._EXT2_
|
||||
generate uint16x8_t:uint8x8_t, uint32x4_t:uint16x4_t, uint64x2_t:uint32x2_t
|
||||
|
||||
/// Saturating extract narrow
|
||||
name = vqmovn
|
||||
multi_fn = simd_extract, {vqmovn-in_ntt-noext, {vdupq_n-in_ntt-noext, a}}, 0
|
||||
a = 1
|
||||
validate 1
|
||||
|
||||
aarch64 = sqxtn
|
||||
generate i16:i8, i32:i16, i64:i32
|
||||
aarch64 = uqxtn
|
||||
generate u16:u8, u32:u16, u64:u32
|
||||
|
||||
/// Signed saturating extract narrow
|
||||
name = vqmovn_high
|
||||
no-q
|
||||
multi_fn = simd_shuffle-out_len-!, a, {vqmovn-noqself-noext, b}, {asc-0-out_len}
|
||||
a = MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX
|
||||
b = MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX
|
||||
validate MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX
|
||||
|
||||
aarch64 = sqxtn2
|
||||
generate int8x8_t:int16x8_t:int8x16_t, int16x4_t:int32x4_t:int16x8_t, int32x2_t:int64x2_t:int32x4_t
|
||||
aarch64 = uqxtn2
|
||||
generate uint8x8_t:uint16x8_t:uint8x16_t, uint16x4_t:uint32x4_t:uint16x8_t, uint32x2_t:uint64x2_t:uint32x4_t
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
name = vqmovun
|
||||
no-q
|
||||
a = -1, -1, -1, -1, -1, -1, -1, -1
|
||||
validate 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
aarch64 = sqxtun
|
||||
link-aarch64 = sqxtun._EXT2_
|
||||
arm = vqmovun
|
||||
link-arm = vqmovnsu._EXT2_
|
||||
generate int16x8_t:uint8x8_t, int32x4_t:uint16x4_t, int64x2_t:uint32x2_t
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
name = vqmovun
|
||||
multi_fn = simd_extract, {vqmovun-in_ntt-noext, {vdupq_n-in_ntt-noext, a}}, 0
|
||||
a = 1
|
||||
validate 1
|
||||
|
||||
aarch64 = sqxtun
|
||||
generate i16:u8, i32:u16, i64:u32
|
||||
|
||||
/// Signed saturating extract unsigned narrow
|
||||
name = vqmovun_high
|
||||
no-q
|
||||
multi_fn = simd_shuffle-out_len-!, a, {vqmovun-noqself-noext, b}, {asc-0-out_len}
|
||||
a = 0, 0, 0, 0, 0, 0, 0, 0
|
||||
b = -1, -1, -1, -1, -1, -1, -1, -1
|
||||
validate 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
|
||||
aarch64 = sqxtun2
|
||||
generate uint8x8_t:int16x8_t:uint8x16_t, uint16x4_t:int32x4_t:uint16x8_t, uint32x2_t:int64x2_t:uint32x4_t
|
||||
|
||||
/// Signed saturating rounding doubling multiply returning high half
|
||||
name = vqrdmulh
|
||||
a = MAX, MAX, MAX, MAX, MAX, MAX, MAX, MAX
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue