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