feature. See also
. The project being documented here (as the example) is the Zig library itself.
Crc32c.crc32
fn crc32(crc: u32, input: []const u8) u32
File
Code
fn crc32(crc: u32, input: []const u8) u32 {
var crc0: u64 = ~crc;
// `next` pointer to an eight-byte boundary.
var next = input;
while (next.len > 0 and @intFromPtr(next.ptr) & 7 != 0) {
asm volatile ("crc32b %[out], %[in]"
: [in] "+r" (crc0),
: [out] "rm" (next[0]),
);
next = next[1..];
}
// CRC instructions, each on LONG bytes. This is an optimization for
// targets where the CRC instruction has a throughput of one CRC per
// cycle, but a latency of three cycles.
while (next.len >= LONG * 3) {
var crc1: u64 = 0;
var crc2: u64 = 0;
const start = next.len;
while (true) {
const long: [*]const u64 = @ptrCast(@alignCast(next));
asm volatile (
\\crc32q %[out0], %[in0]
\\crc32q %[out1], %[in1]
\\crc32q %[out2], %[in2]
: [in0] "+r" (crc0),
[in1] "+r" (crc1),
[in2] "+r" (crc2),
: [out0] "rm" (long[0 * LONG / 8]),
[out1] "rm" (long[1 * LONG / 8]),
[out2] "rm" (long[2 * LONG / 8]),
);
next = next[8..];
if (next.len <= start - LONG) break;
}
crc0 = shift(&long_lookup_table, @truncate(crc0)) ^ crc1;
crc0 = shift(&long_lookup_table, @truncate(crc0)) ^ crc2;
next = next[LONG * 2 ..];
}
while (next.len >= SHORT * 3) {
var crc1: u64 = 0;
var crc2: u64 = 0;
const start = next.len;
while (true) {
const long: [*]const u64 = @ptrCast(@alignCast(next));
asm volatile (
\\crc32q %[out0], %[in0]
\\crc32q %[out1], %[in1]
\\crc32q %[out2], %[in2]
: [in0] "+r" (crc0),
[in1] "+r" (crc1),
[in2] "+r" (crc2),
: [out0] "rm" (long[0 * SHORT / 8]),
[out1] "rm" (long[1 * SHORT / 8]),
[out2] "rm" (long[2 * SHORT / 8]),
);
next = next[8..];
if (next.len <= start - SHORT) break;
}
crc0 = shift(&short_lookup_table, @truncate(crc0)) ^ crc1;
crc0 = shift(&short_lookup_table, @truncate(crc0)) ^ crc2;
next = next[SHORT * 2 ..];
}
while (next.len >= 8) {
const long: [*]const u64 = @ptrCast(@alignCast(next));
asm volatile ("crc32q %[out], %[in]"
: [in] "+r" (crc0),
: [out] "rm" (long[0]),
);
next = next[8..];
}
while (next.len > 0) {
asm volatile ("crc32b %[out], %[in]"
: [in] "+r" (crc0),
: [out] "rm" (next[0]),
);
next = next[1..];
}
return @truncate(~crc0);
}