Skip to main content

diskann_wide/arch/aarch64/
u8x16_.rs

1/*
2 * Copyright (c) Microsoft Corporation. All rights reserved.
3 * Licensed under the MIT license.
4 */
5
6use crate::{
7    Emulated,
8    constant::Const,
9    helpers,
10    traits::{SIMDMask, SIMDMulAdd, SIMDPartialEq, SIMDPartialOrd, SIMDVector},
11};
12
13// AArch64 masks
14use super::{
15    Neon, internal,
16    macros::{self, AArchLoadStore, AArchSplat},
17    masks::mask8x16,
18    u8x8,
19};
20
21// AArch64 intrinsics
22use std::arch::aarch64::*;
23
24////////////////////
25// 8-bit unsigned //
26////////////////////
27
28macros::aarch64_define_register!(u8x16, uint8x16_t, mask8x16, u8, 16, Neon);
29macros::aarch64_define_splat!(u8x16, vmovq_n_u8);
30macros::aarch64_define_loadstore!(u8x16, vld1q_u8, internal::load_first::u8x16, vst1q_u8, 16);
31macros::aarch64_splitjoin!(u8x16, u8x8, vget_low_u8, vget_high_u8, vcombine_u8);
32
33helpers::unsafe_map_binary_op!(u8x16, std::ops::Add, add, vaddq_u8, "neon");
34helpers::unsafe_map_binary_op!(u8x16, std::ops::Sub, sub, vsubq_u8, "neon");
35helpers::unsafe_map_binary_op!(u8x16, std::ops::Mul, mul, vmulq_u8, "neon");
36macros::aarch64_define_fma!(u8x16, vmlaq_u8);
37
38macros::aarch64_define_cmp!(
39    u8x16,
40    vceqq_u8,
41    (vmvnq_u8),
42    vcltq_u8,
43    vcleq_u8,
44    vcgtq_u8,
45    vcgeq_u8
46);
47macros::aarch64_define_bitops!(
48    u8x16,
49    vmvnq_u8,
50    vandq_u8,
51    vorrq_u8,
52    veorq_u8,
53    (
54        vshlq_u8,
55        8,
56        vnegq_s8,
57        vminq_u8,
58        vreinterpretq_s8_u8,
59        std::convert::identity
60    ),
61    (u8, i8, vmovq_n_s8),
62);
63
64///////////
65// Tests //
66///////////
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use crate::{arch::aarch64::test_neon, reference::ReferenceScalarOps, test_utils};
72
73    #[test]
74    fn miri_test_load() {
75        if let Some(arch) = test_neon() {
76            test_utils::test_load_simd::<u8, 16, u8x16>(arch);
77        }
78    }
79
80    #[test]
81    fn miri_test_store() {
82        if let Some(arch) = test_neon() {
83            test_utils::test_store_simd::<u8, 16, u8x16>(arch);
84        }
85    }
86
87    // constructors
88    #[test]
89    fn test_constructors() {
90        if let Some(arch) = test_neon() {
91            test_utils::ops::test_splat::<u8, 16, u8x16>(arch);
92        }
93    }
94
95    // Ops
96    test_utils::ops::test_add!(u8x16, 0x3017fd73c99cc633, test_neon());
97    test_utils::ops::test_sub!(u8x16, 0xfc627f10b5f8db8a, test_neon());
98    test_utils::ops::test_mul!(u8x16, 0x0f4caa80eceaa523, test_neon());
99    test_utils::ops::test_fma!(u8x16, 0xb8f702ba85375041, test_neon());
100    test_utils::ops::test_splitjoin!(u8x16 => u8x8, 0xa4d00a4d04293967, test_neon());
101
102    test_utils::ops::test_cmp!(u8x16, 0x941757bd5cc641a1, test_neon());
103
104    // Bit ops
105    test_utils::ops::test_bitops!(u8x16, 0xd62d8de09f82ed4e, test_neon());
106}