1- /* auto-generated on 2024-11-14 14:52:31 -0500. Do not edit! */
1+ /* auto-generated on 2024-11-21 10:33:28 -0500. Do not edit! */
22/* begin file src/simdutf.cpp */
33#include "simdutf.h"
44// We include base64_tables once.
@@ -23495,7 +23495,7 @@ size_t encode_base64(char *dst, const char *src, size_t srclen,
2349523495}
2349623496
2349723497template <bool base64_url>
23498- static inline uint64_t to_base64_mask(block64 *b, bool *error) {
23498+ static inline uint64_t to_base64_mask(block64 *b, uint64_t *error) {
2349923499 __m512i input = b->chunks[0];
2350023500 const __m512i ascii_space_tbl = _mm512_set_epi8(
2350123501 0, 0, 13, 12, 0, 10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 13, 12, 0, 10,
@@ -23538,7 +23538,7 @@ static inline uint64_t to_base64_mask(block64 *b, bool *error) {
2353823538 if (mask) {
2353923539 const __mmask64 spaces = _mm512_cmpeq_epi8_mask(
2354023540 _mm512_shuffle_epi8(ascii_space_tbl, input), input);
23541- *error | = (mask != spaces);
23541+ *error = (mask ^ spaces);
2354223542 }
2354323543 b->chunks[0] = translated;
2354423544
@@ -23646,16 +23646,13 @@ compress_decode_base64(char *dst, const chartype *src, size_t srclen,
2364623646 block64 b;
2364723647 load_block(&b, src);
2364823648 src += 64;
23649- bool error = false ;
23649+ uint64_t error = 0 ;
2365023650 uint64_t badcharmask = to_base64_mask<base64_url>(&b, &error);
2365123651 if (error) {
2365223652 src -= 64;
23653- while (src < srcend && scalar::base64::is_eight_byte(*src) &&
23654- to_base64[uint8_t(*src)] <= 64) {
23655- src++;
23656- }
23657- return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit),
23658- size_t(dst - dstinit)};
23653+ size_t error_offset = _tzcnt_u64(error);
23654+ return {error_code::INVALID_BASE64_CHARACTER,
23655+ size_t(src - srcinit + error_offset), size_t(dst - dstinit)};
2365923656 }
2366023657 if (badcharmask != 0) {
2366123658 // optimization opportunity: check for simple masks like those made of
@@ -28240,7 +28237,7 @@ struct block64 {
2824028237};
2824128238
2824228239template <bool base64_url>
28243- static inline uint32_t to_base64_mask(__m256i *src, bool *error) {
28240+ static inline uint32_t to_base64_mask(__m256i *src, uint32_t *error) {
2824428241 const __m256i ascii_space_tbl =
2824528242 _mm256_setr_epi8(0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xa,
2824628243 0x0, 0xc, 0xd, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0,
@@ -28324,17 +28321,19 @@ static inline uint32_t to_base64_mask(__m256i *src, bool *error) {
2832428321 if (mask) {
2832528322 __m256i ascii_space =
2832628323 _mm256_cmpeq_epi8(_mm256_shuffle_epi8(ascii_space_tbl, *src), *src);
28327- *error | = (mask != _mm256_movemask_epi8(ascii_space));
28324+ *error = (mask ^ _mm256_movemask_epi8(ascii_space));
2832828325 }
2832928326 *src = out;
2833028327 return (uint32_t)mask;
2833128328}
2833228329
2833328330template <bool base64_url>
28334- static inline uint64_t to_base64_mask(block64 *b, bool *error) {
28335- *error = 0;
28336- uint64_t m0 = to_base64_mask<base64_url>(&b->chunks[0], error);
28337- uint64_t m1 = to_base64_mask<base64_url>(&b->chunks[1], error);
28331+ static inline uint64_t to_base64_mask(block64 *b, uint64_t *error) {
28332+ uint32_t err0 = 0;
28333+ uint32_t err1 = 0;
28334+ uint64_t m0 = to_base64_mask<base64_url>(&b->chunks[0], &err0);
28335+ uint64_t m1 = to_base64_mask<base64_url>(&b->chunks[1], &err1);
28336+ *error = err0 | ((uint64_t)err1 << 32);
2833828337 return m0 | (m1 << 32);
2833928338}
2834028339
@@ -28466,16 +28465,13 @@ compress_decode_base64(char *dst, const chartype *src, size_t srclen,
2846628465 block64 b;
2846728466 load_block(&b, src);
2846828467 src += 64;
28469- bool error = false ;
28468+ uint64_t error = 0 ;
2847028469 uint64_t badcharmask = to_base64_mask<base64_url>(&b, &error);
2847128470 if (error) {
2847228471 src -= 64;
28473- while (src < srcend && scalar::base64::is_eight_byte(*src) &&
28474- to_base64[uint8_t(*src)] <= 64) {
28475- src++;
28476- }
28477- return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit),
28478- size_t(dst - dstinit)};
28472+ size_t error_offset = _tzcnt_u64(error);
28473+ return {error_code::INVALID_BASE64_CHARACTER,
28474+ size_t(src - srcinit + error_offset), size_t(dst - dstinit)};
2847928475 }
2848028476 if (badcharmask != 0) {
2848128477 // optimization opportunity: check for simple masks like those made of
@@ -37992,7 +37988,7 @@ struct block64 {
3799237988};
3799337989
3799437990template <bool base64_url>
37995- static inline uint16_t to_base64_mask(__m128i *src, bool *error) {
37991+ static inline uint16_t to_base64_mask(__m128i *src, uint32_t *error) {
3799637992 const __m128i ascii_space_tbl =
3799737993 _mm_setr_epi8(0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0xa, 0x0,
3799837994 0xc, 0xd, 0x0, 0x0);
@@ -38059,22 +38055,42 @@ static inline uint16_t to_base64_mask(__m128i *src, bool *error) {
3805938055 if (mask) {
3806038056 __m128i ascii_space =
3806138057 _mm_cmpeq_epi8(_mm_shuffle_epi8(ascii_space_tbl, *src), *src);
38062- *error | = (mask != _mm_movemask_epi8(ascii_space));
38058+ *error = (mask ^ _mm_movemask_epi8(ascii_space));
3806338059 }
3806438060 *src = out;
3806538061 return (uint16_t)mask;
3806638062}
3806738063
3806838064template <bool base64_url>
38069- static inline uint64_t to_base64_mask(block64 *b, bool *error) {
38070- *error = 0;
38071- uint64_t m0 = to_base64_mask<base64_url>(&b->chunks[0], error);
38072- uint64_t m1 = to_base64_mask<base64_url>(&b->chunks[1], error);
38073- uint64_t m2 = to_base64_mask<base64_url>(&b->chunks[2], error);
38074- uint64_t m3 = to_base64_mask<base64_url>(&b->chunks[3], error);
38065+ static inline uint64_t to_base64_mask(block64 *b, uint64_t *error) {
38066+ uint32_t err0 = 0;
38067+ uint32_t err1 = 0;
38068+ uint32_t err2 = 0;
38069+ uint32_t err3 = 0;
38070+ uint64_t m0 = to_base64_mask<base64_url>(&b->chunks[0], &err0);
38071+ uint64_t m1 = to_base64_mask<base64_url>(&b->chunks[1], &err1);
38072+ uint64_t m2 = to_base64_mask<base64_url>(&b->chunks[2], &err2);
38073+ uint64_t m3 = to_base64_mask<base64_url>(&b->chunks[3], &err3);
38074+ *error = (err0) | ((uint64_t)err1 << 16) | ((uint64_t)err2 << 32) |
38075+ ((uint64_t)err3 << 48);
3807538076 return m0 | (m1 << 16) | (m2 << 32) | (m3 << 48);
3807638077}
3807738078
38079+ #if defined(_MSC_VER) && !defined(__clang__)
38080+ static inline size_t simdutf_tzcnt_u64(uint64_t num) {
38081+ unsigned long ret;
38082+ if (num == 0) {
38083+ return 64;
38084+ }
38085+ _BitScanForward64(&ret, num);
38086+ return ret;
38087+ }
38088+ #else // GCC or Clang
38089+ static inline size_t simdutf_tzcnt_u64(uint64_t num) {
38090+ return num ? __builtin_ctzll(num) : 64;
38091+ }
38092+ #endif
38093+
3807838094static inline void copy_block(block64 *b, char *output) {
3807938095 _mm_storeu_si128(reinterpret_cast<__m128i *>(output), b->chunks[0]);
3808038096 _mm_storeu_si128(reinterpret_cast<__m128i *>(output + 16), b->chunks[1]);
@@ -38222,16 +38238,13 @@ compress_decode_base64(char *dst, const chartype *src, size_t srclen,
3822238238 block64 b;
3822338239 load_block(&b, src);
3822438240 src += 64;
38225- bool error = false ;
38241+ uint64_t error = 0 ;
3822638242 uint64_t badcharmask = to_base64_mask<base64_url>(&b, &error);
3822738243 if (error) {
3822838244 src -= 64;
38229- while (src < srcend && scalar::base64::is_eight_byte(*src) &&
38230- to_base64[uint8_t(*src)] <= 64) {
38231- src++;
38232- }
38233- return {error_code::INVALID_BASE64_CHARACTER, size_t(src - srcinit),
38234- size_t(dst - dstinit)};
38245+ size_t error_offset = simdutf_tzcnt_u64(error);
38246+ return {error_code::INVALID_BASE64_CHARACTER,
38247+ size_t(src - srcinit + error_offset), size_t(dst - dstinit)};
3823538248 }
3823638249 if (badcharmask != 0) {
3823738250 // optimization opportunity: check for simple masks like those made of
0 commit comments