xref: /titanic_51/usr/src/lib/libsum/common/sum-crc.c (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
17c2fbfb3SApril Chin /***********************************************************************
27c2fbfb3SApril Chin *                                                                      *
37c2fbfb3SApril Chin *               This software is part of the ast package               *
4*3e14f97fSRoger A. Faulkner *          Copyright (c) 1996-2010 AT&T Intellectual Property          *
57c2fbfb3SApril Chin *                      and is licensed under the                       *
67c2fbfb3SApril Chin *                  Common Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
87c2fbfb3SApril Chin *                                                                      *
97c2fbfb3SApril Chin *                A copy of the License is available at                 *
107c2fbfb3SApril Chin *            http://www.opensource.org/licenses/cpl1.0.txt             *
117c2fbfb3SApril Chin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
127c2fbfb3SApril Chin *                                                                      *
137c2fbfb3SApril Chin *              Information and Software Systems Research               *
147c2fbfb3SApril Chin *                            AT&T Research                             *
157c2fbfb3SApril Chin *                           Florham Park NJ                            *
167c2fbfb3SApril Chin *                                                                      *
177c2fbfb3SApril Chin *                 Glenn Fowler <gsf@research.att.com>                  *
187c2fbfb3SApril Chin *                                                                      *
197c2fbfb3SApril Chin ***********************************************************************/
207c2fbfb3SApril Chin #pragma prototyped
217c2fbfb3SApril Chin 
227c2fbfb3SApril Chin /*
237c2fbfb3SApril Chin  * crc
247c2fbfb3SApril Chin  */
257c2fbfb3SApril Chin 
267c2fbfb3SApril Chin #define crc_description \
277c2fbfb3SApril Chin 	"32 bit CRC (cyclic redundancy check)."
287c2fbfb3SApril Chin #define crc_options	"\
297c2fbfb3SApril Chin [+polynomial?The 32 bit crc polynomial bitmask with implicit bit 32.]:[mask:=0xedb88320]\
307c2fbfb3SApril Chin [+done?XOR the final crc value with \anumber\a. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0]\
317c2fbfb3SApril Chin [+init?The initial crc value. 0xffffffff is used if \anumber\a is omitted.]:?[number:=0]\
327c2fbfb3SApril Chin [+rotate?XOR each input character with the high order crc byte (instead of the low order).]\
337c2fbfb3SApril Chin [+size?Include the total number of bytes in the crc. \anumber\a, if specified, is first XOR'd into the size.]:?[number:=0]\
347c2fbfb3SApril Chin "
357c2fbfb3SApril Chin #define crc_match	"crc"
367c2fbfb3SApril Chin #define crc_open	crc_open
377c2fbfb3SApril Chin #define crc_print	long_print
387c2fbfb3SApril Chin #define crc_data	long_data
397c2fbfb3SApril Chin #define crc_scale	0
407c2fbfb3SApril Chin 
417c2fbfb3SApril Chin typedef uint32_t Crcnum_t;
427c2fbfb3SApril Chin 
437c2fbfb3SApril Chin typedef struct Crc_s
447c2fbfb3SApril Chin {
457c2fbfb3SApril Chin 	_SUM_PUBLIC_
467c2fbfb3SApril Chin 	_SUM_PRIVATE_
477c2fbfb3SApril Chin 	_INTEGRAL_PRIVATE_
487c2fbfb3SApril Chin 	Crcnum_t		init;
497c2fbfb3SApril Chin 	Crcnum_t		done;
507c2fbfb3SApril Chin 	Crcnum_t		xorsize;
5134f9b3eeSRoland Mainz 	const Crcnum_t		*tab; /* use |const| to give the compiler a hint that the data won't change */
5234f9b3eeSRoland Mainz 	Crcnum_t		tabdata[256];
537c2fbfb3SApril Chin 	unsigned int		addsize;
547c2fbfb3SApril Chin 	unsigned int		rotate;
557c2fbfb3SApril Chin } Crc_t;
567c2fbfb3SApril Chin 
577c2fbfb3SApril Chin #define CRC(p,s,c)		(s = (s >> 8) ^ (p)->tab[(s ^ (c)) & 0xff])
587c2fbfb3SApril Chin #define CRCROTATE(p,s,c)	(s = (s << 8) ^ (p)->tab[((s >> 24) ^ (c)) & 0xff])
597c2fbfb3SApril Chin 
6034f9b3eeSRoland Mainz static const
6134f9b3eeSRoland Mainz Crcnum_t posix_cksum_tab[256] = {
6234f9b3eeSRoland Mainz 	0x00000000U,
6334f9b3eeSRoland Mainz 	0x04c11db7U, 0x09823b6eU, 0x0d4326d9U, 0x130476dcU, 0x17c56b6bU,
6434f9b3eeSRoland Mainz 	0x1a864db2U, 0x1e475005U, 0x2608edb8U, 0x22c9f00fU, 0x2f8ad6d6U,
6534f9b3eeSRoland Mainz 	0x2b4bcb61U, 0x350c9b64U, 0x31cd86d3U, 0x3c8ea00aU, 0x384fbdbdU,
6634f9b3eeSRoland Mainz 	0x4c11db70U, 0x48d0c6c7U, 0x4593e01eU, 0x4152fda9U, 0x5f15adacU,
6734f9b3eeSRoland Mainz 	0x5bd4b01bU, 0x569796c2U, 0x52568b75U, 0x6a1936c8U, 0x6ed82b7fU,
6834f9b3eeSRoland Mainz 	0x639b0da6U, 0x675a1011U, 0x791d4014U, 0x7ddc5da3U, 0x709f7b7aU,
6934f9b3eeSRoland Mainz 	0x745e66cdU, 0x9823b6e0U, 0x9ce2ab57U, 0x91a18d8eU, 0x95609039U,
7034f9b3eeSRoland Mainz 	0x8b27c03cU, 0x8fe6dd8bU, 0x82a5fb52U, 0x8664e6e5U, 0xbe2b5b58U,
7134f9b3eeSRoland Mainz 	0xbaea46efU, 0xb7a96036U, 0xb3687d81U, 0xad2f2d84U, 0xa9ee3033U,
7234f9b3eeSRoland Mainz 	0xa4ad16eaU, 0xa06c0b5dU, 0xd4326d90U, 0xd0f37027U, 0xddb056feU,
7334f9b3eeSRoland Mainz 	0xd9714b49U, 0xc7361b4cU, 0xc3f706fbU, 0xceb42022U, 0xca753d95U,
7434f9b3eeSRoland Mainz 	0xf23a8028U, 0xf6fb9d9fU, 0xfbb8bb46U, 0xff79a6f1U, 0xe13ef6f4U,
7534f9b3eeSRoland Mainz 	0xe5ffeb43U, 0xe8bccd9aU, 0xec7dd02dU, 0x34867077U, 0x30476dc0U,
7634f9b3eeSRoland Mainz 	0x3d044b19U, 0x39c556aeU, 0x278206abU, 0x23431b1cU, 0x2e003dc5U,
7734f9b3eeSRoland Mainz 	0x2ac12072U, 0x128e9dcfU, 0x164f8078U, 0x1b0ca6a1U, 0x1fcdbb16U,
7834f9b3eeSRoland Mainz 	0x018aeb13U, 0x054bf6a4U, 0x0808d07dU, 0x0cc9cdcaU, 0x7897ab07U,
7934f9b3eeSRoland Mainz 	0x7c56b6b0U, 0x71159069U, 0x75d48ddeU, 0x6b93dddbU, 0x6f52c06cU,
8034f9b3eeSRoland Mainz 	0x6211e6b5U, 0x66d0fb02U, 0x5e9f46bfU, 0x5a5e5b08U, 0x571d7dd1U,
8134f9b3eeSRoland Mainz 	0x53dc6066U, 0x4d9b3063U, 0x495a2dd4U, 0x44190b0dU, 0x40d816baU,
8234f9b3eeSRoland Mainz 	0xaca5c697U, 0xa864db20U, 0xa527fdf9U, 0xa1e6e04eU, 0xbfa1b04bU,
8334f9b3eeSRoland Mainz 	0xbb60adfcU, 0xb6238b25U, 0xb2e29692U, 0x8aad2b2fU, 0x8e6c3698U,
8434f9b3eeSRoland Mainz 	0x832f1041U, 0x87ee0df6U, 0x99a95df3U, 0x9d684044U, 0x902b669dU,
8534f9b3eeSRoland Mainz 	0x94ea7b2aU, 0xe0b41de7U, 0xe4750050U, 0xe9362689U, 0xedf73b3eU,
8634f9b3eeSRoland Mainz 	0xf3b06b3bU, 0xf771768cU, 0xfa325055U, 0xfef34de2U, 0xc6bcf05fU,
8734f9b3eeSRoland Mainz 	0xc27dede8U, 0xcf3ecb31U, 0xcbffd686U, 0xd5b88683U, 0xd1799b34U,
8834f9b3eeSRoland Mainz 	0xdc3abdedU, 0xd8fba05aU, 0x690ce0eeU, 0x6dcdfd59U, 0x608edb80U,
8934f9b3eeSRoland Mainz 	0x644fc637U, 0x7a089632U, 0x7ec98b85U, 0x738aad5cU, 0x774bb0ebU,
9034f9b3eeSRoland Mainz 	0x4f040d56U, 0x4bc510e1U, 0x46863638U, 0x42472b8fU, 0x5c007b8aU,
9134f9b3eeSRoland Mainz 	0x58c1663dU, 0x558240e4U, 0x51435d53U, 0x251d3b9eU, 0x21dc2629U,
9234f9b3eeSRoland Mainz 	0x2c9f00f0U, 0x285e1d47U, 0x36194d42U, 0x32d850f5U, 0x3f9b762cU,
9334f9b3eeSRoland Mainz 	0x3b5a6b9bU, 0x0315d626U, 0x07d4cb91U, 0x0a97ed48U, 0x0e56f0ffU,
9434f9b3eeSRoland Mainz 	0x1011a0faU, 0x14d0bd4dU, 0x19939b94U, 0x1d528623U, 0xf12f560eU,
9534f9b3eeSRoland Mainz 	0xf5ee4bb9U, 0xf8ad6d60U, 0xfc6c70d7U, 0xe22b20d2U, 0xe6ea3d65U,
9634f9b3eeSRoland Mainz 	0xeba91bbcU, 0xef68060bU, 0xd727bbb6U, 0xd3e6a601U, 0xdea580d8U,
9734f9b3eeSRoland Mainz 	0xda649d6fU, 0xc423cd6aU, 0xc0e2d0ddU, 0xcda1f604U, 0xc960ebb3U,
9834f9b3eeSRoland Mainz 	0xbd3e8d7eU, 0xb9ff90c9U, 0xb4bcb610U, 0xb07daba7U, 0xae3afba2U,
9934f9b3eeSRoland Mainz 	0xaafbe615U, 0xa7b8c0ccU, 0xa379dd7bU, 0x9b3660c6U, 0x9ff77d71U,
10034f9b3eeSRoland Mainz 	0x92b45ba8U, 0x9675461fU, 0x8832161aU, 0x8cf30badU, 0x81b02d74U,
10134f9b3eeSRoland Mainz 	0x857130c3U, 0x5d8a9099U, 0x594b8d2eU, 0x5408abf7U, 0x50c9b640U,
10234f9b3eeSRoland Mainz 	0x4e8ee645U, 0x4a4ffbf2U, 0x470cdd2bU, 0x43cdc09cU, 0x7b827d21U,
10334f9b3eeSRoland Mainz 	0x7f436096U, 0x7200464fU, 0x76c15bf8U, 0x68860bfdU, 0x6c47164aU,
10434f9b3eeSRoland Mainz 	0x61043093U, 0x65c52d24U, 0x119b4be9U, 0x155a565eU, 0x18197087U,
10534f9b3eeSRoland Mainz 	0x1cd86d30U, 0x029f3d35U, 0x065e2082U, 0x0b1d065bU, 0x0fdc1becU,
10634f9b3eeSRoland Mainz 	0x3793a651U, 0x3352bbe6U, 0x3e119d3fU, 0x3ad08088U, 0x2497d08dU,
10734f9b3eeSRoland Mainz 	0x2056cd3aU, 0x2d15ebe3U, 0x29d4f654U, 0xc5a92679U, 0xc1683bceU,
10834f9b3eeSRoland Mainz 	0xcc2b1d17U, 0xc8ea00a0U, 0xd6ad50a5U, 0xd26c4d12U, 0xdf2f6bcbU,
10934f9b3eeSRoland Mainz 	0xdbee767cU, 0xe3a1cbc1U, 0xe760d676U, 0xea23f0afU, 0xeee2ed18U,
11034f9b3eeSRoland Mainz 	0xf0a5bd1dU, 0xf464a0aaU, 0xf9278673U, 0xfde69bc4U, 0x89b8fd09U,
11134f9b3eeSRoland Mainz 	0x8d79e0beU, 0x803ac667U, 0x84fbdbd0U, 0x9abc8bd5U, 0x9e7d9662U,
11234f9b3eeSRoland Mainz 	0x933eb0bbU, 0x97ffad0cU, 0xafb010b1U, 0xab710d06U, 0xa6322bdfU,
11334f9b3eeSRoland Mainz 	0xa2f33668U, 0xbcb4666dU, 0xb8757bdaU, 0xb5365d03U, 0xb1f740b4U
11434f9b3eeSRoland Mainz };
11534f9b3eeSRoland Mainz 
1167c2fbfb3SApril Chin static Sum_t*
crc_open(const Method_t * method,const char * name)1177c2fbfb3SApril Chin crc_open(const Method_t* method, const char* name)
1187c2fbfb3SApril Chin {
1197c2fbfb3SApril Chin 	register Crc_t*		sum;
1207c2fbfb3SApril Chin 	register const char*	s;
1217c2fbfb3SApril Chin 	register const char*	t;
1227c2fbfb3SApril Chin 	register const char*	v;
1237c2fbfb3SApril Chin 	register int		i;
1247c2fbfb3SApril Chin 	register int		j;
1257c2fbfb3SApril Chin 	Crcnum_t		polynomial;
1267c2fbfb3SApril Chin 	Crcnum_t		x;
1277c2fbfb3SApril Chin 
1287c2fbfb3SApril Chin 	if (sum = newof(0, Crc_t, 1, 0))
1297c2fbfb3SApril Chin 	{
1307c2fbfb3SApril Chin 		sum->method = (Method_t*)method;
1317c2fbfb3SApril Chin 		sum->name = name;
1327c2fbfb3SApril Chin 	}
13334f9b3eeSRoland Mainz 
13434f9b3eeSRoland Mainz 	if(!strcmp(name, "crc-0x04c11db7-rotate-done-size"))
13534f9b3eeSRoland Mainz 	{
13634f9b3eeSRoland Mainz 		sum->init=0;
13734f9b3eeSRoland Mainz 		sum->done=0xffffffff;
13834f9b3eeSRoland Mainz 		sum->xorsize=0x0;
13934f9b3eeSRoland Mainz 		sum->addsize=0x1;
14034f9b3eeSRoland Mainz 		sum->rotate=1;
14134f9b3eeSRoland Mainz 
14234f9b3eeSRoland Mainz 		/* Optimized codepath for POSIX cksum to save startup time */
14334f9b3eeSRoland Mainz 		sum->tab=posix_cksum_tab;
14434f9b3eeSRoland Mainz 	}
14534f9b3eeSRoland Mainz 	else
14634f9b3eeSRoland Mainz 	{
1477c2fbfb3SApril Chin 		polynomial = 0xedb88320;
1487c2fbfb3SApril Chin 		s = name;
1497c2fbfb3SApril Chin 		while (*(t = s))
1507c2fbfb3SApril Chin 		{
1517c2fbfb3SApril Chin 			for (t = s, v = 0; *s && *s != '-'; s++)
1527c2fbfb3SApril Chin 				if (*s == '=' && !v)
1537c2fbfb3SApril Chin 					v = s;
1547c2fbfb3SApril Chin 			i = (v ? v : s) - t;
1557c2fbfb3SApril Chin 			if (isdigit(*t) || v && i >= 4 && strneq(t, "poly", 4) && (t = v + 1))
1567c2fbfb3SApril Chin 				polynomial = strtoul(t, NiL, 0);
1577c2fbfb3SApril Chin 			else if (strneq(t, "done", i))
1587c2fbfb3SApril Chin 				sum->done = v ? strtoul(v + 1, NiL, 0) : ~sum->done;
1597c2fbfb3SApril Chin 			else if (strneq(t, "init", i))
1607c2fbfb3SApril Chin 				sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
1617c2fbfb3SApril Chin 			else if (strneq(t, "rotate", i))
1627c2fbfb3SApril Chin 				sum->rotate = 1;
1637c2fbfb3SApril Chin 			else if (strneq(t, "size", i))
1647c2fbfb3SApril Chin 			{
1657c2fbfb3SApril Chin 				sum->addsize = 1;
1667c2fbfb3SApril Chin 				if (v)
1677c2fbfb3SApril Chin 					sum->xorsize = strtoul(v + 1, NiL, 0);
1687c2fbfb3SApril Chin 			}
1697c2fbfb3SApril Chin 			if (*s == '-')
1707c2fbfb3SApril Chin 				s++;
1717c2fbfb3SApril Chin 		}
1727c2fbfb3SApril Chin 		if (sum->rotate)
1737c2fbfb3SApril Chin 		{
1747c2fbfb3SApril Chin 			Crcnum_t	t;
1757c2fbfb3SApril Chin 			Crcnum_t	p[8];
1767c2fbfb3SApril Chin 
1777c2fbfb3SApril Chin 			p[0] = polynomial;
1787c2fbfb3SApril Chin 			for (i = 1; i < 8; i++)
1797c2fbfb3SApril Chin 				p[i] = (p[i-1] << 1) ^ ((p[i-1] & 0x80000000) ? polynomial : 0);
18034f9b3eeSRoland Mainz 			for (i = 0; i < elementsof(sum->tabdata); i++)
1817c2fbfb3SApril Chin 			{
1827c2fbfb3SApril Chin 				t = 0;
1837c2fbfb3SApril Chin 				x = i;
1847c2fbfb3SApril Chin 				for (j = 0; j < 8; j++)
1857c2fbfb3SApril Chin 				{
1867c2fbfb3SApril Chin 					if (x & 1)
1877c2fbfb3SApril Chin 						t ^= p[j];
1887c2fbfb3SApril Chin 					x >>= 1;
1897c2fbfb3SApril Chin 				}
19034f9b3eeSRoland Mainz 				sum->tabdata[i] = t;
1917c2fbfb3SApril Chin 			}
1927c2fbfb3SApril Chin 		}
1937c2fbfb3SApril Chin 		else
1947c2fbfb3SApril Chin 		{
19534f9b3eeSRoland Mainz 			for (i = 0; i < elementsof(sum->tabdata); i++)
1967c2fbfb3SApril Chin 			{
1977c2fbfb3SApril Chin 				x = i;
1987c2fbfb3SApril Chin 				for (j = 0; j < 8; j++)
1997c2fbfb3SApril Chin 					x = (x>>1) ^ ((x & 1) ? polynomial : 0);
20034f9b3eeSRoland Mainz 				sum->tabdata[i] = x;
2017c2fbfb3SApril Chin 			}
2027c2fbfb3SApril Chin 		}
20334f9b3eeSRoland Mainz 
20434f9b3eeSRoland Mainz 		sum->tab=sum->tabdata;
20534f9b3eeSRoland Mainz 	}
20634f9b3eeSRoland Mainz 
2077c2fbfb3SApril Chin 	return (Sum_t*)sum;
2087c2fbfb3SApril Chin }
2097c2fbfb3SApril Chin 
2107c2fbfb3SApril Chin static int
crc_init(Sum_t * p)2117c2fbfb3SApril Chin crc_init(Sum_t* p)
2127c2fbfb3SApril Chin {
2137c2fbfb3SApril Chin 	Crc_t*		sum = (Crc_t*)p;
2147c2fbfb3SApril Chin 
2157c2fbfb3SApril Chin 	sum->sum = sum->init;
2167c2fbfb3SApril Chin 	return 0;
2177c2fbfb3SApril Chin }
2187c2fbfb3SApril Chin 
21934f9b3eeSRoland Mainz #if defined(__SUNPRO_C) || defined(__GNUC__)
22034f9b3eeSRoland Mainz 
22134f9b3eeSRoland Mainz #if defined(__SUNPRO_C)
22234f9b3eeSRoland Mainz #    include <sun_prefetch.h>
22334f9b3eeSRoland Mainz #    define sum_prefetch(addr) sun_prefetch_read_many((void *)(addr))
22434f9b3eeSRoland Mainz #elif defined(__GNUC__)
22534f9b3eeSRoland Mainz #    define sum_prefetch(addr) __builtin_prefetch((addr), 0, 3)
22634f9b3eeSRoland Mainz #else
22734f9b3eeSRoland Mainz #    error Unknown compiler
22834f9b3eeSRoland Mainz #endif
22934f9b3eeSRoland Mainz 
23034f9b3eeSRoland Mainz #define CBLOCK_SIZE (64)
23134f9b3eeSRoland Mainz #pragma unroll(16)
23234f9b3eeSRoland Mainz 
23334f9b3eeSRoland Mainz static int
crc_block(Sum_t * p,const void * s,size_t n)23434f9b3eeSRoland Mainz crc_block(Sum_t* p, const void* s, size_t n)
23534f9b3eeSRoland Mainz {
23634f9b3eeSRoland Mainz 	Crc_t*			sum = (Crc_t*)p;
23734f9b3eeSRoland Mainz 	register Crcnum_t	c = sum->sum;
23834f9b3eeSRoland Mainz 	register const unsigned char*	b = (const unsigned char*)s;
23934f9b3eeSRoland Mainz 	register const unsigned char*	e = b + n;
24034f9b3eeSRoland Mainz 	unsigned short i;
24134f9b3eeSRoland Mainz 
24234f9b3eeSRoland Mainz 	sum_prefetch(b);
24334f9b3eeSRoland Mainz 
24434f9b3eeSRoland Mainz 	if (sum->rotate)
24534f9b3eeSRoland Mainz 	{
24634f9b3eeSRoland Mainz 		while (n > CBLOCK_SIZE)
24734f9b3eeSRoland Mainz 		{
24834f9b3eeSRoland Mainz 			sum_prefetch(b+CBLOCK_SIZE);
24934f9b3eeSRoland Mainz 			for(i=0 ; i < CBLOCK_SIZE ; i++)
25034f9b3eeSRoland Mainz 			{
25134f9b3eeSRoland Mainz 				CRCROTATE(sum, c, *b++);
25234f9b3eeSRoland Mainz 			}
25334f9b3eeSRoland Mainz 
25434f9b3eeSRoland Mainz 			n-=CBLOCK_SIZE;
25534f9b3eeSRoland Mainz 		}
25634f9b3eeSRoland Mainz 
25734f9b3eeSRoland Mainz 		while (b < e)
25834f9b3eeSRoland Mainz 		{
25934f9b3eeSRoland Mainz 			CRCROTATE(sum, c, *b++);
26034f9b3eeSRoland Mainz 		}
26134f9b3eeSRoland Mainz 	}
26234f9b3eeSRoland Mainz 	else
26334f9b3eeSRoland Mainz 	{
26434f9b3eeSRoland Mainz 		while (n > CBLOCK_SIZE)
26534f9b3eeSRoland Mainz 		{
26634f9b3eeSRoland Mainz 			sum_prefetch(b+CBLOCK_SIZE);
26734f9b3eeSRoland Mainz 			for(i=0 ; i < CBLOCK_SIZE ; i++)
26834f9b3eeSRoland Mainz 			{
26934f9b3eeSRoland Mainz 				CRC(sum, c, *b++);
27034f9b3eeSRoland Mainz 			}
27134f9b3eeSRoland Mainz 
27234f9b3eeSRoland Mainz 			n-=CBLOCK_SIZE;
27334f9b3eeSRoland Mainz 		}
27434f9b3eeSRoland Mainz 
27534f9b3eeSRoland Mainz 		while (b < e)
27634f9b3eeSRoland Mainz 		{
27734f9b3eeSRoland Mainz 			CRC(sum, c, *b++);
27834f9b3eeSRoland Mainz 		}
27934f9b3eeSRoland Mainz 	}
28034f9b3eeSRoland Mainz 
28134f9b3eeSRoland Mainz 	sum->sum = c;
28234f9b3eeSRoland Mainz 	return 0;
28334f9b3eeSRoland Mainz }
28434f9b3eeSRoland Mainz #else
2857c2fbfb3SApril Chin static int
crc_block(Sum_t * p,const void * s,size_t n)2867c2fbfb3SApril Chin crc_block(Sum_t* p, const void* s, size_t n)
2877c2fbfb3SApril Chin {
2887c2fbfb3SApril Chin 	Crc_t*			sum = (Crc_t*)p;
2897c2fbfb3SApril Chin 	register Crcnum_t	c = sum->sum;
2907c2fbfb3SApril Chin 	register unsigned char*	b = (unsigned char*)s;
2917c2fbfb3SApril Chin 	register unsigned char*	e = b + n;
2927c2fbfb3SApril Chin 
2937c2fbfb3SApril Chin 	if (sum->rotate)
2947c2fbfb3SApril Chin 		while (b < e)
2957c2fbfb3SApril Chin 			CRCROTATE(sum, c, *b++);
2967c2fbfb3SApril Chin 	else
2977c2fbfb3SApril Chin 		while (b < e)
2987c2fbfb3SApril Chin 			CRC(sum, c, *b++);
2997c2fbfb3SApril Chin 	sum->sum = c;
3007c2fbfb3SApril Chin 	return 0;
3017c2fbfb3SApril Chin }
30234f9b3eeSRoland Mainz #endif /* defined(__SUNPRO_C) || defined(__GNUC__) */
3037c2fbfb3SApril Chin 
3047c2fbfb3SApril Chin static int
crc_done(Sum_t * p)3057c2fbfb3SApril Chin crc_done(Sum_t* p)
3067c2fbfb3SApril Chin {
3077c2fbfb3SApril Chin 	register Crc_t*		sum = (Crc_t*)p;
3087c2fbfb3SApril Chin 	register Crcnum_t	c;
3097c2fbfb3SApril Chin 	register uintmax_t	n;
3107c2fbfb3SApril Chin 	int			i;
3117c2fbfb3SApril Chin 	int			j;
3127c2fbfb3SApril Chin 
3137c2fbfb3SApril Chin 	c = sum->sum;
3147c2fbfb3SApril Chin 	if (sum->addsize)
3157c2fbfb3SApril Chin 	{
3167c2fbfb3SApril Chin 		n = sum->size ^ sum->xorsize;
3177c2fbfb3SApril Chin 		if (sum->rotate)
3187c2fbfb3SApril Chin 			while (n)
3197c2fbfb3SApril Chin 			{
3207c2fbfb3SApril Chin 				CRCROTATE(sum, c, n);
3217c2fbfb3SApril Chin 				n >>= 8;
3227c2fbfb3SApril Chin 			}
3237c2fbfb3SApril Chin 		else
3247c2fbfb3SApril Chin 			for (i = 0, j = 32; i < 4; i++)
3257c2fbfb3SApril Chin 			{
3267c2fbfb3SApril Chin 				j -= 8;
3277c2fbfb3SApril Chin 				CRC(sum, c, n >> j);
3287c2fbfb3SApril Chin 			}
3297c2fbfb3SApril Chin 	}
3307c2fbfb3SApril Chin 	sum->sum = c ^ sum->done;
3317c2fbfb3SApril Chin 	sum->total_sum ^= (sum->sum &= 0xffffffff);
3327c2fbfb3SApril Chin 	return 0;
3337c2fbfb3SApril Chin }
334