Skip to main content

diskann_wide/arch/aarch64/
i16x8_.rs

1/*
2 * Copyright (c) Microsoft Corporation. All rights reserved.
3 * Licensed under the MIT license.
4 */
5
6use crate::{
7    Emulated, SIMDAbs, SIMDMask, SIMDMulAdd, SIMDPartialEq, SIMDPartialOrd, SIMDVector,
8    constant::Const, helpers,
9};
10
11// AArch64 masks
12use super::{
13    Neon, i8x8, internal,
14    macros::{self, AArchLoadStore, AArchSplat},
15    masks::mask16x8,
16    u8x8,
17};
18
19// AArch64 intrinsics
20use std::arch::aarch64::*;
21
22///////////////////
23// 16-bit signed //
24///////////////////
25
26macros::aarch64_define_register!(i16x8, int16x8_t, mask16x8, i16, 8, Neon);
27macros::aarch64_define_splat!(i16x8, vmovq_n_s16);
28macros::aarch64_define_loadstore!(i16x8, vld1q_s16, internal::load_first::i16x8, vst1q_s16, 8);
29
30helpers::unsafe_map_binary_op!(i16x8, std::ops::Add, add, vaddq_s16, "neon");
31helpers::unsafe_map_binary_op!(i16x8, std::ops::Sub, sub, vsubq_s16, "neon");
32helpers::unsafe_map_binary_op!(i16x8, std::ops::Mul, mul, vmulq_s16, "neon");
33helpers::unsafe_map_unary_op!(i16x8, SIMDAbs, abs_simd, vabsq_s16, "neon");
34macros::aarch64_define_fma!(i16x8, vmlaq_s16);
35
36macros::aarch64_define_cmp!(
37    i16x8,
38    vceqq_s16,
39    (vmvnq_u16),
40    vcltq_s16,
41    vcleq_s16,
42    vcgtq_s16,
43    vcgeq_s16
44);
45macros::aarch64_define_bitops!(
46    i16x8,
47    vmvnq_s16,
48    vandq_s16,
49    vorrq_s16,
50    veorq_s16,
51    (
52        vshlq_s16,
53        16,
54        vnegq_s16,
55        vminq_u16,
56        vreinterpretq_s16_u16,
57        vreinterpretq_u16_s16
58    ),
59    (u16, i16, vmovq_n_s16),
60);
61
62// Conversion
63helpers::unsafe_map_conversion!(i8x8, i16x8, vmovl_s8, "neon");
64helpers::unsafe_map_conversion!(u8x8, i16x8, (vreinterpretq_s16_u16, vmovl_u8), "neon");
65
66///////////
67// Tests //
68///////////
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use crate::{arch::aarch64::test_neon, reference::ReferenceScalarOps, test_utils};
74
75    #[test]
76    fn miri_test_load() {
77        if let Some(arch) = test_neon() {
78            test_utils::test_load_simd::<i16, 8, i16x8>(arch);
79        }
80    }
81
82    #[test]
83    fn miri_test_store() {
84        if let Some(arch) = test_neon() {
85            test_utils::test_store_simd::<i16, 8, i16x8>(arch);
86        }
87    }
88
89    // constructors
90    #[test]
91    fn test_constructors() {
92        if let Some(arch) = test_neon() {
93            test_utils::ops::test_splat::<i16, 8, i16x8>(arch);
94        }
95    }
96
97    // Ops
98    test_utils::ops::test_add!(i16x8, 0x3017fd73c99cc633, test_neon());
99    test_utils::ops::test_sub!(i16x8, 0xfc627f10b5f8db8a, test_neon());
100    test_utils::ops::test_mul!(i16x8, 0x0f4caa80eceaa523, test_neon());
101    test_utils::ops::test_fma!(i16x8, 0xb8f702ba85375041, test_neon());
102    test_utils::ops::test_abs!(i16x8, 0xb8f702ba85375041, test_neon());
103
104    test_utils::ops::test_cmp!(i16x8, 0x941757bd5cc641a1, test_neon());
105
106    // Bit ops
107    test_utils::ops::test_bitops!(i16x8, 0xd62d8de09f82ed4e, test_neon());
108
109    // Conversion
110    test_utils::ops::test_lossless_convert!(i8x8 => i16x8, 0x79458ca52356242e, test_neon());
111    test_utils::ops::test_lossless_convert!(u8x8 => i16x8, 0xa9a57c5c541ce360, test_neon());
112}