Mercurial > crc32
view 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 |
line wrap: on
line source
#include "crc32.h" #include "crc32i.h" #include <stdio.h> #include <string.h> #include <inttypes.h> #include <assert.h> #include <stdlib.h> #include <time.h> /* Align to a byte offset using the given crc function. */ static void crc32_align(uint32_t *crc, crc32_r_spec crcfunc, size_t align, const unsigned char **message, size_t *sz) { size_t sz8, szs; /* Alignment check */ if (ALIGNED(*message, align)) return; /* Calculate size needed to align */ sz8 = align - ((uintptr_t)*message % align); szs = MIN(*sz, sz8); *crc = crcfunc(*crc, *message, sz8); *message += sz8; *sz -= sz8; } CRC32_API uint32_t crc32(const unsigned char *message, size_t sz) { uint32_t crc; size_t i; if (!sz) return 0; crc = 0xFFFFFFFF; crc32_align(&crc, crc32c_r, ALIGNOF(uint32_t), &message, &sz); if (!sz) return ~crc; #if defined(__x86_64__) && defined(__GNUC__) /* Check at runtime if we can use vpclmulqdq */ if (__builtin_cpu_supports("vpclmulqdq")) { /* Align and do the rest with vpclmulqdq */ crc32_align(&crc, crc32qw_r, 16, &message, &sz); if (!sz) return ~crc; return ~crc32x86_vpclmulqdq_r(crc, message, sz); } /* Otherwise just use 32-bit impl */ #endif return ~crc32qw_r(crc, message, sz); }
