diff crc32.c @ 0:422835bc1aca

*: checkin
author Paper <paper@tflc.us>
date Mon, 09 Feb 2026 01:15:00 -0500
parents
children 6483683ac857
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crc32.c	Mon Feb 09 01:15:00 2026 -0500
@@ -0,0 +1,50 @@
+#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;
+
+	if (szs == sz8) assert(ALIGNED(*message, align));
+}
+
+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;
+#ifdef __x86_64__
+	crc32_align(&crc, crc32qw_r, 16, &message, &sz);
+	if (!sz) return ~crc;
+
+	return ~crc32x86_vpclmulqdq_r(crc, message, sz);
+#else
+	return ~crc32qw_r(crc, message, sz);
+#endif
+}