xref: /aosp_15_r20/external/mesa3d/src/util/blake3/blake3_dispatch.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker #include <stdbool.h>
2*61046927SAndroid Build Coastguard Worker #include <stddef.h>
3*61046927SAndroid Build Coastguard Worker #include <stdint.h>
4*61046927SAndroid Build Coastguard Worker 
5*61046927SAndroid Build Coastguard Worker #include "blake3_impl.h"
6*61046927SAndroid Build Coastguard Worker 
7*61046927SAndroid Build Coastguard Worker #if defined(_MSC_VER)
8*61046927SAndroid Build Coastguard Worker #include <Windows.h>
9*61046927SAndroid Build Coastguard Worker #endif
10*61046927SAndroid Build Coastguard Worker 
11*61046927SAndroid Build Coastguard Worker #if defined(IS_X86)
12*61046927SAndroid Build Coastguard Worker #if defined(_MSC_VER)
13*61046927SAndroid Build Coastguard Worker #include <intrin.h>
14*61046927SAndroid Build Coastguard Worker #elif defined(__GNUC__)
15*61046927SAndroid Build Coastguard Worker #include <immintrin.h>
16*61046927SAndroid Build Coastguard Worker #else
17*61046927SAndroid Build Coastguard Worker #undef IS_X86 /* Unimplemented! */
18*61046927SAndroid Build Coastguard Worker #endif
19*61046927SAndroid Build Coastguard Worker #endif
20*61046927SAndroid Build Coastguard Worker 
21*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_ATOMICS)
22*61046927SAndroid Build Coastguard Worker #if defined(__has_include)
23*61046927SAndroid Build Coastguard Worker #if __has_include(<stdatomic.h>) && !defined(_MSC_VER)
24*61046927SAndroid Build Coastguard Worker #define BLAKE3_ATOMICS 1
25*61046927SAndroid Build Coastguard Worker #else
26*61046927SAndroid Build Coastguard Worker #define BLAKE3_ATOMICS 0
27*61046927SAndroid Build Coastguard Worker #endif /* __has_include(<stdatomic.h>) && !defined(_MSC_VER) */
28*61046927SAndroid Build Coastguard Worker #else
29*61046927SAndroid Build Coastguard Worker #define BLAKE3_ATOMICS 0
30*61046927SAndroid Build Coastguard Worker #endif /* defined(__has_include) */
31*61046927SAndroid Build Coastguard Worker #endif /* BLAKE3_ATOMICS */
32*61046927SAndroid Build Coastguard Worker 
33*61046927SAndroid Build Coastguard Worker #if BLAKE3_ATOMICS
34*61046927SAndroid Build Coastguard Worker #define ATOMIC_INT _Atomic int
35*61046927SAndroid Build Coastguard Worker #define ATOMIC_LOAD(x) x
36*61046927SAndroid Build Coastguard Worker #define ATOMIC_STORE(x, y) x = y
37*61046927SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
38*61046927SAndroid Build Coastguard Worker #define ATOMIC_INT LONG
39*61046927SAndroid Build Coastguard Worker #define ATOMIC_LOAD(x) InterlockedOr(&x, 0)
40*61046927SAndroid Build Coastguard Worker #define ATOMIC_STORE(x, y) InterlockedExchange(&x, y)
41*61046927SAndroid Build Coastguard Worker #else
42*61046927SAndroid Build Coastguard Worker #define ATOMIC_INT int
43*61046927SAndroid Build Coastguard Worker #define ATOMIC_LOAD(x) x
44*61046927SAndroid Build Coastguard Worker #define ATOMIC_STORE(x, y) x = y
45*61046927SAndroid Build Coastguard Worker #endif
46*61046927SAndroid Build Coastguard Worker 
47*61046927SAndroid Build Coastguard Worker #define MAYBE_UNUSED(x) (void)((x))
48*61046927SAndroid Build Coastguard Worker 
49*61046927SAndroid Build Coastguard Worker #if defined(IS_X86)
xgetbv(void)50*61046927SAndroid Build Coastguard Worker static uint64_t xgetbv(void) {
51*61046927SAndroid Build Coastguard Worker #if defined(_MSC_VER)
52*61046927SAndroid Build Coastguard Worker   return _xgetbv(0);
53*61046927SAndroid Build Coastguard Worker #else
54*61046927SAndroid Build Coastguard Worker   uint32_t eax = 0, edx = 0;
55*61046927SAndroid Build Coastguard Worker   __asm__ __volatile__("xgetbv\n" : "=a"(eax), "=d"(edx) : "c"(0));
56*61046927SAndroid Build Coastguard Worker   return ((uint64_t)edx << 32) | eax;
57*61046927SAndroid Build Coastguard Worker #endif
58*61046927SAndroid Build Coastguard Worker }
59*61046927SAndroid Build Coastguard Worker 
cpuid(uint32_t out[4],uint32_t id)60*61046927SAndroid Build Coastguard Worker static void cpuid(uint32_t out[4], uint32_t id) {
61*61046927SAndroid Build Coastguard Worker #if defined(_MSC_VER)
62*61046927SAndroid Build Coastguard Worker   __cpuid((int *)out, id);
63*61046927SAndroid Build Coastguard Worker #elif defined(__i386__) || defined(_M_IX86)
64*61046927SAndroid Build Coastguard Worker   __asm__ __volatile__("movl %%ebx, %1\n"
65*61046927SAndroid Build Coastguard Worker                        "cpuid\n"
66*61046927SAndroid Build Coastguard Worker                        "xchgl %1, %%ebx\n"
67*61046927SAndroid Build Coastguard Worker                        : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3])
68*61046927SAndroid Build Coastguard Worker                        : "a"(id));
69*61046927SAndroid Build Coastguard Worker #else
70*61046927SAndroid Build Coastguard Worker   __asm__ __volatile__("cpuid\n"
71*61046927SAndroid Build Coastguard Worker                        : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3])
72*61046927SAndroid Build Coastguard Worker                        : "a"(id));
73*61046927SAndroid Build Coastguard Worker #endif
74*61046927SAndroid Build Coastguard Worker }
75*61046927SAndroid Build Coastguard Worker 
cpuidex(uint32_t out[4],uint32_t id,uint32_t sid)76*61046927SAndroid Build Coastguard Worker static void cpuidex(uint32_t out[4], uint32_t id, uint32_t sid) {
77*61046927SAndroid Build Coastguard Worker #if defined(_MSC_VER)
78*61046927SAndroid Build Coastguard Worker   __cpuidex((int *)out, id, sid);
79*61046927SAndroid Build Coastguard Worker #elif defined(__i386__) || defined(_M_IX86)
80*61046927SAndroid Build Coastguard Worker   __asm__ __volatile__("movl %%ebx, %1\n"
81*61046927SAndroid Build Coastguard Worker                        "cpuid\n"
82*61046927SAndroid Build Coastguard Worker                        "xchgl %1, %%ebx\n"
83*61046927SAndroid Build Coastguard Worker                        : "=a"(out[0]), "=r"(out[1]), "=c"(out[2]), "=d"(out[3])
84*61046927SAndroid Build Coastguard Worker                        : "a"(id), "c"(sid));
85*61046927SAndroid Build Coastguard Worker #else
86*61046927SAndroid Build Coastguard Worker   __asm__ __volatile__("cpuid\n"
87*61046927SAndroid Build Coastguard Worker                        : "=a"(out[0]), "=b"(out[1]), "=c"(out[2]), "=d"(out[3])
88*61046927SAndroid Build Coastguard Worker                        : "a"(id), "c"(sid));
89*61046927SAndroid Build Coastguard Worker #endif
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker 
92*61046927SAndroid Build Coastguard Worker #endif
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker enum cpu_feature {
95*61046927SAndroid Build Coastguard Worker   SSE2 = 1 << 0,
96*61046927SAndroid Build Coastguard Worker   SSSE3 = 1 << 1,
97*61046927SAndroid Build Coastguard Worker   SSE41 = 1 << 2,
98*61046927SAndroid Build Coastguard Worker   AVX = 1 << 3,
99*61046927SAndroid Build Coastguard Worker   AVX2 = 1 << 4,
100*61046927SAndroid Build Coastguard Worker   AVX512F = 1 << 5,
101*61046927SAndroid Build Coastguard Worker   AVX512VL = 1 << 6,
102*61046927SAndroid Build Coastguard Worker   /* ... */
103*61046927SAndroid Build Coastguard Worker   UNDEFINED = 1 << 30
104*61046927SAndroid Build Coastguard Worker };
105*61046927SAndroid Build Coastguard Worker 
106*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_TESTING)
107*61046927SAndroid Build Coastguard Worker static /* Allow the variable to be controlled manually for testing */
108*61046927SAndroid Build Coastguard Worker #endif
109*61046927SAndroid Build Coastguard Worker     ATOMIC_INT g_cpu_features = UNDEFINED;
110*61046927SAndroid Build Coastguard Worker 
111*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_TESTING)
112*61046927SAndroid Build Coastguard Worker static
113*61046927SAndroid Build Coastguard Worker #endif
114*61046927SAndroid Build Coastguard Worker     enum cpu_feature
get_cpu_features(void)115*61046927SAndroid Build Coastguard Worker     get_cpu_features(void) {
116*61046927SAndroid Build Coastguard Worker 
117*61046927SAndroid Build Coastguard Worker   /* If TSAN detects a data race here, try compiling with -DBLAKE3_ATOMICS=1 */
118*61046927SAndroid Build Coastguard Worker   enum cpu_feature features = ATOMIC_LOAD(g_cpu_features);
119*61046927SAndroid Build Coastguard Worker   if (features != UNDEFINED) {
120*61046927SAndroid Build Coastguard Worker     return features;
121*61046927SAndroid Build Coastguard Worker   } else {
122*61046927SAndroid Build Coastguard Worker #if defined(IS_X86)
123*61046927SAndroid Build Coastguard Worker     uint32_t regs[4] = {0};
124*61046927SAndroid Build Coastguard Worker     uint32_t *eax = &regs[0], *ebx = &regs[1], *ecx = &regs[2], *edx = &regs[3];
125*61046927SAndroid Build Coastguard Worker     (void)edx;
126*61046927SAndroid Build Coastguard Worker     features = 0;
127*61046927SAndroid Build Coastguard Worker     cpuid(regs, 0);
128*61046927SAndroid Build Coastguard Worker     const int max_id = *eax;
129*61046927SAndroid Build Coastguard Worker     cpuid(regs, 1);
130*61046927SAndroid Build Coastguard Worker #if defined(__amd64__) || defined(_M_X64)
131*61046927SAndroid Build Coastguard Worker     features |= SSE2;
132*61046927SAndroid Build Coastguard Worker #else
133*61046927SAndroid Build Coastguard Worker     if (*edx & (1UL << 26))
134*61046927SAndroid Build Coastguard Worker       features |= SSE2;
135*61046927SAndroid Build Coastguard Worker #endif
136*61046927SAndroid Build Coastguard Worker     if (*ecx & (1UL << 9))
137*61046927SAndroid Build Coastguard Worker       features |= SSSE3;
138*61046927SAndroid Build Coastguard Worker     if (*ecx & (1UL << 19))
139*61046927SAndroid Build Coastguard Worker       features |= SSE41;
140*61046927SAndroid Build Coastguard Worker 
141*61046927SAndroid Build Coastguard Worker     if (*ecx & (1UL << 27)) { // OSXSAVE
142*61046927SAndroid Build Coastguard Worker       const uint64_t mask = xgetbv();
143*61046927SAndroid Build Coastguard Worker       if ((mask & 6) == 6) { // SSE and AVX states
144*61046927SAndroid Build Coastguard Worker         if (*ecx & (1UL << 28))
145*61046927SAndroid Build Coastguard Worker           features |= AVX;
146*61046927SAndroid Build Coastguard Worker         if (max_id >= 7) {
147*61046927SAndroid Build Coastguard Worker           cpuidex(regs, 7, 0);
148*61046927SAndroid Build Coastguard Worker           if (*ebx & (1UL << 5))
149*61046927SAndroid Build Coastguard Worker             features |= AVX2;
150*61046927SAndroid Build Coastguard Worker           if ((mask & 224) == 224) { // Opmask, ZMM_Hi256, Hi16_Zmm
151*61046927SAndroid Build Coastguard Worker             if (*ebx & (1UL << 31))
152*61046927SAndroid Build Coastguard Worker               features |= AVX512VL;
153*61046927SAndroid Build Coastguard Worker             if (*ebx & (1UL << 16))
154*61046927SAndroid Build Coastguard Worker               features |= AVX512F;
155*61046927SAndroid Build Coastguard Worker           }
156*61046927SAndroid Build Coastguard Worker         }
157*61046927SAndroid Build Coastguard Worker       }
158*61046927SAndroid Build Coastguard Worker     }
159*61046927SAndroid Build Coastguard Worker     ATOMIC_STORE(g_cpu_features, features);
160*61046927SAndroid Build Coastguard Worker     return features;
161*61046927SAndroid Build Coastguard Worker #else
162*61046927SAndroid Build Coastguard Worker     /* How to detect NEON? */
163*61046927SAndroid Build Coastguard Worker     return 0;
164*61046927SAndroid Build Coastguard Worker #endif
165*61046927SAndroid Build Coastguard Worker   }
166*61046927SAndroid Build Coastguard Worker }
167*61046927SAndroid Build Coastguard Worker 
blake3_compress_in_place(uint32_t cv[8],const uint8_t block[BLAKE3_BLOCK_LEN],uint8_t block_len,uint64_t counter,uint8_t flags)168*61046927SAndroid Build Coastguard Worker void blake3_compress_in_place(uint32_t cv[8],
169*61046927SAndroid Build Coastguard Worker                               const uint8_t block[BLAKE3_BLOCK_LEN],
170*61046927SAndroid Build Coastguard Worker                               uint8_t block_len, uint64_t counter,
171*61046927SAndroid Build Coastguard Worker                               uint8_t flags) {
172*61046927SAndroid Build Coastguard Worker #if defined(IS_X86)
173*61046927SAndroid Build Coastguard Worker   const enum cpu_feature features = get_cpu_features();
174*61046927SAndroid Build Coastguard Worker   MAYBE_UNUSED(features);
175*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_AVX512)
176*61046927SAndroid Build Coastguard Worker   if (features & AVX512VL) {
177*61046927SAndroid Build Coastguard Worker     blake3_compress_in_place_avx512(cv, block, block_len, counter, flags);
178*61046927SAndroid Build Coastguard Worker     return;
179*61046927SAndroid Build Coastguard Worker   }
180*61046927SAndroid Build Coastguard Worker #endif
181*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_SSE41)
182*61046927SAndroid Build Coastguard Worker   if (features & SSE41) {
183*61046927SAndroid Build Coastguard Worker     blake3_compress_in_place_sse41(cv, block, block_len, counter, flags);
184*61046927SAndroid Build Coastguard Worker     return;
185*61046927SAndroid Build Coastguard Worker   }
186*61046927SAndroid Build Coastguard Worker #endif
187*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_SSE2)
188*61046927SAndroid Build Coastguard Worker   if (features & SSE2) {
189*61046927SAndroid Build Coastguard Worker     blake3_compress_in_place_sse2(cv, block, block_len, counter, flags);
190*61046927SAndroid Build Coastguard Worker     return;
191*61046927SAndroid Build Coastguard Worker   }
192*61046927SAndroid Build Coastguard Worker #endif
193*61046927SAndroid Build Coastguard Worker #endif
194*61046927SAndroid Build Coastguard Worker   blake3_compress_in_place_portable(cv, block, block_len, counter, flags);
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker 
blake3_compress_xof(const uint32_t cv[8],const uint8_t block[BLAKE3_BLOCK_LEN],uint8_t block_len,uint64_t counter,uint8_t flags,uint8_t out[64])197*61046927SAndroid Build Coastguard Worker void blake3_compress_xof(const uint32_t cv[8],
198*61046927SAndroid Build Coastguard Worker                          const uint8_t block[BLAKE3_BLOCK_LEN],
199*61046927SAndroid Build Coastguard Worker                          uint8_t block_len, uint64_t counter, uint8_t flags,
200*61046927SAndroid Build Coastguard Worker                          uint8_t out[64]) {
201*61046927SAndroid Build Coastguard Worker #if defined(IS_X86)
202*61046927SAndroid Build Coastguard Worker   const enum cpu_feature features = get_cpu_features();
203*61046927SAndroid Build Coastguard Worker   MAYBE_UNUSED(features);
204*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_AVX512)
205*61046927SAndroid Build Coastguard Worker   if (features & AVX512VL) {
206*61046927SAndroid Build Coastguard Worker     blake3_compress_xof_avx512(cv, block, block_len, counter, flags, out);
207*61046927SAndroid Build Coastguard Worker     return;
208*61046927SAndroid Build Coastguard Worker   }
209*61046927SAndroid Build Coastguard Worker #endif
210*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_SSE41)
211*61046927SAndroid Build Coastguard Worker   if (features & SSE41) {
212*61046927SAndroid Build Coastguard Worker     blake3_compress_xof_sse41(cv, block, block_len, counter, flags, out);
213*61046927SAndroid Build Coastguard Worker     return;
214*61046927SAndroid Build Coastguard Worker   }
215*61046927SAndroid Build Coastguard Worker #endif
216*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_SSE2)
217*61046927SAndroid Build Coastguard Worker   if (features & SSE2) {
218*61046927SAndroid Build Coastguard Worker     blake3_compress_xof_sse2(cv, block, block_len, counter, flags, out);
219*61046927SAndroid Build Coastguard Worker     return;
220*61046927SAndroid Build Coastguard Worker   }
221*61046927SAndroid Build Coastguard Worker #endif
222*61046927SAndroid Build Coastguard Worker #endif
223*61046927SAndroid Build Coastguard Worker   blake3_compress_xof_portable(cv, block, block_len, counter, flags, out);
224*61046927SAndroid Build Coastguard Worker }
225*61046927SAndroid Build Coastguard Worker 
blake3_hash_many(const uint8_t * const * inputs,size_t num_inputs,size_t blocks,const uint32_t key[8],uint64_t counter,bool increment_counter,uint8_t flags,uint8_t flags_start,uint8_t flags_end,uint8_t * out)226*61046927SAndroid Build Coastguard Worker void blake3_hash_many(const uint8_t *const *inputs, size_t num_inputs,
227*61046927SAndroid Build Coastguard Worker                       size_t blocks, const uint32_t key[8], uint64_t counter,
228*61046927SAndroid Build Coastguard Worker                       bool increment_counter, uint8_t flags,
229*61046927SAndroid Build Coastguard Worker                       uint8_t flags_start, uint8_t flags_end, uint8_t *out) {
230*61046927SAndroid Build Coastguard Worker #if defined(IS_X86)
231*61046927SAndroid Build Coastguard Worker   const enum cpu_feature features = get_cpu_features();
232*61046927SAndroid Build Coastguard Worker   MAYBE_UNUSED(features);
233*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_AVX512)
234*61046927SAndroid Build Coastguard Worker   if ((features & (AVX512F|AVX512VL)) == (AVX512F|AVX512VL)) {
235*61046927SAndroid Build Coastguard Worker     blake3_hash_many_avx512(inputs, num_inputs, blocks, key, counter,
236*61046927SAndroid Build Coastguard Worker                             increment_counter, flags, flags_start, flags_end,
237*61046927SAndroid Build Coastguard Worker                             out);
238*61046927SAndroid Build Coastguard Worker     return;
239*61046927SAndroid Build Coastguard Worker   }
240*61046927SAndroid Build Coastguard Worker #endif
241*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_AVX2)
242*61046927SAndroid Build Coastguard Worker   if (features & AVX2) {
243*61046927SAndroid Build Coastguard Worker     blake3_hash_many_avx2(inputs, num_inputs, blocks, key, counter,
244*61046927SAndroid Build Coastguard Worker                           increment_counter, flags, flags_start, flags_end,
245*61046927SAndroid Build Coastguard Worker                           out);
246*61046927SAndroid Build Coastguard Worker     return;
247*61046927SAndroid Build Coastguard Worker   }
248*61046927SAndroid Build Coastguard Worker #endif
249*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_SSE41)
250*61046927SAndroid Build Coastguard Worker   if (features & SSE41) {
251*61046927SAndroid Build Coastguard Worker     blake3_hash_many_sse41(inputs, num_inputs, blocks, key, counter,
252*61046927SAndroid Build Coastguard Worker                            increment_counter, flags, flags_start, flags_end,
253*61046927SAndroid Build Coastguard Worker                            out);
254*61046927SAndroid Build Coastguard Worker     return;
255*61046927SAndroid Build Coastguard Worker   }
256*61046927SAndroid Build Coastguard Worker #endif
257*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_SSE2)
258*61046927SAndroid Build Coastguard Worker   if (features & SSE2) {
259*61046927SAndroid Build Coastguard Worker     blake3_hash_many_sse2(inputs, num_inputs, blocks, key, counter,
260*61046927SAndroid Build Coastguard Worker                           increment_counter, flags, flags_start, flags_end,
261*61046927SAndroid Build Coastguard Worker                           out);
262*61046927SAndroid Build Coastguard Worker     return;
263*61046927SAndroid Build Coastguard Worker   }
264*61046927SAndroid Build Coastguard Worker #endif
265*61046927SAndroid Build Coastguard Worker #endif
266*61046927SAndroid Build Coastguard Worker 
267*61046927SAndroid Build Coastguard Worker #if BLAKE3_USE_NEON == 1
268*61046927SAndroid Build Coastguard Worker   blake3_hash_many_neon(inputs, num_inputs, blocks, key, counter,
269*61046927SAndroid Build Coastguard Worker                         increment_counter, flags, flags_start, flags_end, out);
270*61046927SAndroid Build Coastguard Worker   return;
271*61046927SAndroid Build Coastguard Worker #endif
272*61046927SAndroid Build Coastguard Worker 
273*61046927SAndroid Build Coastguard Worker   blake3_hash_many_portable(inputs, num_inputs, blocks, key, counter,
274*61046927SAndroid Build Coastguard Worker                             increment_counter, flags, flags_start, flags_end,
275*61046927SAndroid Build Coastguard Worker                             out);
276*61046927SAndroid Build Coastguard Worker }
277*61046927SAndroid Build Coastguard Worker 
278*61046927SAndroid Build Coastguard Worker // The dynamically detected SIMD degree of the current platform.
blake3_simd_degree(void)279*61046927SAndroid Build Coastguard Worker size_t blake3_simd_degree(void) {
280*61046927SAndroid Build Coastguard Worker #if defined(IS_X86)
281*61046927SAndroid Build Coastguard Worker   const enum cpu_feature features = get_cpu_features();
282*61046927SAndroid Build Coastguard Worker   MAYBE_UNUSED(features);
283*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_AVX512)
284*61046927SAndroid Build Coastguard Worker   if ((features & (AVX512F|AVX512VL)) == (AVX512F|AVX512VL)) {
285*61046927SAndroid Build Coastguard Worker     return 16;
286*61046927SAndroid Build Coastguard Worker   }
287*61046927SAndroid Build Coastguard Worker #endif
288*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_AVX2)
289*61046927SAndroid Build Coastguard Worker   if (features & AVX2) {
290*61046927SAndroid Build Coastguard Worker     return 8;
291*61046927SAndroid Build Coastguard Worker   }
292*61046927SAndroid Build Coastguard Worker #endif
293*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_SSE41)
294*61046927SAndroid Build Coastguard Worker   if (features & SSE41) {
295*61046927SAndroid Build Coastguard Worker     return 4;
296*61046927SAndroid Build Coastguard Worker   }
297*61046927SAndroid Build Coastguard Worker #endif
298*61046927SAndroid Build Coastguard Worker #if !defined(BLAKE3_NO_SSE2)
299*61046927SAndroid Build Coastguard Worker   if (features & SSE2) {
300*61046927SAndroid Build Coastguard Worker     return 4;
301*61046927SAndroid Build Coastguard Worker   }
302*61046927SAndroid Build Coastguard Worker #endif
303*61046927SAndroid Build Coastguard Worker #endif
304*61046927SAndroid Build Coastguard Worker #if BLAKE3_USE_NEON == 1
305*61046927SAndroid Build Coastguard Worker   return 4;
306*61046927SAndroid Build Coastguard Worker #endif
307*61046927SAndroid Build Coastguard Worker   return 1;
308*61046927SAndroid Build Coastguard Worker }
309