1 /* SPDX-License-Identifier: GPL-2.0 */
3 * NH - ε-almost-universal hash function, NEON accelerated version
5 * Copyright 2018 Google LLC
7 * Author: Eric Biggers <ebiggers@google.com>
10 #include <linux/linkage.h>
49 .macro _nh_stride k0, k1, k2, k3
51 // Load next message stride
52 vld1.8 {T3}, [MESSAGE]!
54 // Load next key stride
57 // Add message words to key words
63 // Multiply 32x32 => 64 and accumulate
64 vmlal.u32 PASS0_SUMS, T0_L, T0_H
65 vmlal.u32 PASS1_SUMS, T1_L, T1_H
66 vmlal.u32 PASS2_SUMS, T2_L, T2_H
67 vmlal.u32 PASS3_SUMS, T3_L, T3_H
71 * void nh_neon(const u32 *key, const u8 *message, size_t message_len,
72 * u8 hash[NH_HASH_BYTES])
74 * It's guaranteed that message_len % 16 == 0.
78 vld1.32 {K0,K1}, [KEY]!
79 vmov.u64 PASS0_SUMS, #0
80 vmov.u64 PASS1_SUMS, #0
82 vmov.u64 PASS2_SUMS, #0
83 vmov.u64 PASS3_SUMS, #0
85 subs MESSAGE_LEN, MESSAGE_LEN, #64
88 _nh_stride K0, K1, K2, K3
89 _nh_stride K1, K2, K3, K0
90 _nh_stride K2, K3, K0, K1
91 _nh_stride K3, K0, K1, K2
92 subs MESSAGE_LEN, MESSAGE_LEN, #64
96 ands MESSAGE_LEN, MESSAGE_LEN, #63
98 _nh_stride K0, K1, K2, K3
100 subs MESSAGE_LEN, MESSAGE_LEN, #16
102 _nh_stride K1, K2, K3, K0
104 subs MESSAGE_LEN, MESSAGE_LEN, #16
106 _nh_stride K2, K3, K0, K1
109 // Sum the accumulators for each pass, then store the sums to 'hash'
110 vadd.u64 T0_L, PASS0_SUM_A, PASS0_SUM_B
111 vadd.u64 T0_H, PASS1_SUM_A, PASS1_SUM_B
112 vadd.u64 T1_L, PASS2_SUM_A, PASS2_SUM_B
113 vadd.u64 T1_H, PASS3_SUM_A, PASS3_SUM_B
114 vst1.8 {T0-T1}, [HASH]