Completion of vcvt neon instruction

This commit is contained in:
SparrowLii 2021-05-07 19:58:30 +08:00 committed by Amanieu d'Antras
parent ed761b261c
commit 8a2936b9a2
4 changed files with 1716 additions and 34 deletions

View file

@ -2004,6 +2004,402 @@ pub unsafe fn vcaleq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
vcageq_f32(b, a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_s8(a: u64) -> int8x8_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_s32(a: u64) -> int32x2_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_s64(a: u64) -> int64x1_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_u8(a: u64) -> uint8x8_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_u32(a: u64) -> uint32x2_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_u64(a: u64) -> uint64x1_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_p8(a: u64) -> poly8x8_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_p16(a: u64) -> poly16x4_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon,crypto")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "crypto,v8"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_p64(a: u64) -> poly64x1_t {
transmute(a)
}
/// Insert vector element from another vector element
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(nop))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(nop))]
pub unsafe fn vcreate_f32(a: u64) -> float32x2_t {
transmute(a)
}
/// Fixed-point convert to floating-point
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(scvtf))]
pub unsafe fn vcvt_f32_s32(a: int32x2_t) -> float32x2_t {
simd_cast(a)
}
/// Fixed-point convert to floating-point
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(scvtf))]
pub unsafe fn vcvtq_f32_s32(a: int32x4_t) -> float32x4_t {
simd_cast(a)
}
/// Fixed-point convert to floating-point
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ucvtf))]
pub unsafe fn vcvt_f32_u32(a: uint32x2_t) -> float32x2_t {
simd_cast(a)
}
/// Fixed-point convert to floating-point
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ucvtf))]
pub unsafe fn vcvtq_f32_u32(a: uint32x4_t) -> float32x4_t {
simd_cast(a)
}
/// Fixed-point convert to floating-point
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvt_n_f32_s32<const N: i32>(a: int32x2_t) -> float32x2_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vcvtfxs2fp.v2f32.v2i32")]
fn vcvt_n_f32_s32_(a: int32x2_t, n: i32) -> float32x2_t;
}
vcvt_n_f32_s32_(a, N)
}
/// Fixed-point convert to floating-point
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(scvtf, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvt_n_f32_s32<const N: i32>(a: int32x2_t) -> float32x2_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.vcvtfxs2fp.v2f32.v2i32")]
fn vcvt_n_f32_s32_(a: int32x2_t, n: i32) -> float32x2_t;
}
vcvt_n_f32_s32_(a, N)
}
/// Fixed-point convert to floating-point
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvtq_n_f32_s32<const N: i32>(a: int32x4_t) -> float32x4_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vcvtfxs2fp.v4f32.v4i32")]
fn vcvtq_n_f32_s32_(a: int32x4_t, n: i32) -> float32x4_t;
}
vcvtq_n_f32_s32_(a, N)
}
/// Fixed-point convert to floating-point
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(scvtf, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvtq_n_f32_s32<const N: i32>(a: int32x4_t) -> float32x4_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.vcvtfxs2fp.v4f32.v4i32")]
fn vcvtq_n_f32_s32_(a: int32x4_t, n: i32) -> float32x4_t;
}
vcvtq_n_f32_s32_(a, N)
}
/// Fixed-point convert to floating-point
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvt_n_f32_u32<const N: i32>(a: uint32x2_t) -> float32x2_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vcvtfxu2fp.v2f32.v2i32")]
fn vcvt_n_f32_u32_(a: uint32x2_t, n: i32) -> float32x2_t;
}
vcvt_n_f32_u32_(a, N)
}
/// Fixed-point convert to floating-point
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ucvtf, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvt_n_f32_u32<const N: i32>(a: uint32x2_t) -> float32x2_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.vcvtfxu2fp.v2f32.v2i32")]
fn vcvt_n_f32_u32_(a: uint32x2_t, n: i32) -> float32x2_t;
}
vcvt_n_f32_u32_(a, N)
}
/// Fixed-point convert to floating-point
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvtq_n_f32_u32<const N: i32>(a: uint32x4_t) -> float32x4_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vcvtfxu2fp.v4f32.v4i32")]
fn vcvtq_n_f32_u32_(a: uint32x4_t, n: i32) -> float32x4_t;
}
vcvtq_n_f32_u32_(a, N)
}
/// Fixed-point convert to floating-point
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(ucvtf, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvtq_n_f32_u32<const N: i32>(a: uint32x4_t) -> float32x4_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.vcvtfxu2fp.v4f32.v4i32")]
fn vcvtq_n_f32_u32_(a: uint32x4_t, n: i32) -> float32x4_t;
}
vcvtq_n_f32_u32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvt_n_s32_f32<const N: i32>(a: float32x2_t) -> int32x2_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vcvtfp2fxs.v2i32.v2f32")]
fn vcvt_n_s32_f32_(a: float32x2_t, n: i32) -> int32x2_t;
}
vcvt_n_s32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(fcvtzs, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvt_n_s32_f32<const N: i32>(a: float32x2_t) -> int32x2_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.vcvtfp2fxs.v2i32.v2f32")]
fn vcvt_n_s32_f32_(a: float32x2_t, n: i32) -> int32x2_t;
}
vcvt_n_s32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvtq_n_s32_f32<const N: i32>(a: float32x4_t) -> int32x4_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vcvtfp2fxs.v4i32.v4f32")]
fn vcvtq_n_s32_f32_(a: float32x4_t, n: i32) -> int32x4_t;
}
vcvtq_n_s32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(fcvtzs, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvtq_n_s32_f32<const N: i32>(a: float32x4_t) -> int32x4_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.vcvtfp2fxs.v4i32.v4f32")]
fn vcvtq_n_s32_f32_(a: float32x4_t, n: i32) -> int32x4_t;
}
vcvtq_n_s32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvt_n_u32_f32<const N: i32>(a: float32x2_t) -> uint32x2_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vcvtfp2fxu.v2i32.v2f32")]
fn vcvt_n_u32_f32_(a: float32x2_t, n: i32) -> uint32x2_t;
}
vcvt_n_u32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(fcvtzu, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvt_n_u32_f32<const N: i32>(a: float32x2_t) -> uint32x2_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.vcvtfp2fxu.v2i32.v2f32")]
fn vcvt_n_u32_f32_(a: float32x2_t, n: i32) -> uint32x2_t;
}
vcvt_n_u32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
#[inline]
#[cfg(target_arch = "arm")]
#[target_feature(enable = "neon,v7")]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vcvt, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvtq_n_u32_f32<const N: i32>(a: float32x4_t) -> uint32x4_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "arm", link_name = "llvm.arm.neon.vcvtfp2fxu.v4i32.v4f32")]
fn vcvtq_n_u32_f32_(a: float32x4_t, n: i32) -> uint32x4_t;
}
vcvtq_n_u32_f32_(a, N)
}
/// Floating-point convert to fixed-point, rounding toward zero
#[inline]
#[cfg(target_arch = "aarch64")]
#[target_feature(enable = "neon")]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(fcvtzu, N = 2))]
#[rustc_legacy_const_generics(1)]
pub unsafe fn vcvtq_n_u32_f32<const N: i32>(a: float32x4_t) -> uint32x4_t {
static_assert!(N : i32 where N >= 1 && N <= 32);
#[allow(improper_ctypes)]
extern "C" {
#[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.neon.vcvtfp2fxu.v4i32.v4f32")]
fn vcvtq_n_u32_f32_(a: float32x4_t, n: i32) -> uint32x4_t;
}
vcvtq_n_u32_f32_(a, N)
}
/// Floating-point convert to signed fixed-point, rounding toward zero
#[inline]
#[target_feature(enable = "neon")]
@ -15457,6 +15853,182 @@ mod test {
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_s8() {
let a: u64 = 1;
let e: i8x8 = i8x8::new(1, 0, 0, 0, 0, 0, 0, 0);
let r: i8x8 = transmute(vcreate_s8(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_s32() {
let a: u64 = 1;
let e: i32x2 = i32x2::new(1, 0);
let r: i32x2 = transmute(vcreate_s32(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_s64() {
let a: u64 = 1;
let e: i64x1 = i64x1::new(1);
let r: i64x1 = transmute(vcreate_s64(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_u8() {
let a: u64 = 1;
let e: u8x8 = u8x8::new(1, 0, 0, 0, 0, 0, 0, 0);
let r: u8x8 = transmute(vcreate_u8(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_u32() {
let a: u64 = 1;
let e: u32x2 = u32x2::new(1, 0);
let r: u32x2 = transmute(vcreate_u32(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_u64() {
let a: u64 = 1;
let e: u64x1 = u64x1::new(1);
let r: u64x1 = transmute(vcreate_u64(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_p8() {
let a: u64 = 1;
let e: i8x8 = i8x8::new(1, 0, 0, 0, 0, 0, 0, 0);
let r: i8x8 = transmute(vcreate_p8(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_p16() {
let a: u64 = 1;
let e: i16x4 = i16x4::new(1, 0, 0, 0);
let r: i16x4 = transmute(vcreate_p16(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_p64() {
let a: u64 = 1;
let e: i64x1 = i64x1::new(1);
let r: i64x1 = transmute(vcreate_p64(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcreate_f32() {
let a: u64 = 0;
let e: f32x2 = f32x2::new(0., 0.);
let r: f32x2 = transmute(vcreate_f32(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvt_f32_s32() {
let a: i32x2 = i32x2::new(1, 2);
let e: f32x2 = f32x2::new(1., 2.);
let r: f32x2 = transmute(vcvt_f32_s32(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvtq_f32_s32() {
let a: i32x4 = i32x4::new(1, 2, 3, 4);
let e: f32x4 = f32x4::new(1., 2., 3., 4.);
let r: f32x4 = transmute(vcvtq_f32_s32(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvt_f32_u32() {
let a: u32x2 = u32x2::new(1, 2);
let e: f32x2 = f32x2::new(1., 2.);
let r: f32x2 = transmute(vcvt_f32_u32(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvtq_f32_u32() {
let a: u32x4 = u32x4::new(1, 2, 3, 4);
let e: f32x4 = f32x4::new(1., 2., 3., 4.);
let r: f32x4 = transmute(vcvtq_f32_u32(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvt_n_f32_s32() {
let a: i32x2 = i32x2::new(1, 2);
let e: f32x2 = f32x2::new(0.25, 0.5);
let r: f32x2 = transmute(vcvt_n_f32_s32::<2>(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvtq_n_f32_s32() {
let a: i32x4 = i32x4::new(1, 2, 3, 4);
let e: f32x4 = f32x4::new(0.25, 0.5, 0.75, 1.);
let r: f32x4 = transmute(vcvtq_n_f32_s32::<2>(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvt_n_f32_u32() {
let a: u32x2 = u32x2::new(1, 2);
let e: f32x2 = f32x2::new(0.25, 0.5);
let r: f32x2 = transmute(vcvt_n_f32_u32::<2>(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvtq_n_f32_u32() {
let a: u32x4 = u32x4::new(1, 2, 3, 4);
let e: f32x4 = f32x4::new(0.25, 0.5, 0.75, 1.);
let r: f32x4 = transmute(vcvtq_n_f32_u32::<2>(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvt_n_s32_f32() {
let a: f32x2 = f32x2::new(0.25, 0.5);
let e: i32x2 = i32x2::new(1, 2);
let r: i32x2 = transmute(vcvt_n_s32_f32::<2>(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvtq_n_s32_f32() {
let a: f32x4 = f32x4::new(0.25, 0.5, 0.75, 1.);
let e: i32x4 = i32x4::new(1, 2, 3, 4);
let r: i32x4 = transmute(vcvtq_n_s32_f32::<2>(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvt_n_u32_f32() {
let a: f32x2 = f32x2::new(0.25, 0.5);
let e: u32x2 = u32x2::new(1, 2);
let r: u32x2 = transmute(vcvt_n_u32_f32::<2>(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvtq_n_u32_f32() {
let a: f32x4 = f32x4::new(0.25, 0.5, 0.75, 1.);
let e: u32x4 = u32x4::new(1, 2, 3, 4);
let r: u32x4 = transmute(vcvtq_n_u32_f32::<2>(transmute(a)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vcvt_s32_f32() {
let a: f32x2 = f32x2::new(-1.1, 2.1);

View file

@ -839,6 +839,51 @@ generate float32x4_t:float32x2_t:float32x4_t
aarch64 = zip1
generate float64x2_t:float64x1_t:float64x2_t
/// Insert vector element from another vector element
name = vcreate
out-suffix
multi_fn = transmute, a
a = 1
validate 1, 0, 0, 0, 0, 0, 0, 0
aarch64 = nop
arm = nop
generate u64:int8x8_t, u64:int16x4_t: u64:int32x2_t, u64:int64x1_t
generate u64:uint8x8_t, u64:uint16x4_t: u64:uint32x2_t, u64:uint64x1_t
generate u64:poly8x8_t, u64:poly16x4_t
target = crypto
generate u64:poly64x1_t
/// Insert vector element from another vector element
name = vcreate
out-suffix
multi_fn = transmute, a
a = 0
validate 0., 0.
aarch64 = nop
generate u64:float64x1_t
arm = nop
generate u64:float32x2_t
/// Fixed-point convert to floating-point
name = vcvt
double-suffixes
fn = simd_cast
a = 1, 2, 3, 4
validate 1., 2., 3., 4.
aarch64 = scvtf
generate int64x1_t:float64x1_t, int64x2_t:float64x2_t
aarch64 = ucvtf
generate uint64x1_t:float64x1_t, uint64x2_t:float64x2_t
arm = vcvt
aarch64 = scvtf
generate int32x2_t:float32x2_t, int32x4_t:float32x4_t
aarch64 = ucvtf
generate uint32x2_t:float32x2_t, uint32x4_t:float32x4_t
/// Floating-point convert to higher precision long
name = vcvt
double-suffixes
@ -902,6 +947,96 @@ validate -1.0, 2.0, -3.0, 4.0
aarch64 = fcvtxn
generate float32x2_t:float64x2_t:float32x4_t
/// Fixed-point convert to floating-point
name = vcvt
double-n-suffixes
constn = N
multi_fn = static_assert-N-1-bits
a = 1, 2, 3, 4
n = 2
validate 0.25, 0.5, 0.75, 1.
aarch64 = scvtf
link-aarch64 = vcvtfxs2fp._EXT2_._EXT_
const-aarch64 = N
generate int64x1_t:float64x1_t, int64x2_t:float64x2_t, i32:f32, i64:f64
aarch64 = ucvtf
link-aarch64 = vcvtfxu2fp._EXT2_._EXT_
const-aarch64 = N
generate uint64x1_t:float64x1_t, uint64x2_t:float64x2_t, u32:f32, u64:f64
aarch64 = scvtf
link-aarch64 = vcvtfxs2fp._EXT2_._EXT_
arm = vcvt
link-arm = vcvtfxs2fp._EXT2_._EXT_
const-arm = N:i32
generate int32x2_t:float32x2_t, int32x4_t:float32x4_t
aarch64 = ucvtf
link-aarch64 = vcvtfxu2fp._EXT2_._EXT_
arm = vcvt
link-arm = vcvtfxu2fp._EXT2_._EXT_
const-arm = N:i32
generate uint32x2_t:float32x2_t, uint32x4_t:float32x4_t
/// Floating-point convert to fixed-point, rounding toward zero
name = vcvt
double-n-suffixes
constn = N
multi_fn = static_assert-N-1-bits
a = 0.25, 0.5, 0.75, 1.
n = 2
validate 1, 2, 3, 4
aarch64 = fcvtzs
link-aarch64 = vcvtfp2fxs._EXT2_._EXT_
const-aarch64 = N
generate float64x1_t:int64x1_t, float64x2_t:int64x2_t, f32:i32, f64:i64
aarch64 = fcvtzu
link-aarch64 = vcvtfp2fxu._EXT2_._EXT_
const-aarch64 = N
generate float64x1_t:uint64x1_t, float64x2_t:uint64x2_t, f32:u32, f64:u64
aarch64 = fcvtzs
link-aarch64 = vcvtfp2fxs._EXT2_._EXT_
arm = vcvt
link-arm = vcvtfp2fxs._EXT2_._EXT_
const-arm = N:i32
generate float32x2_t:int32x2_t, float32x4_t:int32x4_t
aarch64 = fcvtzu
link-aarch64 = vcvtfp2fxu._EXT2_._EXT_
arm = vcvt
link-arm = vcvtfp2fxu._EXT2_._EXT_
const-arm = N:i32
generate float32x2_t:uint32x2_t, float32x4_t:uint32x4_t
/// Fixed-point convert to floating-point
name = vcvt
double-suffixes
multi_fn = a as out_t
a = 1
validate 1.
aarch64 = scvtf
generate i32:f32, i64:f64
aarch64 = ucvtf
generate u32:f32, u64:f64
/// Fixed-point convert to floating-point
name = vcvt
double-suffixes
multi_fn = a as out_t
a = 1.
validate 1
aarch64 = fcvtzs
generate f32:i32, f64:i64
aarch64 = fcvtzu
generate f32:u32, f64:u64
/// Floating-point convert to signed fixed-point, rounding toward zero
name = vcvt
double-suffixes
@ -938,6 +1073,20 @@ aarch64 = fcvtas
link-aarch64 = fcvtas._EXT2_._EXT_
generate float32x2_t:int32x2_t, float32x4_t:int32x4_t, float64x1_t:int64x1_t, float64x2_t:int64x2_t
/// Floating-point convert to integer, rounding to nearest with ties to away
name = vcvta
double-suffixes
a = 2.9
validate 3
aarch64 = fcvtas
link-aarch64 = fcvtas._EXT2_._EXT_
generate f32:i32, f64:i64
aarch64 = fcvtau
link-aarch64 = fcvtau._EXT2_._EXT_
generate f32:u32, f64:u64
/// Floating-point convert to signed integer, rounding to nearest with ties to even
name = vcvtn
double-suffixes
@ -946,7 +1095,7 @@ validate -2, 2, -3, 4
aarch64 = fcvtns
link-aarch64 = fcvtns._EXT2_._EXT_
generate float32x2_t:int32x2_t, float32x4_t:int32x4_t, float64x1_t:int64x1_t, float64x2_t:int64x2_t
generate float32x2_t:int32x2_t, float32x4_t:int32x4_t, float64x1_t:int64x1_t, float64x2_t:int64x2_t, f32:i32, f64:i64
/// Floating-point convert to signed integer, rounding toward minus infinity
name = vcvtm
@ -956,7 +1105,7 @@ validate -2, 2, -3, 3
aarch64 = fcvtms
link-aarch64 = fcvtms._EXT2_._EXT_
generate float32x2_t:int32x2_t, float32x4_t:int32x4_t, float64x1_t:int64x1_t, float64x2_t:int64x2_t
generate float32x2_t:int32x2_t, float32x4_t:int32x4_t, float64x1_t:int64x1_t, float64x2_t:int64x2_t, f32:i32, f64:i64
/// Floating-point convert to signed integer, rounding toward plus infinity
name = vcvtp
@ -966,7 +1115,7 @@ validate -1, 3, -2, 4
aarch64 = fcvtps
link-aarch64 = fcvtps._EXT2_._EXT_
generate float32x2_t:int32x2_t, float32x4_t:int32x4_t, float64x1_t:int64x1_t, float64x2_t:int64x2_t
generate float32x2_t:int32x2_t, float32x4_t:int32x4_t, float64x1_t:int64x1_t, float64x2_t:int64x2_t, f32:i32, f64:i64
/// Floating-point convert to unsigned integer, rounding to nearest with ties to away
name = vcvta
@ -986,7 +1135,7 @@ validate 2, 2, 3, 4
aarch64 = fcvtnu
link-aarch64 = fcvtnu._EXT2_._EXT_
generate float32x2_t:uint32x2_t, float32x4_t:uint32x4_t, float64x1_t:uint64x1_t, float64x2_t:uint64x2_t
generate float32x2_t:uint32x2_t, float32x4_t:uint32x4_t, float64x1_t:uint64x1_t, float64x2_t:uint64x2_t, f32:u32, f64:u64
/// Floating-point convert to unsigned integer, rounding toward minus infinity
name = vcvtm
@ -996,7 +1145,7 @@ validate 1, 2, 2, 3
aarch64 = fcvtmu
link-aarch64 = fcvtmu._EXT2_._EXT_
generate float32x2_t:uint32x2_t, float32x4_t:uint32x4_t, float64x1_t:uint64x1_t, float64x2_t:uint64x2_t
generate float32x2_t:uint32x2_t, float32x4_t:uint32x4_t, float64x1_t:uint64x1_t, float64x2_t:uint64x2_t, f32:u32, f64:u64
/// Floating-point convert to unsigned integer, rounding toward plus infinity
name = vcvtp
@ -1006,7 +1155,7 @@ validate 2, 3, 3, 4
aarch64 = fcvtpu
link-aarch64 = fcvtpu._EXT2_._EXT_
generate float32x2_t:uint32x2_t, float32x4_t:uint32x4_t, float64x1_t:uint64x1_t, float64x2_t:uint64x2_t
generate float32x2_t:uint32x2_t, float32x4_t:uint32x4_t, float64x1_t:uint64x1_t, float64x2_t:uint64x2_t, f32:u32, f64:u64
/// Set all vector lanes to the same value
name = vdup

View file

@ -92,9 +92,10 @@ fn type_bits(t: &str) -> usize {
| "i8" | "u8" => 8,
"int16x4_t" | "int16x8_t" | "uint16x4_t" | "uint16x8_t" | "poly16x4_t" | "poly16x8_t"
| "i16" | "u16" => 16,
"int32x2_t" | "int32x4_t" | "uint32x2_t" | "uint32x4_t" | "i32" | "u32" => 32,
"int32x2_t" | "int32x4_t" | "uint32x2_t" | "uint32x4_t" | "i32" | "u32" | "float32x2_t"
| "float32x4_t" | "f32" => 32,
"int64x1_t" | "int64x2_t" | "uint64x1_t" | "uint64x2_t" | "poly64x1_t" | "poly64x2_t"
| "i64" | "u64" => 64,
| "i64" | "u64" | "float64x1_t" | "float64x2_t" | "f64" => 64,
_ => panic!("unknown type: {}", t),
}
}
@ -303,9 +304,28 @@ fn type_to_unsigned(t: &str) -> &str {
fn type_to_double_suffixes<'a>(out_t: &'a str, in_t: &'a str) -> String {
let mut str = String::new();
if type_to_suffix(in_t).starts_with("q") && type_to_suffix(out_t).starts_with("q") {
let suf = type_to_suffix(in_t);
if suf.starts_with("q") && type_to_suffix(out_t).starts_with("q") {
str.push_str("q");
}
if !suf.starts_with("_") && !suf.starts_with("q") {
str.push_str(&suf[0..1]);
}
str.push_str(type_to_noq_suffix(out_t));
str.push_str(type_to_noq_suffix(in_t));
str
}
fn type_to_double_n_suffixes<'a>(out_t: &'a str, in_t: &'a str) -> String {
let mut str = String::new();
let suf = type_to_suffix(in_t);
if suf.starts_with("q") && type_to_suffix(out_t).starts_with("q") {
str.push_str("q");
}
if !suf.starts_with("_") && !suf.starts_with("q") {
str.push_str(&suf[0..1]);
}
str.push_str("_n");
str.push_str(type_to_noq_suffix(out_t));
str.push_str(type_to_noq_suffix(in_t));
str
@ -329,8 +349,8 @@ fn type_to_noq_suffix(t: &str) -> &str {
"uint32x2_t" | "uint32x4_t" | "u32" => "_u32",
"uint64x1_t" | "uint64x2_t" | "u64" => "_u64",
"float16x4_t" | "float16x8_t" => "_f16",
"float32x2_t" | "float32x4_t" => "_f32",
"float64x1_t" | "float64x2_t" => "_f64",
"float32x2_t" | "float32x4_t" | "f32" => "_f32",
"float64x1_t" | "float64x2_t" | "f64" => "_f64",
"poly8x8_t" | "poly8x16_t" => "_p8",
"poly16x4_t" | "poly16x8_t" => "_p16",
"poly64x1_t" | "poly64x2_t" | "p64" => "_p64",
@ -345,6 +365,7 @@ enum Suffix {
NoQ,
NoQDouble,
NSuffix,
DoubleN,
NoQNSuffix,
OutSuffix,
OutNSuffix,
@ -489,14 +510,14 @@ fn type_to_ext(t: &str) -> &str {
"poly8x16_t" => "v16i8",
"poly16x4_t" => "v4i16",
"poly16x8_t" => "v8i16",
"i8" => "v8i8",
"i16" => "v4i16",
"i32" => "v2i32",
"i64" => "v1i64",
"u8" => "v8i8",
"u16" => "v4i16",
"u32" => "v2i32",
"u64" => "v1i64",
"i8" => "i8",
"i16" => "i16",
"i32" => "i32",
"i64" => "i64",
"u8" => "i8",
"u16" => "i16",
"u32" => "i32",
"u64" => "i64",
"f32" => "f32",
"f64" => "f64",
"p64" => "p64",
@ -854,6 +875,11 @@ fn gen_aarch64(
type_to_noq_double_suffixes(out_t, in_t[1])
),
NSuffix => format!("{}{}", current_name, type_to_n_suffix(in_t[1])),
DoubleN => format!(
"{}{}",
current_name,
type_to_double_n_suffixes(out_t, in_t[1])
),
NoQNSuffix => format!("{}{}", current_name, type_to_noq_n_suffix(in_t[1])),
OutSuffix => format!("{}{}", current_name, type_to_suffix(out_t)),
OutNSuffix => format!("{}{}", current_name, type_to_n_suffix(out_t)),
@ -1295,6 +1321,11 @@ fn gen_arm(
type_to_noq_double_suffixes(out_t, in_t[1])
),
NSuffix => format!("{}{}", current_name, type_to_n_suffix(in_t[1])),
DoubleN => format!(
"{}{}",
current_name,
type_to_double_n_suffixes(out_t, in_t[1])
),
NoQNSuffix => format!("{}{}", current_name, type_to_noq_n_suffix(in_t[1])),
OutSuffix => format!("{}{}", current_name, type_to_suffix(out_t)),
OutNSuffix => format!("{}{}", current_name, type_to_n_suffix(out_t)),
@ -1432,7 +1463,16 @@ fn gen_arm(
out_t
);
};
if const_arm.is_some() {
if let Some(const_arm) = const_arm {
let (_, const_type) = if const_arm.contains(":") {
let consts: Vec<_> = const_arm.split(':').map(|v| v.trim().to_string()).collect();
(consts[0].clone(), consts[1].clone())
} else {
(
const_arm.to_string(),
in_t[para_num as usize - 1].to_string(),
)
};
ext_c_arm.push_str(&format!(
r#"#[allow(improper_ctypes)]
extern "C" {{
@ -1444,15 +1484,15 @@ fn gen_arm(
current_fn,
match para_num {
1 => {
format!("a: {}, n: {}", in_t[0], in_t[0])
format!("a: {}, n: {}", in_t[0], const_type)
}
2 => {
format!("a: {}, b: {}, n: {}", in_t[0], in_t[1], in_t[1])
format!("a: {}, b: {}, n: {}", in_t[0], in_t[1], const_type)
}
3 => {
format!(
"a: {}, b: {}, c: {}, n: {}",
in_t[0], in_t[1], in_t[2], in_t[2]
in_t[0], in_t[1], in_t[2], const_type
)
}
_ => unimplemented!("unknown para_num"),
@ -1641,16 +1681,22 @@ fn gen_arm(
(_, _, _) => String::new(),
};
let call_arm = if let Some(const_arm) = const_arm {
let const_arm = const_arm.replace("ttn", type_to_native_type(in_t[1]));
let mut cnt = String::from(in_t[1]);
cnt.push_str("(");
for i in 0..type_len(in_t[1]) {
if i != 0 {
cnt.push_str(", ");
let cnt = if const_arm.contains(':') {
let consts: Vec<_> = const_arm.split(':').map(|v| v.trim().to_string()).collect();
consts[0].clone()
} else {
let const_arm = const_arm.replace("ttn", type_to_native_type(in_t[1]));
let mut cnt = String::from(in_t[1]);
cnt.push_str("(");
for i in 0..type_len(in_t[1]) {
if i != 0 {
cnt.push_str(", ");
}
cnt.push_str(&const_arm);
}
cnt.push_str(&const_arm);
}
cnt.push_str(")");
cnt.push_str(")");
cnt
};
match para_num {
1 => format!(
r#"pub unsafe fn {}{}(a: {}) -> {} {{
@ -1815,13 +1861,14 @@ fn gen_arm(
r#"
{}
#[inline]
#[target_feature(enable = "neon")]
#[target_feature(enable = "{}")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "{}"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr({}{}))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr({}{}))]{}
{}
"#,
current_comment,
current_target_aarch64,
current_target_arm,
expand_intrinsic(&current_arm, in_t[1]),
const_assert,
@ -2305,7 +2352,7 @@ fn get_call(
}
}
if param_str.is_empty() {
return fn_name;
return fn_name.replace("out_t", out_t);
}
let fn_str = if let Some((re_name, re_type)) = re.clone() {
format!(
@ -2453,6 +2500,8 @@ mod test {
suffix = NoQDouble;
} else if line.starts_with("n-suffix") {
suffix = NSuffix;
} else if line.starts_with("double-n-suffixes") {
suffix = DoubleN;
} else if line.starts_with("out-n-suffix") {
suffix = OutNSuffix;
} else if line.starts_with("noq-n-suffix") {