@@ -120,10 +120,13 @@ uint64_t crc64ecma_sw(const uint8_t *buffer, size_t nbytes, uint64_t crc) {
120120uint64_t crc64ecma_hw_sse128 (const uint8_t *buf, size_t len, uint64_t crc);
121121uint64_t crc64ecma_hw_avx512 (const uint8_t *buf, size_t len, uint64_t crc);
122122uint32_t (*crc32c_auto)(const uint8_t *, size_t , uint32_t ) = nullptr ;
123- uint64_t (*crc64ecma_auto)(const uint8_t *data, size_t nbytes, uint64_t crc);
124123uint32_t (*crc32c_combine_auto)(uint32_t crc1, uint32_t crc2, uint32_t len2);
125124uint32_t (*crc32c_combine_series_auto)(uint32_t * crc, uint32_t part_size, uint32_t n_parts);
126125void (*crc32c_series_auto)(const uint8_t *buffer, uint32_t part_size, uint32_t n_parts, uint32_t * crc_parts);
126+ uint64_t (*crc64ecma_auto)(const uint8_t *data, size_t nbytes, uint64_t crc);
127+ uint64_t (*crc64ecma_combine_auto)(uint64_t crc1, uint64_t crc2, uint32_t len2);
128+ uint64_t (*crc64ecma_combine_series_auto)(uint64_t * crc, uint32_t part_size, uint32_t n_parts);
129+ void (*crc64ecma_series_auto)(const uint8_t *buffer, uint32_t part_size, uint32_t n_parts, uint64_t * crc_parts);
127130
128131__attribute__ ((constructor))
129132static void crc_init() {
@@ -157,6 +160,9 @@ static void crc_init() {
157160 tie32 = sw32;
158161 crc64ecma_auto = crc64ecma_sw;
159162#endif
163+ crc64ecma_combine_auto = (crc64ecma_auto == crc64ecma_sw) ?
164+ crc64ecma_combine_sw :
165+ crc64ecma_combine_hw ;
160166}
161167
162168#ifdef __x86_64__
@@ -912,6 +918,33 @@ uint64_t crc64ecma_combine_hw(uint64_t crc1, uint64_t crc2, uint32_t len2) {
912918 return crc1 ^ crc2;
913919}
914920
921+ inline __uint128_t clmul (uint64_t a, uint64_t b) {
922+ __uint128_t ret = 0 ;
923+ for (uint32_t i = 0 ; i < 64 ; ++i)
924+ if ((a >> i) & 1 )
925+ ret ^= (__uint128_t )b << i;
926+ return ret;
927+ }
928+
929+ static uint64_t do_crc64ecma_lshift_sw (uint64_t crc, uint64_t x) {
930+ __uint128_t crc1x = clmul (crc, x);
931+ __uint128_t crc2x = clmul (crc1x, rk[5 -1 ]);
932+ __uint128_t crc3x = crc1x >> 64 ;
933+ crc1x = crc2x ^ crc3x;
934+ crc2x = clmul (crc1x, rk[7 -1 ]);
935+ crc3x = clmul (crc2x, rk[7 ]);
936+ return (crc1x >> 64 ) ^ crc2x ^ (crc3x >> 64 );
937+ }
938+
939+ uint64_t crc64ecma_combine_sw (uint64_t crc1, uint64_t crc2, uint32_t len2) {
940+ if (unlikely (!crc1)) return crc2;
941+ if (unlikely (!len2)) return crc1;
942+ if (unlikely (len2 & 31 )) {
943+ crc1 = ~crc64ecma_sw (zeros, len2 & 31 , ~crc1);
944+ }
945+ crc1 = crc64ecma_lshift_big (crc1, len2, do_crc64ecma_lshift_sw);
946+ return crc1 ^ crc2;
947+ }
915948
916949#ifdef __x86_64__
917950#ifdef __clang__
0 commit comments