17c2fbfb3SApril Chin /***********************************************************************
27c2fbfb3SApril Chin *                                                                      *
37c2fbfb3SApril Chin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1996-2011 AT&T Intellectual Property          *
57c2fbfb3SApril Chin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
87c2fbfb3SApril Chin *                                                                      *
97c2fbfb3SApril Chin *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
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 };
115*b30d1939SAndy Fiddaman 
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"))
1357c2fbfb3SApril Chin 	{
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;
1447c2fbfb3SApril Chin 	}
14534f9b3eeSRoland Mainz 	else
1467c2fbfb3SApril Chin 	{
147*b30d1939SAndy Fiddaman 	polynomial = 0xedb88320;
148*b30d1939SAndy Fiddaman 	s = name;
149*b30d1939SAndy Fiddaman 	while (*(t = s))
150*b30d1939SAndy Fiddaman 	{
151*b30d1939SAndy Fiddaman 		for (t = s, v = 0; *s && *s != '-'; s++)
152*b30d1939SAndy Fiddaman 			if (*s == '=' && !v)
153*b30d1939SAndy Fiddaman 				v = s;
154*b30d1939SAndy Fiddaman 		i = (v ? v : s) - t;
155*b30d1939SAndy Fiddaman 		if (isdigit(*t) || v && i >= 4 && strneq(t, "poly", 4) && (t = v + 1))
156*b30d1939SAndy Fiddaman 			polynomial = strtoul(t, NiL, 0);
157*b30d1939SAndy Fiddaman 		else if (strneq(t, "done", i))
158*b30d1939SAndy Fiddaman 			sum->done = v ? strtoul(v + 1, NiL, 0) : ~sum->done;
159*b30d1939SAndy Fiddaman 		else if (strneq(t, "init", i))
160*b30d1939SAndy Fiddaman 			sum->init = v ? strtoul(v + 1, NiL, 0) : ~sum->init;
161*b30d1939SAndy Fiddaman 		else if (strneq(t, "rotate", i))
162*b30d1939SAndy Fiddaman 			sum->rotate = 1;
163*b30d1939SAndy Fiddaman 		else if (strneq(t, "size", i))
1647c2fbfb3SApril Chin 		{
165*b30d1939SAndy Fiddaman 			sum->addsize = 1;
166*b30d1939SAndy Fiddaman 			if (v)
167*b30d1939SAndy Fiddaman 				sum->xorsize = strtoul(v + 1, NiL, 0);
1687c2fbfb3SApril Chin 		}
169*b30d1939SAndy Fiddaman 		if (*s == '-')
170*b30d1939SAndy Fiddaman 			s++;
171*b30d1939SAndy Fiddaman 	}
172*b30d1939SAndy Fiddaman 	if (sum->rotate)
173*b30d1939SAndy Fiddaman 	{
174*b30d1939SAndy Fiddaman 		Crcnum_t	t;
175*b30d1939SAndy Fiddaman 		Crcnum_t	p[8];
17634f9b3eeSRoland Mainz 
177*b30d1939SAndy Fiddaman 		p[0] = polynomial;
178*b30d1939SAndy Fiddaman 		for (i = 1; i < 8; i++)
179*b30d1939SAndy Fiddaman 			p[i] = (p[i-1] << 1) ^ ((p[i-1] & 0x80000000) ? polynomial : 0);
180*b30d1939SAndy Fiddaman 		for (i = 0; i < elementsof(sum->tabdata); i++)
181*b30d1939SAndy Fiddaman 		{
182*b30d1939SAndy Fiddaman 			t = 0;
183*b30d1939SAndy Fiddaman 			x = i;
184*b30d1939SAndy Fiddaman 			for (j = 0; j < 8; j++)
18534f9b3eeSRoland Mainz 			{
186*b30d1939SAndy Fiddaman 				if (x & 1)
187*b30d1939SAndy Fiddaman 					t ^= p[j];
188*b30d1939SAndy Fiddaman 				x >>= 1;
18934f9b3eeSRoland Mainz 			}
190*b30d1939SAndy Fiddaman 			sum->tabdata[i] = t;
19134f9b3eeSRoland Mainz 		}
192*b30d1939SAndy Fiddaman 	}
193*b30d1939SAndy Fiddaman 	else
194*b30d1939SAndy Fiddaman 	{
195*b30d1939SAndy Fiddaman 		for (i = 0; i < elementsof(sum->tabdata); i++)
1967c2fbfb3SApril Chin 		{
197*b30d1939SAndy Fiddaman 			x = i;
198*b30d1939SAndy Fiddaman 			for (j = 0; j < 8; j++)
199*b30d1939SAndy Fiddaman 				x = (x>>1) ^ ((x & 1) ? polynomial : 0);
200*b30d1939SAndy Fiddaman 			sum->tabdata[i] = x;
2017c2fbfb3SApril Chin 		}
20234f9b3eeSRoland Mainz 
20334f9b3eeSRoland Mainz 		sum->tab=sum->tabdata;
2047c2fbfb3SApril Chin 	}
205*b30d1939SAndy Fiddaman 	}
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 		}
256*b30d1939SAndy Fiddaman 
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 		}
274*b30d1939SAndy Fiddaman 
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 }