@@ -313,39 +313,63 @@ inline int count_digits( char const* p ) noexcept
313
313
314
314
// parse_unsigned
315
315
316
+ inline
317
+ uint64_t
318
+ parse_four_digits (void const * p) noexcept
319
+ {
320
+ #ifdef BOOST_JSON_USE_SSE2
321
+ auto const c0 = _mm_cvtsi32_si128 (0x0F0F0F0F );
322
+ auto v0 = _mm_and_si128 (_mm_loadu_si32 (p), c0);
323
+
324
+ // auto const c1 = _mm_cvtsi64_si128(0x0001'000A'0064'03E8);
325
+ auto const c1 = _mm_setr_epi16 (1000 , 100 , 10 , 1 , 0 , 0 , 0 , 0 );
326
+
327
+ auto v1 = _mm_unpacklo_epi8 ( v0, _mm_setzero_si128 () );
328
+ auto v2 = _mm_madd_epi16 (v1, c1);
329
+ auto v3 = _mm_srli_epi64 (v2, 32 );
330
+ auto v4 = _mm_add_epi32 (v2, v3);
331
+ return static_cast <uint32_t >( _mm_cvtsi128_si32 (v4) );
332
+ #else // BOOST_JSON_USE_SSE2
333
+ uint32_t v;
334
+ std::memcpy ( &v, p, 4 );
335
+ endian::native_to_little_inplace (v);
336
+ v = (v & 0x0F0F0F0F ) * 2561 >> 8 ;
337
+ v = (v & 0x00FF00FF ) * 6553601 >> 16 ;
338
+ return v;
339
+ #endif // BOOST_JSON_USE_SSE2
340
+ }
341
+
316
342
inline uint64_t parse_unsigned ( uint64_t r, char const * p, std::size_t n ) noexcept
317
343
{
318
- char const * e = p + n;
344
+ auto const e = p + n;
319
345
320
- if ( n & 1 )
346
+ if (n & 2 )
321
347
{
322
- r = r * 10 + p[0 ] - ' 0' ;
323
- ++p;
348
+ uint32_t v0 = 0 ;
349
+ std::memcpy ( &v0, p, 2 );
350
+ endian::native_to_little_inplace (v0);
351
+ v0 = v0 & 0x0F0F ;
352
+ r = (r * 100 ) + ((v0 & 0xFF ) * 10 ) + (v0 >> 8 );
353
+ p += 2 ;
324
354
}
325
- if ( n & 2 )
355
+ if (n & 1 )
326
356
{
327
- r = r * 10 + p[0 ] - ' 0' ;
328
- r = r * 10 + p[1 ] - ' 0' ;
329
- p += 2 ;
357
+ r = (r * 10 ) + (p[0 ] & 0x0F );
358
+ p += 1 ;
330
359
}
331
- #if BOOST_JSON_ARCH == 64
360
+
361
+ #if defined(BOOST_JSON_USE_SSE2) || (BOOST_JSON_ARCH == 64)
362
+ while (p < e)
363
+ #else // !defined(BOOST_JSON_USE_SSE2) && (BOOST_JSON_ARCH == 32)
332
364
if ( n & 4 )
333
- #else
334
- while ( p != e )
335
365
#endif
336
366
{
337
- uint32_t v;
338
- std::memcpy ( &v, p, 4 );
339
- endian::native_to_little_inplace (v);
340
- v = (v & 0x0F0F0F0F ) * 2561 >> 8 ;
341
- v = (v & 0x00FF00FF ) * 6553601 >> 16 ;
342
-
343
- r = r * 10000 + v;
367
+ r = r * 10000 + parse_four_digits (p);
344
368
p += 4 ;
345
369
}
346
370
347
371
#if BOOST_JSON_ARCH == 64
348
- while ( p != e )
372
+ while ( p < e )
349
373
{
350
374
uint64_t v;
351
375
std::memcpy ( &v, p, 8 );
0 commit comments