Mercurial > crc32
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 } |
