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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "crc32.h"
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
2 #include "crc32i.h"
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
3 #include <stdio.h>
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
4 #include <string.h>
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
5 #include <inttypes.h>
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
6 #include <assert.h>
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
7 #include <stdlib.h>
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
8 #include <time.h>
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
9
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
10 /* Align to a byte offset using the given crc function. */
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
11 static void crc32_align(uint32_t *crc, crc32_r_spec crcfunc, size_t align, const unsigned char **message, size_t *sz)
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
12 {
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
13 size_t sz8, szs;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
14
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
15 /* Alignment check */
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
16 if (ALIGNED(*message, align))
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
17 return;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
18
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
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
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
21 szs = MIN(*sz, sz8);
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
22
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
23 *crc = crcfunc(*crc, *message, sz8);
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
24 *message += sz8;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
25 *sz -= sz8;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
26 }
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
27
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
28 CRC32_API
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
29 uint32_t crc32(const unsigned char *message, size_t sz)
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
30 {
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
31 uint32_t crc;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
32 size_t i;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
33
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
34 if (!sz)
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
35 return 0;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
36
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
37 crc = 0xFFFFFFFF;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
38 crc32_align(&crc, crc32c_r, ALIGNOF(uint32_t), &message, &sz);
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
39 if (!sz) return ~crc;
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
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
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
52 return ~crc32qw_r(crc, message, sz);
422835bc1aca *: checkin
Paper <paper@tflc.us>
parents:
diff changeset
53 }