1 /* $NetBSD: crc32.c,v 1.3 2009/03/25 19:21:39 tls Exp $ */
3 /* crc32.c -- compute the CRC-32 of a data stream
5 * Adapted from zlib's crc code.
7 * Copyright (C) 1995-2005 Mark Adler
8 * For conditions of distribution and use, see copyright notice in zlib.h
10 * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
11 * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
12 * tables for updating the shift register in one step with three exclusive-ors
13 * instead of four steps with four exclusive-ors. This results in about a
14 * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
19 #include <sys/param.h>
20 #include <machine/endian.h>
24 /* Definitions for doing the crc four data bytes at a time. */
25 #define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
26 (((w)&0xff00)<<8)+(((w)&0xff)<<24))
28 /* ========================================================================
29 * Tables of CRC-32s of all single-byte values, made by make_crc_table().
31 #include <lib/libkern/libkern.h>
34 #if BYTE_ORDER == LITTLE_ENDIAN
35 /* ========================================================================= */
36 #define DOLIT4 c ^= *buf4++; \
37 c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
38 crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
39 #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
41 /* ========================================================================= */
42 uint32_t crc32(uint32_t crc
, const uint8_t *buf
, size_t len
)
45 register const u4
*buf4
;
47 if (buf
== NULL
) return 0UL;
51 while (len
&& ((uintptr_t)buf
& 3)) {
52 c
= crc_table
[0][(c
^ *buf
++) & 0xff] ^ (c
>> 8);
56 buf4
= (const u4
*)(const void *)buf
;
65 buf
= (const unsigned char *)buf4
;
68 c
= crc_table
[0][(c
^ *buf
++) & 0xff] ^ (c
>> 8);
74 #else /* BIG_ENDIAN */
76 /* ========================================================================= */
77 #define DOBIG4 c ^= *++buf4; \
78 c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
79 crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
80 #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
82 /* ========================================================================= */
83 uint32_t crc32(uint32_t crc
, const uint8_t *buf
, size_t len
)
86 register const u4
*buf4
;
88 if (buf
== NULL
) return 0UL;
92 while (len
&& ((uintptr_t)buf
& 3)) {
93 c
= crc_table
[4][(c
>> 24) ^ *buf
++] ^ (c
<< 8);
97 buf4
= (const u4
*)(const void *)buf
;
108 buf
= (const unsigned char *)buf4
;
111 c
= crc_table
[4][(c
>> 24) ^ *buf
++] ^ (c
<< 8);
114 return (uint32_t)(REV(c
));