Modify stdarch-gen to generate instructions composed of multiple functions and add vtst instructions (#1063)

This commit is contained in:
Sparrow Li 2021-03-08 19:15:04 +08:00 committed by GitHub
parent 6b8d9a67ca
commit b042298bc4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 537 additions and 34 deletions

View file

@ -297,6 +297,66 @@ pub unsafe fn vceqzq_f64(a: float64x2_t) -> uint64x2_t {
simd_eq(a, transmute(b))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
pub unsafe fn vtst_s64(a: int64x1_t, b: int64x1_t) -> uint64x1_t {
let c: int64x1_t = simd_and(a, b);
let d: i64x1 = i64x1::new(0);
simd_ne(c, transmute(d))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
pub unsafe fn vtstq_s64(a: int64x2_t, b: int64x2_t) -> uint64x2_t {
let c: int64x2_t = simd_and(a, b);
let d: i64x2 = i64x2::new(0, 0);
simd_ne(c, transmute(d))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
pub unsafe fn vtst_p64(a: poly64x1_t, b: poly64x1_t) -> uint64x1_t {
let c: poly64x1_t = simd_and(a, b);
let d: i64x1 = i64x1::new(0);
simd_ne(c, transmute(d))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
pub unsafe fn vtstq_p64(a: poly64x2_t, b: poly64x2_t) -> uint64x2_t {
let c: poly64x2_t = simd_and(a, b);
let d: i64x2 = i64x2::new(0, 0);
simd_ne(c, transmute(d))
}
/// Unsigned compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
pub unsafe fn vtst_u64(a: uint64x1_t, b: uint64x1_t) -> uint64x1_t {
let c: uint64x1_t = simd_and(a, b);
let d: u64x1 = u64x1::new(0);
simd_ne(c, transmute(d))
}
/// Unsigned compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(test, assert_instr(cmtst))]
pub unsafe fn vtstq_u64(a: uint64x2_t, b: uint64x2_t) -> uint64x2_t {
let c: uint64x2_t = simd_and(a, b);
let d: u64x2 = u64x2::new(0, 0);
simd_ne(c, transmute(d))
}
/// Floating-point absolute value
#[inline]
#[target_feature(enable = "neon")]
@ -898,6 +958,60 @@ mod test {
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_s64() {
let a: i64x1 = i64x1::new(-9223372036854775808);
let b: i64x1 = i64x1::new(-9223372036854775808);
let e: u64x1 = u64x1::new(0xFF_FF_FF_FF_FF_FF_FF_FF);
let r: u64x1 = transmute(vtst_s64(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_s64() {
let a: i64x2 = i64x2::new(-9223372036854775808, 0x00);
let b: i64x2 = i64x2::new(-9223372036854775808, 0x00);
let e: u64x2 = u64x2::new(0xFF_FF_FF_FF_FF_FF_FF_FF, 0);
let r: u64x2 = transmute(vtstq_s64(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_p64() {
let a: i64x1 = i64x1::new(-9223372036854775808);
let b: i64x1 = i64x1::new(-9223372036854775808);
let e: u64x1 = u64x1::new(0xFF_FF_FF_FF_FF_FF_FF_FF);
let r: u64x1 = transmute(vtst_p64(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_p64() {
let a: i64x2 = i64x2::new(-9223372036854775808, 0x00);
let b: i64x2 = i64x2::new(-9223372036854775808, 0x00);
let e: u64x2 = u64x2::new(0xFF_FF_FF_FF_FF_FF_FF_FF, 0);
let r: u64x2 = transmute(vtstq_p64(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_u64() {
let a: u64x1 = u64x1::new(0);
let b: u64x1 = u64x1::new(0);
let e: u64x1 = u64x1::new(0);
let r: u64x1 = transmute(vtst_u64(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_u64() {
let a: u64x2 = u64x2::new(0, 0x00);
let b: u64x2 = u64x2::new(0, 0x00);
let e: u64x2 = u64x2::new(0, 0);
let r: u64x2 = transmute(vtstq_u64(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vabs_f64() {
let a: f64 = -0.1;

View file

@ -853,6 +853,150 @@ pub unsafe fn vceqq_f32(a: float32x4_t, b: float32x4_t) -> uint32x4_t {
simd_eq(a, b)
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtst_s8(a: int8x8_t, b: int8x8_t) -> uint8x8_t {
let c: int8x8_t = simd_and(a, b);
let d: i8x8 = i8x8::new(0, 0, 0, 0, 0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtstq_s8(a: int8x16_t, b: int8x16_t) -> uint8x16_t {
let c: int8x16_t = simd_and(a, b);
let d: i8x16 = i8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtst_s16(a: int16x4_t, b: int16x4_t) -> uint16x4_t {
let c: int16x4_t = simd_and(a, b);
let d: i16x4 = i16x4::new(0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtstq_s16(a: int16x8_t, b: int16x8_t) -> uint16x8_t {
let c: int16x8_t = simd_and(a, b);
let d: i16x8 = i16x8::new(0, 0, 0, 0, 0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtst_s32(a: int32x2_t, b: int32x2_t) -> uint32x2_t {
let c: int32x2_t = simd_and(a, b);
let d: i32x2 = i32x2::new(0, 0);
simd_ne(c, transmute(d))
}
/// Signed compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtstq_s32(a: int32x4_t, b: int32x4_t) -> uint32x4_t {
let c: int32x4_t = simd_and(a, b);
let d: i32x4 = i32x4::new(0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Unsigned compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtst_u8(a: uint8x8_t, b: uint8x8_t) -> uint8x8_t {
let c: uint8x8_t = simd_and(a, b);
let d: u8x8 = u8x8::new(0, 0, 0, 0, 0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Unsigned compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtstq_u8(a: uint8x16_t, b: uint8x16_t) -> uint8x16_t {
let c: uint8x16_t = simd_and(a, b);
let d: u8x16 = u8x16::new(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Unsigned compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtst_u16(a: uint16x4_t, b: uint16x4_t) -> uint16x4_t {
let c: uint16x4_t = simd_and(a, b);
let d: u16x4 = u16x4::new(0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Unsigned compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtstq_u16(a: uint16x8_t, b: uint16x8_t) -> uint16x8_t {
let c: uint16x8_t = simd_and(a, b);
let d: u16x8 = u16x8::new(0, 0, 0, 0, 0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Unsigned compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtst_u32(a: uint32x2_t, b: uint32x2_t) -> uint32x2_t {
let c: uint32x2_t = simd_and(a, b);
let d: u32x2 = u32x2::new(0, 0);
simd_ne(c, transmute(d))
}
/// Unsigned compare bitwise Test bits nonzero
#[inline]
#[target_feature(enable = "neon")]
#[cfg_attr(target_arch = "arm", target_feature(enable = "v7"))]
#[cfg_attr(all(test, target_arch = "arm"), assert_instr(vtst))]
#[cfg_attr(all(test, target_arch = "aarch64"), assert_instr(cmtst))]
pub unsafe fn vtstq_u32(a: uint32x4_t, b: uint32x4_t) -> uint32x4_t {
let c: uint32x4_t = simd_and(a, b);
let d: u32x4 = u32x4::new(0, 0, 0, 0);
simd_ne(c, transmute(d))
}
/// Floating-point absolute value
#[inline]
#[target_feature(enable = "neon")]
@ -4021,6 +4165,114 @@ mod test {
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_s8() {
let a: i8x8 = i8x8::new(-128, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06);
let b: i8x8 = i8x8::new(-128, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06);
let e: u8x8 = u8x8::new(0xFF, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
let r: u8x8 = transmute(vtst_s8(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_s8() {
let a: i8x16 = i8x16::new(-128, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x7F);
let b: i8x16 = i8x16::new(-128, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x7F);
let e: u8x16 = u8x16::new(0xFF, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
let r: u8x16 = transmute(vtstq_s8(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_s16() {
let a: i16x4 = i16x4::new(-32768, 0x00, 0x01, 0x02);
let b: i16x4 = i16x4::new(-32768, 0x00, 0x01, 0x02);
let e: u16x4 = u16x4::new(0xFF_FF, 0, 0xFF_FF, 0xFF_FF);
let r: u16x4 = transmute(vtst_s16(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_s16() {
let a: i16x8 = i16x8::new(-32768, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06);
let b: i16x8 = i16x8::new(-32768, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06);
let e: u16x8 = u16x8::new(0xFF_FF, 0, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF);
let r: u16x8 = transmute(vtstq_s16(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_s32() {
let a: i32x2 = i32x2::new(-2147483648, 0x00);
let b: i32x2 = i32x2::new(-2147483648, 0x00);
let e: u32x2 = u32x2::new(0xFF_FF_FF_FF, 0);
let r: u32x2 = transmute(vtst_s32(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_s32() {
let a: i32x4 = i32x4::new(-2147483648, 0x00, 0x01, 0x02);
let b: i32x4 = i32x4::new(-2147483648, 0x00, 0x01, 0x02);
let e: u32x4 = u32x4::new(0xFF_FF_FF_FF, 0, 0xFF_FF_FF_FF, 0xFF_FF_FF_FF);
let r: u32x4 = transmute(vtstq_s32(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_u8() {
let a: u8x8 = u8x8::new(0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06);
let b: u8x8 = u8x8::new(0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06);
let e: u8x8 = u8x8::new(0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
let r: u8x8 = transmute(vtst_u8(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_u8() {
let a: u8x16 = u8x16::new(0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0xFF);
let b: u8x16 = u8x16::new(0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0xFF);
let e: u8x16 = u8x16::new(0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
let r: u8x16 = transmute(vtstq_u8(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_u16() {
let a: u16x4 = u16x4::new(0, 0x00, 0x01, 0x02);
let b: u16x4 = u16x4::new(0, 0x00, 0x01, 0x02);
let e: u16x4 = u16x4::new(0, 0, 0xFF_FF, 0xFF_FF);
let r: u16x4 = transmute(vtst_u16(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_u16() {
let a: u16x8 = u16x8::new(0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06);
let b: u16x8 = u16x8::new(0, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06);
let e: u16x8 = u16x8::new(0, 0, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF, 0xFF_FF);
let r: u16x8 = transmute(vtstq_u16(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtst_u32() {
let a: u32x2 = u32x2::new(0, 0x00);
let b: u32x2 = u32x2::new(0, 0x00);
let e: u32x2 = u32x2::new(0, 0);
let r: u32x2 = transmute(vtst_u32(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vtstq_u32() {
let a: u32x4 = u32x4::new(0, 0x00, 0x01, 0x02);
let b: u32x4 = u32x4::new(0, 0x00, 0x01, 0x02);
let e: u32x4 = u32x4::new(0, 0, 0xFF_FF_FF_FF, 0xFF_FF_FF_FF);
let r: u32x4 = transmute(vtstq_u32(transmute(a), transmute(b)));
assert_eq!(r, e);
}
#[simd_test(enable = "neon")]
unsafe fn test_vabs_f32() {
let a: f32x2 = f32x2::new(-0.1, -2.2);

View file

@ -187,7 +187,7 @@ generate int8x8_t:uint8x8_t, int8x16_t:uint8x16_t, int16x4_t:uint16x4_t, int16x8
/// Unsigned compare bitwise equal to zero
name = vceqz
fn = simd_eq
a = MIN, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, MAX
a = MIN, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, MAX
fixed = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
validate TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE
@ -204,6 +204,38 @@ validate TRUE, FALSE, FALSE, FALSE
aarch64 = fcmeq
generate float32x2_t:uint32x2_t, float32x4_t:uint32x4_t, float64x1_t:uint64x1_t, float64x2_t:uint64x2_t
/// Signed compare bitwise Test bits nonzero
name = vtst
multi_fn = simd_and, c:in_t
multi_fn = fixed, d:in_t
multi_fn = simd_ne, c, transmute(d)
a = MIN, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, MAX
b = MIN, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, MAX
fixed = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
validate TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
aarch64 = cmtst
generate int64x1_t:uint64x1_t, int64x2_t:uint64x2_t, poly64x1_t:uint64x1_t, poly64x2_t:uint64x2_t
arm = vtst
generate int8x8_t:uint8x8_t, int8x16_t:uint8x16_t, int16x4_t:uint16x4_t, int16x8_t:uint16x8_t, int32x2_t:uint32x2_t, int32x4_t:uint32x4_t
/// Unsigned compare bitwise Test bits nonzero
name = vtst
multi_fn = simd_and, c:in_t
multi_fn = fixed, d:in_t
multi_fn = simd_ne, c, transmute(d)
a = MIN, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, MAX
b = MIN, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, MAX
fixed = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
validate FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
aarch64 = cmtst
generate uint64x*_t
arm = vtst
generate uint*_t
////////////////////
// Floating-point absolute value
////////////////////

View file

@ -301,17 +301,32 @@ fn gen_aarch64(
current_tests: &[(Vec<String>, Vec<String>, Vec<String>)],
para_num: i32,
fixed: &Vec<String>,
multi_fn: &Vec<String>,
) -> (String, String) {
let _global_t = type_to_global_type(in_t);
let _global_ret_t = type_to_global_type(out_t);
let current_fn = if let Some(current_fn) = current_fn.clone() {
if link_aarch64.is_some() {
panic!("[{}] Can't specify link and fn at the same time.", name)
panic!(
"[{}] Can't specify link and (multi) fn at the same time.",
name
)
}
current_fn
} else if !multi_fn.is_empty() {
if link_aarch64.is_some() {
panic!(
"[{}] Can't specify link and (multi) fn at the same time.",
name
)
}
String::new()
} else {
if link_aarch64.is_none() {
panic!("[{}] Either fn or link-aarch have to be specified.", name)
panic!(
"[{}] Either (multi) fn or link-aarch have to be specified.",
name
)
}
format!("{}_", name)
};
@ -335,15 +350,32 @@ fn gen_aarch64(
} else {
String::new()
};
let call = if para_num == 2 {
format!(
let multi_calls = if !multi_fn.is_empty() {
let mut calls = String::new();
for i in 0..multi_fn.len() {
if i > 0 {
calls.push_str("\n ");
}
calls.push_str(&get_call(&multi_fn[i], in_t, out_t, fixed));
}
calls
} else {
String::new()
};
let call = match (multi_calls.len(), para_num, fixed.len()) {
(0, 2, _) => format!(
r#"pub unsafe fn {}(a: {}, b: {}) -> {} {{
{}{}(a, b)
}}"#,
name, in_t, in_t, out_t, ext_c, current_fn,
)
} else if para_num == 1 {
if fixed.len() != 0 {
),
(0, 1, 0) => format!(
r#"pub unsafe fn {}(a: {}) -> {} {{
{}{}(a)
}}"#,
name, in_t, out_t, ext_c, current_fn,
),
(0, 1, _) => {
let fixed: Vec<String> = fixed.iter().take(type_len(in_t)).cloned().collect();
format!(
r#"pub unsafe fn {}(a: {}) -> {} {{
@ -357,16 +389,14 @@ fn gen_aarch64(
ext_c,
current_fn,
)
} else {
format!(
r#"pub unsafe fn {}(a: {}) -> {} {{
{}{}(a)
}}"#,
name, in_t, out_t, ext_c, current_fn,
)
}
} else {
String::new()
(_, 2, _) => format!(
r#"pub unsafe fn {}(a: {}, b: {}) -> {} {{
{}{}
}}"#,
name, in_t, in_t, out_t, ext_c, multi_calls,
),
(_, _, _) => String::new(),
};
let function = format!(
r#"
@ -459,6 +489,7 @@ fn gen_arm(
current_tests: &[(Vec<String>, Vec<String>, Vec<String>)],
para_num: i32,
fixed: &Vec<String>,
multi_fn: &Vec<String>,
) -> (String, String) {
let _global_t = type_to_global_type(in_t);
let _global_ret_t = type_to_global_type(out_t);
@ -474,6 +505,14 @@ fn gen_arm(
)
}
current_fn
} else if !multi_fn.is_empty() {
if link_aarch64.is_some() || link_arm.is_some() {
panic!(
"[{}] Can't specify link and function at the same time. multi_fn / {:?} / {:?}",
name, link_aarch64, link_arm
)
}
String::new()
} else {
if link_aarch64.is_none() || link_arm.is_none() {
panic!(
@ -505,15 +544,32 @@ fn gen_arm(
} else {
String::new()
};
let call = if para_num == 2 {
format!(
let multi_calls = if !multi_fn.is_empty() {
let mut calls = String::new();
for i in 0..multi_fn.len() {
if i > 0 {
calls.push_str("\n ");
}
calls.push_str(&get_call(&multi_fn[i], in_t, out_t, fixed));
}
calls
} else {
String::new()
};
let call = match (multi_calls.len(), para_num, fixed.len()) {
(0, 2, _) => format!(
r#"pub unsafe fn {}(a: {}, b: {}) -> {} {{
{}{}(a, b)
}}"#,
name, in_t, in_t, out_t, ext_c, current_fn,
)
} else if para_num == 1 {
if fixed.len() != 0 {
),
(0, 1, 0) => format!(
r#"pub unsafe fn {}(a: {}) -> {} {{
{}{}(a)
}}"#,
name, in_t, out_t, ext_c, current_fn,
),
(0, 1, _) => {
let fixed: Vec<String> = fixed.iter().take(type_len(in_t)).cloned().collect();
format!(
r#"pub unsafe fn {}(a: {}) -> {} {{
@ -527,16 +583,14 @@ fn gen_arm(
ext_c,
current_fn,
)
} else {
format!(
r#"pub unsafe fn {}(a: {}) -> {} {{
{}{}(a)
}}"#,
name, in_t, out_t, ext_c, current_fn,
)
}
} else {
String::new()
(_, 2, _) => format!(
r#"pub unsafe fn {}(a: {}, b: {}) -> {} {{
{}{}
}}"#,
name, in_t, in_t, out_t, ext_c, multi_calls,
),
(_, _, _) => String::new(),
};
let function = format!(
r#"
@ -626,6 +680,51 @@ fn expand_intrinsic(intr: &str, t: &str) -> String {
}
}
fn get_call(in_str: &str, in_t: &str, out_t: &str, fixed: &Vec<String>) -> String {
let params: Vec<_> = in_str.split(',').map(|v| v.trim().to_string()).collect();
assert!(params.len() > 0);
let fn_name = &params[0];
let mut re: Option<(String, String)> = None;
let mut param_str = String::new();
for i in 1..params.len() {
let s = &params[i];
if s.contains(':') {
let re_params: Vec<_> = s.split(':').map(|v| v.to_string()).collect();
if re_params.len() == 1 {
re = Some((re_params[0].clone(), in_t.to_string()));
} else if re_params.len() == 2 {
if re_params[1] == "in_t" {
re = Some((re_params[0].clone(), in_t.to_string()));
} else if re_params[1] == "out_t" {
re = Some((re_params[0].clone(), out_t.to_string()));
}
}
} else {
if !param_str.is_empty() {
param_str.push_str(", ");
}
param_str.push_str(s);
}
}
if fn_name == "fixed" {
let (re_name, re_type) = re.unwrap();
let fixed: Vec<String> = fixed.iter().take(type_len(in_t)).cloned().collect();
return format!(r#"let {}{};"#, re_name, values(&re_type, &fixed));
}
if param_str.is_empty() {
param_str.push_str("a, b");
}
let fn_str = if let Some((re_name, re_type)) = re.clone() {
format!(
r#"let {}: {} = {}({});"#,
re_name, re_type, fn_name, param_str
)
} else {
format!(r#"{}({})"#, fn_name, param_str)
};
return fn_str;
}
fn main() -> io::Result<()> {
let args: Vec<String> = env::args().collect();
let in_file = args.get(1).cloned().unwrap_or_else(|| IN.to_string());
@ -645,6 +744,7 @@ fn main() -> io::Result<()> {
let mut b: Vec<String> = Vec::new();
let mut fixed: Vec<String> = Vec::new();
let mut current_tests: Vec<(Vec<String>, Vec<String>, Vec<String>)> = Vec::new();
let mut multi_fn: Vec<String> = Vec::new();
//
// THIS FILE IS GENERATED FORM neon.spec DO NOT CHANGE IT MANUALLY
@ -715,14 +815,17 @@ mod test {
link_arm = None;
current_tests = Vec::new();
para_num = 2;
a = vec![];
b = vec![];
fixed = vec![];
a = Vec::new();
b = Vec::new();
fixed = Vec::new();
multi_fn = Vec::new();
} else if line.starts_with("//") {
} else if line.starts_with("name = ") {
current_name = Some(String::from(&line[7..]));
} else if line.starts_with("fn = ") {
current_fn = Some(String::from(&line[5..]));
} else if line.starts_with("multi_fn = ") {
multi_fn.push(String::from(&line[11..]));
} else if line.starts_with("arm = ") {
current_arm = Some(String::from(&line[6..]));
} else if line.starts_with("aarch64 = ") {
@ -788,6 +891,7 @@ mod test {
&current_tests,
para_num,
&fixed,
&multi_fn,
);
out_arm.push_str(&function);
tests_arm.push_str(&test);
@ -803,6 +907,7 @@ mod test {
&current_tests,
para_num,
&fixed,
&multi_fn,
);
out_aarch64.push_str(&function);
tests_aarch64.push_str(&test);