• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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