comparison crc32.c @ 3:6483683ac857 default tip

*: add profiling code too; expand x86 to use all eight XMM registers basically ported verbatim from the assembly
author Paper <paper@tflc.us>
date Mon, 09 Feb 2026 21:30:30 -0500
parents 422835bc1aca
children
comparison
equal deleted inserted replaced
2:ead9f84d11db 3:6483683ac857
15 /* Alignment check */ 15 /* Alignment check */
16 if (ALIGNED(*message, align)) 16 if (ALIGNED(*message, align))
17 return; 17 return;
18 18
19 /* Calculate size needed to align */ 19 /* Calculate size needed to align */
20 sz8 = align - ((uintptr_t)message % align); 20 sz8 = align - ((uintptr_t)*message % align);
21 szs = MIN(*sz, sz8); 21 szs = MIN(*sz, sz8);
22 22
23 *crc = crcfunc(*crc, *message, sz8); 23 *crc = crcfunc(*crc, *message, sz8);
24 *message += sz8; 24 *message += sz8;
25 *sz -= sz8; 25 *sz -= sz8;
26
27 if (szs == sz8) assert(ALIGNED(*message, align));
28 } 26 }
29 27
30 CRC32_API 28 CRC32_API
31 uint32_t crc32(const unsigned char *message, size_t sz) 29 uint32_t crc32(const unsigned char *message, size_t sz)
32 { 30 {
37 return 0; 35 return 0;
38 36
39 crc = 0xFFFFFFFF; 37 crc = 0xFFFFFFFF;
40 crc32_align(&crc, crc32c_r, ALIGNOF(uint32_t), &message, &sz); 38 crc32_align(&crc, crc32c_r, ALIGNOF(uint32_t), &message, &sz);
41 if (!sz) return ~crc; 39 if (!sz) return ~crc;
42 #ifdef __x86_64__
43 crc32_align(&crc, crc32qw_r, 16, &message, &sz);
44 if (!sz) return ~crc;
45 40
46 return ~crc32x86_vpclmulqdq_r(crc, message, sz); 41 #if defined(__x86_64__) && defined(__GNUC__)
47 #else 42 /* Check at runtime if we can use vpclmulqdq */
43 if (__builtin_cpu_supports("vpclmulqdq")) {
44 /* Align and do the rest with vpclmulqdq */
45 crc32_align(&crc, crc32qw_r, 16, &message, &sz);
46 if (!sz) return ~crc;
47
48 return ~crc32x86_vpclmulqdq_r(crc, message, sz);
49 } /* Otherwise just use 32-bit impl */
50 #endif
51
48 return ~crc32qw_r(crc, message, sz); 52 return ~crc32qw_r(crc, message, sz);
49 #endif
50 } 53 }