21# include <emmintrin.h>
30 __m128i shift_vector = _mm_set1_epi8(
'0');
31 while (source +
sizeof(__m128i) <= source_end) {
32 __m128i bytes = _mm_loadu_si128((
const __m128i *) source);
33 bytes = _mm_xor_si128(bytes, shift_vector);
34 _mm_storeu_si128((__m128i *) dest, bytes);
36 source +=
sizeof(__m128i);
37 dest +=
sizeof(__m128i);
45 while (source +
sizeof(
size_t) <= source_end) {
47 memcpy(&bytes, source,
sizeof(bytes));
50 memcpy(dest, &bytes,
sizeof(bytes));
52 source +=
sizeof(size_t);
53 dest +=
sizeof(size_t);
56 while (source < source_end) {
57 *dest = *source ^
'0';
76 memcpy(&tmp, str,
sizeof(tmp));
81 BC_VECTOR lower_digits = (tmp & 0x0f000f00) >> 8;
82 BC_VECTOR upper_digits = (tmp & 0x000f000f) * 10;
84 tmp = lower_digits + upper_digits;
86 lower_digits = (tmp & 0x00ff0000) >> 16;
87 upper_digits = (tmp & 0x000000ff) * 100;
89 return lower_digits + upper_digits;
91#elif SIZEOF_SIZE_T == 8
95 memcpy(&tmp, str,
sizeof(tmp));
100 BC_VECTOR lower_digits = (tmp & 0x0f000f000f000f00) >> 8;
101 BC_VECTOR upper_digits = (tmp & 0x000f000f000f000f) * 10;
103 tmp = lower_digits + upper_digits;
105 lower_digits = (tmp & 0x00ff000000ff0000) >> 16;
106 upper_digits = (tmp & 0x000000ff000000ff) * 100;
108 tmp = lower_digits + upper_digits;
110 lower_digits = (tmp & 0x0000ffff00000000) >> 32;
111 upper_digits = (tmp & 0x000000000000ffff) * 10000;
113 return lower_digits + upper_digits;
118# define BC_ENCODE_LUT(A, B) ((A) | (B) << 4)
120# define BC_ENCODE_LUT(A, B) ((B) | (A) << 4)
123#define LUT_ITERATE(_, A) \
124 _(A, 0), _(A, 1), _(A, 2), _(A, 3), _(A, 4), _(A, 5), _(A, 6), _(A, 7), _(A, 8), _(A, 9)
128static const unsigned char LUT[100] = {
141static inline unsigned short bc_expand_lut(
unsigned char c)
143 return (c & 0x0f) | (c & 0xf0) << 4;
150 uint32_t upper =
value / 100;
151 uint32_t lower =
value % 100;
155 uint32_t digits = bc_expand_lut(LUT[lower]) << 16 | bc_expand_lut(LUT[upper]);
158 uint32_t digits = bc_expand_lut(LUT[upper]) << 16 | bc_expand_lut(LUT[lower]);
160 memcpy(str, &digits,
sizeof(digits));
void bc_write_bcd_representation(uint32_t value, char *str)
char * bc_copy_and_toggle_bcd(char *restrict dest, const char *source, const char *source_end)
#define LUT_ITERATE(_, A)
#define BC_ENCODE_LUT(A, B)
BC_VECTOR bc_parse_chunk_chars(const char *str)