Mercurial > crc32
annotate 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 |
| rev | line source |
|---|---|
| 0 | 1 #include "crc32.h" |
| 2 #include "crc32i.h" | |
| 3 #include <stdio.h> | |
| 4 #include <string.h> | |
| 5 #include <inttypes.h> | |
| 6 #include <assert.h> | |
| 7 #include <stdlib.h> | |
| 8 #include <time.h> | |
| 9 | |
| 10 /* Align to a byte offset using the given crc function. */ | |
| 11 static void crc32_align(uint32_t *crc, crc32_r_spec crcfunc, size_t align, const unsigned char **message, size_t *sz) | |
| 12 { | |
| 13 size_t sz8, szs; | |
| 14 | |
| 15 /* Alignment check */ | |
| 16 if (ALIGNED(*message, align)) | |
| 17 return; | |
| 18 | |
| 19 /* Calculate size needed to align */ | |
|
3
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
20 sz8 = align - ((uintptr_t)*message % align); |
| 0 | 21 szs = MIN(*sz, sz8); |
| 22 | |
| 23 *crc = crcfunc(*crc, *message, sz8); | |
| 24 *message += sz8; | |
| 25 *sz -= sz8; | |
| 26 } | |
| 27 | |
| 28 CRC32_API | |
| 29 uint32_t crc32(const unsigned char *message, size_t sz) | |
| 30 { | |
| 31 uint32_t crc; | |
| 32 size_t i; | |
| 33 | |
| 34 if (!sz) | |
| 35 return 0; | |
| 36 | |
| 37 crc = 0xFFFFFFFF; | |
| 38 crc32_align(&crc, crc32c_r, ALIGNOF(uint32_t), &message, &sz); | |
| 39 if (!sz) return ~crc; | |
| 40 | |
|
3
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
41 #if defined(__x86_64__) && defined(__GNUC__) |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
42 /* Check at runtime if we can use vpclmulqdq */ |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
43 if (__builtin_cpu_supports("vpclmulqdq")) { |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
44 /* Align and do the rest with vpclmulqdq */ |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
45 crc32_align(&crc, crc32qw_r, 16, &message, &sz); |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
46 if (!sz) return ~crc; |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
47 |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
48 return ~crc32x86_vpclmulqdq_r(crc, message, sz); |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
49 } /* Otherwise just use 32-bit impl */ |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
50 #endif |
|
6483683ac857
*: add profiling code too; expand x86 to use all eight XMM registers
Paper <paper@tflc.us>
parents:
0
diff
changeset
|
51 |
| 0 | 52 return ~crc32qw_r(crc, message, sz); |
| 53 } |
