1 #include <stdint.h>
2 #include <stddef.h>
3 #include <string.h>
4
5 #include "../../../include/libbase64.h"
6 #include "../../tables/tables.h"
7 #include "../../codecs.h"
8 #include "config.h"
9 #include "../../env.h"
10
11 #ifdef __arm__
12 # if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && HAVE_NEON32
13 # define BASE64_USE_NEON32
14 # endif
15 #endif
16
17 #ifdef BASE64_USE_NEON32
18 #include <arm_neon.h>
19
20 // Only enable inline assembly on supported compilers.
21 #if defined(__GNUC__) || defined(__clang__)
22 #define BASE64_NEON32_USE_ASM
23 #endif
24
25 static inline uint8x16_t
vqtbl1q_u8(const uint8x16_t lut,const uint8x16_t indices)26 vqtbl1q_u8 (const uint8x16_t lut, const uint8x16_t indices)
27 {
28 // NEON32 only supports 64-bit wide lookups in 128-bit tables. Emulate
29 // the NEON64 `vqtbl1q_u8` intrinsic to do 128-bit wide lookups.
30 uint8x8x2_t lut2;
31 uint8x8x2_t result;
32
33 lut2.val[0] = vget_low_u8(lut);
34 lut2.val[1] = vget_high_u8(lut);
35
36 result.val[0] = vtbl2_u8(lut2, vget_low_u8(indices));
37 result.val[1] = vtbl2_u8(lut2, vget_high_u8(indices));
38
39 return vcombine_u8(result.val[0], result.val[1]);
40 }
41
42 #include "../generic/32/dec_loop.c"
43 #include "../generic/32/enc_loop.c"
44 #include "dec_loop.c"
45 #include "enc_reshuffle.c"
46 #include "enc_translate.c"
47 #include "enc_loop.c"
48
49 #endif // BASE64_USE_NEON32
50
51 // Stride size is so large on these NEON 32-bit functions
52 // (48 bytes encode, 32 bytes decode) that we inline the
53 // uint32 codec to stay performant on smaller inputs.
54
BASE64_ENC_FUNCTION(neon32)55 BASE64_ENC_FUNCTION(neon32)
56 {
57 #ifdef BASE64_USE_NEON32
58 #include "../generic/enc_head.c"
59 enc_loop_neon32(&s, &slen, &o, &olen);
60 enc_loop_generic_32(&s, &slen, &o, &olen);
61 #include "../generic/enc_tail.c"
62 #else
63 BASE64_ENC_STUB
64 #endif
65 }
66
BASE64_DEC_FUNCTION(neon32)67 BASE64_DEC_FUNCTION(neon32)
68 {
69 #ifdef BASE64_USE_NEON32
70 #include "../generic/dec_head.c"
71 dec_loop_neon32(&s, &slen, &o, &olen);
72 dec_loop_generic_32(&s, &slen, &o, &olen);
73 #include "../generic/dec_tail.c"
74 #else
75 BASE64_DEC_STUB
76 #endif
77 }
78