What exactly is our CRC algorithm?

Started by Heikki Linnakangasover 11 years ago73 messages
#1Heikki Linnakangas
hlinnakangas@vmware.com
1 attachment(s)

Our CRC algorithm is a bit weird. It's supposedly CRC-32, with the same
polynomial as used in Ethernet et al, but it actually is not. The
comments refer to "Painless Guide to CRC Error Detection Algorithms" by
Ross N. Williams [1] (http://www.ross.net/crc/download/crc_v3.txt), but
I think it was implemented incorrectly.

As a test case, I used an input of a single zero byte. I calculated the
CRC using Postgres' INIT_CRC32+COMP_CRC32+FIN_CRC32, and compared with
various online CRC calculation tools and C snippets. The Postgres
algorithm produces the value 2D02EF72, while the correct one is
D202EF8D. The first and last byte are inverted. For longer inputs, the
values diverge, and I can't see any obvious pattern between the Postgres
and correct values.

There are many variants of CRC calculations, as explained in Ross's
guide. But ours doesn't seem to correspond to the reversed or reflected
variants either.

I compiled the code from Ross's document, and built a small test program
to test it. I used Ross's "reverse" lookup table, which is the same
table we use in Postgres. It produces this output:

Calculating CRC-32 (polynomial 04C11DB7) for a single zero byte:
D202EF8D 11010010000000101110111110001101 (simple)
2D02EF72 10101101000000101110111101110010 (lookup)
D202EF8D 11010010000000101110111110001101 (lookup reflected)

Hmm. So the simple, non-table driven, calculation gives the same result
as using the lookup table using the reflected lookup code. That's
expected; the lookup method is supposed to be the same, just faster.
However, using the "normal" lookup code, but with a "reflected" lookup
table, produces the same result as Postgres' algorithm. Indeed, that's
what we do in PostgreSQL. But AFAICS, that's an incorrect combination.
You're supposed to the non-reflected lookup table with the non-reflected
lookup code; you can't mix and match.

As far as I can tell, PostgreSQL's so-called CRC algorithm doesn't
correspond to any bit-by-bit CRC variant and polynomial. My math skills
are not strong enough to determine what the consequences of that are. It
might still be a decent checksum. Or not. I couldn't tell if the good
error detection properties of the normal CRC-32 polynomial apply to our
algorithm or not.

Thoughts? Attached is the test program I used for this.

- Heikki

Attachments:

crcmodel-1.tar.gzapplication/gzip; name=crcmodel-1.tar.gzDownload
#2Andres Freund
andres@2ndquadrant.com
In reply to: Heikki Linnakangas (#1)
Re: What exactly is our CRC algorithm?

On 2014-10-08 22:13:46 +0300, Heikki Linnakangas wrote:

Hmm. So the simple, non-table driven, calculation gives the same result as
using the lookup table using the reflected lookup code. That's expected; the
lookup method is supposed to be the same, just faster. However, using the
"normal" lookup code, but with a "reflected" lookup table, produces the same
result as Postgres' algorithm. Indeed, that's what we do in PostgreSQL. But
AFAICS, that's an incorrect combination. You're supposed to the
non-reflected lookup table with the non-reflected lookup code; you can't mix
and match.

As far as I can tell, PostgreSQL's so-called CRC algorithm doesn't
correspond to any bit-by-bit CRC variant and polynomial. My math skills are
not strong enough to determine what the consequences of that are. It might
still be a decent checksum. Or not. I couldn't tell if the good error
detection properties of the normal CRC-32 polynomial apply to our algorithm
or not.

Additional interesting datapoints are that hstore and ltree contain the
same tables - but properly use the reflected computation.

Thoughts?

It clearly seems like a bad idea to continue with this - I don't think
anybody here knows which guarantees this gives us.

The question is how can we move away from this. There's unfortunately
two places that embed PGC32 that are likely to prove problematic when
fixing the algorithm: pg_trgm and tsgist both seem to include crc's in
their logic in a persistent way. I think we should provide
INIT/COMP/FIN_PG32 using the current algorithm for these.

If we're switching to a saner computation, we should imo also switch to
a better polynom - CRC-32C has better error detection capabilities than
CRC32 and is available in hardware. As we're paying the price pf
breaking compat anyway...

Arguably we could also say that given that there's been little evident
problems with the borked computation we could also switch to a much
faster hash instead of continuing to use crc...

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#3Gavin Flower
GavinFlower@archidevsys.co.nz
In reply to: Andres Freund (#2)
Re: What exactly is our CRC algorithm?

On 09/10/14 10:13, Andres Freund wrote:

On 2014-10-08 22:13:46 +0300, Heikki Linnakangas wrote:

Hmm. So the simple, non-table driven, calculation gives the same result as
using the lookup table using the reflected lookup code. That's expected; the
lookup method is supposed to be the same, just faster. However, using the
"normal" lookup code, but with a "reflected" lookup table, produces the same
result as Postgres' algorithm. Indeed, that's what we do in PostgreSQL. But
AFAICS, that's an incorrect combination. You're supposed to the
non-reflected lookup table with the non-reflected lookup code; you can't mix
and match.

As far as I can tell, PostgreSQL's so-called CRC algorithm doesn't
correspond to any bit-by-bit CRC variant and polynomial. My math skills are
not strong enough to determine what the consequences of that are. It might
still be a decent checksum. Or not. I couldn't tell if the good error
detection properties of the normal CRC-32 polynomial apply to our algorithm
or not.

Additional interesting datapoints are that hstore and ltree contain the
same tables - but properly use the reflected computation.

Thoughts?

It clearly seems like a bad idea to continue with this - I don't think
anybody here knows which guarantees this gives us.

The question is how can we move away from this. There's unfortunately
two places that embed PGC32 that are likely to prove problematic when
fixing the algorithm: pg_trgm and tsgist both seem to include crc's in
their logic in a persistent way. I think we should provide
INIT/COMP/FIN_PG32 using the current algorithm for these.

If we're switching to a saner computation, we should imo also switch to
a better polynom - CRC-32C has better error detection capabilities than
CRC32 and is available in hardware. As we're paying the price pf
breaking compat anyway...

Arguably we could also say that given that there's been little evident
problems with the borked computation we could also switch to a much
faster hash instead of continuing to use crc...

Greetings,

Andres Freund

Could a 64 bit variant of some kind be useful as an option - in addition
to a correct 32 bit?

As most people have 64 bit processors and storage is less constrained
now-a-days, as well as we tend to store much larger chunks of data.

Cheers,
Gavin

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#4Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Gavin Flower (#3)
Re: What exactly is our CRC algorithm?

On 10/09/2014 01:23 AM, Gavin Flower wrote:

On 09/10/14 10:13, Andres Freund wrote:

If we're switching to a saner computation, we should imo also switch to
a better polynom - CRC-32C has better error detection capabilities than
CRC32 and is available in hardware. As we're paying the price pf
breaking compat anyway...

Arguably we could also say that given that there's been little evident
problems with the borked computation we could also switch to a much
faster hash instead of continuing to use crc...

Could a 64 bit variant of some kind be useful as an option - in addition
to a correct 32 bit?

More bits allows you to detect more errors. That's the only advantage.
I've never heard that being a problem, so no, I don't think that's a
good idea.

As most people have 64 bit processors and storage is less constrained
now-a-days, as well as we tend to store much larger chunks of data.

That's irrelevant to the CRC in the WAL. Each WAL record is CRC'd
separately, and they tend to be very small (less than 8k typically)
regardless of how "large chunks of data" you store in the database.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#5Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Andres Freund (#2)
2 attachment(s)
Re: What exactly is our CRC algorithm?

On 10/09/2014 12:13 AM, Andres Freund wrote:

On 2014-10-08 22:13:46 +0300, Heikki Linnakangas wrote:

As far as I can tell, PostgreSQL's so-called CRC algorithm doesn't
correspond to any bit-by-bit CRC variant and polynomial. My math skills are
not strong enough to determine what the consequences of that are. It might
still be a decent checksum. Or not. I couldn't tell if the good error
detection properties of the normal CRC-32 polynomial apply to our algorithm
or not.

Additional interesting datapoints are that hstore and ltree contain the
same tables - but properly use the reflected computation.

Thoughts?

It clearly seems like a bad idea to continue with this - I don't think
anybody here knows which guarantees this gives us.

The question is how can we move away from this. There's unfortunately
two places that embed PGC32 that are likely to prove problematic when
fixing the algorithm: pg_trgm and tsgist both seem to include crc's in
their logic in a persistent way. I think we should provide
INIT/COMP/FIN_PG32 using the current algorithm for these.

Agreed, it's not worth breaking pg_upgrade for this.

If we're switching to a saner computation, we should imo also switch to
a better polynom - CRC-32C has better error detection capabilities than
CRC32 and is available in hardware. As we're paying the price pf
breaking compat anyway...

Agreed.

Arguably we could also say that given that there's been little evident
problems with the borked computation we could also switch to a much
faster hash instead of continuing to use crc...

I don't feel like taking the leap. Once we switch to slice-by-4/8 and/or
use a hardware instruction when available, CRC is fast enough.

I came up with the attached patches. They do three things:

1. Get rid of the 64-bit CRC code. It's not used for anything, and
haven't been for years, so it doesn't seem worth spending any effort to
fix them.

2. Switch to CRC-32C (Castagnoli) for WAL and other places that don't
need to remain compatible across major versions.

3. Use the same lookup table for hstore and ltree, as used for the
legacy "almost CRC-32" algorithm. The tables are identical, so might as
well.

Any objections?

- Heikki

Attachments:

0001-Remove-support-for-64-bit-CRC.patchtext/x-diff; name=0001-Remove-support-for-64-bit-CRC.patchDownload
>From 4fe6472976f2efc22035e802067a70d3cca61d79 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 27 Oct 2014 12:01:19 +0200
Subject: [PATCH 1/2] Remove support for 64-bit CRC.

It hasn't been used for anything in backend code for a long time.
---
 src/include/utils/pg_crc.h        |  96 ---------
 src/include/utils/pg_crc_tables.h | 416 --------------------------------------
 2 files changed, 512 deletions(-)

diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index 375c405..f43f4aa 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -10,9 +10,6 @@
  * We use a normal (not "reflected", in Williams' terms) CRC, using initial
  * all-ones register contents and a final bit inversion.
  *
- * The 64-bit variant is not used as of PostgreSQL 8.1, but we retain the
- * code for possible future use.
- *
  *
  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -56,97 +53,4 @@ do { \
 /* Constant table for CRC calculation */
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
-
-#ifdef PROVIDE_64BIT_CRC
-
-/*
- * If we use a 64-bit integer type, then a 64-bit CRC looks just like the
- * usual sort of implementation.  However, we can also fake it with two
- * 32-bit registers.  Experience has shown that the two-32-bit-registers code
- * is as fast as, or even much faster than, the 64-bit code on all but true
- * 64-bit machines.  We use SIZEOF_VOID_P to check the native word width.
- */
-
-#if SIZEOF_VOID_P < 8
-
-/*
- * crc0 represents the LSBs of the 64-bit value, crc1 the MSBs.  Note that
- * with crc0 placed first, the output of 32-bit and 64-bit implementations
- * will be bit-compatible only on little-endian architectures.  If it were
- * important to make the two possible implementations bit-compatible on
- * all machines, we could do a configure test to decide how to order the
- * two fields, but it seems not worth the trouble.
- */
-typedef struct pg_crc64
-{
-	uint32		crc0;
-	uint32		crc1;
-}	pg_crc64;
-
-/* Initialize a CRC accumulator */
-#define INIT_CRC64(crc) ((crc).crc0 = 0xffffffff, (crc).crc1 = 0xffffffff)
-
-/* Finish a CRC calculation */
-#define FIN_CRC64(crc)	((crc).crc0 ^= 0xffffffff, (crc).crc1 ^= 0xffffffff)
-
-/* Accumulate some (more) bytes into a CRC */
-#define COMP_CRC64(crc, data, len)	\
-do { \
-	uint32		__crc0 = (crc).crc0; \
-	uint32		__crc1 = (crc).crc1; \
-	unsigned char *__data = (unsigned char *) (data); \
-	uint32		__len = (len); \
-\
-	while (__len-- > 0) \
-	{ \
-		int		__tab_index = ((int) (__crc1 >> 24) ^ *__data++) & 0xFF; \
-		__crc1 = pg_crc64_table1[__tab_index] ^ ((__crc1 << 8) | (__crc0 >> 24)); \
-		__crc0 = pg_crc64_table0[__tab_index] ^ (__crc0 << 8); \
-	} \
-	(crc).crc0 = __crc0; \
-	(crc).crc1 = __crc1; \
-} while (0)
-
-/* Check for equality of two CRCs */
-#define EQ_CRC64(c1,c2)  ((c1).crc0 == (c2).crc0 && (c1).crc1 == (c2).crc1)
-
-/* Constant table for CRC calculation */
-extern CRCDLLIMPORT const uint32 pg_crc64_table0[];
-extern CRCDLLIMPORT const uint32 pg_crc64_table1[];
-#else							/* use int64 implementation */
-
-typedef struct pg_crc64
-{
-	uint64		crc0;
-}	pg_crc64;
-
-/* Initialize a CRC accumulator */
-#define INIT_CRC64(crc) ((crc).crc0 = UINT64CONST(0xffffffffffffffff))
-
-/* Finish a CRC calculation */
-#define FIN_CRC64(crc)	((crc).crc0 ^= UINT64CONST(0xffffffffffffffff))
-
-/* Accumulate some (more) bytes into a CRC */
-#define COMP_CRC64(crc, data, len)	\
-do { \
-	uint64		__crc0 = (crc).crc0; \
-	unsigned char *__data = (unsigned char *) (data); \
-	uint32		__len = (len); \
-\
-	while (__len-- > 0) \
-	{ \
-		int		__tab_index = ((int) (__crc0 >> 56) ^ *__data++) & 0xFF; \
-		__crc0 = pg_crc64_table[__tab_index] ^ (__crc0 << 8); \
-	} \
-	(crc).crc0 = __crc0; \
-} while (0)
-
-/* Check for equality of two CRCs */
-#define EQ_CRC64(c1,c2)  ((c1).crc0 == (c2).crc0)
-
-/* Constant table for CRC calculation */
-extern CRCDLLIMPORT const uint64 pg_crc64_table[];
-#endif   /* SIZEOF_VOID_P < 8 */
-#endif   /* PROVIDE_64BIT_CRC */
-
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index a487ee4..f566137 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -14,9 +14,6 @@
  * We use a normal (not "reflected", in Williams' terms) CRC, using initial
  * all-ones register contents and a final bit inversion.
  *
- * The 64-bit variant is not used as of PostgreSQL 8.1, but we retain the
- * code for possible future use.
- *
  *
  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -100,417 +97,4 @@ const uint32 pg_crc32_table[256] = {
 	0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
 };
 
-
-#ifdef PROVIDE_64BIT_CRC
-
-/*
- * This table is based on the polynomial
- *
- * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 +
- * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 +
- * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 +
- * x^7 + x^4 + x + 1
- *
- * which is borrowed from the DLT1 spec
- * (ECMA-182, available from http://www.ecma.ch/ecma1/STAND/ECMA-182.HTM)
- */
-
-#if SIZEOF_VOID_P < 8			/* this test must match the one in pg_crc.h */
-
-const uint32 pg_crc64_table0[256] = {
-	0x00000000, 0xA9EA3693,
-	0x53D46D26, 0xFA3E5BB5,
-	0x0E42ECDF, 0xA7A8DA4C,
-	0x5D9681F9, 0xF47CB76A,
-	0x1C85D9BE, 0xB56FEF2D,
-	0x4F51B498, 0xE6BB820B,
-	0x12C73561, 0xBB2D03F2,
-	0x41135847, 0xE8F96ED4,
-	0x90E185EF, 0x390BB37C,
-	0xC335E8C9, 0x6ADFDE5A,
-	0x9EA36930, 0x37495FA3,
-	0xCD770416, 0x649D3285,
-	0x8C645C51, 0x258E6AC2,
-	0xDFB03177, 0x765A07E4,
-	0x8226B08E, 0x2BCC861D,
-	0xD1F2DDA8, 0x7818EB3B,
-	0x21C30BDE, 0x88293D4D,
-	0x721766F8, 0xDBFD506B,
-	0x2F81E701, 0x866BD192,
-	0x7C558A27, 0xD5BFBCB4,
-	0x3D46D260, 0x94ACE4F3,
-	0x6E92BF46, 0xC77889D5,
-	0x33043EBF, 0x9AEE082C,
-	0x60D05399, 0xC93A650A,
-	0xB1228E31, 0x18C8B8A2,
-	0xE2F6E317, 0x4B1CD584,
-	0xBF6062EE, 0x168A547D,
-	0xECB40FC8, 0x455E395B,
-	0xADA7578F, 0x044D611C,
-	0xFE733AA9, 0x57990C3A,
-	0xA3E5BB50, 0x0A0F8DC3,
-	0xF031D676, 0x59DBE0E5,
-	0xEA6C212F, 0x438617BC,
-	0xB9B84C09, 0x10527A9A,
-	0xE42ECDF0, 0x4DC4FB63,
-	0xB7FAA0D6, 0x1E109645,
-	0xF6E9F891, 0x5F03CE02,
-	0xA53D95B7, 0x0CD7A324,
-	0xF8AB144E, 0x514122DD,
-	0xAB7F7968, 0x02954FFB,
-	0x7A8DA4C0, 0xD3679253,
-	0x2959C9E6, 0x80B3FF75,
-	0x74CF481F, 0xDD257E8C,
-	0x271B2539, 0x8EF113AA,
-	0x66087D7E, 0xCFE24BED,
-	0x35DC1058, 0x9C3626CB,
-	0x684A91A1, 0xC1A0A732,
-	0x3B9EFC87, 0x9274CA14,
-	0xCBAF2AF1, 0x62451C62,
-	0x987B47D7, 0x31917144,
-	0xC5EDC62E, 0x6C07F0BD,
-	0x9639AB08, 0x3FD39D9B,
-	0xD72AF34F, 0x7EC0C5DC,
-	0x84FE9E69, 0x2D14A8FA,
-	0xD9681F90, 0x70822903,
-	0x8ABC72B6, 0x23564425,
-	0x5B4EAF1E, 0xF2A4998D,
-	0x089AC238, 0xA170F4AB,
-	0x550C43C1, 0xFCE67552,
-	0x06D82EE7, 0xAF321874,
-	0x47CB76A0, 0xEE214033,
-	0x141F1B86, 0xBDF52D15,
-	0x49899A7F, 0xE063ACEC,
-	0x1A5DF759, 0xB3B7C1CA,
-	0x7D3274CD, 0xD4D8425E,
-	0x2EE619EB, 0x870C2F78,
-	0x73709812, 0xDA9AAE81,
-	0x20A4F534, 0x894EC3A7,
-	0x61B7AD73, 0xC85D9BE0,
-	0x3263C055, 0x9B89F6C6,
-	0x6FF541AC, 0xC61F773F,
-	0x3C212C8A, 0x95CB1A19,
-	0xEDD3F122, 0x4439C7B1,
-	0xBE079C04, 0x17EDAA97,
-	0xE3911DFD, 0x4A7B2B6E,
-	0xB04570DB, 0x19AF4648,
-	0xF156289C, 0x58BC1E0F,
-	0xA28245BA, 0x0B687329,
-	0xFF14C443, 0x56FEF2D0,
-	0xACC0A965, 0x052A9FF6,
-	0x5CF17F13, 0xF51B4980,
-	0x0F251235, 0xA6CF24A6,
-	0x52B393CC, 0xFB59A55F,
-	0x0167FEEA, 0xA88DC879,
-	0x4074A6AD, 0xE99E903E,
-	0x13A0CB8B, 0xBA4AFD18,
-	0x4E364A72, 0xE7DC7CE1,
-	0x1DE22754, 0xB40811C7,
-	0xCC10FAFC, 0x65FACC6F,
-	0x9FC497DA, 0x362EA149,
-	0xC2521623, 0x6BB820B0,
-	0x91867B05, 0x386C4D96,
-	0xD0952342, 0x797F15D1,
-	0x83414E64, 0x2AAB78F7,
-	0xDED7CF9D, 0x773DF90E,
-	0x8D03A2BB, 0x24E99428,
-	0x975E55E2, 0x3EB46371,
-	0xC48A38C4, 0x6D600E57,
-	0x991CB93D, 0x30F68FAE,
-	0xCAC8D41B, 0x6322E288,
-	0x8BDB8C5C, 0x2231BACF,
-	0xD80FE17A, 0x71E5D7E9,
-	0x85996083, 0x2C735610,
-	0xD64D0DA5, 0x7FA73B36,
-	0x07BFD00D, 0xAE55E69E,
-	0x546BBD2B, 0xFD818BB8,
-	0x09FD3CD2, 0xA0170A41,
-	0x5A2951F4, 0xF3C36767,
-	0x1B3A09B3, 0xB2D03F20,
-	0x48EE6495, 0xE1045206,
-	0x1578E56C, 0xBC92D3FF,
-	0x46AC884A, 0xEF46BED9,
-	0xB69D5E3C, 0x1F7768AF,
-	0xE549331A, 0x4CA30589,
-	0xB8DFB2E3, 0x11358470,
-	0xEB0BDFC5, 0x42E1E956,
-	0xAA188782, 0x03F2B111,
-	0xF9CCEAA4, 0x5026DC37,
-	0xA45A6B5D, 0x0DB05DCE,
-	0xF78E067B, 0x5E6430E8,
-	0x267CDBD3, 0x8F96ED40,
-	0x75A8B6F5, 0xDC428066,
-	0x283E370C, 0x81D4019F,
-	0x7BEA5A2A, 0xD2006CB9,
-	0x3AF9026D, 0x931334FE,
-	0x692D6F4B, 0xC0C759D8,
-	0x34BBEEB2, 0x9D51D821,
-	0x676F8394, 0xCE85B507
-};
-
-const uint32 pg_crc64_table1[256] = {
-	0x00000000, 0x42F0E1EB,
-	0x85E1C3D7, 0xC711223C,
-	0x49336645, 0x0BC387AE,
-	0xCCD2A592, 0x8E224479,
-	0x9266CC8A, 0xD0962D61,
-	0x17870F5D, 0x5577EEB6,
-	0xDB55AACF, 0x99A54B24,
-	0x5EB46918, 0x1C4488F3,
-	0x663D78FF, 0x24CD9914,
-	0xE3DCBB28, 0xA12C5AC3,
-	0x2F0E1EBA, 0x6DFEFF51,
-	0xAAEFDD6D, 0xE81F3C86,
-	0xF45BB475, 0xB6AB559E,
-	0x71BA77A2, 0x334A9649,
-	0xBD68D230, 0xFF9833DB,
-	0x388911E7, 0x7A79F00C,
-	0xCC7AF1FF, 0x8E8A1014,
-	0x499B3228, 0x0B6BD3C3,
-	0x854997BA, 0xC7B97651,
-	0x00A8546D, 0x4258B586,
-	0x5E1C3D75, 0x1CECDC9E,
-	0xDBFDFEA2, 0x990D1F49,
-	0x172F5B30, 0x55DFBADB,
-	0x92CE98E7, 0xD03E790C,
-	0xAA478900, 0xE8B768EB,
-	0x2FA64AD7, 0x6D56AB3C,
-	0xE374EF45, 0xA1840EAE,
-	0x66952C92, 0x2465CD79,
-	0x3821458A, 0x7AD1A461,
-	0xBDC0865D, 0xFF3067B6,
-	0x711223CF, 0x33E2C224,
-	0xF4F3E018, 0xB60301F3,
-	0xDA050215, 0x98F5E3FE,
-	0x5FE4C1C2, 0x1D142029,
-	0x93366450, 0xD1C685BB,
-	0x16D7A787, 0x5427466C,
-	0x4863CE9F, 0x0A932F74,
-	0xCD820D48, 0x8F72ECA3,
-	0x0150A8DA, 0x43A04931,
-	0x84B16B0D, 0xC6418AE6,
-	0xBC387AEA, 0xFEC89B01,
-	0x39D9B93D, 0x7B2958D6,
-	0xF50B1CAF, 0xB7FBFD44,
-	0x70EADF78, 0x321A3E93,
-	0x2E5EB660, 0x6CAE578B,
-	0xABBF75B7, 0xE94F945C,
-	0x676DD025, 0x259D31CE,
-	0xE28C13F2, 0xA07CF219,
-	0x167FF3EA, 0x548F1201,
-	0x939E303D, 0xD16ED1D6,
-	0x5F4C95AF, 0x1DBC7444,
-	0xDAAD5678, 0x985DB793,
-	0x84193F60, 0xC6E9DE8B,
-	0x01F8FCB7, 0x43081D5C,
-	0xCD2A5925, 0x8FDAB8CE,
-	0x48CB9AF2, 0x0A3B7B19,
-	0x70428B15, 0x32B26AFE,
-	0xF5A348C2, 0xB753A929,
-	0x3971ED50, 0x7B810CBB,
-	0xBC902E87, 0xFE60CF6C,
-	0xE224479F, 0xA0D4A674,
-	0x67C58448, 0x253565A3,
-	0xAB1721DA, 0xE9E7C031,
-	0x2EF6E20D, 0x6C0603E6,
-	0xF6FAE5C0, 0xB40A042B,
-	0x731B2617, 0x31EBC7FC,
-	0xBFC98385, 0xFD39626E,
-	0x3A284052, 0x78D8A1B9,
-	0x649C294A, 0x266CC8A1,
-	0xE17DEA9D, 0xA38D0B76,
-	0x2DAF4F0F, 0x6F5FAEE4,
-	0xA84E8CD8, 0xEABE6D33,
-	0x90C79D3F, 0xD2377CD4,
-	0x15265EE8, 0x57D6BF03,
-	0xD9F4FB7A, 0x9B041A91,
-	0x5C1538AD, 0x1EE5D946,
-	0x02A151B5, 0x4051B05E,
-	0x87409262, 0xC5B07389,
-	0x4B9237F0, 0x0962D61B,
-	0xCE73F427, 0x8C8315CC,
-	0x3A80143F, 0x7870F5D4,
-	0xBF61D7E8, 0xFD913603,
-	0x73B3727A, 0x31439391,
-	0xF652B1AD, 0xB4A25046,
-	0xA8E6D8B5, 0xEA16395E,
-	0x2D071B62, 0x6FF7FA89,
-	0xE1D5BEF0, 0xA3255F1B,
-	0x64347D27, 0x26C49CCC,
-	0x5CBD6CC0, 0x1E4D8D2B,
-	0xD95CAF17, 0x9BAC4EFC,
-	0x158E0A85, 0x577EEB6E,
-	0x906FC952, 0xD29F28B9,
-	0xCEDBA04A, 0x8C2B41A1,
-	0x4B3A639D, 0x09CA8276,
-	0x87E8C60F, 0xC51827E4,
-	0x020905D8, 0x40F9E433,
-	0x2CFFE7D5, 0x6E0F063E,
-	0xA91E2402, 0xEBEEC5E9,
-	0x65CC8190, 0x273C607B,
-	0xE02D4247, 0xA2DDA3AC,
-	0xBE992B5F, 0xFC69CAB4,
-	0x3B78E888, 0x79880963,
-	0xF7AA4D1A, 0xB55AACF1,
-	0x724B8ECD, 0x30BB6F26,
-	0x4AC29F2A, 0x08327EC1,
-	0xCF235CFD, 0x8DD3BD16,
-	0x03F1F96F, 0x41011884,
-	0x86103AB8, 0xC4E0DB53,
-	0xD8A453A0, 0x9A54B24B,
-	0x5D459077, 0x1FB5719C,
-	0x919735E5, 0xD367D40E,
-	0x1476F632, 0x568617D9,
-	0xE085162A, 0xA275F7C1,
-	0x6564D5FD, 0x27943416,
-	0xA9B6706F, 0xEB469184,
-	0x2C57B3B8, 0x6EA75253,
-	0x72E3DAA0, 0x30133B4B,
-	0xF7021977, 0xB5F2F89C,
-	0x3BD0BCE5, 0x79205D0E,
-	0xBE317F32, 0xFCC19ED9,
-	0x86B86ED5, 0xC4488F3E,
-	0x0359AD02, 0x41A94CE9,
-	0xCF8B0890, 0x8D7BE97B,
-	0x4A6ACB47, 0x089A2AAC,
-	0x14DEA25F, 0x562E43B4,
-	0x913F6188, 0xD3CF8063,
-	0x5DEDC41A, 0x1F1D25F1,
-	0xD80C07CD, 0x9AFCE626
-};
-#else							/* use int64 implementation */
-
-const uint64 pg_crc64_table[256] = {
-	UINT64CONST(0x0000000000000000), UINT64CONST(0x42F0E1EBA9EA3693),
-	UINT64CONST(0x85E1C3D753D46D26), UINT64CONST(0xC711223CFA3E5BB5),
-	UINT64CONST(0x493366450E42ECDF), UINT64CONST(0x0BC387AEA7A8DA4C),
-	UINT64CONST(0xCCD2A5925D9681F9), UINT64CONST(0x8E224479F47CB76A),
-	UINT64CONST(0x9266CC8A1C85D9BE), UINT64CONST(0xD0962D61B56FEF2D),
-	UINT64CONST(0x17870F5D4F51B498), UINT64CONST(0x5577EEB6E6BB820B),
-	UINT64CONST(0xDB55AACF12C73561), UINT64CONST(0x99A54B24BB2D03F2),
-	UINT64CONST(0x5EB4691841135847), UINT64CONST(0x1C4488F3E8F96ED4),
-	UINT64CONST(0x663D78FF90E185EF), UINT64CONST(0x24CD9914390BB37C),
-	UINT64CONST(0xE3DCBB28C335E8C9), UINT64CONST(0xA12C5AC36ADFDE5A),
-	UINT64CONST(0x2F0E1EBA9EA36930), UINT64CONST(0x6DFEFF5137495FA3),
-	UINT64CONST(0xAAEFDD6DCD770416), UINT64CONST(0xE81F3C86649D3285),
-	UINT64CONST(0xF45BB4758C645C51), UINT64CONST(0xB6AB559E258E6AC2),
-	UINT64CONST(0x71BA77A2DFB03177), UINT64CONST(0x334A9649765A07E4),
-	UINT64CONST(0xBD68D2308226B08E), UINT64CONST(0xFF9833DB2BCC861D),
-	UINT64CONST(0x388911E7D1F2DDA8), UINT64CONST(0x7A79F00C7818EB3B),
-	UINT64CONST(0xCC7AF1FF21C30BDE), UINT64CONST(0x8E8A101488293D4D),
-	UINT64CONST(0x499B3228721766F8), UINT64CONST(0x0B6BD3C3DBFD506B),
-	UINT64CONST(0x854997BA2F81E701), UINT64CONST(0xC7B97651866BD192),
-	UINT64CONST(0x00A8546D7C558A27), UINT64CONST(0x4258B586D5BFBCB4),
-	UINT64CONST(0x5E1C3D753D46D260), UINT64CONST(0x1CECDC9E94ACE4F3),
-	UINT64CONST(0xDBFDFEA26E92BF46), UINT64CONST(0x990D1F49C77889D5),
-	UINT64CONST(0x172F5B3033043EBF), UINT64CONST(0x55DFBADB9AEE082C),
-	UINT64CONST(0x92CE98E760D05399), UINT64CONST(0xD03E790CC93A650A),
-	UINT64CONST(0xAA478900B1228E31), UINT64CONST(0xE8B768EB18C8B8A2),
-	UINT64CONST(0x2FA64AD7E2F6E317), UINT64CONST(0x6D56AB3C4B1CD584),
-	UINT64CONST(0xE374EF45BF6062EE), UINT64CONST(0xA1840EAE168A547D),
-	UINT64CONST(0x66952C92ECB40FC8), UINT64CONST(0x2465CD79455E395B),
-	UINT64CONST(0x3821458AADA7578F), UINT64CONST(0x7AD1A461044D611C),
-	UINT64CONST(0xBDC0865DFE733AA9), UINT64CONST(0xFF3067B657990C3A),
-	UINT64CONST(0x711223CFA3E5BB50), UINT64CONST(0x33E2C2240A0F8DC3),
-	UINT64CONST(0xF4F3E018F031D676), UINT64CONST(0xB60301F359DBE0E5),
-	UINT64CONST(0xDA050215EA6C212F), UINT64CONST(0x98F5E3FE438617BC),
-	UINT64CONST(0x5FE4C1C2B9B84C09), UINT64CONST(0x1D14202910527A9A),
-	UINT64CONST(0x93366450E42ECDF0), UINT64CONST(0xD1C685BB4DC4FB63),
-	UINT64CONST(0x16D7A787B7FAA0D6), UINT64CONST(0x5427466C1E109645),
-	UINT64CONST(0x4863CE9FF6E9F891), UINT64CONST(0x0A932F745F03CE02),
-	UINT64CONST(0xCD820D48A53D95B7), UINT64CONST(0x8F72ECA30CD7A324),
-	UINT64CONST(0x0150A8DAF8AB144E), UINT64CONST(0x43A04931514122DD),
-	UINT64CONST(0x84B16B0DAB7F7968), UINT64CONST(0xC6418AE602954FFB),
-	UINT64CONST(0xBC387AEA7A8DA4C0), UINT64CONST(0xFEC89B01D3679253),
-	UINT64CONST(0x39D9B93D2959C9E6), UINT64CONST(0x7B2958D680B3FF75),
-	UINT64CONST(0xF50B1CAF74CF481F), UINT64CONST(0xB7FBFD44DD257E8C),
-	UINT64CONST(0x70EADF78271B2539), UINT64CONST(0x321A3E938EF113AA),
-	UINT64CONST(0x2E5EB66066087D7E), UINT64CONST(0x6CAE578BCFE24BED),
-	UINT64CONST(0xABBF75B735DC1058), UINT64CONST(0xE94F945C9C3626CB),
-	UINT64CONST(0x676DD025684A91A1), UINT64CONST(0x259D31CEC1A0A732),
-	UINT64CONST(0xE28C13F23B9EFC87), UINT64CONST(0xA07CF2199274CA14),
-	UINT64CONST(0x167FF3EACBAF2AF1), UINT64CONST(0x548F120162451C62),
-	UINT64CONST(0x939E303D987B47D7), UINT64CONST(0xD16ED1D631917144),
-	UINT64CONST(0x5F4C95AFC5EDC62E), UINT64CONST(0x1DBC74446C07F0BD),
-	UINT64CONST(0xDAAD56789639AB08), UINT64CONST(0x985DB7933FD39D9B),
-	UINT64CONST(0x84193F60D72AF34F), UINT64CONST(0xC6E9DE8B7EC0C5DC),
-	UINT64CONST(0x01F8FCB784FE9E69), UINT64CONST(0x43081D5C2D14A8FA),
-	UINT64CONST(0xCD2A5925D9681F90), UINT64CONST(0x8FDAB8CE70822903),
-	UINT64CONST(0x48CB9AF28ABC72B6), UINT64CONST(0x0A3B7B1923564425),
-	UINT64CONST(0x70428B155B4EAF1E), UINT64CONST(0x32B26AFEF2A4998D),
-	UINT64CONST(0xF5A348C2089AC238), UINT64CONST(0xB753A929A170F4AB),
-	UINT64CONST(0x3971ED50550C43C1), UINT64CONST(0x7B810CBBFCE67552),
-	UINT64CONST(0xBC902E8706D82EE7), UINT64CONST(0xFE60CF6CAF321874),
-	UINT64CONST(0xE224479F47CB76A0), UINT64CONST(0xA0D4A674EE214033),
-	UINT64CONST(0x67C58448141F1B86), UINT64CONST(0x253565A3BDF52D15),
-	UINT64CONST(0xAB1721DA49899A7F), UINT64CONST(0xE9E7C031E063ACEC),
-	UINT64CONST(0x2EF6E20D1A5DF759), UINT64CONST(0x6C0603E6B3B7C1CA),
-	UINT64CONST(0xF6FAE5C07D3274CD), UINT64CONST(0xB40A042BD4D8425E),
-	UINT64CONST(0x731B26172EE619EB), UINT64CONST(0x31EBC7FC870C2F78),
-	UINT64CONST(0xBFC9838573709812), UINT64CONST(0xFD39626EDA9AAE81),
-	UINT64CONST(0x3A28405220A4F534), UINT64CONST(0x78D8A1B9894EC3A7),
-	UINT64CONST(0x649C294A61B7AD73), UINT64CONST(0x266CC8A1C85D9BE0),
-	UINT64CONST(0xE17DEA9D3263C055), UINT64CONST(0xA38D0B769B89F6C6),
-	UINT64CONST(0x2DAF4F0F6FF541AC), UINT64CONST(0x6F5FAEE4C61F773F),
-	UINT64CONST(0xA84E8CD83C212C8A), UINT64CONST(0xEABE6D3395CB1A19),
-	UINT64CONST(0x90C79D3FEDD3F122), UINT64CONST(0xD2377CD44439C7B1),
-	UINT64CONST(0x15265EE8BE079C04), UINT64CONST(0x57D6BF0317EDAA97),
-	UINT64CONST(0xD9F4FB7AE3911DFD), UINT64CONST(0x9B041A914A7B2B6E),
-	UINT64CONST(0x5C1538ADB04570DB), UINT64CONST(0x1EE5D94619AF4648),
-	UINT64CONST(0x02A151B5F156289C), UINT64CONST(0x4051B05E58BC1E0F),
-	UINT64CONST(0x87409262A28245BA), UINT64CONST(0xC5B073890B687329),
-	UINT64CONST(0x4B9237F0FF14C443), UINT64CONST(0x0962D61B56FEF2D0),
-	UINT64CONST(0xCE73F427ACC0A965), UINT64CONST(0x8C8315CC052A9FF6),
-	UINT64CONST(0x3A80143F5CF17F13), UINT64CONST(0x7870F5D4F51B4980),
-	UINT64CONST(0xBF61D7E80F251235), UINT64CONST(0xFD913603A6CF24A6),
-	UINT64CONST(0x73B3727A52B393CC), UINT64CONST(0x31439391FB59A55F),
-	UINT64CONST(0xF652B1AD0167FEEA), UINT64CONST(0xB4A25046A88DC879),
-	UINT64CONST(0xA8E6D8B54074A6AD), UINT64CONST(0xEA16395EE99E903E),
-	UINT64CONST(0x2D071B6213A0CB8B), UINT64CONST(0x6FF7FA89BA4AFD18),
-	UINT64CONST(0xE1D5BEF04E364A72), UINT64CONST(0xA3255F1BE7DC7CE1),
-	UINT64CONST(0x64347D271DE22754), UINT64CONST(0x26C49CCCB40811C7),
-	UINT64CONST(0x5CBD6CC0CC10FAFC), UINT64CONST(0x1E4D8D2B65FACC6F),
-	UINT64CONST(0xD95CAF179FC497DA), UINT64CONST(0x9BAC4EFC362EA149),
-	UINT64CONST(0x158E0A85C2521623), UINT64CONST(0x577EEB6E6BB820B0),
-	UINT64CONST(0x906FC95291867B05), UINT64CONST(0xD29F28B9386C4D96),
-	UINT64CONST(0xCEDBA04AD0952342), UINT64CONST(0x8C2B41A1797F15D1),
-	UINT64CONST(0x4B3A639D83414E64), UINT64CONST(0x09CA82762AAB78F7),
-	UINT64CONST(0x87E8C60FDED7CF9D), UINT64CONST(0xC51827E4773DF90E),
-	UINT64CONST(0x020905D88D03A2BB), UINT64CONST(0x40F9E43324E99428),
-	UINT64CONST(0x2CFFE7D5975E55E2), UINT64CONST(0x6E0F063E3EB46371),
-	UINT64CONST(0xA91E2402C48A38C4), UINT64CONST(0xEBEEC5E96D600E57),
-	UINT64CONST(0x65CC8190991CB93D), UINT64CONST(0x273C607B30F68FAE),
-	UINT64CONST(0xE02D4247CAC8D41B), UINT64CONST(0xA2DDA3AC6322E288),
-	UINT64CONST(0xBE992B5F8BDB8C5C), UINT64CONST(0xFC69CAB42231BACF),
-	UINT64CONST(0x3B78E888D80FE17A), UINT64CONST(0x7988096371E5D7E9),
-	UINT64CONST(0xF7AA4D1A85996083), UINT64CONST(0xB55AACF12C735610),
-	UINT64CONST(0x724B8ECDD64D0DA5), UINT64CONST(0x30BB6F267FA73B36),
-	UINT64CONST(0x4AC29F2A07BFD00D), UINT64CONST(0x08327EC1AE55E69E),
-	UINT64CONST(0xCF235CFD546BBD2B), UINT64CONST(0x8DD3BD16FD818BB8),
-	UINT64CONST(0x03F1F96F09FD3CD2), UINT64CONST(0x41011884A0170A41),
-	UINT64CONST(0x86103AB85A2951F4), UINT64CONST(0xC4E0DB53F3C36767),
-	UINT64CONST(0xD8A453A01B3A09B3), UINT64CONST(0x9A54B24BB2D03F20),
-	UINT64CONST(0x5D45907748EE6495), UINT64CONST(0x1FB5719CE1045206),
-	UINT64CONST(0x919735E51578E56C), UINT64CONST(0xD367D40EBC92D3FF),
-	UINT64CONST(0x1476F63246AC884A), UINT64CONST(0x568617D9EF46BED9),
-	UINT64CONST(0xE085162AB69D5E3C), UINT64CONST(0xA275F7C11F7768AF),
-	UINT64CONST(0x6564D5FDE549331A), UINT64CONST(0x279434164CA30589),
-	UINT64CONST(0xA9B6706FB8DFB2E3), UINT64CONST(0xEB46918411358470),
-	UINT64CONST(0x2C57B3B8EB0BDFC5), UINT64CONST(0x6EA7525342E1E956),
-	UINT64CONST(0x72E3DAA0AA188782), UINT64CONST(0x30133B4B03F2B111),
-	UINT64CONST(0xF7021977F9CCEAA4), UINT64CONST(0xB5F2F89C5026DC37),
-	UINT64CONST(0x3BD0BCE5A45A6B5D), UINT64CONST(0x79205D0E0DB05DCE),
-	UINT64CONST(0xBE317F32F78E067B), UINT64CONST(0xFCC19ED95E6430E8),
-	UINT64CONST(0x86B86ED5267CDBD3), UINT64CONST(0xC4488F3E8F96ED40),
-	UINT64CONST(0x0359AD0275A8B6F5), UINT64CONST(0x41A94CE9DC428066),
-	UINT64CONST(0xCF8B0890283E370C), UINT64CONST(0x8D7BE97B81D4019F),
-	UINT64CONST(0x4A6ACB477BEA5A2A), UINT64CONST(0x089A2AACD2006CB9),
-	UINT64CONST(0x14DEA25F3AF9026D), UINT64CONST(0x562E43B4931334FE),
-	UINT64CONST(0x913F6188692D6F4B), UINT64CONST(0xD3CF8063C0C759D8),
-	UINT64CONST(0x5DEDC41A34BBEEB2), UINT64CONST(0x1F1D25F19D51D821),
-	UINT64CONST(0xD80C07CD676F8394), UINT64CONST(0x9AFCE626CE85B507)
-};
-#endif   /* SIZEOF_VOID_P < 8 */
-#endif   /* PROVIDE_64BIT_CRC */
-
 #endif   /* PG_CRC_TABLES_H */
-- 
2.1.1

0002-Switch-to-CRC-32C-in-WAL-and-other-places.patchtext/x-diff; name=0002-Switch-to-CRC-32C-in-WAL-and-other-places.patchDownload
>From d7718f2f180d6f67181dc13e5d9341ad856e9ada Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 27 Oct 2014 15:31:59 +0200
Subject: [PATCH 2/2] Switch to CRC-32C in WAL and other places.

The old algorithm was found to not be the usual CRC-32 algorithm, used by
Ethernet et al. We were using a non-reflected lookup table with code meant
for a reflected lookup table. That's a strange combination that AFAICS does
not correspond to any bit-wise CRC calculation, which makes it difficult to
reason about its properties. Although it has worked well in practice, seems
safer to use a well-known algorithm.

Since we're changing the algorithm anyway, we might as well choose a
different polynomial. The Castagnoli polynomial has better error-correcting
properties than the traditional CRC-32 polynomial (even if we had
implemented it correctly). Another reason for picking that is that some new
CPUs have hardware support for calculating CRC-32C, but not CRC-32, let
alone our strange variant of it. This patch doesn't add any support for such
hardware, but a future patch now could do that.

The old algorithm is kept around for tsquery and pg_trgm, which use the
values in indexes that need to remain compatible so that pg_upgrade works.

While we're at it, share the lookup table for CRC-32 calculation between
hstore, ltree and core. They all use the same table, so might as well.
---
 contrib/hstore/Makefile                     |   2 +-
 contrib/hstore/crc32.c                      | 106 --------------------------
 contrib/hstore/crc32.h                      |  13 ----
 contrib/hstore/hstore_gist.c                |  16 +++-
 contrib/ltree/Makefile                      |   2 +-
 contrib/ltree/_ltree_gist.c                 |  19 +++--
 contrib/ltree/crc32.c                       | 114 ----------------------------
 contrib/ltree/crc32.h                       |  12 ---
 contrib/ltree/ltree_gist.c                  |  12 ++-
 contrib/ltree/ltree_io.c                    |  11 ++-
 contrib/ltree/ltxtquery_io.c                |  10 ++-
 contrib/pg_trgm/trgm_op.c                   |   6 +-
 src/backend/access/transam/twophase.c       |  24 +++---
 src/backend/access/transam/xlog.c           |  50 ++++++------
 src/backend/access/transam/xlogreader.c     |  12 +--
 src/backend/replication/logical/snapbuild.c |  28 +++----
 src/backend/replication/slot.c              |  20 ++---
 src/backend/utils/adt/tsgistidx.c           |   6 +-
 src/backend/utils/adt/tsquery.c             |  12 +--
 src/backend/utils/cache/relmapper.c         |  16 ++--
 src/bin/pg_controldata/pg_controldata.c     |  12 +--
 src/bin/pg_resetxlog/pg_resetxlog.c         |  30 ++++----
 src/include/utils/pg_crc.h                  |  92 ++++++++++++++++++----
 src/include/utils/pg_crc_tables.h           |  73 ++++++++++++++++++
 24 files changed, 313 insertions(+), 385 deletions(-)
 delete mode 100644 contrib/hstore/crc32.c
 delete mode 100644 contrib/hstore/crc32.h
 delete mode 100644 contrib/ltree/crc32.c
 delete mode 100644 contrib/ltree/crc32.h

diff --git a/contrib/hstore/Makefile b/contrib/hstore/Makefile
index 3193668..82908de 100644
--- a/contrib/hstore/Makefile
+++ b/contrib/hstore/Makefile
@@ -2,7 +2,7 @@
 
 MODULE_big = hstore
 OBJS = hstore_io.o hstore_op.o hstore_gist.o hstore_gin.o hstore_compat.o \
-	crc32.o $(WIN32RES)
+	$(WIN32RES)
 
 EXTENSION = hstore
 DATA = hstore--1.3.sql hstore--1.2--1.3.sql \
diff --git a/contrib/hstore/crc32.c b/contrib/hstore/crc32.c
deleted file mode 100644
index c82fc66..0000000
--- a/contrib/hstore/crc32.c
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * contrib/hstore/crc32.c
- *
- * Both POSIX and CRC32 checksums */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#include "crc32.h"
-
-/*
- * This code implements the AUTODIN II polynomial
- * The variable corresponding to the macro argument "crc" should
- * be an unsigned long.
- * Original code  by Spencer Garrett <srg@quick.com>
- */
-
-#define _CRC32_(crc, ch)	 (crc = (crc >> 8) ^ crc32tab[(crc ^ (ch)) & 0xff])
-
-/* generated using the AUTODIN II polynomial
- *	x^32 + x^26 + x^23 + x^22 + x^16 +
- *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
- */
-
-static const unsigned int crc32tab[256] = {
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-unsigned int
-crc32_sz(char *buf, int size)
-{
-	unsigned int crc = ~((unsigned int) 0);
-	char	   *p;
-	int			len,
-				nr;
-
-	len = 0;
-	nr = size;
-	for (len += nr, p = buf; nr--; ++p)
-		_CRC32_(crc, *p);
-	return ~crc;
-}
diff --git a/contrib/hstore/crc32.h b/contrib/hstore/crc32.h
deleted file mode 100644
index f5bfd82..0000000
--- a/contrib/hstore/crc32.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * contrib/hstore/crc32.h
- */
-#ifndef _CRC32_H
-#define _CRC32_H
-
-/* Returns crc32 of data block */
-extern unsigned int crc32_sz(char *buf, int size);
-
-/* Returns crc32 of null-terminated string */
-#define crc32(buf) crc32_sz((buf),strlen(buf))
-
-#endif
diff --git a/contrib/hstore/hstore_gist.c b/contrib/hstore/hstore_gist.c
index d4a9aaa..876b435 100644
--- a/contrib/hstore/hstore_gist.c
+++ b/contrib/hstore/hstore_gist.c
@@ -6,8 +6,8 @@
 #include "access/gist.h"
 #include "access/skey.h"
 #include "catalog/pg_type.h"
+#include "utils/pg_crc.h"
 
-#include "crc32.h"
 #include "hstore.h"
 
 /* bigint defines */
@@ -68,6 +68,20 @@ typedef struct
 
 #define WISH_F(a,b,c) (double)( -(double)(((a)-(b))*((a)-(b))*((a)-(b)))*(c) )
 
+/* shorthand for calculating CRC-32 of a single chunk of data. */
+static pg_crc32
+crc32_sz(char *buf, int size)
+{
+	pg_crc32 crc;
+
+	INIT_TRADITIONAL_CRC32(crc);
+	COMP_TRADITIONAL_CRC32(crc, buf, size);
+	FIN_TRADITIONAL_CRC32(crc);
+
+	return crc;
+}
+
+
 PG_FUNCTION_INFO_V1(ghstore_in);
 PG_FUNCTION_INFO_V1(ghstore_out);
 
diff --git a/contrib/ltree/Makefile b/contrib/ltree/Makefile
index a41e457..d7604d6 100644
--- a/contrib/ltree/Makefile
+++ b/contrib/ltree/Makefile
@@ -1,7 +1,7 @@
 # contrib/ltree/Makefile
 
 MODULE_big = ltree
-OBJS = 	ltree_io.o ltree_op.o lquery_op.o _ltree_op.o crc32.o \
+OBJS = 	ltree_io.o ltree_op.o lquery_op.o _ltree_op.o \
 	ltxtquery_io.o ltxtquery_op.o ltree_gist.o _ltree_gist.o $(WIN32RES)
 PG_CPPFLAGS = -DLOWER_NODE
 
diff --git a/contrib/ltree/_ltree_gist.c b/contrib/ltree/_ltree_gist.c
index 41be68d..64fb173 100644
--- a/contrib/ltree/_ltree_gist.c
+++ b/contrib/ltree/_ltree_gist.c
@@ -9,7 +9,7 @@
 
 #include "access/gist.h"
 #include "access/skey.h"
-#include "crc32.h"
+#include "utils/pg_crc.h"
 #include "ltree.h"
 
 
@@ -51,12 +51,14 @@ hashing(BITVECP sign, ltree *t)
 {
 	int			tlen = t->numlevel;
 	ltree_level *cur = LTREE_FIRST(t);
-	int			hash;
+	pg_crc32	crc;
 
 	while (tlen > 0)
 	{
-		hash = ltree_crc32_sz(cur->name, cur->len);
-		AHASH(sign, hash);
+		INIT_TRADITIONAL_CRC32(crc);
+		COMP_TRADITIONAL_CRC32(crc, cur->name, cur->len);
+		FIN_TRADITIONAL_CRC32(crc);
+		AHASH(sign, crc);
 		cur = LEVEL_NEXT(cur);
 		tlen--;
 	}
@@ -441,15 +443,18 @@ gist_te(ltree_gist *key, ltree *query)
 	ltree_level *curq = LTREE_FIRST(query);
 	BITVECP		sign = LTG_SIGN(key);
 	int			qlen = query->numlevel;
-	unsigned int hv;
+	pg_crc32	crc;
 
 	if (LTG_ISALLTRUE(key))
 		return true;
 
 	while (qlen > 0)
 	{
-		hv = ltree_crc32_sz(curq->name, curq->len);
-		if (!GETBIT(sign, AHASHVAL(hv)))
+		INIT_TRADITIONAL_CRC32(crc);
+		COMP_TRADITIONAL_CRC32(crc, curq->name, curq->len);
+		FIN_TRADITIONAL_CRC32(crc);
+
+		if (!GETBIT(sign, AHASHVAL(crc)))
 			return false;
 		curq = LEVEL_NEXT(curq);
 		qlen--;
diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c
deleted file mode 100644
index ea1a661..0000000
--- a/contrib/ltree/crc32.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/* Both POSIX and CRC32 checksums */
-
-/* contrib/ltree/crc32.c */
-
-#include "postgres.h"
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <sys/types.h>
-
-#ifdef LOWER_NODE
-#include <ctype.h>
-#define TOLOWER(x)	tolower((unsigned char) (x))
-#else
-#define TOLOWER(x)	(x)
-#endif
-
-#include "crc32.h"
-
-/*
- * This code implements the AUTODIN II polynomial
- * The variable corresponding to the macro argument "crc" should
- * be an unsigned long.
- * Oroginal code  by Spencer Garrett <srg@quick.com>
- */
-
-#define _CRC32_(crc, ch)	 ((crc) = ((crc) >> 8) ^ crc32tab[((crc) ^ (ch)) & 0xff])
-
-/* generated using the AUTODIN II polynomial
- *	x^32 + x^26 + x^23 + x^22 + x^16 +
- *	x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
- */
-
-static const unsigned int crc32tab[256] = {
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
-};
-
-unsigned int
-ltree_crc32_sz(char *buf, int size)
-{
-	unsigned int crc = ~((unsigned int) 0);
-	char	   *p;
-	int			len,
-				nr;
-
-	len = 0;
-	nr = size;
-	for (len += nr, p = buf; nr--; ++p)
-		_CRC32_(crc, TOLOWER((unsigned int) *p));
-	return ~crc;
-}
diff --git a/contrib/ltree/crc32.h b/contrib/ltree/crc32.h
deleted file mode 100644
index 269d05d..0000000
--- a/contrib/ltree/crc32.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef _CRC32_H
-#define _CRC32_H
-
-/* contrib/ltree/crc32.h */
-
-/* Returns crc32 of data block */
-extern unsigned int ltree_crc32_sz(char *buf, int size);
-
-/* Returns crc32 of null-terminated string */
-#define crc32(buf) ltree_crc32_sz((buf),strlen(buf))
-
-#endif
diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c
index 2d89f1a..91c5081 100644
--- a/contrib/ltree/ltree_gist.c
+++ b/contrib/ltree/ltree_gist.c
@@ -7,7 +7,7 @@
 
 #include "access/gist.h"
 #include "access/skey.h"
-#include "crc32.h"
+#include "utils/pg_crc.h"
 #include "ltree.h"
 
 #define NEXTVAL(x) ( (lquery*)( (char*)(x) + INTALIGN( VARSIZE(x) ) ) )
@@ -136,12 +136,16 @@ hashing(BITVECP sign, ltree *t)
 {
 	int			tlen = t->numlevel;
 	ltree_level *cur = LTREE_FIRST(t);
-	int			hash;
 
 	while (tlen > 0)
 	{
-		hash = ltree_crc32_sz(cur->name, cur->len);
-		HASH(sign, hash);
+		pg_crc32 crc;
+
+		INIT_TRADITIONAL_CRC32(crc);
+		COMP_TRADITIONAL_CRC32(crc, cur->name, cur->len);
+		FIN_TRADITIONAL_CRC32(crc);
+
+		HASH(sign, crc);
 		cur = LEVEL_NEXT(cur);
 		tlen--;
 	}
diff --git a/contrib/ltree/ltree_io.c b/contrib/ltree/ltree_io.c
index a1d4a0d..80b507a 100644
--- a/contrib/ltree/ltree_io.c
+++ b/contrib/ltree/ltree_io.c
@@ -9,7 +9,7 @@
 
 #include "ltree.h"
 #include "utils/memutils.h"
-#include "crc32.h"
+#include "utils/pg_crc.h"
 
 PG_FUNCTION_INFO_V1(ltree_in);
 PG_FUNCTION_INFO_V1(ltree_out);
@@ -494,10 +494,17 @@ lquery_in(PG_FUNCTION_ARGS)
 			lptr = GETVAR(curqlevel);
 			while (lptr - GETVAR(curqlevel) < curqlevel->numvar)
 			{
+				pg_crc32 crc;
+
 				cur->totallen += MAXALIGN(LVAR_HDRSIZE + lptr->len);
 				lrptr->len = lptr->len;
 				lrptr->flag = lptr->flag;
-				lrptr->val = ltree_crc32_sz(lptr->start, lptr->len);
+
+				INIT_CRC32(crc);
+				COMP_CRC32(crc, lptr->start, lptr->len);
+				FIN_CRC32(crc);
+				lrptr->val = crc;
+
 				memcpy(lrptr->name, lptr->start, lptr->len);
 				lptr++;
 				lrptr = LVAR_NEXT(lrptr);
diff --git a/contrib/ltree/ltxtquery_io.c b/contrib/ltree/ltxtquery_io.c
index ddc63d7..26b24d9 100644
--- a/contrib/ltree/ltxtquery_io.c
+++ b/contrib/ltree/ltxtquery_io.c
@@ -7,7 +7,7 @@
 
 #include <ctype.h>
 
-#include "crc32.h"
+#include "utils/pg_crc.h"
 #include "ltree.h"
 #include "miscadmin.h"
 
@@ -171,12 +171,18 @@ pushquery(QPRS_STATE *state, int32 type, int32 val, int32 distance, int32 lenval
 static void
 pushval_asis(QPRS_STATE *state, int type, char *strval, int lenval, uint16 flag)
 {
+	pg_crc32	crc;
+
 	if (lenval > 0xffff)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 				 errmsg("word is too long")));
 
-	pushquery(state, type, ltree_crc32_sz(strval, lenval),
+	INIT_CRC32(crc);
+	COMP_CRC32(crc, strval, lenval);
+	FIN_CRC32(crc);
+
+	pushquery(state, type, crc,
 			  state->curop - state->op, lenval, flag);
 
 	while (state->curop - state->op + lenval + 1 >= state->lenop)
diff --git a/contrib/pg_trgm/trgm_op.c b/contrib/pg_trgm/trgm_op.c
index df15b52..5ec7f26 100644
--- a/contrib/pg_trgm/trgm_op.c
+++ b/contrib/pg_trgm/trgm_op.c
@@ -108,9 +108,9 @@ compact_trigram(trgm *tptr, char *str, int bytelen)
 	{
 		pg_crc32	crc;
 
-		INIT_CRC32(crc);
-		COMP_CRC32(crc, str, bytelen);
-		FIN_CRC32(crc);
+		INIT_LEGACY_CRC32(crc);
+		COMP_LEGACY_CRC32(crc, str, bytelen);
+		FIN_LEGACY_CRC32(crc);
 
 		/*
 		 * use only 3 upper bytes from crc, hope, it's good enough hashing
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index d5409a6..c4069c3 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -847,9 +847,9 @@ TwoPhaseGetDummyProc(TransactionId xid)
  *	6. TwoPhaseRecordOnDisk
  *	7. ...
  *	8. TwoPhaseRecordOnDisk (end sentinel, rmid == TWOPHASE_RM_END_ID)
- *	9. CRC32
+ *	9. checksum (CRC-32C)
  *
- * Each segment except the final CRC32 is MAXALIGN'd.
+ * Each segment except the final checksum is MAXALIGN'd.
  */
 
 /*
@@ -1056,11 +1056,11 @@ EndPrepare(GlobalTransaction gxact)
 						path)));
 
 	/* Write data to file, and calculate CRC as we pass over it */
-	INIT_CRC32(statefile_crc);
+	INIT_CRC32C(statefile_crc);
 
 	for (record = records.head; record != NULL; record = record->next)
 	{
-		COMP_CRC32(statefile_crc, record->data, record->len);
+		COMP_CRC32C(statefile_crc, record->data, record->len);
 		if ((write(fd, record->data, record->len)) != record->len)
 		{
 			CloseTransientFile(fd);
@@ -1070,7 +1070,7 @@ EndPrepare(GlobalTransaction gxact)
 		}
 	}
 
-	FIN_CRC32(statefile_crc);
+	FIN_CRC32C(statefile_crc);
 
 	/*
 	 * Write a deliberately bogus CRC to the state file; this is just paranoia
@@ -1289,13 +1289,13 @@ ReadTwoPhaseFile(TransactionId xid, bool give_warnings)
 		return NULL;
 	}
 
-	INIT_CRC32(calc_crc);
-	COMP_CRC32(calc_crc, buf, crc_offset);
-	FIN_CRC32(calc_crc);
+	INIT_CRC32C(calc_crc);
+	COMP_CRC32C(calc_crc, buf, crc_offset);
+	FIN_CRC32C(calc_crc);
 
 	file_crc = *((pg_crc32 *) (buf + crc_offset));
 
-	if (!EQ_CRC32(calc_crc, file_crc))
+	if (!EQ_CRC32C(calc_crc, file_crc))
 	{
 		pfree(buf);
 		return NULL;
@@ -1540,9 +1540,9 @@ RecreateTwoPhaseFile(TransactionId xid, void *content, int len)
 	int			fd;
 
 	/* Recompute CRC */
-	INIT_CRC32(statefile_crc);
-	COMP_CRC32(statefile_crc, content, len);
-	FIN_CRC32(statefile_crc);
+	INIT_CRC32C(statefile_crc);
+	COMP_CRC32C(statefile_crc, content, len);
+	FIN_CRC32C(statefile_crc);
 
 	TwoPhaseFilePath(path, xid);
 
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 3c9aeae..3160db7 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -1059,9 +1059,9 @@ begin:;
 	 * the whole record in the order: rdata, then backup blocks, then record
 	 * header.
 	 */
-	INIT_CRC32(rdata_crc);
+	INIT_CRC32C(rdata_crc);
 	for (rdt = rdata; rdt != NULL; rdt = rdt->next)
-		COMP_CRC32(rdata_crc, rdt->data, rdt->len);
+		COMP_CRC32C(rdata_crc, rdt->data, rdt->len);
 
 	/*
 	 * Construct record header (prev-link is filled in later, after reserving
@@ -1076,7 +1076,7 @@ begin:;
 	rechdr->xl_info = info;
 	rechdr->xl_rmid = rmid;
 	rechdr->xl_prev = InvalidXLogRecPtr;
-	COMP_CRC32(rdata_crc, ((char *) rechdr), offsetof(XLogRecord, xl_prev));
+	COMP_CRC32C(rdata_crc, ((char *) rechdr), offsetof(XLogRecord, xl_prev));
 
 	hdr_rdt.next = rdata;
 	hdr_rdt.data = (char *) rechdr;
@@ -1193,8 +1193,8 @@ begin:;
 		 * Now that xl_prev has been filled in, finish CRC calculation of the
 		 * record header.
 		 */
-		COMP_CRC32(rdata_crc, ((char *) &rechdr->xl_prev), sizeof(XLogRecPtr));
-		FIN_CRC32(rdata_crc);
+		COMP_CRC32C(rdata_crc, ((char *) &rechdr->xl_prev), sizeof(XLogRecPtr));
+		FIN_CRC32C(rdata_crc);
 		rechdr->xl_crc = rdata_crc;
 
 		/*
@@ -4344,11 +4344,11 @@ WriteControlFile(void)
 	ControlFile->float8ByVal = FLOAT8PASSBYVAL;
 
 	/* Contents are protected with a CRC */
-	INIT_CRC32(ControlFile->crc);
-	COMP_CRC32(ControlFile->crc,
-			   (char *) ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(ControlFile->crc);
+	INIT_CRC32C(ControlFile->crc);
+	COMP_CRC32C(ControlFile->crc,
+				(char *) ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(ControlFile->crc);
 
 	/*
 	 * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the
@@ -4444,13 +4444,13 @@ ReadControlFile(void)
 				 errhint("It looks like you need to initdb.")));
 
 	/* Now check the CRC. */
-	INIT_CRC32(crc);
-	COMP_CRC32(crc,
-			   (char *) ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc,
+				(char *) ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(crc);
 
-	if (!EQ_CRC32(crc, ControlFile->crc))
+	if (!EQ_CRC32C(crc, ControlFile->crc))
 		ereport(FATAL,
 				(errmsg("incorrect checksum in control file")));
 
@@ -4593,11 +4593,11 @@ UpdateControlFile(void)
 {
 	int			fd;
 
-	INIT_CRC32(ControlFile->crc);
-	COMP_CRC32(ControlFile->crc,
-			   (char *) ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(ControlFile->crc);
+	INIT_CRC32C(ControlFile->crc);
+	COMP_CRC32C(ControlFile->crc,
+				(char *) ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(ControlFile->crc);
 
 	fd = BasicOpenFile(XLOG_CONTROL_FILE,
 					   O_RDWR | PG_BINARY,
@@ -4975,10 +4975,10 @@ BootStrapXLOG(void)
 	record->xl_rmid = RM_XLOG_ID;
 	memcpy(XLogRecGetData(record), &checkPoint, sizeof(checkPoint));
 
-	INIT_CRC32(crc);
-	COMP_CRC32(crc, &checkPoint, sizeof(checkPoint));
-	COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc, &checkPoint, sizeof(checkPoint));
+	COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
+	FIN_CRC32C(crc);
 	record->xl_crc = crc;
 
 	/* Create first XLOG segment file */
diff --git a/src/backend/access/transam/xlogreader.c b/src/backend/access/transam/xlogreader.c
index f06daa2..da7ed92 100644
--- a/src/backend/access/transam/xlogreader.c
+++ b/src/backend/access/transam/xlogreader.c
@@ -684,8 +684,8 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
 		return false;
 	}
 	remaining -= SizeOfXLogRecord + len;
-	INIT_CRC32(crc);
-	COMP_CRC32(crc, XLogRecGetData(record), len);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc, XLogRecGetData(record), len);
 
 	/* Add in the backup blocks, if any */
 	blk = (char *) XLogRecGetData(record) + len;
@@ -722,7 +722,7 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
 			return false;
 		}
 		remaining -= blen;
-		COMP_CRC32(crc, blk, blen);
+		COMP_CRC32C(crc, blk, blen);
 		blk += blen;
 	}
 
@@ -736,10 +736,10 @@ ValidXLogRecord(XLogReaderState *state, XLogRecord *record, XLogRecPtr recptr)
 	}
 
 	/* Finally include the record header */
-	COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc));
-	FIN_CRC32(crc);
+	COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
+	FIN_CRC32C(crc);
 
-	if (!EQ_CRC32(record->xl_crc, crc))
+	if (!EQ_CRC32C(record->xl_crc, crc))
 	{
 		report_invalid_record(state,
 			   "incorrect resource manager data checksum in record at %X/%X",
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 5e59c6b..71c5fe2 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -1517,9 +1517,9 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 	ondisk->magic = SNAPBUILD_MAGIC;
 	ondisk->version = SNAPBUILD_VERSION;
 	ondisk->length = needed_length;
-	INIT_CRC32(ondisk->checksum);
-	COMP_CRC32(ondisk->checksum,
-			   ((char *) ondisk) + SnapBuildOnDiskNotChecksummedSize,
+	INIT_CRC32C(ondisk->checksum);
+	COMP_CRC32C(ondisk->checksum,
+				((char *) ondisk) + SnapBuildOnDiskNotChecksummedSize,
 			SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize);
 	ondisk_c += sizeof(SnapBuildOnDisk);
 
@@ -1531,20 +1531,20 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn)
 	ondisk->builder.running.xip = NULL;
 	ondisk->builder.committed.xip = NULL;
 
-	COMP_CRC32(ondisk->checksum,
-			   &ondisk->builder,
-			   sizeof(SnapBuild));
+	COMP_CRC32C(ondisk->checksum,
+				&ondisk->builder,
+				sizeof(SnapBuild));
 
 	/* copy running xacts */
 	sz = sizeof(TransactionId) * builder->running.xcnt_space;
 	memcpy(ondisk_c, builder->running.xip, sz);
-	COMP_CRC32(ondisk->checksum, ondisk_c, sz);
+	COMP_CRC32C(ondisk->checksum, ondisk_c, sz);
 	ondisk_c += sz;
 
 	/* copy committed xacts */
 	sz = sizeof(TransactionId) * builder->committed.xcnt;
 	memcpy(ondisk_c, builder->committed.xip, sz);
-	COMP_CRC32(ondisk->checksum, ondisk_c, sz);
+	COMP_CRC32C(ondisk->checksum, ondisk_c, sz);
 	ondisk_c += sz;
 
 	/* we have valid data now, open tempfile and write it there */
@@ -1672,8 +1672,8 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 				(errmsg("snapbuild state file \"%s\" has unsupported version %u instead of %u",
 						path, ondisk.version, SNAPBUILD_VERSION)));
 
-	INIT_CRC32(checksum);
-	COMP_CRC32(checksum,
+	INIT_CRC32C(checksum);
+	COMP_CRC32C(checksum,
 			   ((char *) &ondisk) + SnapBuildOnDiskNotChecksummedSize,
 			SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize);
 
@@ -1687,7 +1687,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 				 errmsg("could not read file \"%s\", read %d of %d: %m",
 						path, readBytes, (int) sizeof(SnapBuild))));
 	}
-	COMP_CRC32(checksum, &ondisk.builder, sizeof(SnapBuild));
+	COMP_CRC32C(checksum, &ondisk.builder, sizeof(SnapBuild));
 
 	/* restore running xacts information */
 	sz = sizeof(TransactionId) * ondisk.builder.running.xcnt_space;
@@ -1701,7 +1701,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 				 errmsg("could not read file \"%s\", read %d of %d: %m",
 						path, readBytes, (int) sz)));
 	}
-	COMP_CRC32(checksum, ondisk.builder.running.xip, sz);
+	COMP_CRC32C(checksum, ondisk.builder.running.xip, sz);
 
 	/* restore committed xacts information */
 	sz = sizeof(TransactionId) * ondisk.builder.committed.xcnt;
@@ -1715,12 +1715,12 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn)
 				 errmsg("could not read file \"%s\", read %d of %d: %m",
 						path, readBytes, (int) sz)));
 	}
-	COMP_CRC32(checksum, ondisk.builder.committed.xip, sz);
+	COMP_CRC32C(checksum, ondisk.builder.committed.xip, sz);
 
 	CloseTransientFile(fd);
 
 	/* verify checksum of what we've read */
-	if (!EQ_CRC32(checksum, ondisk.checksum))
+	if (!EQ_CRC32C(checksum, ondisk.checksum))
 		ereport(ERROR,
 				(errcode_for_file_access(),
 				 errmsg("snapbuild state file %s: checksum mismatch, is %u, should be %u",
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index f355f13..2c3ea55 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -993,7 +993,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
 	}
 
 	cp.magic = SLOT_MAGIC;
-	INIT_CRC32(cp.checksum);
+	INIT_CRC32C(cp.checksum);
 	cp.version = 1;
 	cp.length = ReplicationSlotOnDiskDynamicSize;
 
@@ -1003,9 +1003,9 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel)
 
 	SpinLockRelease(&slot->mutex);
 
-	COMP_CRC32(cp.checksum,
-			   (char *) (&cp) + ReplicationSlotOnDiskConstantSize,
-			   ReplicationSlotOnDiskDynamicSize);
+	COMP_CRC32C(cp.checksum,
+				(char *) (&cp) + ReplicationSlotOnDiskConstantSize,
+				ReplicationSlotOnDiskDynamicSize);
 
 	if ((write(fd, &cp, sizeof(cp))) != sizeof(cp))
 	{
@@ -1181,13 +1181,13 @@ RestoreSlotFromDisk(const char *name)
 
 	CloseTransientFile(fd);
 
-	/* now verify the CRC32 */
-	INIT_CRC32(checksum);
-	COMP_CRC32(checksum,
-			   (char *) &cp + ReplicationSlotOnDiskConstantSize,
-			   ReplicationSlotOnDiskDynamicSize);
+	/* now verify the CRC */
+	INIT_CRC32C(checksum);
+	COMP_CRC32C(checksum,
+				(char *) &cp + ReplicationSlotOnDiskConstantSize,
+				ReplicationSlotOnDiskDynamicSize);
 
-	if (!EQ_CRC32(checksum, cp.checksum))
+	if (!EQ_CRC32C(checksum, cp.checksum))
 		ereport(PANIC,
 				(errmsg("replication slot file %s: checksum mismatch, is %u, should be %u",
 						path, checksum, cp.checksum)));
diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c
index 8003918..e9cff4f 100644
--- a/src/backend/utils/adt/tsgistidx.c
+++ b/src/backend/utils/adt/tsgistidx.c
@@ -201,9 +201,9 @@ gtsvector_compress(PG_FUNCTION_ARGS)
 		{
 			pg_crc32	c;
 
-			INIT_CRC32(c);
-			COMP_CRC32(c, words + ptr->pos, ptr->len);
-			FIN_CRC32(c);
+			INIT_LEGACY_CRC32(c);
+			COMP_LEGACY_CRC32(c, words + ptr->pos, ptr->len);
+			FIN_LEGACY_CRC32(c);
 
 			*arr = *(int32 *) &c;
 			arr++;
diff --git a/src/backend/utils/adt/tsquery.c b/src/backend/utils/adt/tsquery.c
index c8011a8..5226bae 100644
--- a/src/backend/utils/adt/tsquery.c
+++ b/src/backend/utils/adt/tsquery.c
@@ -280,9 +280,9 @@ pushValue(TSQueryParserState state, char *strval, int lenval, int16 weight, bool
 				 errmsg("word is too long in tsquery: \"%s\"",
 						state->buffer)));
 
-	INIT_CRC32(valcrc);
-	COMP_CRC32(valcrc, strval, lenval);
-	FIN_CRC32(valcrc);
+	INIT_LEGACY_CRC32(valcrc);
+	COMP_LEGACY_CRC32(valcrc, strval, lenval);
+	FIN_LEGACY_CRC32(valcrc);
 	pushValue_internal(state, valcrc, state->curop - state->op, lenval, weight, prefix);
 
 	/* append the value string to state.op, enlarging buffer if needed first */
@@ -883,9 +883,9 @@ tsqueryrecv(PG_FUNCTION_ARGS)
 
 			/* Looks valid. */
 
-			INIT_CRC32(valcrc);
-			COMP_CRC32(valcrc, val, val_len);
-			FIN_CRC32(valcrc);
+			INIT_LEGACY_CRC32(valcrc);
+			COMP_LEGACY_CRC32(valcrc, val, val_len);
+			FIN_LEGACY_CRC32(valcrc);
 
 			item->qoperand.weight = weight;
 			item->qoperand.prefix = (prefix) ? true : false;
diff --git a/src/backend/utils/cache/relmapper.c b/src/backend/utils/cache/relmapper.c
index 95a2689..b6b1330 100644
--- a/src/backend/utils/cache/relmapper.c
+++ b/src/backend/utils/cache/relmapper.c
@@ -84,7 +84,7 @@ typedef struct RelMapFile
 	int32		magic;			/* always RELMAPPER_FILEMAGIC */
 	int32		num_mappings;	/* number of valid RelMapping entries */
 	RelMapping	mappings[MAX_MAPPINGS];
-	int32		crc;			/* CRC of all above */
+	pg_crc32	crc;			/* CRC of all above */
 	int32		pad;			/* to make the struct size be 512 exactly */
 } RelMapFile;
 
@@ -673,11 +673,11 @@ load_relmap_file(bool shared)
 						mapfilename)));
 
 	/* verify the CRC */
-	INIT_CRC32(crc);
-	COMP_CRC32(crc, (char *) map, offsetof(RelMapFile, crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
+	FIN_CRC32C(crc);
 
-	if (!EQ_CRC32(crc, map->crc))
+	if (!EQ_CRC32C(crc, map->crc))
 		ereport(FATAL,
 		  (errmsg("relation mapping file \"%s\" contains incorrect checksum",
 				  mapfilename)));
@@ -719,9 +719,9 @@ write_relmap_file(bool shared, RelMapFile *newmap,
 	if (newmap->num_mappings < 0 || newmap->num_mappings > MAX_MAPPINGS)
 		elog(ERROR, "attempt to write bogus relation mapping");
 
-	INIT_CRC32(newmap->crc);
-	COMP_CRC32(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
-	FIN_CRC32(newmap->crc);
+	INIT_CRC32C(newmap->crc);
+	COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
+	FIN_CRC32C(newmap->crc);
 
 	/*
 	 * Open the target file.  We prefer to do this before entering the
diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c
index 32cc100..b2e0793 100644
--- a/src/bin/pg_controldata/pg_controldata.c
+++ b/src/bin/pg_controldata/pg_controldata.c
@@ -178,13 +178,13 @@ main(int argc, char *argv[])
 	close(fd);
 
 	/* Check the CRC. */
-	INIT_CRC32(crc);
-	COMP_CRC32(crc,
-			   (char *) &ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc,
+				(char *) &ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(crc);
 
-	if (!EQ_CRC32(crc, ControlFile.crc))
+	if (!EQ_CRC32C(crc, ControlFile.crc))
 		printf(_("WARNING: Calculated CRC checksum does not match value stored in file.\n"
 				 "Either the file is corrupt, or it has a different layout than this program\n"
 				 "is expecting.  The results below are untrustworthy.\n\n"));
diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c
index f4c1eaf..e224e67 100644
--- a/src/bin/pg_resetxlog/pg_resetxlog.c
+++ b/src/bin/pg_resetxlog/pg_resetxlog.c
@@ -456,13 +456,13 @@ ReadControlFile(void)
 	  ((ControlFileData *) buffer)->pg_control_version == PG_CONTROL_VERSION)
 	{
 		/* Check the CRC. */
-		INIT_CRC32(crc);
-		COMP_CRC32(crc,
-				   buffer,
-				   offsetof(ControlFileData, crc));
-		FIN_CRC32(crc);
+		INIT_CRC32C(crc);
+		COMP_CRC32C(crc,
+					buffer,
+					offsetof(ControlFileData, crc));
+		FIN_CRC32C(crc);
 
-		if (EQ_CRC32(crc, ((ControlFileData *) buffer)->crc))
+		if (EQ_CRC32C(crc, ((ControlFileData *) buffer)->crc))
 		{
 			/* Valid data... */
 			memcpy(&ControlFile, buffer, sizeof(ControlFile));
@@ -747,11 +747,11 @@ RewriteControlFile(void)
 	ControlFile.xlog_seg_size = XLogSegSize;
 
 	/* Contents are protected with a CRC */
-	INIT_CRC32(ControlFile.crc);
-	COMP_CRC32(ControlFile.crc,
-			   (char *) &ControlFile,
-			   offsetof(ControlFileData, crc));
-	FIN_CRC32(ControlFile.crc);
+	INIT_CRC32C(ControlFile.crc);
+	COMP_CRC32C(ControlFile.crc,
+				(char *) &ControlFile,
+				offsetof(ControlFileData, crc));
+	FIN_CRC32C(ControlFile.crc);
 
 	/*
 	 * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the
@@ -1032,10 +1032,10 @@ WriteEmptyXLOG(void)
 	memcpy(XLogRecGetData(record), &ControlFile.checkPointCopy,
 		   sizeof(CheckPoint));
 
-	INIT_CRC32(crc);
-	COMP_CRC32(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint));
-	COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc));
-	FIN_CRC32(crc);
+	INIT_CRC32C(crc);
+	COMP_CRC32C(crc, &ControlFile.checkPointCopy, sizeof(CheckPoint));
+	COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc));
+	FIN_CRC32C(crc);
 	record->xl_crc = crc;
 
 	/* Write the first page */
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index f43f4aa..978b06a 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -7,9 +7,22 @@
  * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
  * http://www.ross.net/crc/ or several other net sites.
  *
- * We use a normal (not "reflected", in Williams' terms) CRC, using initial
- * all-ones register contents and a final bit inversion.
+ * We have three slightly different variants of a 32-bit CRC calculation:
+ * CRC-32C (Castagnoli polynomial), CRC-32 (Ethernet polynomial), and a legacy
+ * CRC-32 version that uses the lookup table in a funny way. They all consist
+ * of four macros:
  *
+ * INIT_<variant>(crc)
+ *		Initialize a CRC accumulator
+ *
+ * COMP_<variant>(crc, data, len)
+ *		Accumulate some (more) bytes into a CRC
+ *
+ * FIN_<variant>(crc)
+ *		Finish a CRC calculation
+ *
+ * EQ_<variant>(c1, c2)
+ *		Check for equality of two CRCs.
  *
  * Portions Copyright (c) 1996-2014, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -28,29 +41,80 @@
 
 typedef uint32 pg_crc32;
 
-/* Initialize a CRC accumulator */
-#define INIT_CRC32(crc) ((crc) = 0xFFFFFFFF)
+/*
+ * CRC calculation using the CRC-32C (Castagnoli) polynomial. We use all-ones
+ * as the initial register contents and final bit inversion. This is the same
+ * algorithm used e.g. in iSCSI. See RFC 3385 for more details on the choice
+ * of polynomial.
+ */
+#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
+#define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
+#define COMP_CRC32C(crc, data, len)	\
+	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table)
+#define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
-/* Finish a CRC calculation */
-#define FIN_CRC32(crc)	((crc) ^= 0xFFFFFFFF)
+/*
+ * CRC-32, the same used e.g. in Ethernet.
+ *
+ * This is currently only used in ltree and hstore contrib modules. It uses
+ * the same lookup table as the legacy algorithm below. New code should
+ * use the Castagnoli version instead.
+ */
+#define INIT_TRADITIONAL_CRC32(crc) ((crc) = 0xFFFFFFFF)
+#define FIN_TRADITIONAL_CRC32(crc)	((crc) ^= 0xFFFFFFFF)
+#define COMP_TRADITIONAL_CRC32(crc, data, len)	\
+	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32_table)
+#define EQ_TRADITIONAL_CRC32(c1, c2) ((c1) == (c2))
+
+/*
+ * The CRC algorithm used for WAL et al in pre-9.5 versions.
+ *
+ * This closely resembles the normal CRC-32 algorithm, but is subtly
+ * different. Using Williams' terms, we use the "normal" table, but with
+ * "reflected" code. That's bogus, but it was like that for years before
+ * anyone noticed. It does not correspond to any polynomial in a normal CRC
+ * algorithm, so it's not clear what the error-detection properties of this
+ * algorithm actually are.
+ *
+ * We still need to carry this around because this is used in a few on-disk
+ * structures that need to be pg_upgradeable. It should not be used in new
+ * code.
+ */
+#define INIT_LEGACY_CRC32(crc) ((crc) = 0xFFFFFFFF)
+#define FIN_LEGACY_CRC32(crc)	((crc) ^= 0xFFFFFFFF)
+#define COMP_LEGACY_CRC32(crc, data, len)	\
+	COMP_CRC32_REFLECTED_TABLE(crc, data, len, pg_crc32_table)
+#define EQ_LEGACY_CRC32(c1, c2) ((c1) == (c2))
 
-/* Accumulate some (more) bytes into a CRC */
-#define COMP_CRC32(crc, data, len)	\
-do { \
+/*
+ * Common code for CRC computation using a lookup table.
+ */
+#define COMP_CRC32_NORMAL_TABLE(crc, data, len, table)			  \
+do {															  \
 	const unsigned char *__data = (const unsigned char *) (data); \
 	uint32		__len = (len); \
 \
 	while (__len-- > 0) \
 	{ \
-		int		__tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF; \
-		(crc) = pg_crc32_table[__tab_index] ^ ((crc) << 8); \
+		int		__tab_index = ((int) (crc) ^ *__data++) & 0xFF; \
+		(crc) = table[__tab_index] ^ ((crc) >> 8); \
 	} \
 } while (0)
 
-/* Check for equality of two CRCs */
-#define EQ_CRC32(c1,c2)  ((c1) == (c2))
+#define COMP_CRC32_REFLECTED_TABLE(crc, data, len, table) \
+do {															  \
+	const unsigned char *__data = (const unsigned char *) (data); \
+	uint32		__len = (len); \
+\
+	while (__len-- > 0) \
+	{ \
+		int		__tab_index = ((int) (crc) ^ *__data++) & 0xFF; \
+		(crc) = table[__tab_index] ^ ((crc) >> 8); \
+	} \
+} while (0)
 
-/* Constant table for CRC calculation */
+/* Constant tables for CRC-32C and CRC-32 polynomials */
+extern CRCDLLIMPORT const uint32 pg_crc32c_table[];
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index f566137..e070ec1 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -25,6 +25,79 @@
 #ifndef PG_CRC_TABLES_H
 #define PG_CRC_TABLES_H
 
+
+/*
+ * This table is based on the so-called Castagnoli polynomial (the same
+ * that is used e.g. in iSCSI).
+ */
+const uint32 pg_crc32c_table[256] = {
+	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+};
+
+
 /*
  * This table is based on the polynomial
  *	x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
-- 
2.1.1

#6Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Heikki Linnakangas (#5)
Re: What exactly is our CRC algorithm?

On 10/27/2014 06:02 PM, Heikki Linnakangas wrote:

I came up with the attached patches. They do three things:

1. Get rid of the 64-bit CRC code. It's not used for anything, and
haven't been for years, so it doesn't seem worth spending any effort to
fix them.

2. Switch to CRC-32C (Castagnoli) for WAL and other places that don't
need to remain compatible across major versions.

3. Use the same lookup table for hstore and ltree, as used for the
legacy "almost CRC-32" algorithm. The tables are identical, so might as
well.

Any objections?

I hear none, so committed with some small fixes.
- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#7Robert Haas
robertmhaas@gmail.com
In reply to: Heikki Linnakangas (#6)
Re: What exactly is our CRC algorithm?

On Tue, Nov 4, 2014 at 4:47 AM, Heikki Linnakangas
<hlinnakangas@vmware.com> wrote:

I hear none, so committed with some small fixes.

Are you going to get the slice-by-N stuff working next, to speed this up?

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#8Andres Freund
andres@2ndquadrant.com
In reply to: Robert Haas (#7)
Re: What exactly is our CRC algorithm?

On 2014-11-04 08:21:13 -0500, Robert Haas wrote:

On Tue, Nov 4, 2014 at 4:47 AM, Heikki Linnakangas
<hlinnakangas@vmware.com> wrote:

I hear none, so committed with some small fixes.

Are you going to get the slice-by-N stuff working next, to speed this up?

I don't plan to do anything serious with it, but I've hacked up the crc
code to use the hardware instruction. The results are quite good - crc
vanishes entirely from the profile for most workloads. It's still
visible for bulk copy, but that's pretty much it.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#9Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Robert Haas (#7)
Re: What exactly is our CRC algorithm?

On 11/04/2014 03:21 PM, Robert Haas wrote:

On Tue, Nov 4, 2014 at 4:47 AM, Heikki Linnakangas
<hlinnakangas@vmware.com> wrote:

I hear none, so committed with some small fixes.

Are you going to get the slice-by-N stuff working next, to speed this up?

I don't have any concrete plans, but yeah, that would be great. So
definitely maybe.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#10Amit Kapila
amit.kapila16@gmail.com
In reply to: Heikki Linnakangas (#6)
Re: What exactly is our CRC algorithm?

On Tue, Nov 4, 2014 at 3:17 PM, Heikki Linnakangas <hlinnakangas@vmware.com>
wrote:

On 10/27/2014 06:02 PM, Heikki Linnakangas wrote:

I came up with the attached patches. They do three things:

1. Get rid of the 64-bit CRC code. It's not used for anything, and
haven't been for years, so it doesn't seem worth spending any effort to
fix them.

2. Switch to CRC-32C (Castagnoli) for WAL and other places that don't
need to remain compatible across major versions.

Will this change allow database created before this commit to be
started after this commit?

With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com

#11Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Amit Kapila (#10)
Re: What exactly is our CRC algorithm?

On 11/07/2014 07:08 AM, Amit Kapila wrote:

On Tue, Nov 4, 2014 at 3:17 PM, Heikki Linnakangas <hlinnakangas@vmware.com>
wrote:

On 10/27/2014 06:02 PM, Heikki Linnakangas wrote:

I came up with the attached patches. They do three things:

1. Get rid of the 64-bit CRC code. It's not used for anything, and
haven't been for years, so it doesn't seem worth spending any effort to
fix them.

2. Switch to CRC-32C (Castagnoli) for WAL and other places that don't
need to remain compatible across major versions.

Will this change allow database created before this commit to be
started after this commit?

No. You could use pg_resetxlog to fix the WAL, but I think at least
relmap files would still prevent you from starting up. You could use
pg_upgrade.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#12Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Andres Freund (#8)
Re: What exactly is our CRC algorithm?

At 2014-11-04 14:40:36 +0100, andres@2ndquadrant.com wrote:

On 2014-11-04 08:21:13 -0500, Robert Haas wrote:

Are you going to get the slice-by-N stuff working next, to speed
this up?

I don't plan to do anything serious with it, but I've hacked up the
crc code to use the hardware instruction.

I'm working on this (first speeding up the default calculation using
slice-by-N, then adding support for the SSE4.2 CRC instruction on top).

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#13Robert Haas
robertmhaas@gmail.com
In reply to: Abhijit Menon-Sen (#12)
Re: What exactly is our CRC algorithm?

On Tue, Nov 11, 2014 at 6:26 AM, Abhijit Menon-Sen <ams@2ndquadrant.com> wrote:

At 2014-11-04 14:40:36 +0100, andres@2ndquadrant.com wrote:

On 2014-11-04 08:21:13 -0500, Robert Haas wrote:

Are you going to get the slice-by-N stuff working next, to speed
this up?

I don't plan to do anything serious with it, but I've hacked up the
crc code to use the hardware instruction.

I'm working on this (first speeding up the default calculation using
slice-by-N, then adding support for the SSE4.2 CRC instruction on top).

Great!

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#14Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Abhijit Menon-Sen (#12)
1 attachment(s)
Re: What exactly is our CRC algorithm?

At 2014-11-11 16:56:00 +0530, ams@2ndQuadrant.com wrote:

I'm working on this (first speeding up the default calculation using
slice-by-N, then adding support for the SSE4.2 CRC instruction on
top).

I've done the first part in the attached patch, and I'm working on the
second (especially the bits to issue CPUID at startup and decide which
implementation to use).

As a benchmark, I ran pg_xlogdump --stats against 11GB of WAL data (674
segments) generated by running a total of 2M pgbench transactions on a
db initialised with scale factor 25. The tests were run on my i5-3230
CPU, and the code in each case was compiled with "-O3 -msse4.2" (and
without --enable-debug). The profile was dominated by the CRC
calculation in ValidXLogRecord.

With HEAD's CRC code:

bin/pg_xlogdump --stats wal/000000010000000000000001 29.81s user 3.56s system 77% cpu 43.274 total
bin/pg_xlogdump --stats wal/000000010000000000000001 29.59s user 3.85s system 75% cpu 44.227 total

With slice-by-4 (a minor variant of the attached patch; the results are
included only for curiosity's sake, but I can post the code if needed):

bin/pg_xlogdump --stats wal/000000010000000000000001 13.52s user 3.82s system 48% cpu 35.808 total
bin/pg_xlogdump --stats wal/000000010000000000000001 13.34s user 3.96s system 48% cpu 35.834 total

With slice-by-8 (i.e. the attached patch):

bin/pg_xlogdump --stats wal/000000010000000000000001 7.88s user 3.96s system 34% cpu 34.414 total
bin/pg_xlogdump --stats wal/000000010000000000000001 7.85s user 4.10s system 34% cpu 35.001 total

(Note the progressive reduction in user time from ~29s to ~8s.)

Finally, just for comparison, here's what happens when we use the
hardware instruction via gcc's __builtin_ia32_crc32xx intrinsics
(i.e. the additional patch I'm working on):

bin/pg_xlogdump --stats wal/000000010000000000000001 3.33s user 4.79s system 23% cpu 34.832 total

There are a number of potential micro-optimisations, I just wanted to
submit the obvious thing first and explore more possibilities later.

-- Abhijit

Attachments:

slice8.difftext/x-diff; charset=us-asciiDownload
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index f871cba..55934e5 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,6 +41,8 @@
 
 typedef uint32 pg_crc32;
 
+extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
  *
@@ -51,7 +53,7 @@ typedef uint32 pg_crc32;
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
 #define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
 #define COMP_CRC32C(crc, data, len)	\
-	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table)
+	((crc) = pg_comp_crc32c((crc), (char *) (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
 /*
@@ -115,7 +117,7 @@ do {															  \
 } while (0)
 
 /* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[];
+extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index cb6b470..f814c91 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -28,71 +28,519 @@
  * This table is based on the so-called Castagnoli polynomial (the same
  * that is used e.g. in iSCSI).
  */
-const uint32 pg_crc32c_table[256] = {
-	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
-	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
-	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
-	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
-	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
-	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
-	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
-	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
-	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
-	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
-	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
-	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
-	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
-	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
-	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
-	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
-	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
-	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
-	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
-	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
-	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
-	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
-	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
-	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
-	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
-	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
-	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
-	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
-	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
-	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
-	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
-	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
-	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
-	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
-	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
-	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
-	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
-	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
-	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
-	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
-	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
-	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
-	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
-	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
-	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
-	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
-	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
-	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
-	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
-	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
-	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
-	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
-	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
-	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
-	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
-	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
-	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
-	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
-	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
-	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
-	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
-	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
-	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
-	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+const uint32 pg_crc32c_table[8][256] = {
+	{ 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+	  0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+	  0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+	  0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+	  0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+	  0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+	  0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+	  0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+	  0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+	  0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+	  0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+	  0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+	  0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+	  0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+	  0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+	  0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+	  0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+	  0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+	  0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+	  0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+	  0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+	  0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+	  0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+	  0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+	  0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+	  0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+	  0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+	  0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+	  0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+	  0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+	  0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+	  0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+	  0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+	  0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+	  0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+	  0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+	  0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+	  0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+	  0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+	  0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+	  0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+	  0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+	  0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+	  0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+	  0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+	  0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+	  0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+	  0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+	  0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+	  0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+	  0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+	  0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+	  0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+	  0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+	  0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+	  0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+	  0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+	  0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+	  0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+	  0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+	  0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+	  0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+	  0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+	  0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 },
+	{ 0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
+	  0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
+	  0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
+	  0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
+	  0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
+	  0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
+	  0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
+	  0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
+	  0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
+	  0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
+	  0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
+	  0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
+	  0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
+	  0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
+	  0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
+	  0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
+	  0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
+	  0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
+	  0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
+	  0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
+	  0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
+	  0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
+	  0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
+	  0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
+	  0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
+	  0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
+	  0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
+	  0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
+	  0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
+	  0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
+	  0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
+	  0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
+	  0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
+	  0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
+	  0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
+	  0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
+	  0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
+	  0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
+	  0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
+	  0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
+	  0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
+	  0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
+	  0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
+	  0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
+	  0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
+	  0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
+	  0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
+	  0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
+	  0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
+	  0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
+	  0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
+	  0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
+	  0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
+	  0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
+	  0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
+	  0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
+	  0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
+	  0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
+	  0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
+	  0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
+	  0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
+	  0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
+	  0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
+	  0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483 },
+	{ 0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
+	  0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
+	  0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
+	  0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
+	  0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
+	  0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
+	  0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
+	  0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
+	  0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
+	  0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
+	  0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
+	  0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
+	  0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
+	  0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
+	  0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
+	  0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
+	  0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
+	  0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
+	  0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
+	  0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
+	  0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
+	  0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
+	  0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
+	  0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
+	  0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
+	  0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
+	  0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
+	  0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
+	  0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
+	  0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
+	  0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
+	  0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
+	  0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
+	  0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
+	  0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
+	  0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
+	  0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
+	  0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
+	  0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
+	  0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
+	  0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
+	  0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
+	  0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
+	  0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
+	  0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
+	  0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
+	  0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
+	  0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
+	  0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
+	  0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
+	  0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
+	  0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
+	  0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
+	  0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
+	  0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
+	  0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
+	  0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
+	  0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
+	  0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
+	  0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
+	  0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
+	  0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
+	  0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
+	  0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8 },
+	{ 0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
+	  0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
+	  0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
+	  0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
+	  0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
+	  0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
+	  0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
+	  0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
+	  0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
+	  0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
+	  0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
+	  0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
+	  0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
+	  0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
+	  0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
+	  0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
+	  0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
+	  0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
+	  0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
+	  0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
+	  0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
+	  0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
+	  0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
+	  0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
+	  0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
+	  0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
+	  0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
+	  0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
+	  0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
+	  0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
+	  0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
+	  0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
+	  0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
+	  0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
+	  0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
+	  0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
+	  0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
+	  0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
+	  0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
+	  0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
+	  0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
+	  0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
+	  0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
+	  0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
+	  0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
+	  0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
+	  0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
+	  0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
+	  0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
+	  0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
+	  0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
+	  0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
+	  0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
+	  0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
+	  0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
+	  0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
+	  0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
+	  0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
+	  0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
+	  0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
+	  0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
+	  0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
+	  0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
+	  0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842 },
+	{ 0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
+	  0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
+	  0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
+	  0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
+	  0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
+	  0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
+	  0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
+	  0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
+	  0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
+	  0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
+	  0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
+	  0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
+	  0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
+	  0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
+	  0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
+	  0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
+	  0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
+	  0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
+	  0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
+	  0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
+	  0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
+	  0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
+	  0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
+	  0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
+	  0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
+	  0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
+	  0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
+	  0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
+	  0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
+	  0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
+	  0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
+	  0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
+	  0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
+	  0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
+	  0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
+	  0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
+	  0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
+	  0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
+	  0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
+	  0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
+	  0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
+	  0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
+	  0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
+	  0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
+	  0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
+	  0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
+	  0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
+	  0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
+	  0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
+	  0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
+	  0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
+	  0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
+	  0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
+	  0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
+	  0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
+	  0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
+	  0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
+	  0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
+	  0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
+	  0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
+	  0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
+	  0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
+	  0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
+	  0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3 },
+	{ 0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
+	  0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
+	  0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
+	  0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
+	  0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
+	  0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
+	  0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
+	  0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
+	  0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
+	  0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
+	  0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
+	  0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
+	  0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
+	  0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
+	  0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
+	  0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
+	  0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
+	  0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
+	  0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
+	  0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
+	  0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
+	  0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
+	  0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
+	  0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
+	  0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
+	  0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
+	  0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
+	  0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
+	  0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
+	  0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
+	  0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
+	  0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
+	  0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
+	  0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
+	  0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
+	  0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
+	  0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
+	  0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
+	  0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
+	  0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
+	  0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
+	  0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
+	  0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
+	  0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
+	  0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
+	  0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
+	  0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
+	  0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
+	  0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
+	  0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
+	  0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
+	  0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
+	  0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
+	  0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
+	  0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
+	  0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
+	  0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
+	  0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
+	  0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
+	  0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
+	  0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
+	  0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
+	  0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
+	  0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C },
+	{ 0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
+	  0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
+	  0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
+	  0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
+	  0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
+	  0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
+	  0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
+	  0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
+	  0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
+	  0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
+	  0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
+	  0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
+	  0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
+	  0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
+	  0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
+	  0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
+	  0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
+	  0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
+	  0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
+	  0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
+	  0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
+	  0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
+	  0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
+	  0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
+	  0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
+	  0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
+	  0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
+	  0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
+	  0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
+	  0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
+	  0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
+	  0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
+	  0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
+	  0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
+	  0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
+	  0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
+	  0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
+	  0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
+	  0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
+	  0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
+	  0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
+	  0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
+	  0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
+	  0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
+	  0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
+	  0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
+	  0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
+	  0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
+	  0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
+	  0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
+	  0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
+	  0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
+	  0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
+	  0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
+	  0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
+	  0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
+	  0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
+	  0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
+	  0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
+	  0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
+	  0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
+	  0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
+	  0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
+	  0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F },
+	{ 0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
+	  0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
+	  0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
+	  0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
+	  0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
+	  0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
+	  0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
+	  0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
+	  0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
+	  0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
+	  0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
+	  0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
+	  0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
+	  0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
+	  0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
+	  0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
+	  0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
+	  0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
+	  0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
+	  0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
+	  0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
+	  0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
+	  0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
+	  0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
+	  0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
+	  0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
+	  0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
+	  0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
+	  0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
+	  0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
+	  0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
+	  0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
+	  0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
+	  0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
+	  0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
+	  0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
+	  0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
+	  0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
+	  0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
+	  0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
+	  0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
+	  0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
+	  0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
+	  0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
+	  0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
+	  0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
+	  0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
+	  0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
+	  0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
+	  0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
+	  0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
+	  0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
+	  0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
+	  0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
+	  0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
+	  0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
+	  0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
+	  0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
+	  0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
+	  0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
+	  0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
+	  0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
+	  0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
+	  0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5 }
 };
 
 
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index ac6f6ff..2f9857b 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -18,4 +18,91 @@
 
 #include "c.h"
 
+#include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
+
+static inline uint32 bswap32(uint32 x)
+{
+#if defined(__GNUC__) || defined(__clang__)
+	return __builtin_bswap32(x);
+#else
+	return  ((x << 24) & 0xff000000) |
+			((x <<  8) & 0x00ff0000) |
+			((x >>  8) & 0x0000ff00) |
+			((x >> 24) & 0x000000ff);
+#endif
+}
+
+#ifdef WORDS_BIGENDIAN
+#define cpu_to_le32(x) bswap32(x)
+#else
+#define cpu_to_le32(x) x
+#endif
+
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint32 *p8;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that
+	 * the loop below starts with a pointer aligned to four bytes.
+	 */
+
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint32 *) p;
+
+	while (len >= 8)
+	{
+		uint32 a = *p8++ ^ cpu_to_le32(crc);
+		uint32 b = *p8++;
+
+#ifdef WORDS_BIGENDIAN
+		const uint8 c0 = b;
+		const uint8 c1 = b >> 8;
+		const uint8 c2 = b >> 16;
+		const uint8 c3 = b >> 24;
+		const uint8 c4 = a;
+		const uint8 c5 = a >> 8;
+		const uint8 c6 = a >> 16;
+		const uint8 c7 = a >> 24;
+#else
+		const uint8 c0 = b >> 24;
+		const uint8 c1 = b >> 16;
+		const uint8 c2 = b >> 8;
+		const uint8 c3 = b;
+		const uint8 c4 = a >> 24;
+		const uint8 c5 = a >> 16;
+		const uint8 c6 = a >> 8;
+		const uint8 c7 = a;
+#endif
+
+		crc =
+			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
+			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
+			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
+			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
+
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len-- > 0)
+		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+
+	return crc;
+}
#15Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#14)
Re: What exactly is our CRC algorithm?

On 11/19/2014 05:58 PM, Abhijit Menon-Sen wrote:

At 2014-11-11 16:56:00 +0530, ams@2ndQuadrant.com wrote:

I'm working on this (first speeding up the default calculation using
slice-by-N, then adding support for the SSE4.2 CRC instruction on
top).

I've done the first part in the attached patch, and I'm working on the
second (especially the bits to issue CPUID at startup and decide which
implementation to use).

As a benchmark, I ran pg_xlogdump --stats against 11GB of WAL data (674
segments) generated by running a total of 2M pgbench transactions on a
db initialised with scale factor 25.

That's an interesting choice of workload. That sure is heavy on the CRC
calculation, but the speed of pg_xlogdump hardly matters in real life.

With HEAD's CRC code:

bin/pg_xlogdump --stats wal/000000010000000000000001 29.81s user 3.56s system 77% cpu 43.274 total
bin/pg_xlogdump --stats wal/000000010000000000000001 29.59s user 3.85s system 75% cpu 44.227 total

With slice-by-4 (a minor variant of the attached patch; the results are
included only for curiosity's sake, but I can post the code if needed):

bin/pg_xlogdump --stats wal/000000010000000000000001 13.52s user 3.82s system 48% cpu 35.808 total
bin/pg_xlogdump --stats wal/000000010000000000000001 13.34s user 3.96s system 48% cpu 35.834 total

With slice-by-8 (i.e. the attached patch):

bin/pg_xlogdump --stats wal/000000010000000000000001 7.88s user 3.96s system 34% cpu 34.414 total
bin/pg_xlogdump --stats wal/000000010000000000000001 7.85s user 4.10s system 34% cpu 35.001 total

(Note the progressive reduction in user time from ~29s to ~8s.)

Finally, just for comparison, here's what happens when we use the
hardware instruction via gcc's __builtin_ia32_crc32xx intrinsics
(i.e. the additional patch I'm working on):

bin/pg_xlogdump --stats wal/000000010000000000000001 3.33s user 4.79s system 23% cpu 34.832 total

Impressive!

It would be good to see separate benchmarks on WAL generation, and WAL
replay. pg_xlogdump is probably close to WAL replay, but the WAL
generation case is somewhat different, as WAL is generated in small
pieces, and each piece is accumulated to the CRC separately. The
slice-by-X algorithm might be less effective in that scenario. I have no
doubt that it's still a lot faster than the byte-at-a-time operation,
but would be nice to have numbers on it.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#16Robert Haas
robertmhaas@gmail.com
In reply to: Heikki Linnakangas (#15)
Re: What exactly is our CRC algorithm?

On Wed, Nov 19, 2014 at 11:44 AM, Heikki Linnakangas
<hlinnakangas@vmware.com> wrote:

That's an interesting choice of workload. That sure is heavy on the CRC
calculation, but the speed of pg_xlogdump hardly matters in real life.

But isn't a workload that is heavy on CRC calculation exactly what we
want here? That way we can see clearly how much benefit we're getting
on that particular part of the computation. It'll still speed up
other workloads, too, just not as much.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#17Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#16)
Re: What exactly is our CRC algorithm?

Robert Haas <robertmhaas@gmail.com> writes:

On Wed, Nov 19, 2014 at 11:44 AM, Heikki Linnakangas
<hlinnakangas@vmware.com> wrote:

That's an interesting choice of workload. That sure is heavy on the CRC
calculation, but the speed of pg_xlogdump hardly matters in real life.

But isn't a workload that is heavy on CRC calculation exactly what we
want here? That way we can see clearly how much benefit we're getting
on that particular part of the computation. It'll still speed up
other workloads, too, just not as much.

Heikki's point is that it's an unrealistic choice of CRC chunk size.
Maybe that doesn't matter very much, but it's unproven.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#18Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Robert Haas (#16)
Re: What exactly is our CRC algorithm?

On 11/19/2014 06:49 PM, Robert Haas wrote:

On Wed, Nov 19, 2014 at 11:44 AM, Heikki Linnakangas
<hlinnakangas@vmware.com> wrote:

That's an interesting choice of workload. That sure is heavy on the CRC
calculation, but the speed of pg_xlogdump hardly matters in real life.

But isn't a workload that is heavy on CRC calculation exactly what we
want here? That way we can see clearly how much benefit we're getting
on that particular part of the computation. It'll still speed up
other workloads, too, just not as much.

Sure. But pg_xlogdump's way of using the CRC isn't necessarily
representative of how the backend uses it. It's probably pretty close to
WAL replay in the server, but even there the server might be hurt more
by the extra cache used by the lookup tables. And a backend generating
the WAL computes the CRC on smaller pieces than pg_xlogdump and WAL redo
does.

That said, the speedup is so large that I'm sure this is a big win in
the server too, despite those factors.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#19Andres Freund
andres@2ndquadrant.com
In reply to: Heikki Linnakangas (#18)
Re: What exactly is our CRC algorithm?

On 2014-11-19 19:12:22 +0200, Heikki Linnakangas wrote:

On 11/19/2014 06:49 PM, Robert Haas wrote:

On Wed, Nov 19, 2014 at 11:44 AM, Heikki Linnakangas
<hlinnakangas@vmware.com> wrote:

That's an interesting choice of workload. That sure is heavy on the CRC
calculation, but the speed of pg_xlogdump hardly matters in real life.

But isn't a workload that is heavy on CRC calculation exactly what we
want here? That way we can see clearly how much benefit we're getting
on that particular part of the computation. It'll still speed up
other workloads, too, just not as much.

Sure. But pg_xlogdump's way of using the CRC isn't necessarily
representative of how the backend uses it. It's probably pretty close to WAL
replay in the server, but even there the server might be hurt more by the
extra cache used by the lookup tables. And a backend generating the WAL
computes the CRC on smaller pieces than pg_xlogdump and WAL redo does.

Right. Although it hugely depends on the checkpoint settings - if
there's many FPWs it doesn't matter much.

Obviously it won't be a fourfold performance improvement in the server,
but given the profiles I've seen in the past I'm pretty sure it'll bee a
benefit.

That said, the speedup is so large that I'm sure this is a big win in the
server too, despite those factors.

Yep. I've done some fast and loose benchmarking in the past and it was
quite noticeable. Made XLogInsert() nearly entirely drop from profiles.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#20Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#18)
Re: What exactly is our CRC algorithm?

At 2014-11-19 19:12:22 +0200, hlinnakangas@vmware.com wrote:

But pg_xlogdump's way of using the CRC isn't necessarily
representative of how the backend uses it. It's probably pretty close
to WAL replay in the server, but even there the server might be hurt
more by the extra cache used by the lookup tables.

Sure. As Robert said, my initial benchmark was designed to show the CRC
improvements in isolation. I would be happy to conduct other tests and
post the numbers.

If I understand correctly, I need to demonstrate two things that are
"probably fine", but we don't have proof of:

(a) that the improvements in pg_xlogdump performance translate to an
improvement in the server when reading WAL.
(b) that the slice-by-8 code doesn't hurt performance for writing WAL.

To address (a), I am timing a standby restoring the same 11GB of WAL via
restore_command with and without the CRC patch. My earlier tests showed
that this time can vary quite a bit between runs even with no changes,
but I expect to see an improvement anyway.

Suggestions for how to address (b) are welcome.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#21Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Abhijit Menon-Sen (#20)
Re: What exactly is our CRC algorithm?

At 2014-11-20 09:52:01 +0530, ams@2ndQuadrant.com wrote:

To address (a), I am timing a standby restoring the same 11GB of WAL
via restore_command with and without the CRC patch.

I ran "perf record -F 100 --call-graph=dwarf bin/postgres -D backup",
where:

(a) bin/postgres was compiled, as before, with CFLAGS="-O3 -msse4.2" and
without --enable-debug.
(b) backup is a basebackup of the original data directory before I ran
pgbench; it has a recovery.conf with a restore_command to fetch the
WAL generated during the pgbench run.

I ran the test "frice" (as my daughter would say) with HEAD and the
slice-by-8 patch, and counted the time between the first and last
�restored log file "NNN" from archive� log messages. The number in
parentheses shows the order in which I ran the tests.

HEAD: 6m47s (1), 6m23s (2), 3m12s (6), 3m04s (7)
8CRC: 5m16s (3), 3m13s (4), 2m57s (5), 2m46s (8)

In the unpatched server, the profile shows ValidXLogRecord at >50% in
every case (54.81%, 59.41%, 58.82%, 59.05%).

In the patched server, pg_comp_crc32c was at the top of the profile in
three cases, with 10.29%, 12.01%, and 10.99%. In test (4), however, it
was at 6.38%, and first place went to copy_user_enhanced_fast_string
with 10.03% (which was in second place the other three times).

I believe the wallclock runtime in these tests was influenced more by IO
than CPU, but that the profile shows a worthwhile improvement anyway. I
have the perf.data from each run, and I can rerun the tests if anyone
wants to suggest a different strategy.

Suggestions for how to address (b) are welcome.

I'll think about how to do this, and work on the SSE4.2 patch meanwhile.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#22Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Abhijit Menon-Sen (#21)
Re: What exactly is our CRC algorithm?

At 2014-11-20 13:47:00 +0530, ams@2ndQuadrant.com wrote:

Suggestions for how to address (b) are welcome.

With help from Andres, I set up a workload where XLogInsert* was at the
top of my profiles: server with fsync and synchronous_commit off, and
pgbench running a multiple-row insert into a single-text-column table
with -M prepared -c 25 -t 250000 -f script.

Unfortunately I can't see much difference despite running things with
slightly different parameters a few dozen times. For example, here are
real/user/sys times from three runs each with HEAD and slice-by-8 on an
otherwise-idle i7-3770 server with a couple of undistinguished Toshiba
7200rpm SATA disks in RAID-1:

HEAD:
2m24.822s/0m18.776s/0m23.156s
3m34.586s/0m18.784s/0m24.324s
3m41.557s/0m18.640s/0m23.920s

Slice-by-8:
2m26.977s/0m18.420s/0m22.884s
3m36.664s/0m18.376s/0m24.232s
3m43.930s/0m18.580s/0m24.560s

I don't know how to interpret these results (especially the tendency for
the tests to slow down as time passes, with every version). At best, it
shows that the new CRC code doesn't hurt, at worst it's just irrelevant.
Supporting the latter interpretation, using the hardware-CRC patch also
gives similar results (but XLogInsert is not at the top of the profile).

Hardware-CRC:
2m29.090s/0m18.652s/0m23.764s
3m30.188s/0m18.692s/0m25.332s
3m38.110s/0m20.424s/0m24.532s

If anyone has other suggestions, I'm all ears.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#23Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#22)
Re: What exactly is our CRC algorithm?

On 11/21/2014 12:11 PM, Abhijit Menon-Sen wrote:

At 2014-11-20 13:47:00 +0530, ams@2ndQuadrant.com wrote:

Suggestions for how to address (b) are welcome.

With help from Andres, I set up a workload where XLogInsert* was at the
top of my profiles: server with fsync and synchronous_commit off, and
pgbench running a multiple-row insert into a single-text-column table
with -M prepared -c 25 -t 250000 -f script.

How wide is the row, in terms of bytes? You should see bigger
improvement with wider rows, as you get longer contiguous chunks of data
to CRC that way. With very narrow rows, you might not see much
difference because the chunks are so small.

Did you run these tests with a fresh checkout, including the WAL format
patch I committed yesterday? That would make some difference to how many
XLogRecData chunks there are for each insertion record.

If that's the problem, it might be beneficial to memcpy() all the data
to a temporary buffer, and calculate the CRC over the whole, instead of
CRC'ing each XLogRecData chunk separately. XLogRecordAssemble() uses a
scratch area, hdr_scratch, for building all the headers. You could check
how much rmgr-specific data there is, and if there isn't much, just
append the data to that scratch area too.

Unfortunately I can't see much difference despite running things with
slightly different parameters a few dozen times. For example, here are
real/user/sys times from three runs each with HEAD and slice-by-8 on an
otherwise-idle i7-3770 server with a couple of undistinguished Toshiba
7200rpm SATA disks in RAID-1:

HEAD:
2m24.822s/0m18.776s/0m23.156s
3m34.586s/0m18.784s/0m24.324s
3m41.557s/0m18.640s/0m23.920s

Slice-by-8:
2m26.977s/0m18.420s/0m22.884s
3m36.664s/0m18.376s/0m24.232s
3m43.930s/0m18.580s/0m24.560s

I don't know how to interpret these results (especially the tendency for
the tests to slow down as time passes, with every version).

The user/sys times are very stable, but the real time is much higher and
increases. Does that mean that it's blocked on I/O?

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#24Andres Freund
andres@2ndquadrant.com
In reply to: Heikki Linnakangas (#23)
Re: What exactly is our CRC algorithm?

On 2014-11-21 13:01:50 +0200, Heikki Linnakangas wrote:

On 11/21/2014 12:11 PM, Abhijit Menon-Sen wrote:

At 2014-11-20 13:47:00 +0530, ams@2ndQuadrant.com wrote:

Suggestions for how to address (b) are welcome.

With help from Andres, I set up a workload where XLogInsert* was at the
top of my profiles: server with fsync and synchronous_commit off, and
pgbench running a multiple-row insert into a single-text-column table
with -M prepared -c 25 -t 250000 -f script.

How wide is the row, in terms of bytes? You should see bigger improvement
with wider rows, as you get longer contiguous chunks of data to CRC that
way. With very narrow rows, you might not see much difference because the
chunks are so small.

The primary goal, as I understood it, was to test very short records to
test whether there's a regression due to slice-by-8. There doesn't seem
to be any.

It's, IIRC, trivial to reproduce significant performance benefits in
workloads with lots of FPWs or large records (like COPY), but those
weren't what you and Tom were concerned about...

If that's the problem, it might be beneficial to memcpy() all the data to a
temporary buffer, and calculate the CRC over the whole, instead of CRC'ing
each XLogRecData chunk separately. XLogRecordAssemble() uses a scratch area,
hdr_scratch, for building all the headers. You could check how much
rmgr-specific data there is, and if there isn't much, just append the data
to that scratch area too.

I think that might very well make sense - but it's imo something better
done separately from the smarter CRC algorithm.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#25Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Andres Freund (#24)
Re: What exactly is our CRC algorithm?

On 11/21/2014 01:06 PM, Andres Freund wrote:

On 2014-11-21 13:01:50 +0200, Heikki Linnakangas wrote:

On 11/21/2014 12:11 PM, Abhijit Menon-Sen wrote:

At 2014-11-20 13:47:00 +0530, ams@2ndQuadrant.com wrote:

Suggestions for how to address (b) are welcome.

With help from Andres, I set up a workload where XLogInsert* was at the
top of my profiles: server with fsync and synchronous_commit off, and
pgbench running a multiple-row insert into a single-text-column table
with -M prepared -c 25 -t 250000 -f script.

How wide is the row, in terms of bytes? You should see bigger improvement
with wider rows, as you get longer contiguous chunks of data to CRC that
way. With very narrow rows, you might not see much difference because the
chunks are so small.

The primary goal, as I understood it, was to test very short records to
test whether there's a regression due to slice-by-8. There doesn't seem
to be any.

Ah, OK. Mission accomplished, then.

It's, IIRC, trivial to reproduce significant performance benefits in
workloads with lots of FPWs or large records (like COPY), but those
weren't what you and Tom were concerned about...

Yeah.

If that's the problem, it might be beneficial to memcpy() all the data to a
temporary buffer, and calculate the CRC over the whole, instead of CRC'ing
each XLogRecData chunk separately. XLogRecordAssemble() uses a scratch area,
hdr_scratch, for building all the headers. You could check how much
rmgr-specific data there is, and if there isn't much, just append the data
to that scratch area too.

I think that might very well make sense - but it's imo something better
done separately from the smarter CRC algorithm.

Agreed.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#26Ants Aasma
ants@cybertec.at
In reply to: Abhijit Menon-Sen (#22)
Re: What exactly is our CRC algorithm?

On Fri, Nov 21, 2014 at 12:11 PM, Abhijit Menon-Sen <ams@2ndquadrant.com> wrote:

If anyone has other suggestions, I'm all ears.

Do you have a WIP patch I could take a look at and tweak? Maybe
there's something about the compilers code generation that could be
improved.

Regards,
Ants Aasma
--
Cybertec Schönig & Schönig GmbH
Gröhrmühlgasse 26
A-2700 Wiener Neustadt
Web: http://www.postgresql-support.de

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#27ktm@rice.edu
ktm@rice.edu
In reply to: Abhijit Menon-Sen (#22)
Re: What exactly is our CRC algorithm?

On Fri, Nov 21, 2014 at 03:41:45PM +0530, Abhijit Menon-Sen wrote:

At 2014-11-20 13:47:00 +0530, ams@2ndQuadrant.com wrote:

Suggestions for how to address (b) are welcome.

With help from Andres, I set up a workload where XLogInsert* was at the
top of my profiles: server with fsync and synchronous_commit off, and
pgbench running a multiple-row insert into a single-text-column table
with -M prepared -c 25 -t 250000 -f script.

Unfortunately I can't see much difference despite running things with
slightly different parameters a few dozen times. For example, here are
real/user/sys times from three runs each with HEAD and slice-by-8 on an
otherwise-idle i7-3770 server with a couple of undistinguished Toshiba
7200rpm SATA disks in RAID-1:

HEAD:
2m24.822s/0m18.776s/0m23.156s
3m34.586s/0m18.784s/0m24.324s
3m41.557s/0m18.640s/0m23.920s

Slice-by-8:
2m26.977s/0m18.420s/0m22.884s
3m36.664s/0m18.376s/0m24.232s
3m43.930s/0m18.580s/0m24.560s

I don't know how to interpret these results (especially the tendency for
the tests to slow down as time passes, with every version). At best, it
shows that the new CRC code doesn't hurt, at worst it's just irrelevant.
Supporting the latter interpretation, using the hardware-CRC patch also
gives similar results (but XLogInsert is not at the top of the profile).

Hardware-CRC:
2m29.090s/0m18.652s/0m23.764s
3m30.188s/0m18.692s/0m25.332s
3m38.110s/0m20.424s/0m24.532s

If anyone has other suggestions, I'm all ears.

-- Abhijit

Hi,

This indicates that another part of the system is the resource limit,
not the CRC calculation. My money is on the I/O system. Try it using
an in memory filesystem and see if that matters. Even if it is still
the same results, at least the new version of CRC is no worse than
the current version.

Regards,
Ken

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#28Bruce Momjian
bruce@momjian.us
In reply to: ktm@rice.edu (#27)
Re: What exactly is our CRC algorithm?

On Fri, Nov 21, 2014 at 07:49:45AM -0600, ktm@rice.edu wrote:

Hi,

This indicates that another part of the system is the resource limit,
not the CRC calculation. My money is on the I/O system. Try it using
an in memory filesystem and see if that matters. Even if it is still
the same results, at least the new version of CRC is no worse than
the current version.

I would test it with fsync=off to remove the fsync delay. That will
simulate an SSD or BBU controller.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ Everyone has their own god. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#29Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Bruce Momjian (#28)
Re: What exactly is our CRC algorithm?

At 2014-11-26 18:56:52 -0500, bruce@momjian.us wrote:

I would test it with fsync=off to remove the fsync delay. That will
simulate an SSD or BBU controller.

The earlier tests were run with fsync=off.

I ran another round of the replay tests on the i7 server, this time
replaying 30GB of WAL segments.

master

16:08:03 16:16:23 08:20
16:19:33 16:28:03 08:30
16:32:20 16:41:17 08:57
16:42:42 16:51:22 08:40

8crc

16:52:11 16:59:48 07:37
17:01:07 17:08:30 07:23
17:22:16 17:30:11 07:55
17:31:29 17:39:06 07:37

These are just the results of the last four runs with each branch, but
the difference was consistent over many more runs.

To summarise: the slice-by-8 patch (a) increases pure CRC performance by
a large margin, (b) has a positive effect on reading WAL during replay,
(c) doesn't hurt XLogInsert in typical cases (which was the main worry).

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#30Bruce Momjian
bruce@momjian.us
In reply to: Abhijit Menon-Sen (#29)
Re: What exactly is our CRC algorithm?

On Thu, Nov 27, 2014 at 11:19:51AM +0530, Abhijit Menon-Sen wrote:

At 2014-11-26 18:56:52 -0500, bruce@momjian.us wrote:

I would test it with fsync=off to remove the fsync delay. That will
simulate an SSD or BBU controller.

The earlier tests were run with fsync=off.

I ran another round of the replay tests on the i7 server, this time
replaying 30GB of WAL segments.

master

16:08:03 16:16:23 08:20
16:19:33 16:28:03 08:30
16:32:20 16:41:17 08:57
16:42:42 16:51:22 08:40

8crc

16:52:11 16:59:48 07:37
17:01:07 17:08:30 07:23
17:22:16 17:30:11 07:55
17:31:29 17:39:06 07:37

These are just the results of the last four runs with each branch, but
the difference was consistent over many more runs.

To summarise: the slice-by-8 patch (a) increases pure CRC performance by
a large margin, (b) has a positive effect on reading WAL during replay,
(c) doesn't hurt XLogInsert in typical cases (which was the main worry).

Thanks, these are good numbers.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ Everyone has their own god. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#31Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Abhijit Menon-Sen (#21)
1 attachment(s)
Re: What exactly is our CRC algorithm?

Hi.

Here's a proposed patch to use CPUID at startup to determine if the
SSE4.2 CRC instructions are available, to use them instead of the
slice-by-8 implementation (posted earlier).

A few notes:

1. GCC has included cpuid.h since 4.3.0, so I figured it was safe to
use. It can be replaced with some inline assembly otherwise.

2. I've also used the crc32b/crc32q instructions directly rather than
using ".bytes" to encode the instructions; bintuils versions since
2007 or so have supported them.

3. I've included the MSVC implementation mostly as an example of how to
extend this to different compilers/platforms. It's written according
to the documentation for MSVC intrinsics, but I have not tested it.
Suggestions/improvements are welcome.

-- Abhijit

Attachments:

crc.difftext/x-diff; charset=us-asciiDownload
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index 73c30c5..ae34876 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -37,6 +37,7 @@
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
 #include "utils/ps_status.h"
+#include "utils/pg_crc.h"
 
 
 const char *progname;
@@ -76,6 +77,12 @@ main(int argc, char *argv[])
 	argv = save_ps_display_args(argc, argv);
 
 	/*
+	 * Select the fastest available CRC32 implementation for the
+	 * platform.
+	 */
+	pg_init_comp_crc32c();
+
+	/*
 	 * If supported on the current platform, set up a handler to be called if
 	 * the backend/postmaster crashes with a fatal signal or exception.
 	 */

diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index 55934e5..c59c05b 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,7 +41,8 @@
 
 typedef uint32 pg_crc32;
 
-extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+extern void pg_init_comp_crc32c(void);
+extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);
 
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.

diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index 2f9857b..6be17b0 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -21,6 +21,13 @@
 #include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
 
+#if defined(HAVE_CPUID_H)
+#include <cpuid.h>
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#include <nmmintrin.h>
+#endif
+
 static inline uint32 bswap32(uint32 x)
 {
 #if defined(__GNUC__) || defined(__clang__)
@@ -39,8 +46,8 @@ static inline uint32 bswap32(uint32 x)
 #define cpu_to_le32(x) x
 #endif
 
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
 {
 	const unsigned char *p = data;
 	const uint32 *p8;
@@ -61,7 +68,6 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
 	 */
 
 	p8 = (const uint32 *) p;
-
 	while (len >= 8)
 	{
 		uint32 a = *p8++ ^ cpu_to_le32(crc);
@@ -101,8 +107,102 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
 	 */
 
 	p = (const unsigned char *) p8;
-	while (len-- > 0)
+	while (len > 0)
+	{
 		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	return crc;
+}
 
+static pg_crc32
+pg_asm_crc32b(pg_crc32 crc, unsigned char data)
+{
+#ifdef __GNUC__
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
 	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u8(crc, data);
+#else
+#error "Don't know how to generate crc32b instruction"
+#endif
 }
+
+static pg_crc32
+pg_asm_crc32q(uint64 crc, unsigned long long data)
+{
+#ifdef __GNUC__
+	__asm__ ("crc32q %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
+	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u64(crc, data);
+#else
+#error "Don't know how to generate crc32q instruction"
+#endif
+}
+
+static pg_crc32
+pg_comp_crc32c_sse(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that
+	 * the loop below starts with a pointer aligned to four bytes.
+	 */
+
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = pg_asm_crc32q(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
+
+/*
+ * If (we can tell that) the CPU supports SSE4.2 instructions, we can
+ * use the CRC instruction, otherwise we fall back to slice-by-8 in
+ * software.
+ */
+
+void
+pg_init_comp_crc32c(void)
+{
+	unsigned int exx[4] = { 0, 0, 0, 0 };
+
+#if defined(__GNUC__) && defined(HAVE_CPUID_H)
+	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+#elif defined(_MSC_VER)
+	__cpuid(exx, 1);
+#endif
+
+	if (exx[2] & (1 << 20))
+		pg_comp_crc32c = pg_comp_crc32c_sse;
+}
+
+pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_sb8;

diff --git a/configure b/configure
index 7594401..284ca6f 100755
--- a/configure
+++ b/configure
@@ -9195,7 +9195,7 @@ fi
 done
 
 
-for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"

diff --git a/configure.in b/configure.in
index 0dc3f18..8ab888d 100644
--- a/configure.in
+++ b/configure.in
@@ -1023,7 +1023,7 @@ AC_SUBST(UUID_LIBS)
 ##
 
 dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES
-AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.

diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 465281c..355f5fc 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -99,6 +99,9 @@
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 05941e6..c2fe01f 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the `class' function. */
 /* #undef HAVE_CLASS */
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+/* #undef HAVE_CPUID_H */
+
 /* Define to 1 if you have the `crypt' function. */
 /* #undef HAVE_CRYPT */
 
#32Bruce Momjian
bruce@momjian.us
In reply to: Abhijit Menon-Sen (#31)
Re: What exactly is our CRC algorithm?

On Thu, Dec 25, 2014 at 11:57:29AM +0530, Abhijit Menon-Sen wrote:

Hi.

Here's a proposed patch to use CPUID at startup to determine if the
SSE4.2 CRC instructions are available, to use them instead of the
slice-by-8 implementation (posted earlier).

A few notes:

1. GCC has included cpuid.h since 4.3.0, so I figured it was safe to
use. It can be replaced with some inline assembly otherwise.

2. I've also used the crc32b/crc32q instructions directly rather than
using ".bytes" to encode the instructions; bintuils versions since
2007 or so have supported them.

3. I've included the MSVC implementation mostly as an example of how to
extend this to different compilers/platforms. It's written according
to the documentation for MSVC intrinsics, but I have not tested it.
Suggestions/improvements are welcome.

Uh, what happens if the system is compiled on a different CPU that it is
run on? Seems we would need a run-time CPU test.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ Everyone has their own god. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#33Andres Freund
andres@2ndquadrant.com
In reply to: Bruce Momjian (#32)
Re: What exactly is our CRC algorithm?

On December 26, 2014 4:50:33 PM CET, Bruce Momjian <bruce@momjian.us> wrote:

On Thu, Dec 25, 2014 at 11:57:29AM +0530, Abhijit Menon-Sen wrote:

Hi.

Here's a proposed patch to use CPUID at startup to determine if the
SSE4.2 CRC instructions are available, to use them instead of the
slice-by-8 implementation (posted earlier).

A few notes:

1. GCC has included cpuid.h since 4.3.0, so I figured it was safe to
use. It can be replaced with some inline assembly otherwise.

2. I've also used the crc32b/crc32q instructions directly rather than
using ".bytes" to encode the instructions; bintuils versions since
2007 or so have supported them.

3. I've included the MSVC implementation mostly as an example of how

to

extend this to different compilers/platforms. It's written

according

to the documentation for MSVC intrinsics, but I have not tested

it.

Suggestions/improvements are welcome.

Uh, what happens if the system is compiled on a different CPU that it
is
run on? Seems we would need a run-time CPU test.

That's the cpuid thing mentioned above.

Andres

--
Please excuse brevity and formatting - I am writing this on my mobile phone.

Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#34Bruce Momjian
bruce@momjian.us
In reply to: Andres Freund (#33)
Re: What exactly is our CRC algorithm?

On Fri, Dec 26, 2014 at 04:52:58PM +0100, Andres Freund wrote:

On December 26, 2014 4:50:33 PM CET, Bruce Momjian <bruce@momjian.us> wrote:

On Thu, Dec 25, 2014 at 11:57:29AM +0530, Abhijit Menon-Sen wrote:

Hi.

Here's a proposed patch to use CPUID at startup to determine if the
SSE4.2 CRC instructions are available, to use them instead of the
slice-by-8 implementation (posted earlier).

A few notes:

1. GCC has included cpuid.h since 4.3.0, so I figured it was safe to
use. It can be replaced with some inline assembly otherwise.

2. I've also used the crc32b/crc32q instructions directly rather than
using ".bytes" to encode the instructions; bintuils versions since
2007 or so have supported them.

3. I've included the MSVC implementation mostly as an example of how

to

extend this to different compilers/platforms. It's written

according

to the documentation for MSVC intrinsics, but I have not tested

it.

Suggestions/improvements are welcome.

Uh, what happens if the system is compiled on a different CPU that it
is
run on? Seems we would need a run-time CPU test.

That's the cpuid thing mentioned above.

Oh, so cpuid is not a macro exported by the compiler but a C API. Good.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ Everyone has their own god. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#35Andres Freund
andres@2ndquadrant.com
In reply to: Bruce Momjian (#34)
Re: What exactly is our CRC algorithm?

On December 26, 2014 6:05:34 PM CET, Bruce Momjian <bruce@momjian.us> wrote:

On Fri, Dec 26, 2014 at 04:52:58PM +0100, Andres Freund wrote:

On December 26, 2014 4:50:33 PM CET, Bruce Momjian <bruce@momjian.us>

wrote:

On Thu, Dec 25, 2014 at 11:57:29AM +0530, Abhijit Menon-Sen wrote:

Hi.

Here's a proposed patch to use CPUID at startup to determine if

the

SSE4.2 CRC instructions are available, to use them instead of the
slice-by-8 implementation (posted earlier).

A few notes:

1. GCC has included cpuid.h since 4.3.0, so I figured it was safe

to

use. It can be replaced with some inline assembly otherwise.

2. I've also used the crc32b/crc32q instructions directly rather

than

using ".bytes" to encode the instructions; bintuils versions

since

2007 or so have supported them.

3. I've included the MSVC implementation mostly as an example of

how

to

extend this to different compilers/platforms. It's written

according

to the documentation for MSVC intrinsics, but I have not tested

it.

Suggestions/improvements are welcome.

Uh, what happens if the system is compiled on a different CPU that

it

is
run on? Seems we would need a run-time CPU test.

That's the cpuid thing mentioned above.

Oh, so cpuid is not a macro exported by the compiler but a C API.
Good

Neither, really. It's a instruction returning CPU capabilities.

--
Please excuse brevity and formatting - I am writing this on my mobile phone.

Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#36Bruce Momjian
bruce@momjian.us
In reply to: Andres Freund (#33)
Re: What exactly is our CRC algorithm?

On Fri, Dec 26, 2014 at 04:52:58PM +0100, Andres Freund wrote:

Uh, what if the system is compiled on a different CPU that it
is
run on? Seems we would need a run-time CPU test.

That's the cpuid thing mentioned above.

Is this something that could potentially change the data stored on disk?
Does pg_upgrade need to check for changes in this area? Is the
detection exposed by pg_controldata? Could this affect running the data
directory on a different CPU?

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ Everyone has their own god. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#37Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Bruce Momjian (#36)
Re: What exactly is our CRC algorithm?

At 2014-12-26 13:11:43 -0500, bruce@momjian.us wrote:

Is this something that could potentially change the data stored on
disk? Does pg_upgrade need to check for changes in this area? Is the
detection exposed by pg_controldata? Could this affect running the
data directory on a different CPU?

No to all.

Subsequent to Heikki's change (already in master) to use the CRC-32C
algorithm (instead of the earlier mistakenly-reflected-but-not-quite
one), both the slice-by-8 software implementation posted earlier and
the SSE4.2 CRC32* instructions will compute exactly the same value.

(Yes, I have verified this in both cases.)

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#38Bruce Momjian
bruce@momjian.us
In reply to: Abhijit Menon-Sen (#37)
Re: What exactly is our CRC algorithm?

On Fri, Dec 26, 2014 at 11:52:41PM +0530, Abhijit Menon-Sen wrote:

At 2014-12-26 13:11:43 -0500, bruce@momjian.us wrote:

Is this something that could potentially change the data stored on
disk? Does pg_upgrade need to check for changes in this area? Is the
detection exposed by pg_controldata? Could this affect running the
data directory on a different CPU?

No to all.

Subsequent to Heikki's change (already in master) to use the CRC-32C
algorithm (instead of the earlier mistakenly-reflected-but-not-quite
one), both the slice-by-8 software implementation posted earlier and
the SSE4.2 CRC32* instructions will compute exactly the same value.

(Yes, I have verified this in both cases.)

Uh, we didn't fully change all code to use the new algorithm because
there were cases that the CRC was already stored on disk, e.g hstore,
ltree. I assume you are only linking into Heikki's new code and will
not change the places that use the old CRC method on disk --- just
checking.

--
Bruce Momjian <bruce@momjian.us> http://momjian.us
EnterpriseDB http://enterprisedb.com

+ Everyone has their own god. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#39Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Bruce Momjian (#38)
Re: What exactly is our CRC algorithm?

At 2014-12-26 13:48:40 -0500, bruce@momjian.us wrote:

I assume you are only linking into Heikki's new code and will not
change the places that use the old CRC method on disk --- just
checking.

Correct. The legacy CRC computation code used by ltree etc. is
completely unaffected by both my sets of changes.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#40Andres Freund
andres@2ndquadrant.com
In reply to: Abhijit Menon-Sen (#31)
Re: What exactly is our CRC algorithm?

Hi,

On 2014-12-25 11:57:29 +0530, Abhijit Menon-Sen wrote:

-extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+extern void pg_init_comp_crc32c(void);

How about pg_choose_crc_impl() or something?

+extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);

/*
* CRC calculation using the CRC-32C (Castagnoli) polynomial.

diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index 2f9857b..6be17b0 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -21,6 +21,13 @@
#include "utils/pg_crc.h"
#include "utils/pg_crc_tables.h"
+#if defined(HAVE_CPUID_H)
+#include <cpuid.h>
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#include <nmmintrin.h>
+#endif
+
static inline uint32 bswap32(uint32 x)
{
#if defined(__GNUC__) || defined(__clang__)
@@ -39,8 +46,8 @@ static inline uint32 bswap32(uint32 x)
#define cpu_to_le32(x) x
#endif
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)

_sb8? Unless I miss something it's not slice by 8 but rather bytewise?

{
const unsigned char *p = data;
const uint32 *p8;
@@ -61,7 +68,6 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
*/

p8 = (const uint32 *) p;
-
while (len >= 8)
{
uint32 a = *p8++ ^ cpu_to_le32(crc);
@@ -101,8 +107,102 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
*/

p = (const unsigned char *) p8;
-	while (len-- > 0)
+	while (len > 0)
+	{
crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	return crc;
+}
+static pg_crc32
+pg_asm_crc32b(pg_crc32 crc, unsigned char data)
+{

Should be marked inline.

+#ifdef __GNUC__
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));

Have you checked which version of gcc introduced named references to
input/output parameters?

return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u8(crc, data);
+#else
+#error "Don't know how to generate crc32b instruction"
+#endif
}
+
+static pg_crc32
+pg_asm_crc32q(uint64 crc, unsigned long long data)
+{

inline.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#41Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Andres Freund (#40)
2 attachment(s)
Re: What exactly is our CRC algorithm?

At 2014-12-29 13:22:28 +0100, andres@2ndquadrant.com wrote:

How about pg_choose_crc_impl() or something?

Done.

_sb8? Unless I miss something it's not slice by 8 but rather bytewise?

This is meant to apply on top of the earlier patches I posted to
implement slice-by-8. I'll attach both here.

Should be marked inline.

Done (and the other one too).

+#ifdef __GNUC__
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));

Have you checked which version of gcc introduced named references to
input/output parameters?

No. The documentation calls them "asmSymbolicName"s, but I can't find
the term (or various likely alternatives, e.g. symbolic_operand may be
related) either in the release notes, the changelog, or the source (on
Github). Does anyone know, or know how to find out?

Meanwhile, I have attached the two patches with the other modifications.

-- Abhijit

Attachments:

sb8.difftext/x-diff; charset=us-asciiDownload
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index f871cba..55934e5 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,6 +41,8 @@
 
 typedef uint32 pg_crc32;
 
+extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
  *
@@ -51,7 +53,7 @@ typedef uint32 pg_crc32;
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
 #define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
 #define COMP_CRC32C(crc, data, len)	\
-	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table)
+	((crc) = pg_comp_crc32c((crc), (char *) (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
 /*
@@ -115,7 +117,7 @@ do {															  \
 } while (0)
 
 /* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[];
+extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index cb6b470..f814c91 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -28,71 +28,519 @@
  * This table is based on the so-called Castagnoli polynomial (the same
  * that is used e.g. in iSCSI).
  */
-const uint32 pg_crc32c_table[256] = {
-	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
-	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
-	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
-	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
-	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
-	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
-	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
-	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
-	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
-	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
-	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
-	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
-	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
-	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
-	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
-	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
-	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
-	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
-	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
-	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
-	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
-	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
-	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
-	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
-	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
-	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
-	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
-	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
-	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
-	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
-	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
-	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
-	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
-	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
-	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
-	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
-	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
-	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
-	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
-	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
-	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
-	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
-	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
-	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
-	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
-	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
-	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
-	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
-	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
-	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
-	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
-	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
-	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
-	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
-	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
-	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
-	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
-	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
-	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
-	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
-	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
-	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
-	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
-	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+const uint32 pg_crc32c_table[8][256] = {
+	{ 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+	  0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+	  0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+	  0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+	  0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+	  0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+	  0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+	  0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+	  0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+	  0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+	  0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+	  0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+	  0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+	  0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+	  0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+	  0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+	  0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+	  0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+	  0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+	  0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+	  0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+	  0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+	  0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+	  0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+	  0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+	  0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+	  0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+	  0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+	  0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+	  0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+	  0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+	  0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+	  0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+	  0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+	  0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+	  0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+	  0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+	  0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+	  0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+	  0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+	  0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+	  0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+	  0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+	  0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+	  0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+	  0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+	  0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+	  0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+	  0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+	  0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+	  0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+	  0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+	  0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+	  0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+	  0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+	  0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+	  0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+	  0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+	  0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+	  0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+	  0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+	  0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+	  0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+	  0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 },
+	{ 0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
+	  0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
+	  0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
+	  0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
+	  0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
+	  0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
+	  0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
+	  0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
+	  0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
+	  0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
+	  0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
+	  0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
+	  0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
+	  0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
+	  0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
+	  0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
+	  0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
+	  0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
+	  0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
+	  0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
+	  0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
+	  0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
+	  0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
+	  0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
+	  0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
+	  0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
+	  0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
+	  0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
+	  0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
+	  0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
+	  0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
+	  0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
+	  0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
+	  0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
+	  0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
+	  0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
+	  0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
+	  0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
+	  0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
+	  0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
+	  0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
+	  0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
+	  0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
+	  0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
+	  0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
+	  0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
+	  0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
+	  0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
+	  0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
+	  0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
+	  0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
+	  0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
+	  0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
+	  0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
+	  0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
+	  0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
+	  0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
+	  0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
+	  0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
+	  0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
+	  0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
+	  0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
+	  0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
+	  0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483 },
+	{ 0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
+	  0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
+	  0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
+	  0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
+	  0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
+	  0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
+	  0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
+	  0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
+	  0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
+	  0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
+	  0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
+	  0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
+	  0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
+	  0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
+	  0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
+	  0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
+	  0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
+	  0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
+	  0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
+	  0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
+	  0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
+	  0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
+	  0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
+	  0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
+	  0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
+	  0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
+	  0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
+	  0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
+	  0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
+	  0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
+	  0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
+	  0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
+	  0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
+	  0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
+	  0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
+	  0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
+	  0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
+	  0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
+	  0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
+	  0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
+	  0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
+	  0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
+	  0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
+	  0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
+	  0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
+	  0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
+	  0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
+	  0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
+	  0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
+	  0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
+	  0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
+	  0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
+	  0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
+	  0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
+	  0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
+	  0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
+	  0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
+	  0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
+	  0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
+	  0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
+	  0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
+	  0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
+	  0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
+	  0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8 },
+	{ 0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
+	  0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
+	  0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
+	  0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
+	  0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
+	  0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
+	  0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
+	  0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
+	  0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
+	  0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
+	  0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
+	  0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
+	  0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
+	  0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
+	  0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
+	  0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
+	  0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
+	  0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
+	  0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
+	  0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
+	  0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
+	  0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
+	  0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
+	  0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
+	  0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
+	  0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
+	  0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
+	  0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
+	  0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
+	  0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
+	  0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
+	  0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
+	  0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
+	  0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
+	  0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
+	  0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
+	  0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
+	  0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
+	  0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
+	  0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
+	  0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
+	  0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
+	  0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
+	  0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
+	  0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
+	  0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
+	  0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
+	  0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
+	  0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
+	  0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
+	  0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
+	  0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
+	  0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
+	  0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
+	  0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
+	  0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
+	  0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
+	  0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
+	  0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
+	  0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
+	  0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
+	  0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
+	  0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
+	  0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842 },
+	{ 0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
+	  0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
+	  0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
+	  0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
+	  0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
+	  0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
+	  0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
+	  0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
+	  0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
+	  0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
+	  0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
+	  0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
+	  0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
+	  0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
+	  0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
+	  0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
+	  0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
+	  0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
+	  0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
+	  0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
+	  0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
+	  0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
+	  0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
+	  0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
+	  0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
+	  0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
+	  0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
+	  0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
+	  0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
+	  0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
+	  0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
+	  0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
+	  0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
+	  0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
+	  0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
+	  0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
+	  0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
+	  0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
+	  0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
+	  0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
+	  0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
+	  0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
+	  0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
+	  0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
+	  0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
+	  0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
+	  0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
+	  0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
+	  0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
+	  0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
+	  0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
+	  0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
+	  0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
+	  0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
+	  0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
+	  0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
+	  0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
+	  0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
+	  0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
+	  0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
+	  0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
+	  0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
+	  0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
+	  0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3 },
+	{ 0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
+	  0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
+	  0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
+	  0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
+	  0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
+	  0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
+	  0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
+	  0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
+	  0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
+	  0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
+	  0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
+	  0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
+	  0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
+	  0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
+	  0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
+	  0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
+	  0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
+	  0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
+	  0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
+	  0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
+	  0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
+	  0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
+	  0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
+	  0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
+	  0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
+	  0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
+	  0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
+	  0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
+	  0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
+	  0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
+	  0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
+	  0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
+	  0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
+	  0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
+	  0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
+	  0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
+	  0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
+	  0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
+	  0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
+	  0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
+	  0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
+	  0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
+	  0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
+	  0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
+	  0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
+	  0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
+	  0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
+	  0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
+	  0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
+	  0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
+	  0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
+	  0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
+	  0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
+	  0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
+	  0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
+	  0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
+	  0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
+	  0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
+	  0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
+	  0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
+	  0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
+	  0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
+	  0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
+	  0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C },
+	{ 0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
+	  0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
+	  0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
+	  0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
+	  0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
+	  0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
+	  0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
+	  0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
+	  0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
+	  0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
+	  0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
+	  0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
+	  0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
+	  0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
+	  0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
+	  0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
+	  0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
+	  0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
+	  0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
+	  0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
+	  0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
+	  0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
+	  0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
+	  0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
+	  0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
+	  0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
+	  0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
+	  0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
+	  0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
+	  0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
+	  0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
+	  0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
+	  0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
+	  0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
+	  0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
+	  0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
+	  0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
+	  0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
+	  0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
+	  0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
+	  0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
+	  0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
+	  0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
+	  0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
+	  0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
+	  0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
+	  0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
+	  0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
+	  0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
+	  0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
+	  0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
+	  0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
+	  0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
+	  0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
+	  0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
+	  0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
+	  0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
+	  0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
+	  0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
+	  0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
+	  0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
+	  0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
+	  0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
+	  0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F },
+	{ 0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
+	  0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
+	  0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
+	  0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
+	  0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
+	  0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
+	  0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
+	  0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
+	  0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
+	  0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
+	  0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
+	  0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
+	  0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
+	  0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
+	  0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
+	  0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
+	  0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
+	  0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
+	  0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
+	  0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
+	  0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
+	  0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
+	  0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
+	  0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
+	  0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
+	  0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
+	  0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
+	  0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
+	  0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
+	  0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
+	  0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
+	  0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
+	  0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
+	  0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
+	  0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
+	  0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
+	  0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
+	  0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
+	  0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
+	  0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
+	  0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
+	  0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
+	  0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
+	  0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
+	  0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
+	  0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
+	  0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
+	  0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
+	  0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
+	  0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
+	  0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
+	  0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
+	  0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
+	  0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
+	  0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
+	  0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
+	  0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
+	  0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
+	  0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
+	  0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
+	  0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
+	  0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
+	  0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
+	  0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5 }
 };
 
 
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index ac6f6ff..2f9857b 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -18,4 +18,91 @@
 
 #include "c.h"
 
+#include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
+
+static inline uint32 bswap32(uint32 x)
+{
+#if defined(__GNUC__) || defined(__clang__)
+	return __builtin_bswap32(x);
+#else
+	return  ((x << 24) & 0xff000000) |
+			((x <<  8) & 0x00ff0000) |
+			((x >>  8) & 0x0000ff00) |
+			((x >> 24) & 0x000000ff);
+#endif
+}
+
+#ifdef WORDS_BIGENDIAN
+#define cpu_to_le32(x) bswap32(x)
+#else
+#define cpu_to_le32(x) x
+#endif
+
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint32 *p8;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that
+	 * the loop below starts with a pointer aligned to four bytes.
+	 */
+
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint32 *) p;
+
+	while (len >= 8)
+	{
+		uint32 a = *p8++ ^ cpu_to_le32(crc);
+		uint32 b = *p8++;
+
+#ifdef WORDS_BIGENDIAN
+		const uint8 c0 = b;
+		const uint8 c1 = b >> 8;
+		const uint8 c2 = b >> 16;
+		const uint8 c3 = b >> 24;
+		const uint8 c4 = a;
+		const uint8 c5 = a >> 8;
+		const uint8 c6 = a >> 16;
+		const uint8 c7 = a >> 24;
+#else
+		const uint8 c0 = b >> 24;
+		const uint8 c1 = b >> 16;
+		const uint8 c2 = b >> 8;
+		const uint8 c3 = b;
+		const uint8 c4 = a >> 24;
+		const uint8 c5 = a >> 16;
+		const uint8 c6 = a >> 8;
+		const uint8 c7 = a;
+#endif
+
+		crc =
+			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
+			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
+			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
+			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
+
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len-- > 0)
+		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+
+	return crc;
+}
crc.difftext/x-diff; charset=us-asciiDownload
diff --git a/configure b/configure
index 7594401..284ca6f 100755
--- a/configure
+++ b/configure
@@ -9195,7 +9195,7 @@ fi
 done
 
 
-for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.in b/configure.in
index 0dc3f18..8ab888d 100644
--- a/configure.in
+++ b/configure.in
@@ -1023,7 +1023,7 @@ AC_SUBST(UUID_LIBS)
 ##
 
 dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES
-AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index 73c30c5..5a5ea2b 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -37,6 +37,7 @@
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
 #include "utils/ps_status.h"
+#include "utils/pg_crc.h"
 
 
 const char *progname;
@@ -76,6 +77,12 @@ main(int argc, char *argv[])
 	argv = save_ps_display_args(argc, argv);
 
 	/*
+	 * Select the fastest available CRC32 implementation for the
+	 * platform.
+	 */
+	pg_choose_crc_impl();
+
+	/*
 	 * If supported on the current platform, set up a handler to be called if
 	 * the backend/postmaster crashes with a fatal signal or exception.
 	 */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 465281c..355f5fc 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -99,6 +99,9 @@
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 05941e6..c2fe01f 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the `class' function. */
 /* #undef HAVE_CLASS */
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+/* #undef HAVE_CPUID_H */
+
 /* Define to 1 if you have the `crypt' function. */
 /* #undef HAVE_CRYPT */
 
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index 55934e5..238701d 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,7 +41,8 @@
 
 typedef uint32 pg_crc32;
 
-extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+extern void pg_choose_crc_impl(void);
+extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);
 
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index 2f9857b..de89c18 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -21,6 +21,13 @@
 #include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
 
+#if defined(HAVE_CPUID_H)
+#include <cpuid.h>
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#include <nmmintrin.h>
+#endif
+
 static inline uint32 bswap32(uint32 x)
 {
 #if defined(__GNUC__) || defined(__clang__)
@@ -39,8 +46,8 @@ static inline uint32 bswap32(uint32 x)
 #define cpu_to_le32(x) x
 #endif
 
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
 {
 	const unsigned char *p = data;
 	const uint32 *p8;
@@ -61,7 +68,6 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
 	 */
 
 	p8 = (const uint32 *) p;
-
 	while (len >= 8)
 	{
 		uint32 a = *p8++ ^ cpu_to_le32(crc);
@@ -101,8 +107,102 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
 	 */
 
 	p = (const unsigned char *) p8;
-	while (len-- > 0)
+	while (len > 0)
+	{
 		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	return crc;
+}
 
+static inline pg_crc32
+pg_asm_crc32b(pg_crc32 crc, unsigned char data)
+{
+#ifdef __GNUC__
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
 	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u8(crc, data);
+#else
+#error "Don't know how to generate crc32b instruction"
+#endif
 }
+
+static inline pg_crc32
+pg_asm_crc32q(uint64 crc, unsigned long long data)
+{
+#ifdef __GNUC__
+	__asm__ ("crc32q %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
+	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u64(crc, data);
+#else
+#error "Don't know how to generate crc32q instruction"
+#endif
+}
+
+static pg_crc32
+pg_comp_crc32c_sse(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that
+	 * the loop below starts with a pointer aligned to four bytes.
+	 */
+
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = pg_asm_crc32q(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
+
+/*
+ * If (we can tell that) the CPU supports SSE4.2 instructions, we can
+ * use the CRC instruction, otherwise we fall back to slice-by-8 in
+ * software.
+ */
+
+void
+pg_choose_crc_impl(void)
+{
+	unsigned int exx[4] = { 0, 0, 0, 0 };
+
+#if defined(__GNUC__) && defined(HAVE_CPUID_H)
+	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+#elif defined(_MSC_VER)
+	__cpuid(exx, 1);
+#endif
+
+	if (exx[2] & (1 << 20))
+		pg_comp_crc32c = pg_comp_crc32c_sse;
+}
+
+pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_sb8;
#42Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Abhijit Menon-Sen (#41)
Re: What exactly is our CRC algorithm?

At 2014-12-29 18:44:18 +0530, ams@2ndQuadrant.com wrote:

+#ifdef __GNUC__
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));

Have you checked which version of gcc introduced named references to
input/output parameters?

OK, here we go:

�As of GCC version 3.1, it is also possible to specify input and
output operands using symbolic names which can be referenced within
the assembler code.�

GCC 3.1 was released on May 15, 2002. So it should be quite safe to use
this feature.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#43Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Abhijit Menon-Sen (#41)
2 attachment(s)
Re: What exactly is our CRC algorithm?

Hi.

I'm re-attaching the two patches as produced by format-patch. I haven't
listed any reviewers. It's either just Andres, or maybe a lot of people.

Is anyone in a position to try out the patches on MSVC and see if they
build and work sensibly, please? (Otherwise it may be better to remove
those bits from the patch for now.)

Thanks.

-- Abhijit

Attachments:

0001-Implement-slice-by-8-CRC-calculation.patchtext/x-diff; charset=us-asciiDownload
>From d5a90d31f9c35fea2636ec6baf6acc66e91fd655 Mon Sep 17 00:00:00 2001
From: Abhijit Menon-Sen <ams@2ndQuadrant.com>
Date: Tue, 30 Dec 2014 12:41:19 +0530
Subject: Implement slice-by-8 CRC calculation

The COMP_CRC32C macro now calls pg_comp_crc32c(), which processes eight
data bytes at a time. Its output is identical to the byte-at-a-time CRC
code. (This change does not apply to the LEGACY_CRC32 computation.)

Author: Abhijit Menon-Sen
---
 src/include/utils/pg_crc.h        |   6 +-
 src/include/utils/pg_crc_tables.h | 578 +++++++++++++++++++++++++++++++++-----
 src/port/pg_crc.c                 |  87 ++++++
 3 files changed, 604 insertions(+), 67 deletions(-)

diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index f871cba..55934e5 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,6 +41,8 @@
 
 typedef uint32 pg_crc32;
 
+extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
  *
@@ -51,7 +53,7 @@ typedef uint32 pg_crc32;
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
 #define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
 #define COMP_CRC32C(crc, data, len)	\
-	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table)
+	((crc) = pg_comp_crc32c((crc), (char *) (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
 /*
@@ -115,7 +117,7 @@ do {															  \
 } while (0)
 
 /* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[];
+extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index cb6b470..f814c91 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -28,71 +28,519 @@
  * This table is based on the so-called Castagnoli polynomial (the same
  * that is used e.g. in iSCSI).
  */
-const uint32 pg_crc32c_table[256] = {
-	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
-	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
-	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
-	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
-	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
-	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
-	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
-	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
-	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
-	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
-	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
-	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
-	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
-	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
-	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
-	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
-	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
-	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
-	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
-	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
-	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
-	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
-	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
-	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
-	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
-	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
-	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
-	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
-	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
-	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
-	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
-	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
-	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
-	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
-	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
-	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
-	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
-	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
-	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
-	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
-	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
-	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
-	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
-	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
-	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
-	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
-	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
-	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
-	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
-	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
-	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
-	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
-	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
-	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
-	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
-	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
-	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
-	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
-	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
-	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
-	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
-	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
-	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
-	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+const uint32 pg_crc32c_table[8][256] = {
+	{ 0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+	  0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+	  0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+	  0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+	  0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+	  0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+	  0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+	  0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+	  0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+	  0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+	  0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+	  0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+	  0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+	  0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+	  0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+	  0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+	  0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+	  0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+	  0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+	  0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+	  0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+	  0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+	  0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+	  0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+	  0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+	  0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+	  0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+	  0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+	  0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+	  0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+	  0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+	  0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+	  0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+	  0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+	  0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+	  0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+	  0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+	  0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+	  0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+	  0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+	  0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+	  0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+	  0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+	  0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+	  0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+	  0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+	  0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+	  0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+	  0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+	  0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+	  0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+	  0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+	  0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+	  0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+	  0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+	  0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+	  0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+	  0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+	  0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+	  0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+	  0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+	  0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+	  0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+	  0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351 },
+	{ 0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
+	  0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
+	  0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
+	  0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
+	  0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
+	  0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
+	  0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
+	  0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
+	  0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
+	  0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
+	  0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
+	  0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
+	  0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
+	  0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
+	  0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
+	  0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
+	  0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
+	  0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
+	  0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
+	  0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
+	  0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
+	  0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
+	  0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
+	  0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
+	  0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
+	  0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
+	  0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
+	  0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
+	  0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
+	  0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
+	  0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
+	  0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
+	  0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
+	  0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
+	  0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
+	  0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
+	  0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
+	  0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
+	  0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
+	  0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
+	  0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
+	  0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
+	  0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
+	  0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
+	  0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
+	  0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
+	  0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
+	  0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
+	  0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
+	  0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
+	  0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
+	  0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
+	  0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
+	  0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
+	  0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
+	  0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
+	  0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
+	  0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
+	  0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
+	  0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
+	  0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
+	  0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
+	  0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
+	  0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483 },
+	{ 0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
+	  0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
+	  0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
+	  0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
+	  0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
+	  0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
+	  0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
+	  0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
+	  0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
+	  0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
+	  0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
+	  0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
+	  0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
+	  0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
+	  0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
+	  0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
+	  0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
+	  0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
+	  0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
+	  0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
+	  0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
+	  0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
+	  0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
+	  0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
+	  0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
+	  0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
+	  0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
+	  0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
+	  0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
+	  0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
+	  0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
+	  0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
+	  0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
+	  0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
+	  0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
+	  0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
+	  0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
+	  0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
+	  0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
+	  0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
+	  0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
+	  0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
+	  0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
+	  0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
+	  0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
+	  0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
+	  0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
+	  0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
+	  0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
+	  0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
+	  0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
+	  0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
+	  0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
+	  0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
+	  0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
+	  0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
+	  0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
+	  0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
+	  0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
+	  0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
+	  0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
+	  0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
+	  0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
+	  0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8 },
+	{ 0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
+	  0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
+	  0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
+	  0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
+	  0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
+	  0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
+	  0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
+	  0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
+	  0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
+	  0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
+	  0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
+	  0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
+	  0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
+	  0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
+	  0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
+	  0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
+	  0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
+	  0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
+	  0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
+	  0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
+	  0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
+	  0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
+	  0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
+	  0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
+	  0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
+	  0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
+	  0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
+	  0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
+	  0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
+	  0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
+	  0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
+	  0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
+	  0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
+	  0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
+	  0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
+	  0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
+	  0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
+	  0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
+	  0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
+	  0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
+	  0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
+	  0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
+	  0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
+	  0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
+	  0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
+	  0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
+	  0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
+	  0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
+	  0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
+	  0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
+	  0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
+	  0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
+	  0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
+	  0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
+	  0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
+	  0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
+	  0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
+	  0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
+	  0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
+	  0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
+	  0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
+	  0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
+	  0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
+	  0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842 },
+	{ 0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
+	  0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
+	  0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
+	  0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
+	  0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
+	  0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
+	  0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
+	  0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
+	  0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
+	  0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
+	  0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
+	  0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
+	  0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
+	  0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
+	  0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
+	  0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
+	  0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
+	  0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
+	  0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
+	  0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
+	  0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
+	  0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
+	  0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
+	  0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
+	  0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
+	  0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
+	  0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
+	  0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
+	  0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
+	  0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
+	  0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
+	  0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
+	  0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
+	  0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
+	  0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
+	  0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
+	  0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
+	  0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
+	  0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
+	  0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
+	  0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
+	  0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
+	  0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
+	  0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
+	  0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
+	  0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
+	  0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
+	  0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
+	  0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
+	  0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
+	  0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
+	  0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
+	  0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
+	  0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
+	  0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
+	  0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
+	  0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
+	  0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
+	  0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
+	  0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
+	  0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
+	  0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
+	  0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
+	  0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3 },
+	{ 0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
+	  0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
+	  0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
+	  0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
+	  0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
+	  0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
+	  0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
+	  0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
+	  0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
+	  0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
+	  0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
+	  0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
+	  0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
+	  0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
+	  0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
+	  0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
+	  0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
+	  0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
+	  0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
+	  0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
+	  0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
+	  0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
+	  0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
+	  0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
+	  0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
+	  0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
+	  0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
+	  0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
+	  0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
+	  0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
+	  0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
+	  0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
+	  0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
+	  0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
+	  0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
+	  0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
+	  0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
+	  0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
+	  0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
+	  0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
+	  0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
+	  0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
+	  0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
+	  0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
+	  0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
+	  0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
+	  0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
+	  0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
+	  0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
+	  0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
+	  0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
+	  0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
+	  0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
+	  0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
+	  0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
+	  0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
+	  0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
+	  0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
+	  0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
+	  0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
+	  0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
+	  0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
+	  0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
+	  0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C },
+	{ 0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
+	  0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
+	  0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
+	  0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
+	  0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
+	  0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
+	  0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
+	  0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
+	  0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
+	  0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
+	  0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
+	  0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
+	  0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
+	  0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
+	  0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
+	  0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
+	  0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
+	  0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
+	  0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
+	  0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
+	  0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
+	  0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
+	  0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
+	  0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
+	  0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
+	  0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
+	  0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
+	  0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
+	  0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
+	  0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
+	  0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
+	  0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
+	  0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
+	  0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
+	  0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
+	  0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
+	  0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
+	  0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
+	  0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
+	  0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
+	  0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
+	  0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
+	  0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
+	  0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
+	  0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
+	  0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
+	  0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
+	  0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
+	  0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
+	  0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
+	  0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
+	  0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
+	  0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
+	  0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
+	  0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
+	  0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
+	  0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
+	  0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
+	  0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
+	  0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
+	  0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
+	  0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
+	  0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
+	  0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F },
+	{ 0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
+	  0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
+	  0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
+	  0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
+	  0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
+	  0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
+	  0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
+	  0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
+	  0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
+	  0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
+	  0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
+	  0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
+	  0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
+	  0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
+	  0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
+	  0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
+	  0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
+	  0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
+	  0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
+	  0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
+	  0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
+	  0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
+	  0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
+	  0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
+	  0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
+	  0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
+	  0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
+	  0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
+	  0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
+	  0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
+	  0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
+	  0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
+	  0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
+	  0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
+	  0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
+	  0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
+	  0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
+	  0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
+	  0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
+	  0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
+	  0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
+	  0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
+	  0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
+	  0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
+	  0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
+	  0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
+	  0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
+	  0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
+	  0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
+	  0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
+	  0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
+	  0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
+	  0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
+	  0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
+	  0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
+	  0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
+	  0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
+	  0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
+	  0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
+	  0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
+	  0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
+	  0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
+	  0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
+	  0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5 }
 };
 
 
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index ac6f6ff..2f9857b 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -18,4 +18,91 @@
 
 #include "c.h"
 
+#include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
+
+static inline uint32 bswap32(uint32 x)
+{
+#if defined(__GNUC__) || defined(__clang__)
+	return __builtin_bswap32(x);
+#else
+	return  ((x << 24) & 0xff000000) |
+			((x <<  8) & 0x00ff0000) |
+			((x >>  8) & 0x0000ff00) |
+			((x >> 24) & 0x000000ff);
+#endif
+}
+
+#ifdef WORDS_BIGENDIAN
+#define cpu_to_le32(x) bswap32(x)
+#else
+#define cpu_to_le32(x) x
+#endif
+
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint32 *p8;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that
+	 * the loop below starts with a pointer aligned to four bytes.
+	 */
+
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint32 *) p;
+
+	while (len >= 8)
+	{
+		uint32 a = *p8++ ^ cpu_to_le32(crc);
+		uint32 b = *p8++;
+
+#ifdef WORDS_BIGENDIAN
+		const uint8 c0 = b;
+		const uint8 c1 = b >> 8;
+		const uint8 c2 = b >> 16;
+		const uint8 c3 = b >> 24;
+		const uint8 c4 = a;
+		const uint8 c5 = a >> 8;
+		const uint8 c6 = a >> 16;
+		const uint8 c7 = a >> 24;
+#else
+		const uint8 c0 = b >> 24;
+		const uint8 c1 = b >> 16;
+		const uint8 c2 = b >> 8;
+		const uint8 c3 = b;
+		const uint8 c4 = a >> 24;
+		const uint8 c5 = a >> 16;
+		const uint8 c6 = a >> 8;
+		const uint8 c7 = a;
+#endif
+
+		crc =
+			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
+			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
+			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
+			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
+
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len-- > 0)
+		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+
+	return crc;
+}
-- 
1.9.1

0002-Use-the-SSE4.2-CRC-instructions-where-available.patchtext/x-diff; charset=us-asciiDownload
>From 25015df9e60257bb414b6fb64ca2c7c6b8dbc08d Mon Sep 17 00:00:00 2001
From: Abhijit Menon-Sen <ams@2ndQuadrant.com>
Date: Tue, 30 Dec 2014 12:55:53 +0530
Subject: Use the SSE4.2 CRC instructions where available

We execute cpuid at startup to determine if the processor supports
SSE4.2 instructions, and use the crc32* instructions instead of the
default slice-by-8 code (both produce identical results).

Author: Abhijit Menon-Sen
---
 configure                     |   2 +-
 configure.in                  |   2 +-
 src/backend/main/main.c       |   7 +++
 src/include/pg_config.h.in    |   3 ++
 src/include/pg_config.h.win32 |   3 ++
 src/include/utils/pg_crc.h    |   3 +-
 src/port/pg_crc.c             | 108 ++++++++++++++++++++++++++++++++++++++++--
 7 files changed, 121 insertions(+), 7 deletions(-)

diff --git a/configure b/configure
index 7594401..284ca6f 100755
--- a/configure
+++ b/configure
@@ -9195,7 +9195,7 @@ fi
 done
 
 
-for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.in b/configure.in
index 0dc3f18..8ab888d 100644
--- a/configure.in
+++ b/configure.in
@@ -1023,7 +1023,7 @@ AC_SUBST(UUID_LIBS)
 ##
 
 dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES
-AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index 73c30c5..5a5ea2b 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -37,6 +37,7 @@
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
 #include "utils/ps_status.h"
+#include "utils/pg_crc.h"
 
 
 const char *progname;
@@ -76,6 +77,12 @@ main(int argc, char *argv[])
 	argv = save_ps_display_args(argc, argv);
 
 	/*
+	 * Select the fastest available CRC32 implementation for the
+	 * platform.
+	 */
+	pg_choose_crc_impl();
+
+	/*
 	 * If supported on the current platform, set up a handler to be called if
 	 * the backend/postmaster crashes with a fatal signal or exception.
 	 */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 465281c..355f5fc 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -99,6 +99,9 @@
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 05941e6..c2fe01f 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the `class' function. */
 /* #undef HAVE_CLASS */
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+/* #undef HAVE_CPUID_H */
+
 /* Define to 1 if you have the `crypt' function. */
 /* #undef HAVE_CRYPT */
 
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index 55934e5..238701d 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,7 +41,8 @@
 
 typedef uint32 pg_crc32;
 
-extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+extern void pg_choose_crc_impl(void);
+extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);
 
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index 2f9857b..de89c18 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -21,6 +21,13 @@
 #include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
 
+#if defined(HAVE_CPUID_H)
+#include <cpuid.h>
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#include <nmmintrin.h>
+#endif
+
 static inline uint32 bswap32(uint32 x)
 {
 #if defined(__GNUC__) || defined(__clang__)
@@ -39,8 +46,8 @@ static inline uint32 bswap32(uint32 x)
 #define cpu_to_le32(x) x
 #endif
 
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
 {
 	const unsigned char *p = data;
 	const uint32 *p8;
@@ -61,7 +68,6 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
 	 */
 
 	p8 = (const uint32 *) p;
-
 	while (len >= 8)
 	{
 		uint32 a = *p8++ ^ cpu_to_le32(crc);
@@ -101,8 +107,102 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
 	 */
 
 	p = (const unsigned char *) p8;
-	while (len-- > 0)
+	while (len > 0)
+	{
 		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	return crc;
+}
 
+static inline pg_crc32
+pg_asm_crc32b(pg_crc32 crc, unsigned char data)
+{
+#ifdef __GNUC__
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
 	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u8(crc, data);
+#else
+#error "Don't know how to generate crc32b instruction"
+#endif
 }
+
+static inline pg_crc32
+pg_asm_crc32q(uint64 crc, unsigned long long data)
+{
+#ifdef __GNUC__
+	__asm__ ("crc32q %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
+	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u64(crc, data);
+#else
+#error "Don't know how to generate crc32q instruction"
+#endif
+}
+
+static pg_crc32
+pg_comp_crc32c_sse(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that
+	 * the loop below starts with a pointer aligned to four bytes.
+	 */
+
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = pg_asm_crc32q(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
+
+/*
+ * If (we can tell that) the CPU supports SSE4.2 instructions, we can
+ * use the CRC instruction, otherwise we fall back to slice-by-8 in
+ * software.
+ */
+
+void
+pg_choose_crc_impl(void)
+{
+	unsigned int exx[4] = { 0, 0, 0, 0 };
+
+#if defined(__GNUC__) && defined(HAVE_CPUID_H)
+	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+#elif defined(_MSC_VER)
+	__cpuid(exx, 1);
+#endif
+
+	if (exx[2] & (1 << 20))
+		pg_comp_crc32c = pg_comp_crc32c_sse;
+}
+
+pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_sb8;
-- 
1.9.1

#44Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#43)
Re: What exactly is our CRC algorithm?

On 12/30/2014 09:40 AM, Abhijit Menon-Sen wrote:

Hi.

I'm re-attaching the two patches as produced by format-patch. I haven't
listed any reviewers. It's either just Andres, or maybe a lot of people.

Is anyone in a position to try out the patches on MSVC and see if they
build and work sensibly, please? (Otherwise it may be better to remove
those bits from the patch for now.)

A couple of quick comments:

bswap32 is unused on on little-endian systems. That will give a compiler
warning.

pg_comp_crc32c_sse processes one byte at a time, until the pointer is
4-bytes aligned. Then it processes 8 bytes at a time. So it fetches the
8-byte chunks from only 4-byte aligned addresses. Is that intentional?
If unaligned access performs well, why bother with the initial
byte-at-a-time processing at all?

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#45Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#44)
Re: What exactly is our CRC algorithm?

At 2014-12-30 16:05:50 +0200, hlinnakangas@vmware.com wrote:

A couple of quick comments:

bswap32 is unused on on little-endian systems. That will give a
compiler warning.

Huh. I don't get a warning, even when I add -Wunused to the build flags.
But since you mention it, it would be better to write the function thus:

static inline uint32 cpu_to_le32(uint32 x)
{
#ifndef WORDS_BIGENDIAN
return x;
#elif defined(__GNUC__) || defined(__clang__)
return __builtin_bswap32(x);
#else
return ((x << 24) & 0xff000000) |
((x << 8) & 0x00ff0000) |
((x >> 8) & 0x0000ff00) |
((x >> 24) & 0x000000ff);
#endif
}

pg_comp_crc32c_sse […] fetches the 8-byte chunks from only 4-byte
aligned addresses. Is that intentional?

Thanks for spotting that. I had meant to change the test to "& 7". But
again, now that you mention it, I'm not sure it's necessary. The CRC32*
instructions don't have the usual SSE alignment requirements, and I see
that the Linux kernel (among other implementations) process eight bytes
at a time from the start of the buffer and then process the remaining
bytes one at a time. I'll do a bit more research and post an update.

Thanks for having a look.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#46Andres Freund
andres@2ndquadrant.com
In reply to: Abhijit Menon-Sen (#45)
Re: What exactly is our CRC algorithm?

On 2014-12-30 21:36:19 +0530, Abhijit Menon-Sen wrote:

Thanks for spotting that. I had meant to change the test to "& 7". But
again, now that you mention it, I'm not sure it's necessary. The CRC32*
instructions don't have the usual SSE alignment requirements, and I see
that the Linux kernel (among other implementations) process eight bytes
at a time from the start of the buffer and then process the remaining
bytes one at a time. I'll do a bit more research and post an update.

I'd done some quick and dirty benchmarking when writing my initial
crc32c POC and I found that four byte aligned accesses were faster than
ones not. But it really just was running it a couple times, nothing more.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#47Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Abhijit Menon-Sen (#45)
2 attachment(s)
Re: What exactly is our CRC algorithm?

Hi.

OK, here are the patches with the various suggestions applied.

I found that the alignment didn't seem to make much difference for the
CRC32* instructions, so I changed to process (len/8)*8bytes followed by
(len%8)*1bytes, the way the Linux kernel does.

-- Abhijit

Attachments:

0001-Implement-slice-by-8-CRC-calculation.patchtext/x-diff; charset=us-asciiDownload
>From 82de6abbc05afabbf575941743b0ee355d2888ed Mon Sep 17 00:00:00 2001
From: Abhijit Menon-Sen <ams@2ndQuadrant.com>
Date: Tue, 30 Dec 2014 12:41:19 +0530
Subject: Implement slice-by-8 CRC calculation

The COMP_CRC32C macro now calls pg_comp_crc32c(), which processes eight
data bytes at a time. Its output is identical to the byte-at-a-time CRC
code. (This change does not apply to the LEGACY_CRC32 computation.)

Reviewers: Andres Freund, Heikki Linnakangas

Author: Abhijit Menon-Sen
---
 src/include/utils/pg_crc.h        |   6 +-
 src/include/utils/pg_crc_tables.h | 594 +++++++++++++++++++++++++++++++++-----
 src/port/pg_crc.c                 |  86 ++++++
 3 files changed, 619 insertions(+), 67 deletions(-)

diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index f871cba..55934e5 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,6 +41,8 @@
 
 typedef uint32 pg_crc32;
 
+extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
  *
@@ -51,7 +53,7 @@ typedef uint32 pg_crc32;
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
 #define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
 #define COMP_CRC32C(crc, data, len)	\
-	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table)
+	((crc) = pg_comp_crc32c((crc), (char *) (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
 /*
@@ -115,7 +117,7 @@ do {															  \
 } while (0)
 
 /* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[];
+extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index cb6b470..707b363 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -28,71 +28,535 @@
  * This table is based on the so-called Castagnoli polynomial (the same
  * that is used e.g. in iSCSI).
  */
-const uint32 pg_crc32c_table[256] = {
-	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
-	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
-	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
-	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
-	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
-	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
-	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
-	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
-	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
-	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
-	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
-	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
-	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
-	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
-	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
-	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
-	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
-	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
-	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
-	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
-	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
-	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
-	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
-	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
-	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
-	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
-	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
-	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
-	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
-	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
-	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
-	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
-	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
-	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
-	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
-	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
-	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
-	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
-	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
-	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
-	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
-	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
-	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
-	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
-	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
-	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
-	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
-	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
-	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
-	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
-	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
-	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
-	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
-	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
-	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
-	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
-	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
-	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
-	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
-	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
-	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
-	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
-	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
-	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+const uint32 pg_crc32c_table[8][256] = {
+	{
+		0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+		0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+		0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+		0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+		0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+		0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+		0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+		0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+		0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+		0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+		0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+		0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+		0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+		0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+		0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+		0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+		0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+		0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+		0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+		0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+		0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+		0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+		0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+		0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+		0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+		0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+		0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+		0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+		0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+		0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+		0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+		0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+		0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+		0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+		0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+		0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+		0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+		0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+		0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+		0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+		0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+		0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+		0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+		0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+		0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+		0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+		0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+		0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+		0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+		0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+		0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+		0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+		0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+		0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+		0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+		0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+		0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+		0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+		0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+		0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+		0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+		0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+		0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+		0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+	},
+	{
+		0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
+		0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
+		0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
+		0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
+		0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
+		0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
+		0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
+		0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
+		0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
+		0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
+		0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
+		0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
+		0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
+		0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
+		0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
+		0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
+		0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
+		0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
+		0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
+		0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
+		0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
+		0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
+		0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
+		0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
+		0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
+		0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
+		0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
+		0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
+		0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
+		0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
+		0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
+		0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
+		0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
+		0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
+		0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
+		0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
+		0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
+		0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
+		0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
+		0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
+		0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
+		0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
+		0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
+		0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
+		0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
+		0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
+		0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
+		0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
+		0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
+		0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
+		0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
+		0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
+		0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
+		0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
+		0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
+		0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
+		0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
+		0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
+		0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
+		0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
+		0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
+		0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
+		0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
+		0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483
+	},
+	{
+		0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
+		0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
+		0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
+		0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
+		0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
+		0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
+		0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
+		0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
+		0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
+		0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
+		0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
+		0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
+		0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
+		0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
+		0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
+		0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
+		0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
+		0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
+		0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
+		0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
+		0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
+		0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
+		0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
+		0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
+		0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
+		0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
+		0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
+		0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
+		0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
+		0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
+		0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
+		0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
+		0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
+		0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
+		0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
+		0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
+		0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
+		0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
+		0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
+		0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
+		0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
+		0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
+		0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
+		0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
+		0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
+		0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
+		0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
+		0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
+		0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
+		0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
+		0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
+		0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
+		0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
+		0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
+		0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
+		0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
+		0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
+		0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
+		0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
+		0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
+		0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
+		0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
+		0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
+		0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8
+	},
+	{
+		0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
+		0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
+		0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
+		0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
+		0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
+		0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
+		0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
+		0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
+		0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
+		0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
+		0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
+		0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
+		0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
+		0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
+		0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
+		0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
+		0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
+		0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
+		0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
+		0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
+		0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
+		0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
+		0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
+		0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
+		0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
+		0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
+		0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
+		0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
+		0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
+		0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
+		0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
+		0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
+		0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
+		0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
+		0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
+		0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
+		0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
+		0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
+		0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
+		0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
+		0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
+		0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
+		0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
+		0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
+		0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
+		0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
+		0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
+		0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
+		0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
+		0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
+		0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
+		0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
+		0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
+		0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
+		0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
+		0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
+		0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
+		0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
+		0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
+		0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
+		0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
+		0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
+		0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
+		0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842
+	},
+	{
+		0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
+		0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
+		0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
+		0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
+		0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
+		0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
+		0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
+		0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
+		0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
+		0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
+		0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
+		0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
+		0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
+		0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
+		0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
+		0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
+		0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
+		0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
+		0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
+		0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
+		0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
+		0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
+		0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
+		0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
+		0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
+		0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
+		0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
+		0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
+		0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
+		0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
+		0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
+		0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
+		0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
+		0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
+		0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
+		0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
+		0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
+		0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
+		0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
+		0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
+		0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
+		0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
+		0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
+		0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
+		0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
+		0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
+		0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
+		0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
+		0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
+		0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
+		0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
+		0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
+		0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
+		0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
+		0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
+		0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
+		0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
+		0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
+		0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
+		0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
+		0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
+		0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
+		0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
+		0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3
+	},
+	{
+		0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
+		0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
+		0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
+		0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
+		0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
+		0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
+		0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
+		0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
+		0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
+		0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
+		0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
+		0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
+		0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
+		0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
+		0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
+		0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
+		0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
+		0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
+		0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
+		0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
+		0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
+		0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
+		0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
+		0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
+		0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
+		0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
+		0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
+		0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
+		0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
+		0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
+		0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
+		0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
+		0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
+		0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
+		0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
+		0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
+		0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
+		0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
+		0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
+		0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
+		0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
+		0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
+		0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
+		0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
+		0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
+		0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
+		0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
+		0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
+		0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
+		0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
+		0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
+		0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
+		0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
+		0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
+		0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
+		0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
+		0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
+		0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
+		0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
+		0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
+		0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
+		0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
+		0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
+		0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C
+	},
+	{
+		0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
+		0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
+		0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
+		0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
+		0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
+		0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
+		0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
+		0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
+		0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
+		0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
+		0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
+		0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
+		0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
+		0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
+		0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
+		0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
+		0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
+		0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
+		0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
+		0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
+		0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
+		0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
+		0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
+		0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
+		0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
+		0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
+		0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
+		0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
+		0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
+		0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
+		0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
+		0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
+		0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
+		0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
+		0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
+		0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
+		0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
+		0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
+		0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
+		0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
+		0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
+		0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
+		0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
+		0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
+		0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
+		0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
+		0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
+		0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
+		0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
+		0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
+		0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
+		0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
+		0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
+		0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
+		0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
+		0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
+		0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
+		0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
+		0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
+		0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
+		0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
+		0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
+		0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
+		0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F
+	},
+	{
+		0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
+		0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
+		0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
+		0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
+		0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
+		0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
+		0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
+		0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
+		0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
+		0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
+		0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
+		0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
+		0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
+		0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
+		0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
+		0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
+		0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
+		0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
+		0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
+		0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
+		0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
+		0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
+		0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
+		0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
+		0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
+		0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
+		0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
+		0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
+		0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
+		0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
+		0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
+		0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
+		0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
+		0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
+		0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
+		0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
+		0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
+		0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
+		0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
+		0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
+		0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
+		0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
+		0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
+		0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
+		0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
+		0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
+		0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
+		0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
+		0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
+		0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
+		0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
+		0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
+		0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
+		0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
+		0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
+		0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
+		0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
+		0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
+		0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
+		0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
+		0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
+		0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
+		0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
+		0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5
+	}
 };
 
 
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index ac6f6ff..a5666fa 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -18,4 +18,90 @@
 
 #include "c.h"
 
+#include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
+
+static inline uint32
+cpu_to_le32(uint32 x)
+{
+#ifndef WORDS_BIGENDIAN
+	return x;
+#elif defined(__GNUC__) || defined(__clang__)
+	return __builtin_bswap32(x);
+#else
+	return ((x << 24) & 0xff000000) |
+			((x << 8) & 0x00ff0000) |
+			((x >> 8) & 0x0000ff00) |
+			((x >> 24) & 0x000000ff);
+#endif
+}
+
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint32 *p8;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that the loop
+	 * below starts with a pointer aligned to four bytes.
+	 */
+
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint32 *) p;
+	while (len >= 8)
+	{
+		uint32		a = *p8++ ^ cpu_to_le32(crc);
+		uint32		b = *p8++;
+
+#ifdef WORDS_BIGENDIAN
+		const uint8 c0 = b;
+		const uint8 c1 = b >> 8;
+		const uint8 c2 = b >> 16;
+		const uint8 c3 = b >> 24;
+		const uint8 c4 = a;
+		const uint8 c5 = a >> 8;
+		const uint8 c6 = a >> 16;
+		const uint8 c7 = a >> 24;
+#else
+		const uint8 c0 = b >> 24;
+		const uint8 c1 = b >> 16;
+		const uint8 c2 = b >> 8;
+		const uint8 c3 = b;
+		const uint8 c4 = a >> 24;
+		const uint8 c5 = a >> 16;
+		const uint8 c6 = a >> 8;
+		const uint8 c7 = a;
+#endif
+
+		crc =
+			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
+			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
+			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
+			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
+
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_crc32c_table[0][(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+		len--;
+	}
+
+	return crc;
+}
-- 
1.9.1

0002-Use-the-SSE4.2-CRC-instructions-where-available.patchtext/x-diff; charset=us-asciiDownload
>From a7a9f3fa3fb08513422473326cc2ba399938640b Mon Sep 17 00:00:00 2001
From: Abhijit Menon-Sen <ams@2ndQuadrant.com>
Date: Tue, 30 Dec 2014 12:55:53 +0530
Subject: Use the SSE4.2 CRC instructions where available

We execute cpuid at startup to determine if the processor supports
SSE4.2 instructions, and use the crc32* instructions instead of the
default slice-by-8 code (both produce identical results).

Reviewers: Andres Freund, Heikki Linnakangas

Author: Abhijit Menon-Sen
---
 configure                     |  2 +-
 configure.in                  |  2 +-
 src/backend/main/main.c       |  7 ++++
 src/include/pg_config.h.in    |  3 ++
 src/include/pg_config.h.win32 |  3 ++
 src/include/utils/pg_crc.h    |  3 +-
 src/port/pg_crc.c             | 91 ++++++++++++++++++++++++++++++++++++++++++-
 7 files changed, 106 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index 7594401..284ca6f 100755
--- a/configure
+++ b/configure
@@ -9195,7 +9195,7 @@ fi
 done
 
 
-for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.in b/configure.in
index 0dc3f18..8ab888d 100644
--- a/configure.in
+++ b/configure.in
@@ -1023,7 +1023,7 @@ AC_SUBST(UUID_LIBS)
 ##
 
 dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES
-AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index 73c30c5..5a5ea2b 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -37,6 +37,7 @@
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
 #include "utils/ps_status.h"
+#include "utils/pg_crc.h"
 
 
 const char *progname;
@@ -76,6 +77,12 @@ main(int argc, char *argv[])
 	argv = save_ps_display_args(argc, argv);
 
 	/*
+	 * Select the fastest available CRC32 implementation for the
+	 * platform.
+	 */
+	pg_choose_crc_impl();
+
+	/*
 	 * If supported on the current platform, set up a handler to be called if
 	 * the backend/postmaster crashes with a fatal signal or exception.
 	 */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 465281c..355f5fc 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -99,6 +99,9 @@
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 05941e6..c2fe01f 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the `class' function. */
 /* #undef HAVE_CLASS */
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+/* #undef HAVE_CPUID_H */
+
 /* Define to 1 if you have the `crypt' function. */
 /* #undef HAVE_CRYPT */
 
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index 55934e5..238701d 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,7 +41,8 @@
 
 typedef uint32 pg_crc32;
 
-extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+extern void pg_choose_crc_impl(void);
+extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);
 
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index a5666fa..b52b6d7 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -21,6 +21,13 @@
 #include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
 
+#if defined(HAVE_CPUID_H)
+#include <cpuid.h>
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#include <nmmintrin.h>
+#endif
+
 static inline uint32
 cpu_to_le32(uint32 x)
 {
@@ -36,8 +43,8 @@ cpu_to_le32(uint32 x)
 #endif
 }
 
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
 {
 	const unsigned char *p = data;
 	const uint32 *p8;
@@ -105,3 +112,83 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
 
 	return crc;
 }
+
+static inline pg_crc32
+pg_asm_crc32b(pg_crc32 crc, unsigned char data)
+{
+#ifdef __GNUC__
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
+	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u8(crc, data);
+#else
+#error "Don't know how to generate crc32b instruction"
+#endif
+}
+
+static inline pg_crc32
+pg_asm_crc32q(uint64 crc, unsigned long long data)
+{
+#ifdef __GNUC__
+	__asm__ ("crc32q %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
+	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u64(crc, data);
+#else
+#error "Don't know how to generate crc32q instruction"
+#endif
+}
+
+static pg_crc32
+pg_comp_crc32c_sse(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = pg_asm_crc32q(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
+
+/*
+ * If (we can tell that) the CPU supports SSE4.2 instructions, we can
+ * use the CRC instruction, otherwise we fall back to slice-by-8 in
+ * software.
+ */
+
+void
+pg_choose_crc_impl(void)
+{
+	unsigned int exx[4] = {0, 0, 0, 0};
+
+#if defined(__GNUC__) && defined(HAVE_CPUID_H)
+	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+#elif defined(_MSC_VER)
+	__cpuid(exx, 1);
+#endif
+
+	if (exx[2] & (1 << 20))
+		pg_comp_crc32c = pg_comp_crc32c_sse;
+}
+
+pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_sb8;
-- 
1.9.1

#48Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#47)
Re: What exactly is our CRC algorithm?

On 01/01/2015 09:17 AM, Abhijit Menon-Sen wrote:

Hi.

OK, here are the patches with the various suggestions applied.

I found that the alignment didn't seem to make much difference for the
CRC32* instructions, so I changed to process (len/8)*8bytes followed by
(len%8)*1bytes, the way the Linux kernel does.

Ok.

In the slicing-by-8 version, I wonder if it would be better to do
single-byte loads to c0-c7, instead of two 4-byte loads and shifts.
4-byte loads are presumably faster than single byte loads, but then
you'd avoid the shifts. And then you could go straight into the
8-bytes-at-a-time loop, without the initial single-byte processing to
get the start address aligned. (the Linux implementation doesn't do
that, so maybe it's a bad idea, but might be worth testing..)

Looking at the Linux implementation, I think it only does the bswap once
per call, not inside the hot loop. Would it even make sense to keep the
crc variable in different byte order, and only do the byte-swap once in
END_CRC32() ?

The comments need some work. I note that there is no mention of the
slicing-by-8 algorithm anywhere in the comments (in the first patch).

Instead of checking for "defined(__GNUC__) || defined(__clang__)",
should add an explicit configure test for __builtin_bswap32().

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#49Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#48)
Re: What exactly is our CRC algorithm?

At 2015-01-02 16:46:29 +0200, hlinnakangas@vmware.com wrote:

In the slicing-by-8 version, I wonder if it would be better to do
single-byte loads to c0-c7, instead of two 4-byte loads and shifts.

Nope. I did some tests, and the sb8 code is slightly slower if I remove
the 0-7byte alignment loop, and significantly slower if I switch to one
byte loads for the whole thing. So I think we should leave that part as
it is, but:

Would it even make sense to keep the crc variable in different byte
order, and only do the byte-swap once in END_CRC32() ?

…this certainly does make a noticeable difference. Will investigate.

The comments need some work. I note that there is no mention of the
slicing-by-8 algorithm anywhere in the comments (in the first patch).

Will fix. (Unfortunately the widely cited original Intel paper about
slice-by-8 seems to have gone AWOL, but I'll find something.)

Instead of checking for "defined(__GNUC__) || defined(__clang__)",
should add an explicit configure test for __builtin_bswap32().

Will do.

Thanks again.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#50Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Abhijit Menon-Sen (#49)
2 attachment(s)
Re: What exactly is our CRC algorithm?

Hi Heikki.

I've attached two regenerated CRC patches, split up as before.

1. The slicing-by-8 patch contains numerous changes:

a. A configure test for __builtin_bswap32
b. A comment referencing the slicing-by-8 paper (which is behind a
paywall, unfortunately, so I haven't even read it). Are more
comments needed? If so, where/what kind?
c. A byte-reversed big-endian version of the 8*256 table. In Linux,
there's only one table that uses __constant_swab32, but for us
it's simpler to have two tables.
d. Thanks to (c), we can avoid the bswap32 in the hot loop.
e. On big-endian systems, FIN_CRC32C now bswap32()s the CRC before
finalising it. (We don't need to do this in INIT_CRC32C only
because the initialiser is 0xFFFFFFFF.)

2. The sse4.2 patch has only some minor compile fixes.

I have built and tested both patches individually on little-endian
(amd64) and big-endian (ppc) systems. I verified that the _sse is
chosen at startup on the former, and _sb8 on the latter, and that
both implementations function correctly with respect to HEAD.

Please let me know if there's anything else I need to do.

-- Abhijit

Attachments:

0001-Implement-slicing-by-8-CRC-calculation.patchtext/x-diff; charset=us-asciiDownload
>From a202673fa8e4e60e7fd5087fd8577a90a75e90ee Mon Sep 17 00:00:00 2001
From: Abhijit Menon-Sen <ams@2ndQuadrant.com>
Date: Fri, 9 Jan 2015 10:38:47 +0530
Subject: Implement slicing-by-8 CRC calculation

The COMP_CRC32C macro now calls pg_comp_crc32c(), which processes eight
data bytes at a time. Its output is identical to the byte-at-a-time CRC
code. (This change does not apply to the LEGACY_CRC32 computation.)

Reviewers: Andres Freund, Heikki Linnakangas

Author: Abhijit Menon-Sen
---
 config/c-compiler.m4              |   17 +
 configure                         |   30 +
 configure.in                      |    1 +
 src/include/pg_config.h.in        |    3 +
 src/include/pg_config.h.win32     |    3 +
 src/include/utils/pg_crc.h        |   11 +-
 src/include/utils/pg_crc_tables.h | 1128 ++++++++++++++++++++++++++++++++++---
 src/port/pg_crc.c                 |  105 +++-
 8 files changed, 1228 insertions(+), 70 deletions(-)

diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 90b56e7..509f961 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -193,6 +193,23 @@ fi])# PGAC_C_TYPES_COMPATIBLE
 
 
 
+# PGAC_C_BUILTIN_BSWAP32
+# -------------------------
+# Check if the C compiler understands __builtin_bswap32(),
+# and define HAVE__BUILTIN_BSWAP32 if so.
+AC_DEFUN([PGAC_C_BUILTIN_BSWAP32],
+[AC_CACHE_CHECK(for __builtin_bswap32, pgac_cv__builtin_bswap32,
+[AC_TRY_COMPILE([static unsigned long int x = __builtin_bswap32(0xaabbccdd);],
+[],
+[pgac_cv__builtin_bswap32=yes],
+[pgac_cv__builtin_bswap32=no])])
+if test x"$pgac_cv__builtin_bswap32" = xyes ; then
+AC_DEFINE(HAVE__BUILTIN_BSWAP32, 1,
+          [Define to 1 if your compiler understands __builtin_bswap32.])
+fi])# PGAC_C_BUILTIN_BSWAP32
+
+
+
 # PGAC_C_BUILTIN_CONSTANT_P
 # -------------------------
 # Check if the C compiler understands __builtin_constant_p(),
diff --git a/configure b/configure
index fce4908..27092ec 100755
--- a/configure
+++ b/configure
@@ -10324,6 +10324,36 @@ if test x"$pgac_cv__types_compatible" = xyes ; then
 $as_echo "#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1" >>confdefs.h
 
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5
+$as_echo_n "checking for __builtin_bswap32... " >&6; }
+if ${pgac_cv__builtin_bswap32+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+static unsigned long int x = __builtin_bswap32(0xaabbccdd);
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  pgac_cv__builtin_bswap32=yes
+else
+  pgac_cv__builtin_bswap32=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap32" >&5
+$as_echo "$pgac_cv__builtin_bswap32" >&6; }
+if test x"$pgac_cv__builtin_bswap32" = xyes ; then
+
+$as_echo "#define HAVE__BUILTIN_BSWAP32 1" >>confdefs.h
+
+fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_constant_p" >&5
 $as_echo_n "checking for __builtin_constant_p... " >&6; }
 if ${pgac_cv__builtin_constant_p+:} false; then :
diff --git a/configure.in b/configure.in
index 6aa69fb..0206836 100644
--- a/configure.in
+++ b/configure.in
@@ -1176,6 +1176,7 @@ PGAC_C_SIGNED
 PGAC_C_FUNCNAME_SUPPORT
 PGAC_C_STATIC_ASSERT
 PGAC_C_TYPES_COMPATIBLE
+PGAC_C_BUILTIN_BSWAP32
 PGAC_C_BUILTIN_CONSTANT_P
 PGAC_C_BUILTIN_UNREACHABLE
 PGAC_C_VA_ARGS
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 83f04e9..7962757 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -666,6 +666,9 @@
 /* Define to 1 if you have the <winldap.h> header file. */
 #undef HAVE_WINLDAP_H
 
+/* Define to 1 if your compiler understands __builtin_bswap32. */
+#undef HAVE__BUILTIN_BSWAP32
+
 /* Define to 1 if your compiler understands __builtin_constant_p. */
 #undef HAVE__BUILTIN_CONSTANT_P
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 05941e6..18da922 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -520,6 +520,9 @@
 /* Define to 1 if you have the <winldap.h> header file. */
 /* #undef HAVE_WINLDAP_H */
 
+/* Define to 1 if your compiler understands __builtin_bswap32. */
+/* #undef HAVE__BUILTIN_BSWAP32 */
+
 /* Define to 1 if your compiler understands __builtin_constant_p. */
 /* #undef HAVE__BUILTIN_CONSTANT_P */
 
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index 9bbd6d2..4d35601 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -41,6 +41,9 @@
 
 typedef uint32 pg_crc32;
 
+extern uint32 bswap32(uint32 x);
+extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
  *
@@ -49,9 +52,13 @@ typedef uint32 pg_crc32;
  * details on the choice of polynomial.
  */
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
+#ifndef WORDS_BIGENDIAN
 #define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
+#else
+#define FIN_CRC32C(crc)	((crc) = bswap32((crc)) ^ 0xFFFFFFFF)
+#endif
 #define COMP_CRC32C(crc, data, len)	\
-	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table)
+	((crc) = pg_comp_crc32c((crc), (char *) (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
 /*
@@ -115,7 +122,7 @@ do {															  \
 } while (0)
 
 /* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[];
+extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/utils/pg_crc_tables.h b/src/include/utils/pg_crc_tables.h
index 5524fda..f0e1750 100644
--- a/src/include/utils/pg_crc_tables.h
+++ b/src/include/utils/pg_crc_tables.h
@@ -26,73 +26,1069 @@
 
 /*
  * This table is based on the so-called Castagnoli polynomial (the same
- * that is used e.g. in iSCSI).
+ * that is used e.g. in iSCSI), 0x1EDC6F41. We define the normal table
+ * as well as a byte-reversed version for big-endian systems.
  */
-const uint32 pg_crc32c_table[256] = {
-	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
-	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
-	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
-	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
-	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
-	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
-	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
-	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
-	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
-	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
-	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
-	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
-	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
-	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
-	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
-	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
-	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
-	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
-	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
-	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
-	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
-	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
-	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
-	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
-	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
-	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
-	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
-	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
-	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
-	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
-	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
-	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
-	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
-	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
-	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
-	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
-	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
-	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
-	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
-	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
-	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
-	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
-	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
-	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
-	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
-	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
-	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
-	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
-	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
-	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
-	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
-	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
-	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
-	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
-	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
-	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
-	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
-	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
-	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
-	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
-	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
-	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
-	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
-	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+const uint32 pg_crc32c_table[8][256] = {
+#ifndef WORDS_BIGENDIAN
+	{
+		0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+		0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+		0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+		0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+		0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+		0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+		0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+		0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+		0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+		0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+		0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+		0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+		0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+		0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+		0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+		0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+		0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+		0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+		0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+		0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+		0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+		0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+		0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+		0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+		0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+		0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+		0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+		0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+		0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+		0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+		0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+		0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+		0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+		0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+		0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+		0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+		0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+		0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+		0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+		0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+		0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+		0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+		0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+		0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+		0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+		0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+		0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+		0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+		0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+		0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+		0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+		0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+		0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+		0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+		0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+		0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+		0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+		0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+		0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+		0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+		0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+		0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+		0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+		0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+	},
+	{
+		0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
+		0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
+		0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
+		0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
+		0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
+		0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
+		0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
+		0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
+		0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
+		0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
+		0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
+		0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
+		0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
+		0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
+		0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
+		0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
+		0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
+		0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
+		0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
+		0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
+		0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
+		0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
+		0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
+		0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
+		0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
+		0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
+		0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
+		0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
+		0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
+		0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
+		0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
+		0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
+		0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
+		0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
+		0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
+		0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
+		0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
+		0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
+		0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
+		0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
+		0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
+		0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
+		0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
+		0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
+		0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
+		0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
+		0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
+		0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
+		0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
+		0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
+		0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
+		0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
+		0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
+		0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
+		0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
+		0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
+		0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
+		0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
+		0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
+		0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
+		0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
+		0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
+		0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
+		0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483
+	},
+	{
+		0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
+		0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
+		0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
+		0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
+		0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
+		0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
+		0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
+		0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
+		0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
+		0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
+		0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
+		0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
+		0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
+		0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
+		0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
+		0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
+		0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
+		0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
+		0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
+		0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
+		0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
+		0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
+		0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
+		0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
+		0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
+		0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
+		0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
+		0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
+		0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
+		0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
+		0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
+		0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
+		0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
+		0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
+		0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
+		0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
+		0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
+		0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
+		0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
+		0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
+		0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
+		0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
+		0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
+		0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
+		0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
+		0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
+		0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
+		0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
+		0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
+		0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
+		0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
+		0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
+		0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
+		0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
+		0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
+		0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
+		0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
+		0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
+		0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
+		0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
+		0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
+		0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
+		0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
+		0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8
+	},
+	{
+		0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
+		0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
+		0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
+		0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
+		0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
+		0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
+		0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
+		0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
+		0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
+		0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
+		0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
+		0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
+		0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
+		0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
+		0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
+		0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
+		0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
+		0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
+		0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
+		0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
+		0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
+		0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
+		0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
+		0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
+		0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
+		0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
+		0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
+		0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
+		0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
+		0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
+		0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
+		0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
+		0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
+		0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
+		0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
+		0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
+		0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
+		0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
+		0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
+		0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
+		0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
+		0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
+		0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
+		0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
+		0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
+		0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
+		0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
+		0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
+		0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
+		0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
+		0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
+		0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
+		0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
+		0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
+		0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
+		0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
+		0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
+		0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
+		0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
+		0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
+		0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
+		0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
+		0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
+		0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842
+	},
+	{
+		0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
+		0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
+		0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
+		0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
+		0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
+		0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
+		0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
+		0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
+		0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
+		0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
+		0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
+		0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
+		0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
+		0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
+		0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
+		0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
+		0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
+		0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
+		0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
+		0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
+		0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
+		0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
+		0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
+		0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
+		0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
+		0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
+		0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
+		0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
+		0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
+		0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
+		0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
+		0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
+		0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
+		0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
+		0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
+		0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
+		0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
+		0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
+		0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
+		0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
+		0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
+		0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
+		0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
+		0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
+		0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
+		0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
+		0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
+		0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
+		0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
+		0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
+		0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
+		0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
+		0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
+		0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
+		0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
+		0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
+		0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
+		0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
+		0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
+		0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
+		0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
+		0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
+		0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
+		0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3
+	},
+	{
+		0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
+		0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
+		0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
+		0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
+		0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
+		0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
+		0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
+		0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
+		0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
+		0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
+		0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
+		0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
+		0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
+		0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
+		0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
+		0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
+		0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
+		0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
+		0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
+		0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
+		0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
+		0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
+		0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
+		0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
+		0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
+		0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
+		0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
+		0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
+		0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
+		0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
+		0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
+		0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
+		0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
+		0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
+		0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
+		0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
+		0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
+		0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
+		0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
+		0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
+		0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
+		0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
+		0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
+		0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
+		0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
+		0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
+		0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
+		0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
+		0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
+		0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
+		0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
+		0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
+		0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
+		0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
+		0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
+		0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
+		0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
+		0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
+		0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
+		0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
+		0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
+		0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
+		0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
+		0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C
+	},
+	{
+		0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
+		0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
+		0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
+		0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
+		0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
+		0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
+		0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
+		0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
+		0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
+		0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
+		0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
+		0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
+		0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
+		0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
+		0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
+		0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
+		0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
+		0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
+		0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
+		0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
+		0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
+		0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
+		0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
+		0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
+		0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
+		0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
+		0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
+		0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
+		0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
+		0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
+		0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
+		0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
+		0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
+		0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
+		0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
+		0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
+		0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
+		0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
+		0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
+		0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
+		0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
+		0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
+		0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
+		0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
+		0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
+		0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
+		0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
+		0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
+		0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
+		0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
+		0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
+		0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
+		0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
+		0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
+		0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
+		0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
+		0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
+		0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
+		0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
+		0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
+		0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
+		0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
+		0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
+		0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F
+	},
+	{
+		0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
+		0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
+		0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
+		0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
+		0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
+		0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
+		0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
+		0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
+		0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
+		0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
+		0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
+		0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
+		0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
+		0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
+		0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
+		0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
+		0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
+		0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
+		0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
+		0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
+		0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
+		0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
+		0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
+		0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
+		0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
+		0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
+		0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
+		0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
+		0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
+		0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
+		0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
+		0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
+		0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
+		0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
+		0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
+		0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
+		0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
+		0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
+		0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
+		0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
+		0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
+		0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
+		0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
+		0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
+		0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
+		0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
+		0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
+		0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
+		0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
+		0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
+		0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
+		0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
+		0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
+		0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
+		0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
+		0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
+		0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
+		0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
+		0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
+		0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
+		0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
+		0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
+		0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
+		0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5
+	}
+#else
+	{
+		0x00000000, 0x03836BF2, 0xF7703BE1, 0xF4F35013,
+		0x1F979AC7, 0x1C14F135, 0xE8E7A126, 0xEB64CAD4,
+		0xCF58D98A, 0xCCDBB278, 0x3828E26B, 0x3BAB8999,
+		0xD0CF434D, 0xD34C28BF, 0x27BF78AC, 0x243C135E,
+		0x6FC75E10, 0x6C4435E2, 0x98B765F1, 0x9B340E03,
+		0x7050C4D7, 0x73D3AF25, 0x8720FF36, 0x84A394C4,
+		0xA09F879A, 0xA31CEC68, 0x57EFBC7B, 0x546CD789,
+		0xBF081D5D, 0xBC8B76AF, 0x487826BC, 0x4BFB4D4E,
+		0xDE8EBD20, 0xDD0DD6D2, 0x29FE86C1, 0x2A7DED33,
+		0xC11927E7, 0xC29A4C15, 0x36691C06, 0x35EA77F4,
+		0x11D664AA, 0x12550F58, 0xE6A65F4B, 0xE52534B9,
+		0x0E41FE6D, 0x0DC2959F, 0xF931C58C, 0xFAB2AE7E,
+		0xB149E330, 0xB2CA88C2, 0x4639D8D1, 0x45BAB323,
+		0xAEDE79F7, 0xAD5D1205, 0x59AE4216, 0x5A2D29E4,
+		0x7E113ABA, 0x7D925148, 0x8961015B, 0x8AE26AA9,
+		0x6186A07D, 0x6205CB8F, 0x96F69B9C, 0x9575F06E,
+		0xBC1D7B41, 0xBF9E10B3, 0x4B6D40A0, 0x48EE2B52,
+		0xA38AE186, 0xA0098A74, 0x54FADA67, 0x5779B195,
+		0x7345A2CB, 0x70C6C939, 0x8435992A, 0x87B6F2D8,
+		0x6CD2380C, 0x6F5153FE, 0x9BA203ED, 0x9821681F,
+		0xD3DA2551, 0xD0594EA3, 0x24AA1EB0, 0x27297542,
+		0xCC4DBF96, 0xCFCED464, 0x3B3D8477, 0x38BEEF85,
+		0x1C82FCDB, 0x1F019729, 0xEBF2C73A, 0xE871ACC8,
+		0x0315661C, 0x00960DEE, 0xF4655DFD, 0xF7E6360F,
+		0x6293C661, 0x6110AD93, 0x95E3FD80, 0x96609672,
+		0x7D045CA6, 0x7E873754, 0x8A746747, 0x89F70CB5,
+		0xADCB1FEB, 0xAE487419, 0x5ABB240A, 0x59384FF8,
+		0xB25C852C, 0xB1DFEEDE, 0x452CBECD, 0x46AFD53F,
+		0x0D549871, 0x0ED7F383, 0xFA24A390, 0xF9A7C862,
+		0x12C302B6, 0x11406944, 0xE5B33957, 0xE63052A5,
+		0xC20C41FB, 0xC18F2A09, 0x357C7A1A, 0x36FF11E8,
+		0xDD9BDB3C, 0xDE18B0CE, 0x2AEBE0DD, 0x29688B2F,
+		0x783BF682, 0x7BB89D70, 0x8F4BCD63, 0x8CC8A691,
+		0x67AC6C45, 0x642F07B7, 0x90DC57A4, 0x935F3C56,
+		0xB7632F08, 0xB4E044FA, 0x401314E9, 0x43907F1B,
+		0xA8F4B5CF, 0xAB77DE3D, 0x5F848E2E, 0x5C07E5DC,
+		0x17FCA892, 0x147FC360, 0xE08C9373, 0xE30FF881,
+		0x086B3255, 0x0BE859A7, 0xFF1B09B4, 0xFC986246,
+		0xD8A47118, 0xDB271AEA, 0x2FD44AF9, 0x2C57210B,
+		0xC733EBDF, 0xC4B0802D, 0x3043D03E, 0x33C0BBCC,
+		0xA6B54BA2, 0xA5362050, 0x51C57043, 0x52461BB1,
+		0xB922D165, 0xBAA1BA97, 0x4E52EA84, 0x4DD18176,
+		0x69ED9228, 0x6A6EF9DA, 0x9E9DA9C9, 0x9D1EC23B,
+		0x767A08EF, 0x75F9631D, 0x810A330E, 0x828958FC,
+		0xC97215B2, 0xCAF17E40, 0x3E022E53, 0x3D8145A1,
+		0xD6E58F75, 0xD566E487, 0x2195B494, 0x2216DF66,
+		0x062ACC38, 0x05A9A7CA, 0xF15AF7D9, 0xF2D99C2B,
+		0x19BD56FF, 0x1A3E3D0D, 0xEECD6D1E, 0xED4E06EC,
+		0xC4268DC3, 0xC7A5E631, 0x3356B622, 0x30D5DDD0,
+		0xDBB11704, 0xD8327CF6, 0x2CC12CE5, 0x2F424717,
+		0x0B7E5449, 0x08FD3FBB, 0xFC0E6FA8, 0xFF8D045A,
+		0x14E9CE8E, 0x176AA57C, 0xE399F56F, 0xE01A9E9D,
+		0xABE1D3D3, 0xA862B821, 0x5C91E832, 0x5F1283C0,
+		0xB4764914, 0xB7F522E6, 0x430672F5, 0x40851907,
+		0x64B90A59, 0x673A61AB, 0x93C931B8, 0x904A5A4A,
+		0x7B2E909E, 0x78ADFB6C, 0x8C5EAB7F, 0x8FDDC08D,
+		0x1AA830E3, 0x192B5B11, 0xEDD80B02, 0xEE5B60F0,
+		0x053FAA24, 0x06BCC1D6, 0xF24F91C5, 0xF1CCFA37,
+		0xD5F0E969, 0xD673829B, 0x2280D288, 0x2103B97A,
+		0xCA6773AE, 0xC9E4185C, 0x3D17484F, 0x3E9423BD,
+		0x756F6EF3, 0x76EC0501, 0x821F5512, 0x819C3EE0,
+		0x6AF8F434, 0x697B9FC6, 0x9D88CFD5, 0x9E0BA427,
+		0xBA37B779, 0xB9B4DC8B, 0x4D478C98, 0x4EC4E76A,
+		0xA5A02DBE, 0xA623464C, 0x52D0165F, 0x51537DAD,
+	},
+	{
+		0x00000000, 0x7798A213, 0xEE304527, 0x99A8E734,
+		0xDC618A4E, 0xABF9285D, 0x3251CF69, 0x45C96D7A,
+		0xB8C3149D, 0xCF5BB68E, 0x56F351BA, 0x216BF3A9,
+		0x64A29ED3, 0x133A3CC0, 0x8A92DBF4, 0xFD0A79E7,
+		0x81F1C53F, 0xF669672C, 0x6FC18018, 0x1859220B,
+		0x5D904F71, 0x2A08ED62, 0xB3A00A56, 0xC438A845,
+		0x3932D1A2, 0x4EAA73B1, 0xD7029485, 0xA09A3696,
+		0xE5535BEC, 0x92CBF9FF, 0x0B631ECB, 0x7CFBBCD8,
+		0x02E38B7F, 0x757B296C, 0xECD3CE58, 0x9B4B6C4B,
+		0xDE820131, 0xA91AA322, 0x30B24416, 0x472AE605,
+		0xBA209FE2, 0xCDB83DF1, 0x5410DAC5, 0x238878D6,
+		0x664115AC, 0x11D9B7BF, 0x8871508B, 0xFFE9F298,
+		0x83124E40, 0xF48AEC53, 0x6D220B67, 0x1ABAA974,
+		0x5F73C40E, 0x28EB661D, 0xB1438129, 0xC6DB233A,
+		0x3BD15ADD, 0x4C49F8CE, 0xD5E11FFA, 0xA279BDE9,
+		0xE7B0D093, 0x90287280, 0x098095B4, 0x7E1837A7,
+		0x04C617FF, 0x735EB5EC, 0xEAF652D8, 0x9D6EF0CB,
+		0xD8A79DB1, 0xAF3F3FA2, 0x3697D896, 0x410F7A85,
+		0xBC050362, 0xCB9DA171, 0x52354645, 0x25ADE456,
+		0x6064892C, 0x17FC2B3F, 0x8E54CC0B, 0xF9CC6E18,
+		0x8537D2C0, 0xF2AF70D3, 0x6B0797E7, 0x1C9F35F4,
+		0x5956588E, 0x2ECEFA9D, 0xB7661DA9, 0xC0FEBFBA,
+		0x3DF4C65D, 0x4A6C644E, 0xD3C4837A, 0xA45C2169,
+		0xE1954C13, 0x960DEE00, 0x0FA50934, 0x783DAB27,
+		0x06259C80, 0x71BD3E93, 0xE815D9A7, 0x9F8D7BB4,
+		0xDA4416CE, 0xADDCB4DD, 0x347453E9, 0x43ECF1FA,
+		0xBEE6881D, 0xC97E2A0E, 0x50D6CD3A, 0x274E6F29,
+		0x62870253, 0x151FA040, 0x8CB74774, 0xFB2FE567,
+		0x87D459BF, 0xF04CFBAC, 0x69E41C98, 0x1E7CBE8B,
+		0x5BB5D3F1, 0x2C2D71E2, 0xB58596D6, 0xC21D34C5,
+		0x3F174D22, 0x488FEF31, 0xD1270805, 0xA6BFAA16,
+		0xE376C76C, 0x94EE657F, 0x0D46824B, 0x7ADE2058,
+		0xF9FAC3FB, 0x8E6261E8, 0x17CA86DC, 0x605224CF,
+		0x259B49B5, 0x5203EBA6, 0xCBAB0C92, 0xBC33AE81,
+		0x4139D766, 0x36A17575, 0xAF099241, 0xD8913052,
+		0x9D585D28, 0xEAC0FF3B, 0x7368180F, 0x04F0BA1C,
+		0x780B06C4, 0x0F93A4D7, 0x963B43E3, 0xE1A3E1F0,
+		0xA46A8C8A, 0xD3F22E99, 0x4A5AC9AD, 0x3DC26BBE,
+		0xC0C81259, 0xB750B04A, 0x2EF8577E, 0x5960F56D,
+		0x1CA99817, 0x6B313A04, 0xF299DD30, 0x85017F23,
+		0xFB194884, 0x8C81EA97, 0x15290DA3, 0x62B1AFB0,
+		0x2778C2CA, 0x50E060D9, 0xC94887ED, 0xBED025FE,
+		0x43DA5C19, 0x3442FE0A, 0xADEA193E, 0xDA72BB2D,
+		0x9FBBD657, 0xE8237444, 0x718B9370, 0x06133163,
+		0x7AE88DBB, 0x0D702FA8, 0x94D8C89C, 0xE3406A8F,
+		0xA68907F5, 0xD111A5E6, 0x48B942D2, 0x3F21E0C1,
+		0xC22B9926, 0xB5B33B35, 0x2C1BDC01, 0x5B837E12,
+		0x1E4A1368, 0x69D2B17B, 0xF07A564F, 0x87E2F45C,
+		0xFD3CD404, 0x8AA47617, 0x130C9123, 0x64943330,
+		0x215D5E4A, 0x56C5FC59, 0xCF6D1B6D, 0xB8F5B97E,
+		0x45FFC099, 0x3267628A, 0xABCF85BE, 0xDC5727AD,
+		0x999E4AD7, 0xEE06E8C4, 0x77AE0FF0, 0x0036ADE3,
+		0x7CCD113B, 0x0B55B328, 0x92FD541C, 0xE565F60F,
+		0xA0AC9B75, 0xD7343966, 0x4E9CDE52, 0x39047C41,
+		0xC40E05A6, 0xB396A7B5, 0x2A3E4081, 0x5DA6E292,
+		0x186F8FE8, 0x6FF72DFB, 0xF65FCACF, 0x81C768DC,
+		0xFFDF5F7B, 0x8847FD68, 0x11EF1A5C, 0x6677B84F,
+		0x23BED535, 0x54267726, 0xCD8E9012, 0xBA163201,
+		0x471C4BE6, 0x3084E9F5, 0xA92C0EC1, 0xDEB4ACD2,
+		0x9B7DC1A8, 0xECE563BB, 0x754D848F, 0x02D5269C,
+		0x7E2E9A44, 0x09B63857, 0x901EDF63, 0xE7867D70,
+		0xA24F100A, 0xD5D7B219, 0x4C7F552D, 0x3BE7F73E,
+		0xC6ED8ED9, 0xB1752CCA, 0x28DDCBFE, 0x5F4569ED,
+		0x1A8C0497, 0x6D14A684, 0xF4BC41B0, 0x8324E3A3,
+	},
+	{
+		0x00000000, 0x7E9241A5, 0x0D526F4F, 0x73C02EEA,
+		0x1AA4DE9E, 0x64369F3B, 0x17F6B1D1, 0x6964F074,
+		0xC53E5138, 0xBBAC109D, 0xC86C3E77, 0xB6FE7FD2,
+		0xDF9A8FA6, 0xA108CE03, 0xD2C8E0E9, 0xAC5AA14C,
+		0x8A7DA270, 0xF4EFE3D5, 0x872FCD3F, 0xF9BD8C9A,
+		0x90D97CEE, 0xEE4B3D4B, 0x9D8B13A1, 0xE3195204,
+		0x4F43F348, 0x31D1B2ED, 0x42119C07, 0x3C83DDA2,
+		0x55E72DD6, 0x2B756C73, 0x58B54299, 0x2627033C,
+		0x14FB44E1, 0x6A690544, 0x19A92BAE, 0x673B6A0B,
+		0x0E5F9A7F, 0x70CDDBDA, 0x030DF530, 0x7D9FB495,
+		0xD1C515D9, 0xAF57547C, 0xDC977A96, 0xA2053B33,
+		0xCB61CB47, 0xB5F38AE2, 0xC633A408, 0xB8A1E5AD,
+		0x9E86E691, 0xE014A734, 0x93D489DE, 0xED46C87B,
+		0x8422380F, 0xFAB079AA, 0x89705740, 0xF7E216E5,
+		0x5BB8B7A9, 0x252AF60C, 0x56EAD8E6, 0x28789943,
+		0x411C6937, 0x3F8E2892, 0x4C4E0678, 0x32DC47DD,
+		0xD98065C7, 0xA7122462, 0xD4D20A88, 0xAA404B2D,
+		0xC324BB59, 0xBDB6FAFC, 0xCE76D416, 0xB0E495B3,
+		0x1CBE34FF, 0x622C755A, 0x11EC5BB0, 0x6F7E1A15,
+		0x061AEA61, 0x7888ABC4, 0x0B48852E, 0x75DAC48B,
+		0x53FDC7B7, 0x2D6F8612, 0x5EAFA8F8, 0x203DE95D,
+		0x49591929, 0x37CB588C, 0x440B7666, 0x3A9937C3,
+		0x96C3968F, 0xE851D72A, 0x9B91F9C0, 0xE503B865,
+		0x8C674811, 0xF2F509B4, 0x8135275E, 0xFFA766FB,
+		0xCD7B2126, 0xB3E96083, 0xC0294E69, 0xBEBB0FCC,
+		0xD7DFFFB8, 0xA94DBE1D, 0xDA8D90F7, 0xA41FD152,
+		0x0845701E, 0x76D731BB, 0x05171F51, 0x7B855EF4,
+		0x12E1AE80, 0x6C73EF25, 0x1FB3C1CF, 0x6121806A,
+		0x47068356, 0x3994C2F3, 0x4A54EC19, 0x34C6ADBC,
+		0x5DA25DC8, 0x23301C6D, 0x50F03287, 0x2E627322,
+		0x8238D26E, 0xFCAA93CB, 0x8F6ABD21, 0xF1F8FC84,
+		0x989C0CF0, 0xE60E4D55, 0x95CE63BF, 0xEB5C221A,
+		0x4377278B, 0x3DE5662E, 0x4E2548C4, 0x30B70961,
+		0x59D3F915, 0x2741B8B0, 0x5481965A, 0x2A13D7FF,
+		0x864976B3, 0xF8DB3716, 0x8B1B19FC, 0xF5895859,
+		0x9CEDA82D, 0xE27FE988, 0x91BFC762, 0xEF2D86C7,
+		0xC90A85FB, 0xB798C45E, 0xC458EAB4, 0xBACAAB11,
+		0xD3AE5B65, 0xAD3C1AC0, 0xDEFC342A, 0xA06E758F,
+		0x0C34D4C3, 0x72A69566, 0x0166BB8C, 0x7FF4FA29,
+		0x16900A5D, 0x68024BF8, 0x1BC26512, 0x655024B7,
+		0x578C636A, 0x291E22CF, 0x5ADE0C25, 0x244C4D80,
+		0x4D28BDF4, 0x33BAFC51, 0x407AD2BB, 0x3EE8931E,
+		0x92B23252, 0xEC2073F7, 0x9FE05D1D, 0xE1721CB8,
+		0x8816ECCC, 0xF684AD69, 0x85448383, 0xFBD6C226,
+		0xDDF1C11A, 0xA36380BF, 0xD0A3AE55, 0xAE31EFF0,
+		0xC7551F84, 0xB9C75E21, 0xCA0770CB, 0xB495316E,
+		0x18CF9022, 0x665DD187, 0x159DFF6D, 0x6B0FBEC8,
+		0x026B4EBC, 0x7CF90F19, 0x0F3921F3, 0x71AB6056,
+		0x9AF7424C, 0xE46503E9, 0x97A52D03, 0xE9376CA6,
+		0x80539CD2, 0xFEC1DD77, 0x8D01F39D, 0xF393B238,
+		0x5FC91374, 0x215B52D1, 0x529B7C3B, 0x2C093D9E,
+		0x456DCDEA, 0x3BFF8C4F, 0x483FA2A5, 0x36ADE300,
+		0x108AE03C, 0x6E18A199, 0x1DD88F73, 0x634ACED6,
+		0x0A2E3EA2, 0x74BC7F07, 0x077C51ED, 0x79EE1048,
+		0xD5B4B104, 0xAB26F0A1, 0xD8E6DE4B, 0xA6749FEE,
+		0xCF106F9A, 0xB1822E3F, 0xC24200D5, 0xBCD04170,
+		0x8E0C06AD, 0xF09E4708, 0x835E69E2, 0xFDCC2847,
+		0x94A8D833, 0xEA3A9996, 0x99FAB77C, 0xE768F6D9,
+		0x4B325795, 0x35A01630, 0x466038DA, 0x38F2797F,
+		0x5196890B, 0x2F04C8AE, 0x5CC4E644, 0x2256A7E1,
+		0x0471A4DD, 0x7AE3E578, 0x0923CB92, 0x77B18A37,
+		0x1ED57A43, 0x60473BE6, 0x1387150C, 0x6D1554A9,
+		0xC14FF5E5, 0xBFDDB440, 0xCC1D9AAA, 0xB28FDB0F,
+		0xDBEB2B7B, 0xA5796ADE, 0xD6B94434, 0xA82B0591,
+	},
+	{
+		0x00000000, 0xB8AA45DD, 0x812367BF, 0x39892262,
+		0xF331227B, 0x4B9B67A6, 0x721245C4, 0xCAB80019,
+		0xE66344F6, 0x5EC9012B, 0x67402349, 0xDFEA6694,
+		0x1552668D, 0xADF82350, 0x94710132, 0x2CDB44EF,
+		0x3DB164E9, 0x851B2134, 0xBC920356, 0x0438468B,
+		0xCE804692, 0x762A034F, 0x4FA3212D, 0xF70964F0,
+		0xDBD2201F, 0x637865C2, 0x5AF147A0, 0xE25B027D,
+		0x28E30264, 0x904947B9, 0xA9C065DB, 0x116A2006,
+		0x8B1425D7, 0x33BE600A, 0x0A374268, 0xB29D07B5,
+		0x782507AC, 0xC08F4271, 0xF9066013, 0x41AC25CE,
+		0x6D776121, 0xD5DD24FC, 0xEC54069E, 0x54FE4343,
+		0x9E46435A, 0x26EC0687, 0x1F6524E5, 0xA7CF6138,
+		0xB6A5413E, 0x0E0F04E3, 0x37862681, 0x8F2C635C,
+		0x45946345, 0xFD3E2698, 0xC4B704FA, 0x7C1D4127,
+		0x50C605C8, 0xE86C4015, 0xD1E56277, 0x694F27AA,
+		0xA3F727B3, 0x1B5D626E, 0x22D4400C, 0x9A7E05D1,
+		0xE75FA6AB, 0x5FF5E376, 0x667CC114, 0xDED684C9,
+		0x146E84D0, 0xACC4C10D, 0x954DE36F, 0x2DE7A6B2,
+		0x013CE25D, 0xB996A780, 0x801F85E2, 0x38B5C03F,
+		0xF20DC026, 0x4AA785FB, 0x732EA799, 0xCB84E244,
+		0xDAEEC242, 0x6244879F, 0x5BCDA5FD, 0xE367E020,
+		0x29DFE039, 0x9175A5E4, 0xA8FC8786, 0x1056C25B,
+		0x3C8D86B4, 0x8427C369, 0xBDAEE10B, 0x0504A4D6,
+		0xCFBCA4CF, 0x7716E112, 0x4E9FC370, 0xF63586AD,
+		0x6C4B837C, 0xD4E1C6A1, 0xED68E4C3, 0x55C2A11E,
+		0x9F7AA107, 0x27D0E4DA, 0x1E59C6B8, 0xA6F38365,
+		0x8A28C78A, 0x32828257, 0x0B0BA035, 0xB3A1E5E8,
+		0x7919E5F1, 0xC1B3A02C, 0xF83A824E, 0x4090C793,
+		0x51FAE795, 0xE950A248, 0xD0D9802A, 0x6873C5F7,
+		0xA2CBC5EE, 0x1A618033, 0x23E8A251, 0x9B42E78C,
+		0xB799A363, 0x0F33E6BE, 0x36BAC4DC, 0x8E108101,
+		0x44A88118, 0xFC02C4C5, 0xC58BE6A7, 0x7D21A37A,
+		0x3FC9A052, 0x8763E58F, 0xBEEAC7ED, 0x06408230,
+		0xCCF88229, 0x7452C7F4, 0x4DDBE596, 0xF571A04B,
+		0xD9AAE4A4, 0x6100A179, 0x5889831B, 0xE023C6C6,
+		0x2A9BC6DF, 0x92318302, 0xABB8A160, 0x1312E4BD,
+		0x0278C4BB, 0xBAD28166, 0x835BA304, 0x3BF1E6D9,
+		0xF149E6C0, 0x49E3A31D, 0x706A817F, 0xC8C0C4A2,
+		0xE41B804D, 0x5CB1C590, 0x6538E7F2, 0xDD92A22F,
+		0x172AA236, 0xAF80E7EB, 0x9609C589, 0x2EA38054,
+		0xB4DD8585, 0x0C77C058, 0x35FEE23A, 0x8D54A7E7,
+		0x47ECA7FE, 0xFF46E223, 0xC6CFC041, 0x7E65859C,
+		0x52BEC173, 0xEA1484AE, 0xD39DA6CC, 0x6B37E311,
+		0xA18FE308, 0x1925A6D5, 0x20AC84B7, 0x9806C16A,
+		0x896CE16C, 0x31C6A4B1, 0x084F86D3, 0xB0E5C30E,
+		0x7A5DC317, 0xC2F786CA, 0xFB7EA4A8, 0x43D4E175,
+		0x6F0FA59A, 0xD7A5E047, 0xEE2CC225, 0x568687F8,
+		0x9C3E87E1, 0x2494C23C, 0x1D1DE05E, 0xA5B7A583,
+		0xD89606F9, 0x603C4324, 0x59B56146, 0xE11F249B,
+		0x2BA72482, 0x930D615F, 0xAA84433D, 0x122E06E0,
+		0x3EF5420F, 0x865F07D2, 0xBFD625B0, 0x077C606D,
+		0xCDC46074, 0x756E25A9, 0x4CE707CB, 0xF44D4216,
+		0xE5276210, 0x5D8D27CD, 0x640405AF, 0xDCAE4072,
+		0x1616406B, 0xAEBC05B6, 0x973527D4, 0x2F9F6209,
+		0x034426E6, 0xBBEE633B, 0x82674159, 0x3ACD0484,
+		0xF075049D, 0x48DF4140, 0x71566322, 0xC9FC26FF,
+		0x5382232E, 0xEB2866F3, 0xD2A14491, 0x6A0B014C,
+		0xA0B30155, 0x18194488, 0x219066EA, 0x993A2337,
+		0xB5E167D8, 0x0D4B2205, 0x34C20067, 0x8C6845BA,
+		0x46D045A3, 0xFE7A007E, 0xC7F3221C, 0x7F5967C1,
+		0x6E3347C7, 0xD699021A, 0xEF102078, 0x57BA65A5,
+		0x9D0265BC, 0x25A82061, 0x1C210203, 0xA48B47DE,
+		0x88500331, 0x30FA46EC, 0x0973648E, 0xB1D92153,
+		0x7B61214A, 0xC3CB6497, 0xFA4246F5, 0x42E80328,
+	},
+	{
+		0x00000000, 0xAC6F1138, 0x58DF2270, 0xF4B03348,
+		0xB0BE45E0, 0x1CD154D8, 0xE8616790, 0x440E76A8,
+		0x910B67C5, 0x3D6476FD, 0xC9D445B5, 0x65BB548D,
+		0x21B52225, 0x8DDA331D, 0x796A0055, 0xD505116D,
+		0xD361228F, 0x7F0E33B7, 0x8BBE00FF, 0x27D111C7,
+		0x63DF676F, 0xCFB07657, 0x3B00451F, 0x976F5427,
+		0x426A454A, 0xEE055472, 0x1AB5673A, 0xB6DA7602,
+		0xF2D400AA, 0x5EBB1192, 0xAA0B22DA, 0x066433E2,
+		0x57B5A81B, 0xFBDAB923, 0x0F6A8A6B, 0xA3059B53,
+		0xE70BEDFB, 0x4B64FCC3, 0xBFD4CF8B, 0x13BBDEB3,
+		0xC6BECFDE, 0x6AD1DEE6, 0x9E61EDAE, 0x320EFC96,
+		0x76008A3E, 0xDA6F9B06, 0x2EDFA84E, 0x82B0B976,
+		0x84D48A94, 0x28BB9BAC, 0xDC0BA8E4, 0x7064B9DC,
+		0x346ACF74, 0x9805DE4C, 0x6CB5ED04, 0xC0DAFC3C,
+		0x15DFED51, 0xB9B0FC69, 0x4D00CF21, 0xE16FDE19,
+		0xA561A8B1, 0x090EB989, 0xFDBE8AC1, 0x51D19BF9,
+		0xAE6A5137, 0x0205400F, 0xF6B57347, 0x5ADA627F,
+		0x1ED414D7, 0xB2BB05EF, 0x460B36A7, 0xEA64279F,
+		0x3F6136F2, 0x930E27CA, 0x67BE1482, 0xCBD105BA,
+		0x8FDF7312, 0x23B0622A, 0xD7005162, 0x7B6F405A,
+		0x7D0B73B8, 0xD1646280, 0x25D451C8, 0x89BB40F0,
+		0xCDB53658, 0x61DA2760, 0x956A1428, 0x39050510,
+		0xEC00147D, 0x406F0545, 0xB4DF360D, 0x18B02735,
+		0x5CBE519D, 0xF0D140A5, 0x046173ED, 0xA80E62D5,
+		0xF9DFF92C, 0x55B0E814, 0xA100DB5C, 0x0D6FCA64,
+		0x4961BCCC, 0xE50EADF4, 0x11BE9EBC, 0xBDD18F84,
+		0x68D49EE9, 0xC4BB8FD1, 0x300BBC99, 0x9C64ADA1,
+		0xD86ADB09, 0x7405CA31, 0x80B5F979, 0x2CDAE841,
+		0x2ABEDBA3, 0x86D1CA9B, 0x7261F9D3, 0xDE0EE8EB,
+		0x9A009E43, 0x366F8F7B, 0xC2DFBC33, 0x6EB0AD0B,
+		0xBBB5BC66, 0x17DAAD5E, 0xE36A9E16, 0x4F058F2E,
+		0x0B0BF986, 0xA764E8BE, 0x53D4DBF6, 0xFFBBCACE,
+		0x5CD5A26E, 0xF0BAB356, 0x040A801E, 0xA8659126,
+		0xEC6BE78E, 0x4004F6B6, 0xB4B4C5FE, 0x18DBD4C6,
+		0xCDDEC5AB, 0x61B1D493, 0x9501E7DB, 0x396EF6E3,
+		0x7D60804B, 0xD10F9173, 0x25BFA23B, 0x89D0B303,
+		0x8FB480E1, 0x23DB91D9, 0xD76BA291, 0x7B04B3A9,
+		0x3F0AC501, 0x9365D439, 0x67D5E771, 0xCBBAF649,
+		0x1EBFE724, 0xB2D0F61C, 0x4660C554, 0xEA0FD46C,
+		0xAE01A2C4, 0x026EB3FC, 0xF6DE80B4, 0x5AB1918C,
+		0x0B600A75, 0xA70F1B4D, 0x53BF2805, 0xFFD0393D,
+		0xBBDE4F95, 0x17B15EAD, 0xE3016DE5, 0x4F6E7CDD,
+		0x9A6B6DB0, 0x36047C88, 0xC2B44FC0, 0x6EDB5EF8,
+		0x2AD52850, 0x86BA3968, 0x720A0A20, 0xDE651B18,
+		0xD80128FA, 0x746E39C2, 0x80DE0A8A, 0x2CB11BB2,
+		0x68BF6D1A, 0xC4D07C22, 0x30604F6A, 0x9C0F5E52,
+		0x490A4F3F, 0xE5655E07, 0x11D56D4F, 0xBDBA7C77,
+		0xF9B40ADF, 0x55DB1BE7, 0xA16B28AF, 0x0D043997,
+		0xF2BFF359, 0x5ED0E261, 0xAA60D129, 0x060FC011,
+		0x4201B6B9, 0xEE6EA781, 0x1ADE94C9, 0xB6B185F1,
+		0x63B4949C, 0xCFDB85A4, 0x3B6BB6EC, 0x9704A7D4,
+		0xD30AD17C, 0x7F65C044, 0x8BD5F30C, 0x27BAE234,
+		0x21DED1D6, 0x8DB1C0EE, 0x7901F3A6, 0xD56EE29E,
+		0x91609436, 0x3D0F850E, 0xC9BFB646, 0x65D0A77E,
+		0xB0D5B613, 0x1CBAA72B, 0xE80A9463, 0x4465855B,
+		0x006BF3F3, 0xAC04E2CB, 0x58B4D183, 0xF4DBC0BB,
+		0xA50A5B42, 0x09654A7A, 0xFDD57932, 0x51BA680A,
+		0x15B41EA2, 0xB9DB0F9A, 0x4D6B3CD2, 0xE1042DEA,
+		0x34013C87, 0x986E2DBF, 0x6CDE1EF7, 0xC0B10FCF,
+		0x84BF7967, 0x28D0685F, 0xDC605B17, 0x700F4A2F,
+		0x766B79CD, 0xDA0468F5, 0x2EB45BBD, 0x82DB4A85,
+		0xC6D53C2D, 0x6ABA2D15, 0x9E0A1E5D, 0x32650F65,
+		0xE7601E08, 0x4B0F0F30, 0xBFBF3C78, 0x13D02D40,
+		0x57DE5BE8, 0xFBB14AD0, 0x0F017998, 0xA36E68A0,
+	},
+	{
+		0x00000000, 0x196B30EF, 0xC3A08CDB, 0xDACBBC34,
+		0x7737F5B2, 0x6E5CC55D, 0xB4977969, 0xADFC4986,
+		0x1F180660, 0x0673368F, 0xDCB88ABB, 0xC5D3BA54,
+		0x682FF3D2, 0x7144C33D, 0xAB8F7F09, 0xB2E44FE6,
+		0x3E300CC0, 0x275B3C2F, 0xFD90801B, 0xE4FBB0F4,
+		0x4907F972, 0x506CC99D, 0x8AA775A9, 0x93CC4546,
+		0x21280AA0, 0x38433A4F, 0xE288867B, 0xFBE3B694,
+		0x561FFF12, 0x4F74CFFD, 0x95BF73C9, 0x8CD44326,
+		0x8D16F485, 0x947DC46A, 0x4EB6785E, 0x57DD48B1,
+		0xFA210137, 0xE34A31D8, 0x39818DEC, 0x20EABD03,
+		0x920EF2E5, 0x8B65C20A, 0x51AE7E3E, 0x48C54ED1,
+		0xE5390757, 0xFC5237B8, 0x26998B8C, 0x3FF2BB63,
+		0xB326F845, 0xAA4DC8AA, 0x7086749E, 0x69ED4471,
+		0xC4110DF7, 0xDD7A3D18, 0x07B1812C, 0x1EDAB1C3,
+		0xAC3EFE25, 0xB555CECA, 0x6F9E72FE, 0x76F54211,
+		0xDB090B97, 0xC2623B78, 0x18A9874C, 0x01C2B7A3,
+		0xEB5B040E, 0xF23034E1, 0x28FB88D5, 0x3190B83A,
+		0x9C6CF1BC, 0x8507C153, 0x5FCC7D67, 0x46A74D88,
+		0xF443026E, 0xED283281, 0x37E38EB5, 0x2E88BE5A,
+		0x8374F7DC, 0x9A1FC733, 0x40D47B07, 0x59BF4BE8,
+		0xD56B08CE, 0xCC003821, 0x16CB8415, 0x0FA0B4FA,
+		0xA25CFD7C, 0xBB37CD93, 0x61FC71A7, 0x78974148,
+		0xCA730EAE, 0xD3183E41, 0x09D38275, 0x10B8B29A,
+		0xBD44FB1C, 0xA42FCBF3, 0x7EE477C7, 0x678F4728,
+		0x664DF08B, 0x7F26C064, 0xA5ED7C50, 0xBC864CBF,
+		0x117A0539, 0x081135D6, 0xD2DA89E2, 0xCBB1B90D,
+		0x7955F6EB, 0x603EC604, 0xBAF57A30, 0xA39E4ADF,
+		0x0E620359, 0x170933B6, 0xCDC28F82, 0xD4A9BF6D,
+		0x587DFC4B, 0x4116CCA4, 0x9BDD7090, 0x82B6407F,
+		0x2F4A09F9, 0x36213916, 0xECEA8522, 0xF581B5CD,
+		0x4765FA2B, 0x5E0ECAC4, 0x84C576F0, 0x9DAE461F,
+		0x30520F99, 0x29393F76, 0xF3F28342, 0xEA99B3AD,
+		0xD6B7081C, 0xCFDC38F3, 0x151784C7, 0x0C7CB428,
+		0xA180FDAE, 0xB8EBCD41, 0x62207175, 0x7B4B419A,
+		0xC9AF0E7C, 0xD0C43E93, 0x0A0F82A7, 0x1364B248,
+		0xBE98FBCE, 0xA7F3CB21, 0x7D387715, 0x645347FA,
+		0xE88704DC, 0xF1EC3433, 0x2B278807, 0x324CB8E8,
+		0x9FB0F16E, 0x86DBC181, 0x5C107DB5, 0x457B4D5A,
+		0xF79F02BC, 0xEEF43253, 0x343F8E67, 0x2D54BE88,
+		0x80A8F70E, 0x99C3C7E1, 0x43087BD5, 0x5A634B3A,
+		0x5BA1FC99, 0x42CACC76, 0x98017042, 0x816A40AD,
+		0x2C96092B, 0x35FD39C4, 0xEF3685F0, 0xF65DB51F,
+		0x44B9FAF9, 0x5DD2CA16, 0x87197622, 0x9E7246CD,
+		0x338E0F4B, 0x2AE53FA4, 0xF02E8390, 0xE945B37F,
+		0x6591F059, 0x7CFAC0B6, 0xA6317C82, 0xBF5A4C6D,
+		0x12A605EB, 0x0BCD3504, 0xD1068930, 0xC86DB9DF,
+		0x7A89F639, 0x63E2C6D6, 0xB9297AE2, 0xA0424A0D,
+		0x0DBE038B, 0x14D53364, 0xCE1E8F50, 0xD775BFBF,
+		0x3DEC0C12, 0x24873CFD, 0xFE4C80C9, 0xE727B026,
+		0x4ADBF9A0, 0x53B0C94F, 0x897B757B, 0x90104594,
+		0x22F40A72, 0x3B9F3A9D, 0xE15486A9, 0xF83FB646,
+		0x55C3FFC0, 0x4CA8CF2F, 0x9663731B, 0x8F0843F4,
+		0x03DC00D2, 0x1AB7303D, 0xC07C8C09, 0xD917BCE6,
+		0x74EBF560, 0x6D80C58F, 0xB74B79BB, 0xAE204954,
+		0x1CC406B2, 0x05AF365D, 0xDF648A69, 0xC60FBA86,
+		0x6BF3F300, 0x7298C3EF, 0xA8537FDB, 0xB1384F34,
+		0xB0FAF897, 0xA991C878, 0x735A744C, 0x6A3144A3,
+		0xC7CD0D25, 0xDEA63DCA, 0x046D81FE, 0x1D06B111,
+		0xAFE2FEF7, 0xB689CE18, 0x6C42722C, 0x752942C3,
+		0xD8D50B45, 0xC1BE3BAA, 0x1B75879E, 0x021EB771,
+		0x8ECAF457, 0x97A1C4B8, 0x4D6A788C, 0x54014863,
+		0xF9FD01E5, 0xE096310A, 0x3A5D8D3E, 0x2336BDD1,
+		0x91D2F237, 0x88B9C2D8, 0x52727EEC, 0x4B194E03,
+		0xE6E50785, 0xFF8E376A, 0x25458B5E, 0x3C2EBBB1,
+	},
+	{
+		0x00000000, 0xC82C0368, 0x905906D0, 0x587505B8,
+		0xD1C5E0A5, 0x19E9E3CD, 0x419CE675, 0x89B0E51D,
+		0x53FD2D4E, 0x9BD12E26, 0xC3A42B9E, 0x0B8828F6,
+		0x8238CDEB, 0x4A14CE83, 0x1261CB3B, 0xDA4DC853,
+		0xA6FA5B9C, 0x6ED658F4, 0x36A35D4C, 0xFE8F5E24,
+		0x773FBB39, 0xBF13B851, 0xE766BDE9, 0x2F4ABE81,
+		0xF50776D2, 0x3D2B75BA, 0x655E7002, 0xAD72736A,
+		0x24C29677, 0xECEE951F, 0xB49B90A7, 0x7CB793CF,
+		0xBD835B3D, 0x75AF5855, 0x2DDA5DED, 0xE5F65E85,
+		0x6C46BB98, 0xA46AB8F0, 0xFC1FBD48, 0x3433BE20,
+		0xEE7E7673, 0x2652751B, 0x7E2770A3, 0xB60B73CB,
+		0x3FBB96D6, 0xF79795BE, 0xAFE29006, 0x67CE936E,
+		0x1B7900A1, 0xD35503C9, 0x8B200671, 0x430C0519,
+		0xCABCE004, 0x0290E36C, 0x5AE5E6D4, 0x92C9E5BC,
+		0x48842DEF, 0x80A82E87, 0xD8DD2B3F, 0x10F12857,
+		0x9941CD4A, 0x516DCE22, 0x0918CB9A, 0xC134C8F2,
+		0x7A07B77A, 0xB22BB412, 0xEA5EB1AA, 0x2272B2C2,
+		0xABC257DF, 0x63EE54B7, 0x3B9B510F, 0xF3B75267,
+		0x29FA9A34, 0xE1D6995C, 0xB9A39CE4, 0x718F9F8C,
+		0xF83F7A91, 0x301379F9, 0x68667C41, 0xA04A7F29,
+		0xDCFDECE6, 0x14D1EF8E, 0x4CA4EA36, 0x8488E95E,
+		0x0D380C43, 0xC5140F2B, 0x9D610A93, 0x554D09FB,
+		0x8F00C1A8, 0x472CC2C0, 0x1F59C778, 0xD775C410,
+		0x5EC5210D, 0x96E92265, 0xCE9C27DD, 0x06B024B5,
+		0xC784EC47, 0x0FA8EF2F, 0x57DDEA97, 0x9FF1E9FF,
+		0x16410CE2, 0xDE6D0F8A, 0x86180A32, 0x4E34095A,
+		0x9479C109, 0x5C55C261, 0x0420C7D9, 0xCC0CC4B1,
+		0x45BC21AC, 0x8D9022C4, 0xD5E5277C, 0x1DC92414,
+		0x617EB7DB, 0xA952B4B3, 0xF127B10B, 0x390BB263,
+		0xB0BB577E, 0x78975416, 0x20E251AE, 0xE8CE52C6,
+		0x32839A95, 0xFAAF99FD, 0xA2DA9C45, 0x6AF69F2D,
+		0xE3467A30, 0x2B6A7958, 0x731F7CE0, 0xBB337F88,
+		0xF40E6EF5, 0x3C226D9D, 0x64576825, 0xAC7B6B4D,
+		0x25CB8E50, 0xEDE78D38, 0xB5928880, 0x7DBE8BE8,
+		0xA7F343BB, 0x6FDF40D3, 0x37AA456B, 0xFF864603,
+		0x7636A31E, 0xBE1AA076, 0xE66FA5CE, 0x2E43A6A6,
+		0x52F43569, 0x9AD83601, 0xC2AD33B9, 0x0A8130D1,
+		0x8331D5CC, 0x4B1DD6A4, 0x1368D31C, 0xDB44D074,
+		0x01091827, 0xC9251B4F, 0x91501EF7, 0x597C1D9F,
+		0xD0CCF882, 0x18E0FBEA, 0x4095FE52, 0x88B9FD3A,
+		0x498D35C8, 0x81A136A0, 0xD9D43318, 0x11F83070,
+		0x9848D56D, 0x5064D605, 0x0811D3BD, 0xC03DD0D5,
+		0x1A701886, 0xD25C1BEE, 0x8A291E56, 0x42051D3E,
+		0xCBB5F823, 0x0399FB4B, 0x5BECFEF3, 0x93C0FD9B,
+		0xEF776E54, 0x275B6D3C, 0x7F2E6884, 0xB7026BEC,
+		0x3EB28EF1, 0xF69E8D99, 0xAEEB8821, 0x66C78B49,
+		0xBC8A431A, 0x74A64072, 0x2CD345CA, 0xE4FF46A2,
+		0x6D4FA3BF, 0xA563A0D7, 0xFD16A56F, 0x353AA607,
+		0x8E09D98F, 0x4625DAE7, 0x1E50DF5F, 0xD67CDC37,
+		0x5FCC392A, 0x97E03A42, 0xCF953FFA, 0x07B93C92,
+		0xDDF4F4C1, 0x15D8F7A9, 0x4DADF211, 0x8581F179,
+		0x0C311464, 0xC41D170C, 0x9C6812B4, 0x544411DC,
+		0x28F38213, 0xE0DF817B, 0xB8AA84C3, 0x708687AB,
+		0xF93662B6, 0x311A61DE, 0x696F6466, 0xA143670E,
+		0x7B0EAF5D, 0xB322AC35, 0xEB57A98D, 0x237BAAE5,
+		0xAACB4FF8, 0x62E74C90, 0x3A924928, 0xF2BE4A40,
+		0x338A82B2, 0xFBA681DA, 0xA3D38462, 0x6BFF870A,
+		0xE24F6217, 0x2A63617F, 0x721664C7, 0xBA3A67AF,
+		0x6077AFFC, 0xA85BAC94, 0xF02EA92C, 0x3802AA44,
+		0xB1B24F59, 0x799E4C31, 0x21EB4989, 0xE9C74AE1,
+		0x9570D92E, 0x5D5CDA46, 0x0529DFFE, 0xCD05DC96,
+		0x44B5398B, 0x8C993AE3, 0xD4EC3F5B, 0x1CC03C33,
+		0xC68DF460, 0x0EA1F708, 0x56D4F2B0, 0x9EF8F1D8,
+		0x174814C5, 0xDF6417AD, 0x87111215, 0x4F3D117D,
+	},
+	{
+		0x00000000, 0x277D3C49, 0x4EFA7892, 0x698744DB,
+		0x6D821D21, 0x4AFF2168, 0x237865B3, 0x040559FA,
+		0xDA043B42, 0xFD79070B, 0x94FE43D0, 0xB3837F99,
+		0xB7862663, 0x90FB1A2A, 0xF97C5EF1, 0xDE0162B8,
+		0xB4097684, 0x93744ACD, 0xFAF30E16, 0xDD8E325F,
+		0xD98B6BA5, 0xFEF657EC, 0x97711337, 0xB00C2F7E,
+		0x6E0D4DC6, 0x4970718F, 0x20F73554, 0x078A091D,
+		0x038F50E7, 0x24F26CAE, 0x4D752875, 0x6A08143C,
+		0x9965000D, 0xBE183C44, 0xD79F789F, 0xF0E244D6,
+		0xF4E71D2C, 0xD39A2165, 0xBA1D65BE, 0x9D6059F7,
+		0x43613B4F, 0x641C0706, 0x0D9B43DD, 0x2AE67F94,
+		0x2EE3266E, 0x099E1A27, 0x60195EFC, 0x476462B5,
+		0x2D6C7689, 0x0A114AC0, 0x63960E1B, 0x44EB3252,
+		0x40EE6BA8, 0x679357E1, 0x0E14133A, 0x29692F73,
+		0xF7684DCB, 0xD0157182, 0xB9923559, 0x9EEF0910,
+		0x9AEA50EA, 0xBD976CA3, 0xD4102878, 0xF36D1431,
+		0x32CB001A, 0x15B63C53, 0x7C317888, 0x5B4C44C1,
+		0x5F491D3B, 0x78342172, 0x11B365A9, 0x36CE59E0,
+		0xE8CF3B58, 0xCFB20711, 0xA63543CA, 0x81487F83,
+		0x854D2679, 0xA2301A30, 0xCBB75EEB, 0xECCA62A2,
+		0x86C2769E, 0xA1BF4AD7, 0xC8380E0C, 0xEF453245,
+		0xEB406BBF, 0xCC3D57F6, 0xA5BA132D, 0x82C72F64,
+		0x5CC64DDC, 0x7BBB7195, 0x123C354E, 0x35410907,
+		0x314450FD, 0x16396CB4, 0x7FBE286F, 0x58C31426,
+		0xABAE0017, 0x8CD33C5E, 0xE5547885, 0xC22944CC,
+		0xC62C1D36, 0xE151217F, 0x88D665A4, 0xAFAB59ED,
+		0x71AA3B55, 0x56D7071C, 0x3F5043C7, 0x182D7F8E,
+		0x1C282674, 0x3B551A3D, 0x52D25EE6, 0x75AF62AF,
+		0x1FA77693, 0x38DA4ADA, 0x515D0E01, 0x76203248,
+		0x72256BB2, 0x555857FB, 0x3CDF1320, 0x1BA22F69,
+		0xC5A34DD1, 0xE2DE7198, 0x8B593543, 0xAC24090A,
+		0xA82150F0, 0x8F5C6CB9, 0xE6DB2862, 0xC1A6142B,
+		0x64960134, 0x43EB3D7D, 0x2A6C79A6, 0x0D1145EF,
+		0x09141C15, 0x2E69205C, 0x47EE6487, 0x609358CE,
+		0xBE923A76, 0x99EF063F, 0xF06842E4, 0xD7157EAD,
+		0xD3102757, 0xF46D1B1E, 0x9DEA5FC5, 0xBA97638C,
+		0xD09F77B0, 0xF7E24BF9, 0x9E650F22, 0xB918336B,
+		0xBD1D6A91, 0x9A6056D8, 0xF3E71203, 0xD49A2E4A,
+		0x0A9B4CF2, 0x2DE670BB, 0x44613460, 0x631C0829,
+		0x671951D3, 0x40646D9A, 0x29E32941, 0x0E9E1508,
+		0xFDF30139, 0xDA8E3D70, 0xB30979AB, 0x947445E2,
+		0x90711C18, 0xB70C2051, 0xDE8B648A, 0xF9F658C3,
+		0x27F73A7B, 0x008A0632, 0x690D42E9, 0x4E707EA0,
+		0x4A75275A, 0x6D081B13, 0x048F5FC8, 0x23F26381,
+		0x49FA77BD, 0x6E874BF4, 0x07000F2F, 0x207D3366,
+		0x24786A9C, 0x030556D5, 0x6A82120E, 0x4DFF2E47,
+		0x93FE4CFF, 0xB48370B6, 0xDD04346D, 0xFA790824,
+		0xFE7C51DE, 0xD9016D97, 0xB086294C, 0x97FB1505,
+		0x565D012E, 0x71203D67, 0x18A779BC, 0x3FDA45F5,
+		0x3BDF1C0F, 0x1CA22046, 0x7525649D, 0x525858D4,
+		0x8C593A6C, 0xAB240625, 0xC2A342FE, 0xE5DE7EB7,
+		0xE1DB274D, 0xC6A61B04, 0xAF215FDF, 0x885C6396,
+		0xE25477AA, 0xC5294BE3, 0xACAE0F38, 0x8BD33371,
+		0x8FD66A8B, 0xA8AB56C2, 0xC12C1219, 0xE6512E50,
+		0x38504CE8, 0x1F2D70A1, 0x76AA347A, 0x51D70833,
+		0x55D251C9, 0x72AF6D80, 0x1B28295B, 0x3C551512,
+		0xCF380123, 0xE8453D6A, 0x81C279B1, 0xA6BF45F8,
+		0xA2BA1C02, 0x85C7204B, 0xEC406490, 0xCB3D58D9,
+		0x153C3A61, 0x32410628, 0x5BC642F3, 0x7CBB7EBA,
+		0x78BE2740, 0x5FC31B09, 0x36445FD2, 0x1139639B,
+		0x7B3177A7, 0x5C4C4BEE, 0x35CB0F35, 0x12B6337C,
+		0x16B36A86, 0x31CE56CF, 0x58491214, 0x7F342E5D,
+		0xA1354CE5, 0x864870AC, 0xEFCF3477, 0xC8B2083E,
+		0xCCB751C4, 0xEBCA6D8D, 0x824D2956, 0xA530151F
+	}
+#endif
 };
 
 
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index b944be1..b1bdd1e 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -3,8 +3,7 @@
  * pg_crc.c
  *	  PostgreSQL CRC support
  *
- * This file simply #includes the CRC table definitions so that they are
- * available to programs linked with libpgport.
+ * This file contains implementations of the CRC32C computation.
  *
  * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
@@ -18,4 +17,106 @@
 
 #include "c.h"
 
+#include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
+
+#ifndef WORDS_BIGENDIAN
+#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+#else
+#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+
+uint32
+bswap32(uint32 x)
+{
+#if defined(HAVE__BUILTIN_BSWAP32)
+	return __builtin_bswap32(x);
+#else
+	return ((x << 24) & 0xff000000) |
+			((x << 8) & 0x00ff0000) |
+			((x >> 8) & 0x0000ff00) |
+			((x >> 24) & 0x000000ff);
+#endif
+}
+
+#endif
+
+/*
+ * This function computes a CRC using the slicing-by-8 algorithm, which
+ * uses an 8*256 lookup table to operate on eight bytes in parallel and
+ * recombine the results.
+ *
+ * Michael E. Kounavis, Frank L. Berry,
+ * "Novel Table Lookup-Based Algorithms for High-Performance CRC
+ * Generation", IEEE Transactions on Computers, vol.57, no. 11,
+ * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85
+ */
+
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint32 *p8;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that the loop
+	 * below starts with a pointer aligned to four bytes.
+	 */
+
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = CRC8(*p++);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint32 *) p;
+	while (len >= 8)
+	{
+		uint32		a = *p8++ ^ crc;
+		uint32		b = *p8++;
+
+#ifdef WORDS_BIGENDIAN
+		const uint8 c0 = b;
+		const uint8 c1 = b >> 8;
+		const uint8 c2 = b >> 16;
+		const uint8 c3 = b >> 24;
+		const uint8 c4 = a;
+		const uint8 c5 = a >> 8;
+		const uint8 c6 = a >> 16;
+		const uint8 c7 = a >> 24;
+#else
+		const uint8 c0 = b >> 24;
+		const uint8 c1 = b >> 16;
+		const uint8 c2 = b >> 8;
+		const uint8 c3 = b;
+		const uint8 c4 = a >> 24;
+		const uint8 c5 = a >> 16;
+		const uint8 c6 = a >> 8;
+		const uint8 c7 = a;
+#endif
+
+		crc =
+			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
+			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
+			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
+			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
+
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = CRC8(*p++);
+		len--;
+	}
+
+	return crc;
+}
-- 
1.9.1

0002-Use-the-SSE4.2-CRC-instructions-where-available.patchtext/x-diff; charset=us-asciiDownload
>From 5bb63d463c17b68b022d5375b3e3a4ac643e086c Mon Sep 17 00:00:00 2001
From: Abhijit Menon-Sen <ams@2ndQuadrant.com>
Date: Tue, 30 Dec 2014 12:55:53 +0530
Subject: Use the SSE4.2 CRC instructions where available

We execute cpuid at startup to determine if the processor supports
SSE4.2 instructions, and use the crc32* instructions instead of the
default slice-by-8 code (both produce identical results).

Reviewers: Andres Freund, Heikki Linnakangas

Author: Abhijit Menon-Sen
---
 configure                     |  2 +-
 configure.in                  |  2 +-
 src/backend/main/main.c       |  7 ++++
 src/include/pg_config.h.in    |  3 ++
 src/include/pg_config.h.win32 |  3 ++
 src/include/utils/pg_crc.h    |  3 +-
 src/port/pg_crc.c             | 97 ++++++++++++++++++++++++++++++++++++++++++-
 7 files changed, 112 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index 27092ec..f76cf4b 100755
--- a/configure
+++ b/configure
@@ -9195,7 +9195,7 @@ fi
 done
 
 
-for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.in b/configure.in
index 0206836..6005edc 100644
--- a/configure.in
+++ b/configure.in
@@ -1023,7 +1023,7 @@ AC_SUBST(UUID_LIBS)
 ##
 
 dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES
-AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.
diff --git a/src/backend/main/main.c b/src/backend/main/main.c
index 582198f..153a97d 100644
--- a/src/backend/main/main.c
+++ b/src/backend/main/main.c
@@ -37,6 +37,7 @@
 #include "utils/memutils.h"
 #include "utils/pg_locale.h"
 #include "utils/ps_status.h"
+#include "utils/pg_crc.h"
 
 
 const char *progname;
@@ -77,6 +78,12 @@ main(int argc, char *argv[])
 	argv = save_ps_display_args(argc, argv);
 
 	/*
+	 * Select the fastest available CRC32 implementation for the
+	 * platform.
+	 */
+	pg_choose_crc_impl();
+
+	/*
 	 * If supported on the current platform, set up a handler to be called if
 	 * the backend/postmaster crashes with a fatal signal or exception.
 	 */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 7962757..e12c4c9 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -99,6 +99,9 @@
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 18da922..e2a5e21 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the `class' function. */
 /* #undef HAVE_CLASS */
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+/* #undef HAVE_CPUID_H */
+
 /* Define to 1 if you have the `crypt' function. */
 /* #undef HAVE_CRYPT */
 
diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h
index 4d35601..e5d9668 100644
--- a/src/include/utils/pg_crc.h
+++ b/src/include/utils/pg_crc.h
@@ -42,7 +42,8 @@
 typedef uint32 pg_crc32;
 
 extern uint32 bswap32(uint32 x);
-extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+extern void pg_choose_crc_impl(void);
+extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);
 
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
diff --git a/src/port/pg_crc.c b/src/port/pg_crc.c
index b1bdd1e..e57945b 100644
--- a/src/port/pg_crc.c
+++ b/src/port/pg_crc.c
@@ -20,6 +20,13 @@
 #include "utils/pg_crc.h"
 #include "utils/pg_crc_tables.h"
 
+#if defined(HAVE_CPUID_H)
+#include <cpuid.h>
+#elif defined(_MSC_VER)
+#include <intrin.h>
+#include <nmmintrin.h>
+#endif
+
 #ifndef WORDS_BIGENDIAN
 #define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
 #else
@@ -51,8 +58,8 @@ bswap32(uint32 x)
  * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85
  */
 
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
 {
 	const unsigned char *p = data;
 	const uint32 *p8;
@@ -120,3 +127,89 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
 
 	return crc;
 }
+
+static inline pg_crc32
+pg_asm_crc32b(pg_crc32 crc, unsigned char data)
+{
+#if defined(__GNUC__) && defined(__x86_64__)
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
+	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u8(crc, data);
+#else
+	/* Can't generate crc32b, but keep the compiler quiet. */
+	return 0;
+#endif
+}
+
+static inline pg_crc32
+pg_asm_crc32q(uint64 crc, unsigned long long data)
+{
+#if defined(__GNUC__) && defined(__x86_64__)
+	__asm__ ("crc32q %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
+	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u64(crc, data);
+#else
+	/* Can't generate crc32q, but keep the compiler quiet. */
+	return 0;
+#endif
+}
+
+/*
+ * This function computes a CRC using the SSE4.2 CRC32B and CRC32Q
+ * instructions.
+ */
+
+static pg_crc32
+pg_comp_crc32c_sse(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = pg_asm_crc32q(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
+
+/*
+ * If (we can tell that) the CPU supports SSE4.2, we can use the CRC
+ * instructions, otherwise we fall back to slice-by-8 in software.
+ */
+
+void
+pg_choose_crc_impl(void)
+{
+	unsigned int exx[4] = {0, 0, 0, 0};
+
+#if defined(__GNUC__) && defined(HAVE_CPUID_H)
+	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+#elif defined(_MSC_VER)
+	__cpuid(exx, 1);
+#endif
+
+	if (exx[2] & (1 << 20))
+		pg_comp_crc32c = pg_comp_crc32c_sse;
+}
+
+pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_sb8;
-- 
1.9.1

#51Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#50)
Re: What exactly is our CRC algorithm?

On 01/09/2015 10:32 AM, Abhijit Menon-Sen wrote:

1. The slicing-by-8 patch contains numerous changes:

With this patch, CALC_CRC32C is no longer a pure macro, but includes a
function call. That means that you can no longer just #include pg_crc.h
and pg_crc_tables.h in an external program. We made that arrangement
with two header files in 2012 [1]/messages/by-id/CAAZKuFaNcf3=YtadkWwr8yHb+1axW2RepmQ2j8a9NNGkV7PN=w@mail.gmail.com., and added src/port/pg_crc.c which
just #includes pg_crc_tables.h, so that the backend and frontend
programs that use libpgport will have just one copy of the tables.

Now that there's some actual code in pg_crc.c, I think we have to just
give up on being able to get the CRC implementation without libpgport.
It was a nice thought, but I doubt there are any programs out there that
would have a problem with that. Anything that wants to read the WAL
needs xlogreader.c anyway.

But actually, we should now move pg_crc.c to src/common. It was a bit of
a hack to have it in src/port in the first place, because it has nothing
to do with portability, but src/common didn't exist back then. Now it does.

So I propose to move pg_crc.c to src/common, and move the tables from
pg_crc_tables.h directly to pg_crc.c. Thoughts?

[1]: /messages/by-id/CAAZKuFaNcf3=YtadkWwr8yHb+1axW2RepmQ2j8a9NNGkV7PN=w@mail.gmail.com.
/messages/by-id/CAAZKuFaNcf3=YtadkWwr8yHb+1axW2RepmQ2j8a9NNGkV7PN=w@mail.gmail.com.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#52Andres Freund
andres@2ndquadrant.com
In reply to: Heikki Linnakangas (#51)
Re: What exactly is our CRC algorithm?

On 2015-02-08 18:46:30 +0200, Heikki Linnakangas wrote:

So I propose to move pg_crc.c to src/common, and move the tables from
pg_crc_tables.h directly to pg_crc.c. Thoughts?

+1.

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#53Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#51)
Re: What exactly is our CRC algorithm?

At 2015-02-08 18:46:30 +0200, hlinnakangas@vmware.com wrote:

So I propose to move pg_crc.c to src/common, and move the tables
from pg_crc_tables.h directly to pg_crc.c. Thoughts?

Sounds fine to me.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#54Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#53)
1 attachment(s)
Re: What exactly is our CRC algorithm?

On 02/08/2015 08:33 PM, Abhijit Menon-Sen wrote:

At 2015-02-08 18:46:30 +0200, hlinnakangas@vmware.com wrote:

So I propose to move pg_crc.c to src/common, and move the tables
from pg_crc_tables.h directly to pg_crc.c. Thoughts?

Sounds fine to me.

Ok, I've committed a patch that just moves the existing code to
common/pg_crc.c. I also moved pg_crc.h from include/utils to
include/utils. That'll need any external programs to change their
#include accordingly, but I think it was worth that. include/common is
clearly the correct home for that file, and the only reason to keep it
in include/utils would've been for backwards-compatibility.

Attached is a rebased version of the slicing-by-8 patch. I've made some
cosmetic changes. Most notably, I turned the bswap32() function into a
macro. Better to avoid the overhead of a function call, and it also
avoids building the function altogether on little-endian systems that
don't need it.

I'll continue review this.

At 2015-01-02 16:46:29 +0200, hlinnakangas@vmware.com wrote:

Would it even make sense to keep the crc variable in different byte
order, and only do the byte-swap once in END_CRC32() ?

...this certainly does make a noticeable difference. Will investigate.

Do you have access to big-endian hardware to test this on? It seems like
an obvious optimization to shave off that one instruction from the hot
loop, but if it turns out not to make any measurable difference, I'd
prefer to keep the tables in the same order on big and little endian
systems, reducing the amount of #ifdefs needed.

I tested this on my laptop by adding a BSWAP32() into the hot loop -
which is bogus on a little endian Intel system - and it seems to make
about 5% difference in a quick micro-benchmark. But it would be nice to
get some numbers from the kind of big endian systems that people run in
the real world.

- Heikki

Attachments:

slice-by-8.patchapplication/x-patch; name=slice-by-8.patchDownload
diff --git a/config/c-compiler.m4 b/config/c-compiler.m4
index 90b56e7..509f961 100644
--- a/config/c-compiler.m4
+++ b/config/c-compiler.m4
@@ -193,6 +193,23 @@ fi])# PGAC_C_TYPES_COMPATIBLE
 
 
 
+# PGAC_C_BUILTIN_BSWAP32
+# -------------------------
+# Check if the C compiler understands __builtin_bswap32(),
+# and define HAVE__BUILTIN_BSWAP32 if so.
+AC_DEFUN([PGAC_C_BUILTIN_BSWAP32],
+[AC_CACHE_CHECK(for __builtin_bswap32, pgac_cv__builtin_bswap32,
+[AC_TRY_COMPILE([static unsigned long int x = __builtin_bswap32(0xaabbccdd);],
+[],
+[pgac_cv__builtin_bswap32=yes],
+[pgac_cv__builtin_bswap32=no])])
+if test x"$pgac_cv__builtin_bswap32" = xyes ; then
+AC_DEFINE(HAVE__BUILTIN_BSWAP32, 1,
+          [Define to 1 if your compiler understands __builtin_bswap32.])
+fi])# PGAC_C_BUILTIN_BSWAP32
+
+
+
 # PGAC_C_BUILTIN_CONSTANT_P
 # -------------------------
 # Check if the C compiler understands __builtin_constant_p(),
diff --git a/configure b/configure
index 8490eb7..fa271fe 100755
--- a/configure
+++ b/configure
@@ -10333,6 +10333,36 @@ if test x"$pgac_cv__types_compatible" = xyes ; then
 $as_echo "#define HAVE__BUILTIN_TYPES_COMPATIBLE_P 1" >>confdefs.h
 
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5
+$as_echo_n "checking for __builtin_bswap32... " >&6; }
+if ${pgac_cv__builtin_bswap32+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+static unsigned long int x = __builtin_bswap32(0xaabbccdd);
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  pgac_cv__builtin_bswap32=yes
+else
+  pgac_cv__builtin_bswap32=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__builtin_bswap32" >&5
+$as_echo "$pgac_cv__builtin_bswap32" >&6; }
+if test x"$pgac_cv__builtin_bswap32" = xyes ; then
+
+$as_echo "#define HAVE__BUILTIN_BSWAP32 1" >>confdefs.h
+
+fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_constant_p" >&5
 $as_echo_n "checking for __builtin_constant_p... " >&6; }
 if ${pgac_cv__builtin_constant_p+:} false; then :
diff --git a/configure.in b/configure.in
index b4bd09e..e6a49d1 100644
--- a/configure.in
+++ b/configure.in
@@ -1185,6 +1185,7 @@ PGAC_C_SIGNED
 PGAC_C_FUNCNAME_SUPPORT
 PGAC_C_STATIC_ASSERT
 PGAC_C_TYPES_COMPATIBLE
+PGAC_C_BUILTIN_BSWAP32
 PGAC_C_BUILTIN_CONSTANT_P
 PGAC_C_BUILTIN_UNREACHABLE
 PGAC_C_VA_ARGS
diff --git a/src/common/pg_crc.c b/src/common/pg_crc.c
index faf5a66..281707f 100644
--- a/src/common/pg_crc.c
+++ b/src/common/pg_crc.c
@@ -19,76 +19,1156 @@
 
 #include "c.h"
 
+#include "common/pg_crc.h"
+
+#ifdef WORDS_BIGENDIAN
+#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+#else
+#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+#endif
+
+/*
+ * This function computes a CRC using the slicing-by-8 algorithm, which
+ * uses an 8*256 lookup table to operate on eight bytes in parallel and
+ * recombine the results.
+ *
+ * Michael E. Kounavis, Frank L. Berry,
+ * "Novel Table Lookup-Based Algorithms for High-Performance CRC
+ * Generation", IEEE Transactions on Computers, vol.57, no. 11,
+ * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85
+ */
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint32 *p4;
+
+	/*
+	 * Handle initial bytes one at a time if necessary to ensure that the loop
+	 * below starts with a pointer aligned to four bytes.
+	 */
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = CRC8(*p++);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+	p4 = (const uint32 *) p;
+	while (len >= 8)
+	{
+		uint32		a = *p4++ ^ crc;
+		uint32		b = *p4++;
+
+#ifdef WORDS_BIGENDIAN
+		const uint8 c0 = b;
+		const uint8 c1 = b >> 8;
+		const uint8 c2 = b >> 16;
+		const uint8 c3 = b >> 24;
+		const uint8 c4 = a;
+		const uint8 c5 = a >> 8;
+		const uint8 c6 = a >> 16;
+		const uint8 c7 = a >> 24;
+#else
+		const uint8 c0 = b >> 24;
+		const uint8 c1 = b >> 16;
+		const uint8 c2 = b >> 8;
+		const uint8 c3 = b;
+		const uint8 c4 = a >> 24;
+		const uint8 c5 = a >> 16;
+		const uint8 c6 = a >> 8;
+		const uint8 c7 = a;
+#endif
+
+		crc =
+			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
+			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
+			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
+			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
+
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+	p = (const unsigned char *) p4;
+	while (len > 0)
+	{
+		crc = CRC8(*p++);
+		len--;
+	}
+
+	return crc;
+}
+
 /*
  * This table is based on the so-called Castagnoli polynomial (the same
- * that is used e.g. in iSCSI).  It is for normal, not "reflected", in
- * Williams' terms, CRC.
+ * that is used e.g. in iSCSI), 0x1EDC6F41. We define the normal table
+ * as well as a byte-reversed version for big-endian systems.
  */
-const uint32 pg_crc32c_table[256] = {
-	0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
-	0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
-	0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
-	0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
-	0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
-	0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
-	0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
-	0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
-	0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
-	0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
-	0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
-	0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
-	0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
-	0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
-	0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
-	0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
-	0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
-	0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
-	0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
-	0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
-	0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
-	0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
-	0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
-	0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
-	0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
-	0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
-	0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
-	0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
-	0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
-	0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
-	0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
-	0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
-	0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
-	0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
-	0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
-	0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
-	0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
-	0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
-	0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
-	0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
-	0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
-	0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
-	0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
-	0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
-	0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
-	0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
-	0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
-	0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
-	0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
-	0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
-	0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
-	0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
-	0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
-	0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
-	0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
-	0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
-	0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
-	0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
-	0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
-	0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
-	0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
-	0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
-	0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
-	0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+const uint32 pg_crc32c_table[8][256] = {
+#ifndef WORDS_BIGENDIAN
+	{
+		0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+		0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+		0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+		0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+		0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+		0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+		0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+		0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+		0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+		0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+		0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+		0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+		0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+		0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+		0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+		0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+		0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+		0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+		0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+		0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+		0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+		0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+		0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+		0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+		0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+		0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+		0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+		0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+		0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+		0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+		0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+		0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+		0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+		0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+		0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+		0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+		0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+		0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+		0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+		0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+		0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+		0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+		0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+		0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+		0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+		0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+		0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+		0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+		0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+		0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+		0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+		0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+		0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+		0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+		0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+		0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+		0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+		0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+		0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+		0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+		0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+		0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+		0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+		0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+	},
+	{
+		0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
+		0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
+		0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
+		0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
+		0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
+		0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
+		0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
+		0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
+		0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
+		0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
+		0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
+		0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
+		0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
+		0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
+		0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
+		0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
+		0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
+		0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
+		0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
+		0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
+		0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
+		0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
+		0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
+		0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
+		0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
+		0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
+		0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
+		0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
+		0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
+		0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
+		0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
+		0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
+		0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
+		0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
+		0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
+		0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
+		0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
+		0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
+		0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
+		0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
+		0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
+		0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
+		0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
+		0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
+		0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
+		0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
+		0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
+		0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
+		0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
+		0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
+		0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
+		0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
+		0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
+		0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
+		0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
+		0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
+		0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
+		0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
+		0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
+		0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
+		0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
+		0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
+		0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
+		0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483
+	},
+	{
+		0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
+		0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
+		0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
+		0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
+		0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
+		0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
+		0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
+		0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
+		0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
+		0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
+		0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
+		0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
+		0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
+		0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
+		0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
+		0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
+		0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
+		0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
+		0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
+		0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
+		0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
+		0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
+		0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
+		0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
+		0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
+		0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
+		0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
+		0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
+		0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
+		0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
+		0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
+		0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
+		0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
+		0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
+		0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
+		0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
+		0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
+		0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
+		0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
+		0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
+		0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
+		0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
+		0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
+		0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
+		0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
+		0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
+		0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
+		0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
+		0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
+		0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
+		0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
+		0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
+		0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
+		0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
+		0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
+		0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
+		0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
+		0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
+		0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
+		0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
+		0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
+		0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
+		0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
+		0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8
+	},
+	{
+		0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
+		0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
+		0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
+		0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
+		0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
+		0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
+		0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
+		0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
+		0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
+		0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
+		0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
+		0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
+		0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
+		0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
+		0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
+		0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
+		0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
+		0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
+		0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
+		0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
+		0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
+		0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
+		0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
+		0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
+		0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
+		0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
+		0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
+		0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
+		0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
+		0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
+		0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
+		0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
+		0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
+		0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
+		0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
+		0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
+		0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
+		0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
+		0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
+		0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
+		0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
+		0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
+		0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
+		0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
+		0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
+		0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
+		0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
+		0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
+		0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
+		0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
+		0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
+		0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
+		0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
+		0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
+		0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
+		0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
+		0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
+		0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
+		0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
+		0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
+		0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
+		0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
+		0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
+		0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842
+	},
+	{
+		0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
+		0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
+		0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
+		0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
+		0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
+		0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
+		0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
+		0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
+		0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
+		0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
+		0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
+		0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
+		0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
+		0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
+		0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
+		0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
+		0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
+		0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
+		0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
+		0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
+		0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
+		0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
+		0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
+		0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
+		0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
+		0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
+		0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
+		0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
+		0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
+		0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
+		0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
+		0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
+		0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
+		0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
+		0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
+		0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
+		0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
+		0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
+		0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
+		0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
+		0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
+		0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
+		0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
+		0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
+		0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
+		0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
+		0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
+		0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
+		0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
+		0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
+		0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
+		0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
+		0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
+		0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
+		0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
+		0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
+		0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
+		0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
+		0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
+		0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
+		0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
+		0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
+		0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
+		0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3
+	},
+	{
+		0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
+		0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
+		0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
+		0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
+		0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
+		0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
+		0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
+		0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
+		0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
+		0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
+		0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
+		0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
+		0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
+		0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
+		0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
+		0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
+		0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
+		0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
+		0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
+		0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
+		0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
+		0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
+		0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
+		0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
+		0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
+		0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
+		0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
+		0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
+		0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
+		0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
+		0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
+		0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
+		0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
+		0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
+		0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
+		0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
+		0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
+		0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
+		0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
+		0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
+		0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
+		0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
+		0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
+		0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
+		0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
+		0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
+		0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
+		0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
+		0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
+		0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
+		0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
+		0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
+		0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
+		0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
+		0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
+		0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
+		0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
+		0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
+		0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
+		0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
+		0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
+		0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
+		0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
+		0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C
+	},
+	{
+		0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
+		0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
+		0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
+		0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
+		0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
+		0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
+		0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
+		0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
+		0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
+		0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
+		0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
+		0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
+		0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
+		0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
+		0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
+		0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
+		0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
+		0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
+		0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
+		0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
+		0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
+		0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
+		0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
+		0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
+		0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
+		0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
+		0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
+		0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
+		0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
+		0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
+		0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
+		0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
+		0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
+		0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
+		0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
+		0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
+		0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
+		0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
+		0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
+		0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
+		0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
+		0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
+		0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
+		0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
+		0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
+		0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
+		0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
+		0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
+		0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
+		0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
+		0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
+		0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
+		0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
+		0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
+		0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
+		0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
+		0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
+		0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
+		0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
+		0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
+		0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
+		0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
+		0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
+		0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F
+	},
+	{
+		0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
+		0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
+		0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
+		0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
+		0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
+		0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
+		0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
+		0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
+		0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
+		0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
+		0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
+		0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
+		0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
+		0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
+		0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
+		0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
+		0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
+		0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
+		0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
+		0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
+		0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
+		0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
+		0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
+		0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
+		0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
+		0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
+		0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
+		0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
+		0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
+		0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
+		0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
+		0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
+		0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
+		0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
+		0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
+		0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
+		0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
+		0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
+		0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
+		0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
+		0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
+		0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
+		0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
+		0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
+		0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
+		0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
+		0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
+		0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
+		0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
+		0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
+		0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
+		0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
+		0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
+		0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
+		0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
+		0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
+		0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
+		0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
+		0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
+		0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
+		0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
+		0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
+		0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
+		0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5
+	}
+#else
+	{
+		0x00000000, 0x03836BF2, 0xF7703BE1, 0xF4F35013,
+		0x1F979AC7, 0x1C14F135, 0xE8E7A126, 0xEB64CAD4,
+		0xCF58D98A, 0xCCDBB278, 0x3828E26B, 0x3BAB8999,
+		0xD0CF434D, 0xD34C28BF, 0x27BF78AC, 0x243C135E,
+		0x6FC75E10, 0x6C4435E2, 0x98B765F1, 0x9B340E03,
+		0x7050C4D7, 0x73D3AF25, 0x8720FF36, 0x84A394C4,
+		0xA09F879A, 0xA31CEC68, 0x57EFBC7B, 0x546CD789,
+		0xBF081D5D, 0xBC8B76AF, 0x487826BC, 0x4BFB4D4E,
+		0xDE8EBD20, 0xDD0DD6D2, 0x29FE86C1, 0x2A7DED33,
+		0xC11927E7, 0xC29A4C15, 0x36691C06, 0x35EA77F4,
+		0x11D664AA, 0x12550F58, 0xE6A65F4B, 0xE52534B9,
+		0x0E41FE6D, 0x0DC2959F, 0xF931C58C, 0xFAB2AE7E,
+		0xB149E330, 0xB2CA88C2, 0x4639D8D1, 0x45BAB323,
+		0xAEDE79F7, 0xAD5D1205, 0x59AE4216, 0x5A2D29E4,
+		0x7E113ABA, 0x7D925148, 0x8961015B, 0x8AE26AA9,
+		0x6186A07D, 0x6205CB8F, 0x96F69B9C, 0x9575F06E,
+		0xBC1D7B41, 0xBF9E10B3, 0x4B6D40A0, 0x48EE2B52,
+		0xA38AE186, 0xA0098A74, 0x54FADA67, 0x5779B195,
+		0x7345A2CB, 0x70C6C939, 0x8435992A, 0x87B6F2D8,
+		0x6CD2380C, 0x6F5153FE, 0x9BA203ED, 0x9821681F,
+		0xD3DA2551, 0xD0594EA3, 0x24AA1EB0, 0x27297542,
+		0xCC4DBF96, 0xCFCED464, 0x3B3D8477, 0x38BEEF85,
+		0x1C82FCDB, 0x1F019729, 0xEBF2C73A, 0xE871ACC8,
+		0x0315661C, 0x00960DEE, 0xF4655DFD, 0xF7E6360F,
+		0x6293C661, 0x6110AD93, 0x95E3FD80, 0x96609672,
+		0x7D045CA6, 0x7E873754, 0x8A746747, 0x89F70CB5,
+		0xADCB1FEB, 0xAE487419, 0x5ABB240A, 0x59384FF8,
+		0xB25C852C, 0xB1DFEEDE, 0x452CBECD, 0x46AFD53F,
+		0x0D549871, 0x0ED7F383, 0xFA24A390, 0xF9A7C862,
+		0x12C302B6, 0x11406944, 0xE5B33957, 0xE63052A5,
+		0xC20C41FB, 0xC18F2A09, 0x357C7A1A, 0x36FF11E8,
+		0xDD9BDB3C, 0xDE18B0CE, 0x2AEBE0DD, 0x29688B2F,
+		0x783BF682, 0x7BB89D70, 0x8F4BCD63, 0x8CC8A691,
+		0x67AC6C45, 0x642F07B7, 0x90DC57A4, 0x935F3C56,
+		0xB7632F08, 0xB4E044FA, 0x401314E9, 0x43907F1B,
+		0xA8F4B5CF, 0xAB77DE3D, 0x5F848E2E, 0x5C07E5DC,
+		0x17FCA892, 0x147FC360, 0xE08C9373, 0xE30FF881,
+		0x086B3255, 0x0BE859A7, 0xFF1B09B4, 0xFC986246,
+		0xD8A47118, 0xDB271AEA, 0x2FD44AF9, 0x2C57210B,
+		0xC733EBDF, 0xC4B0802D, 0x3043D03E, 0x33C0BBCC,
+		0xA6B54BA2, 0xA5362050, 0x51C57043, 0x52461BB1,
+		0xB922D165, 0xBAA1BA97, 0x4E52EA84, 0x4DD18176,
+		0x69ED9228, 0x6A6EF9DA, 0x9E9DA9C9, 0x9D1EC23B,
+		0x767A08EF, 0x75F9631D, 0x810A330E, 0x828958FC,
+		0xC97215B2, 0xCAF17E40, 0x3E022E53, 0x3D8145A1,
+		0xD6E58F75, 0xD566E487, 0x2195B494, 0x2216DF66,
+		0x062ACC38, 0x05A9A7CA, 0xF15AF7D9, 0xF2D99C2B,
+		0x19BD56FF, 0x1A3E3D0D, 0xEECD6D1E, 0xED4E06EC,
+		0xC4268DC3, 0xC7A5E631, 0x3356B622, 0x30D5DDD0,
+		0xDBB11704, 0xD8327CF6, 0x2CC12CE5, 0x2F424717,
+		0x0B7E5449, 0x08FD3FBB, 0xFC0E6FA8, 0xFF8D045A,
+		0x14E9CE8E, 0x176AA57C, 0xE399F56F, 0xE01A9E9D,
+		0xABE1D3D3, 0xA862B821, 0x5C91E832, 0x5F1283C0,
+		0xB4764914, 0xB7F522E6, 0x430672F5, 0x40851907,
+		0x64B90A59, 0x673A61AB, 0x93C931B8, 0x904A5A4A,
+		0x7B2E909E, 0x78ADFB6C, 0x8C5EAB7F, 0x8FDDC08D,
+		0x1AA830E3, 0x192B5B11, 0xEDD80B02, 0xEE5B60F0,
+		0x053FAA24, 0x06BCC1D6, 0xF24F91C5, 0xF1CCFA37,
+		0xD5F0E969, 0xD673829B, 0x2280D288, 0x2103B97A,
+		0xCA6773AE, 0xC9E4185C, 0x3D17484F, 0x3E9423BD,
+		0x756F6EF3, 0x76EC0501, 0x821F5512, 0x819C3EE0,
+		0x6AF8F434, 0x697B9FC6, 0x9D88CFD5, 0x9E0BA427,
+		0xBA37B779, 0xB9B4DC8B, 0x4D478C98, 0x4EC4E76A,
+		0xA5A02DBE, 0xA623464C, 0x52D0165F, 0x51537DAD,
+	},
+	{
+		0x00000000, 0x7798A213, 0xEE304527, 0x99A8E734,
+		0xDC618A4E, 0xABF9285D, 0x3251CF69, 0x45C96D7A,
+		0xB8C3149D, 0xCF5BB68E, 0x56F351BA, 0x216BF3A9,
+		0x64A29ED3, 0x133A3CC0, 0x8A92DBF4, 0xFD0A79E7,
+		0x81F1C53F, 0xF669672C, 0x6FC18018, 0x1859220B,
+		0x5D904F71, 0x2A08ED62, 0xB3A00A56, 0xC438A845,
+		0x3932D1A2, 0x4EAA73B1, 0xD7029485, 0xA09A3696,
+		0xE5535BEC, 0x92CBF9FF, 0x0B631ECB, 0x7CFBBCD8,
+		0x02E38B7F, 0x757B296C, 0xECD3CE58, 0x9B4B6C4B,
+		0xDE820131, 0xA91AA322, 0x30B24416, 0x472AE605,
+		0xBA209FE2, 0xCDB83DF1, 0x5410DAC5, 0x238878D6,
+		0x664115AC, 0x11D9B7BF, 0x8871508B, 0xFFE9F298,
+		0x83124E40, 0xF48AEC53, 0x6D220B67, 0x1ABAA974,
+		0x5F73C40E, 0x28EB661D, 0xB1438129, 0xC6DB233A,
+		0x3BD15ADD, 0x4C49F8CE, 0xD5E11FFA, 0xA279BDE9,
+		0xE7B0D093, 0x90287280, 0x098095B4, 0x7E1837A7,
+		0x04C617FF, 0x735EB5EC, 0xEAF652D8, 0x9D6EF0CB,
+		0xD8A79DB1, 0xAF3F3FA2, 0x3697D896, 0x410F7A85,
+		0xBC050362, 0xCB9DA171, 0x52354645, 0x25ADE456,
+		0x6064892C, 0x17FC2B3F, 0x8E54CC0B, 0xF9CC6E18,
+		0x8537D2C0, 0xF2AF70D3, 0x6B0797E7, 0x1C9F35F4,
+		0x5956588E, 0x2ECEFA9D, 0xB7661DA9, 0xC0FEBFBA,
+		0x3DF4C65D, 0x4A6C644E, 0xD3C4837A, 0xA45C2169,
+		0xE1954C13, 0x960DEE00, 0x0FA50934, 0x783DAB27,
+		0x06259C80, 0x71BD3E93, 0xE815D9A7, 0x9F8D7BB4,
+		0xDA4416CE, 0xADDCB4DD, 0x347453E9, 0x43ECF1FA,
+		0xBEE6881D, 0xC97E2A0E, 0x50D6CD3A, 0x274E6F29,
+		0x62870253, 0x151FA040, 0x8CB74774, 0xFB2FE567,
+		0x87D459BF, 0xF04CFBAC, 0x69E41C98, 0x1E7CBE8B,
+		0x5BB5D3F1, 0x2C2D71E2, 0xB58596D6, 0xC21D34C5,
+		0x3F174D22, 0x488FEF31, 0xD1270805, 0xA6BFAA16,
+		0xE376C76C, 0x94EE657F, 0x0D46824B, 0x7ADE2058,
+		0xF9FAC3FB, 0x8E6261E8, 0x17CA86DC, 0x605224CF,
+		0x259B49B5, 0x5203EBA6, 0xCBAB0C92, 0xBC33AE81,
+		0x4139D766, 0x36A17575, 0xAF099241, 0xD8913052,
+		0x9D585D28, 0xEAC0FF3B, 0x7368180F, 0x04F0BA1C,
+		0x780B06C4, 0x0F93A4D7, 0x963B43E3, 0xE1A3E1F0,
+		0xA46A8C8A, 0xD3F22E99, 0x4A5AC9AD, 0x3DC26BBE,
+		0xC0C81259, 0xB750B04A, 0x2EF8577E, 0x5960F56D,
+		0x1CA99817, 0x6B313A04, 0xF299DD30, 0x85017F23,
+		0xFB194884, 0x8C81EA97, 0x15290DA3, 0x62B1AFB0,
+		0x2778C2CA, 0x50E060D9, 0xC94887ED, 0xBED025FE,
+		0x43DA5C19, 0x3442FE0A, 0xADEA193E, 0xDA72BB2D,
+		0x9FBBD657, 0xE8237444, 0x718B9370, 0x06133163,
+		0x7AE88DBB, 0x0D702FA8, 0x94D8C89C, 0xE3406A8F,
+		0xA68907F5, 0xD111A5E6, 0x48B942D2, 0x3F21E0C1,
+		0xC22B9926, 0xB5B33B35, 0x2C1BDC01, 0x5B837E12,
+		0x1E4A1368, 0x69D2B17B, 0xF07A564F, 0x87E2F45C,
+		0xFD3CD404, 0x8AA47617, 0x130C9123, 0x64943330,
+		0x215D5E4A, 0x56C5FC59, 0xCF6D1B6D, 0xB8F5B97E,
+		0x45FFC099, 0x3267628A, 0xABCF85BE, 0xDC5727AD,
+		0x999E4AD7, 0xEE06E8C4, 0x77AE0FF0, 0x0036ADE3,
+		0x7CCD113B, 0x0B55B328, 0x92FD541C, 0xE565F60F,
+		0xA0AC9B75, 0xD7343966, 0x4E9CDE52, 0x39047C41,
+		0xC40E05A6, 0xB396A7B5, 0x2A3E4081, 0x5DA6E292,
+		0x186F8FE8, 0x6FF72DFB, 0xF65FCACF, 0x81C768DC,
+		0xFFDF5F7B, 0x8847FD68, 0x11EF1A5C, 0x6677B84F,
+		0x23BED535, 0x54267726, 0xCD8E9012, 0xBA163201,
+		0x471C4BE6, 0x3084E9F5, 0xA92C0EC1, 0xDEB4ACD2,
+		0x9B7DC1A8, 0xECE563BB, 0x754D848F, 0x02D5269C,
+		0x7E2E9A44, 0x09B63857, 0x901EDF63, 0xE7867D70,
+		0xA24F100A, 0xD5D7B219, 0x4C7F552D, 0x3BE7F73E,
+		0xC6ED8ED9, 0xB1752CCA, 0x28DDCBFE, 0x5F4569ED,
+		0x1A8C0497, 0x6D14A684, 0xF4BC41B0, 0x8324E3A3,
+	},
+	{
+		0x00000000, 0x7E9241A5, 0x0D526F4F, 0x73C02EEA,
+		0x1AA4DE9E, 0x64369F3B, 0x17F6B1D1, 0x6964F074,
+		0xC53E5138, 0xBBAC109D, 0xC86C3E77, 0xB6FE7FD2,
+		0xDF9A8FA6, 0xA108CE03, 0xD2C8E0E9, 0xAC5AA14C,
+		0x8A7DA270, 0xF4EFE3D5, 0x872FCD3F, 0xF9BD8C9A,
+		0x90D97CEE, 0xEE4B3D4B, 0x9D8B13A1, 0xE3195204,
+		0x4F43F348, 0x31D1B2ED, 0x42119C07, 0x3C83DDA2,
+		0x55E72DD6, 0x2B756C73, 0x58B54299, 0x2627033C,
+		0x14FB44E1, 0x6A690544, 0x19A92BAE, 0x673B6A0B,
+		0x0E5F9A7F, 0x70CDDBDA, 0x030DF530, 0x7D9FB495,
+		0xD1C515D9, 0xAF57547C, 0xDC977A96, 0xA2053B33,
+		0xCB61CB47, 0xB5F38AE2, 0xC633A408, 0xB8A1E5AD,
+		0x9E86E691, 0xE014A734, 0x93D489DE, 0xED46C87B,
+		0x8422380F, 0xFAB079AA, 0x89705740, 0xF7E216E5,
+		0x5BB8B7A9, 0x252AF60C, 0x56EAD8E6, 0x28789943,
+		0x411C6937, 0x3F8E2892, 0x4C4E0678, 0x32DC47DD,
+		0xD98065C7, 0xA7122462, 0xD4D20A88, 0xAA404B2D,
+		0xC324BB59, 0xBDB6FAFC, 0xCE76D416, 0xB0E495B3,
+		0x1CBE34FF, 0x622C755A, 0x11EC5BB0, 0x6F7E1A15,
+		0x061AEA61, 0x7888ABC4, 0x0B48852E, 0x75DAC48B,
+		0x53FDC7B7, 0x2D6F8612, 0x5EAFA8F8, 0x203DE95D,
+		0x49591929, 0x37CB588C, 0x440B7666, 0x3A9937C3,
+		0x96C3968F, 0xE851D72A, 0x9B91F9C0, 0xE503B865,
+		0x8C674811, 0xF2F509B4, 0x8135275E, 0xFFA766FB,
+		0xCD7B2126, 0xB3E96083, 0xC0294E69, 0xBEBB0FCC,
+		0xD7DFFFB8, 0xA94DBE1D, 0xDA8D90F7, 0xA41FD152,
+		0x0845701E, 0x76D731BB, 0x05171F51, 0x7B855EF4,
+		0x12E1AE80, 0x6C73EF25, 0x1FB3C1CF, 0x6121806A,
+		0x47068356, 0x3994C2F3, 0x4A54EC19, 0x34C6ADBC,
+		0x5DA25DC8, 0x23301C6D, 0x50F03287, 0x2E627322,
+		0x8238D26E, 0xFCAA93CB, 0x8F6ABD21, 0xF1F8FC84,
+		0x989C0CF0, 0xE60E4D55, 0x95CE63BF, 0xEB5C221A,
+		0x4377278B, 0x3DE5662E, 0x4E2548C4, 0x30B70961,
+		0x59D3F915, 0x2741B8B0, 0x5481965A, 0x2A13D7FF,
+		0x864976B3, 0xF8DB3716, 0x8B1B19FC, 0xF5895859,
+		0x9CEDA82D, 0xE27FE988, 0x91BFC762, 0xEF2D86C7,
+		0xC90A85FB, 0xB798C45E, 0xC458EAB4, 0xBACAAB11,
+		0xD3AE5B65, 0xAD3C1AC0, 0xDEFC342A, 0xA06E758F,
+		0x0C34D4C3, 0x72A69566, 0x0166BB8C, 0x7FF4FA29,
+		0x16900A5D, 0x68024BF8, 0x1BC26512, 0x655024B7,
+		0x578C636A, 0x291E22CF, 0x5ADE0C25, 0x244C4D80,
+		0x4D28BDF4, 0x33BAFC51, 0x407AD2BB, 0x3EE8931E,
+		0x92B23252, 0xEC2073F7, 0x9FE05D1D, 0xE1721CB8,
+		0x8816ECCC, 0xF684AD69, 0x85448383, 0xFBD6C226,
+		0xDDF1C11A, 0xA36380BF, 0xD0A3AE55, 0xAE31EFF0,
+		0xC7551F84, 0xB9C75E21, 0xCA0770CB, 0xB495316E,
+		0x18CF9022, 0x665DD187, 0x159DFF6D, 0x6B0FBEC8,
+		0x026B4EBC, 0x7CF90F19, 0x0F3921F3, 0x71AB6056,
+		0x9AF7424C, 0xE46503E9, 0x97A52D03, 0xE9376CA6,
+		0x80539CD2, 0xFEC1DD77, 0x8D01F39D, 0xF393B238,
+		0x5FC91374, 0x215B52D1, 0x529B7C3B, 0x2C093D9E,
+		0x456DCDEA, 0x3BFF8C4F, 0x483FA2A5, 0x36ADE300,
+		0x108AE03C, 0x6E18A199, 0x1DD88F73, 0x634ACED6,
+		0x0A2E3EA2, 0x74BC7F07, 0x077C51ED, 0x79EE1048,
+		0xD5B4B104, 0xAB26F0A1, 0xD8E6DE4B, 0xA6749FEE,
+		0xCF106F9A, 0xB1822E3F, 0xC24200D5, 0xBCD04170,
+		0x8E0C06AD, 0xF09E4708, 0x835E69E2, 0xFDCC2847,
+		0x94A8D833, 0xEA3A9996, 0x99FAB77C, 0xE768F6D9,
+		0x4B325795, 0x35A01630, 0x466038DA, 0x38F2797F,
+		0x5196890B, 0x2F04C8AE, 0x5CC4E644, 0x2256A7E1,
+		0x0471A4DD, 0x7AE3E578, 0x0923CB92, 0x77B18A37,
+		0x1ED57A43, 0x60473BE6, 0x1387150C, 0x6D1554A9,
+		0xC14FF5E5, 0xBFDDB440, 0xCC1D9AAA, 0xB28FDB0F,
+		0xDBEB2B7B, 0xA5796ADE, 0xD6B94434, 0xA82B0591,
+	},
+	{
+		0x00000000, 0xB8AA45DD, 0x812367BF, 0x39892262,
+		0xF331227B, 0x4B9B67A6, 0x721245C4, 0xCAB80019,
+		0xE66344F6, 0x5EC9012B, 0x67402349, 0xDFEA6694,
+		0x1552668D, 0xADF82350, 0x94710132, 0x2CDB44EF,
+		0x3DB164E9, 0x851B2134, 0xBC920356, 0x0438468B,
+		0xCE804692, 0x762A034F, 0x4FA3212D, 0xF70964F0,
+		0xDBD2201F, 0x637865C2, 0x5AF147A0, 0xE25B027D,
+		0x28E30264, 0x904947B9, 0xA9C065DB, 0x116A2006,
+		0x8B1425D7, 0x33BE600A, 0x0A374268, 0xB29D07B5,
+		0x782507AC, 0xC08F4271, 0xF9066013, 0x41AC25CE,
+		0x6D776121, 0xD5DD24FC, 0xEC54069E, 0x54FE4343,
+		0x9E46435A, 0x26EC0687, 0x1F6524E5, 0xA7CF6138,
+		0xB6A5413E, 0x0E0F04E3, 0x37862681, 0x8F2C635C,
+		0x45946345, 0xFD3E2698, 0xC4B704FA, 0x7C1D4127,
+		0x50C605C8, 0xE86C4015, 0xD1E56277, 0x694F27AA,
+		0xA3F727B3, 0x1B5D626E, 0x22D4400C, 0x9A7E05D1,
+		0xE75FA6AB, 0x5FF5E376, 0x667CC114, 0xDED684C9,
+		0x146E84D0, 0xACC4C10D, 0x954DE36F, 0x2DE7A6B2,
+		0x013CE25D, 0xB996A780, 0x801F85E2, 0x38B5C03F,
+		0xF20DC026, 0x4AA785FB, 0x732EA799, 0xCB84E244,
+		0xDAEEC242, 0x6244879F, 0x5BCDA5FD, 0xE367E020,
+		0x29DFE039, 0x9175A5E4, 0xA8FC8786, 0x1056C25B,
+		0x3C8D86B4, 0x8427C369, 0xBDAEE10B, 0x0504A4D6,
+		0xCFBCA4CF, 0x7716E112, 0x4E9FC370, 0xF63586AD,
+		0x6C4B837C, 0xD4E1C6A1, 0xED68E4C3, 0x55C2A11E,
+		0x9F7AA107, 0x27D0E4DA, 0x1E59C6B8, 0xA6F38365,
+		0x8A28C78A, 0x32828257, 0x0B0BA035, 0xB3A1E5E8,
+		0x7919E5F1, 0xC1B3A02C, 0xF83A824E, 0x4090C793,
+		0x51FAE795, 0xE950A248, 0xD0D9802A, 0x6873C5F7,
+		0xA2CBC5EE, 0x1A618033, 0x23E8A251, 0x9B42E78C,
+		0xB799A363, 0x0F33E6BE, 0x36BAC4DC, 0x8E108101,
+		0x44A88118, 0xFC02C4C5, 0xC58BE6A7, 0x7D21A37A,
+		0x3FC9A052, 0x8763E58F, 0xBEEAC7ED, 0x06408230,
+		0xCCF88229, 0x7452C7F4, 0x4DDBE596, 0xF571A04B,
+		0xD9AAE4A4, 0x6100A179, 0x5889831B, 0xE023C6C6,
+		0x2A9BC6DF, 0x92318302, 0xABB8A160, 0x1312E4BD,
+		0x0278C4BB, 0xBAD28166, 0x835BA304, 0x3BF1E6D9,
+		0xF149E6C0, 0x49E3A31D, 0x706A817F, 0xC8C0C4A2,
+		0xE41B804D, 0x5CB1C590, 0x6538E7F2, 0xDD92A22F,
+		0x172AA236, 0xAF80E7EB, 0x9609C589, 0x2EA38054,
+		0xB4DD8585, 0x0C77C058, 0x35FEE23A, 0x8D54A7E7,
+		0x47ECA7FE, 0xFF46E223, 0xC6CFC041, 0x7E65859C,
+		0x52BEC173, 0xEA1484AE, 0xD39DA6CC, 0x6B37E311,
+		0xA18FE308, 0x1925A6D5, 0x20AC84B7, 0x9806C16A,
+		0x896CE16C, 0x31C6A4B1, 0x084F86D3, 0xB0E5C30E,
+		0x7A5DC317, 0xC2F786CA, 0xFB7EA4A8, 0x43D4E175,
+		0x6F0FA59A, 0xD7A5E047, 0xEE2CC225, 0x568687F8,
+		0x9C3E87E1, 0x2494C23C, 0x1D1DE05E, 0xA5B7A583,
+		0xD89606F9, 0x603C4324, 0x59B56146, 0xE11F249B,
+		0x2BA72482, 0x930D615F, 0xAA84433D, 0x122E06E0,
+		0x3EF5420F, 0x865F07D2, 0xBFD625B0, 0x077C606D,
+		0xCDC46074, 0x756E25A9, 0x4CE707CB, 0xF44D4216,
+		0xE5276210, 0x5D8D27CD, 0x640405AF, 0xDCAE4072,
+		0x1616406B, 0xAEBC05B6, 0x973527D4, 0x2F9F6209,
+		0x034426E6, 0xBBEE633B, 0x82674159, 0x3ACD0484,
+		0xF075049D, 0x48DF4140, 0x71566322, 0xC9FC26FF,
+		0x5382232E, 0xEB2866F3, 0xD2A14491, 0x6A0B014C,
+		0xA0B30155, 0x18194488, 0x219066EA, 0x993A2337,
+		0xB5E167D8, 0x0D4B2205, 0x34C20067, 0x8C6845BA,
+		0x46D045A3, 0xFE7A007E, 0xC7F3221C, 0x7F5967C1,
+		0x6E3347C7, 0xD699021A, 0xEF102078, 0x57BA65A5,
+		0x9D0265BC, 0x25A82061, 0x1C210203, 0xA48B47DE,
+		0x88500331, 0x30FA46EC, 0x0973648E, 0xB1D92153,
+		0x7B61214A, 0xC3CB6497, 0xFA4246F5, 0x42E80328,
+	},
+	{
+		0x00000000, 0xAC6F1138, 0x58DF2270, 0xF4B03348,
+		0xB0BE45E0, 0x1CD154D8, 0xE8616790, 0x440E76A8,
+		0x910B67C5, 0x3D6476FD, 0xC9D445B5, 0x65BB548D,
+		0x21B52225, 0x8DDA331D, 0x796A0055, 0xD505116D,
+		0xD361228F, 0x7F0E33B7, 0x8BBE00FF, 0x27D111C7,
+		0x63DF676F, 0xCFB07657, 0x3B00451F, 0x976F5427,
+		0x426A454A, 0xEE055472, 0x1AB5673A, 0xB6DA7602,
+		0xF2D400AA, 0x5EBB1192, 0xAA0B22DA, 0x066433E2,
+		0x57B5A81B, 0xFBDAB923, 0x0F6A8A6B, 0xA3059B53,
+		0xE70BEDFB, 0x4B64FCC3, 0xBFD4CF8B, 0x13BBDEB3,
+		0xC6BECFDE, 0x6AD1DEE6, 0x9E61EDAE, 0x320EFC96,
+		0x76008A3E, 0xDA6F9B06, 0x2EDFA84E, 0x82B0B976,
+		0x84D48A94, 0x28BB9BAC, 0xDC0BA8E4, 0x7064B9DC,
+		0x346ACF74, 0x9805DE4C, 0x6CB5ED04, 0xC0DAFC3C,
+		0x15DFED51, 0xB9B0FC69, 0x4D00CF21, 0xE16FDE19,
+		0xA561A8B1, 0x090EB989, 0xFDBE8AC1, 0x51D19BF9,
+		0xAE6A5137, 0x0205400F, 0xF6B57347, 0x5ADA627F,
+		0x1ED414D7, 0xB2BB05EF, 0x460B36A7, 0xEA64279F,
+		0x3F6136F2, 0x930E27CA, 0x67BE1482, 0xCBD105BA,
+		0x8FDF7312, 0x23B0622A, 0xD7005162, 0x7B6F405A,
+		0x7D0B73B8, 0xD1646280, 0x25D451C8, 0x89BB40F0,
+		0xCDB53658, 0x61DA2760, 0x956A1428, 0x39050510,
+		0xEC00147D, 0x406F0545, 0xB4DF360D, 0x18B02735,
+		0x5CBE519D, 0xF0D140A5, 0x046173ED, 0xA80E62D5,
+		0xF9DFF92C, 0x55B0E814, 0xA100DB5C, 0x0D6FCA64,
+		0x4961BCCC, 0xE50EADF4, 0x11BE9EBC, 0xBDD18F84,
+		0x68D49EE9, 0xC4BB8FD1, 0x300BBC99, 0x9C64ADA1,
+		0xD86ADB09, 0x7405CA31, 0x80B5F979, 0x2CDAE841,
+		0x2ABEDBA3, 0x86D1CA9B, 0x7261F9D3, 0xDE0EE8EB,
+		0x9A009E43, 0x366F8F7B, 0xC2DFBC33, 0x6EB0AD0B,
+		0xBBB5BC66, 0x17DAAD5E, 0xE36A9E16, 0x4F058F2E,
+		0x0B0BF986, 0xA764E8BE, 0x53D4DBF6, 0xFFBBCACE,
+		0x5CD5A26E, 0xF0BAB356, 0x040A801E, 0xA8659126,
+		0xEC6BE78E, 0x4004F6B6, 0xB4B4C5FE, 0x18DBD4C6,
+		0xCDDEC5AB, 0x61B1D493, 0x9501E7DB, 0x396EF6E3,
+		0x7D60804B, 0xD10F9173, 0x25BFA23B, 0x89D0B303,
+		0x8FB480E1, 0x23DB91D9, 0xD76BA291, 0x7B04B3A9,
+		0x3F0AC501, 0x9365D439, 0x67D5E771, 0xCBBAF649,
+		0x1EBFE724, 0xB2D0F61C, 0x4660C554, 0xEA0FD46C,
+		0xAE01A2C4, 0x026EB3FC, 0xF6DE80B4, 0x5AB1918C,
+		0x0B600A75, 0xA70F1B4D, 0x53BF2805, 0xFFD0393D,
+		0xBBDE4F95, 0x17B15EAD, 0xE3016DE5, 0x4F6E7CDD,
+		0x9A6B6DB0, 0x36047C88, 0xC2B44FC0, 0x6EDB5EF8,
+		0x2AD52850, 0x86BA3968, 0x720A0A20, 0xDE651B18,
+		0xD80128FA, 0x746E39C2, 0x80DE0A8A, 0x2CB11BB2,
+		0x68BF6D1A, 0xC4D07C22, 0x30604F6A, 0x9C0F5E52,
+		0x490A4F3F, 0xE5655E07, 0x11D56D4F, 0xBDBA7C77,
+		0xF9B40ADF, 0x55DB1BE7, 0xA16B28AF, 0x0D043997,
+		0xF2BFF359, 0x5ED0E261, 0xAA60D129, 0x060FC011,
+		0x4201B6B9, 0xEE6EA781, 0x1ADE94C9, 0xB6B185F1,
+		0x63B4949C, 0xCFDB85A4, 0x3B6BB6EC, 0x9704A7D4,
+		0xD30AD17C, 0x7F65C044, 0x8BD5F30C, 0x27BAE234,
+		0x21DED1D6, 0x8DB1C0EE, 0x7901F3A6, 0xD56EE29E,
+		0x91609436, 0x3D0F850E, 0xC9BFB646, 0x65D0A77E,
+		0xB0D5B613, 0x1CBAA72B, 0xE80A9463, 0x4465855B,
+		0x006BF3F3, 0xAC04E2CB, 0x58B4D183, 0xF4DBC0BB,
+		0xA50A5B42, 0x09654A7A, 0xFDD57932, 0x51BA680A,
+		0x15B41EA2, 0xB9DB0F9A, 0x4D6B3CD2, 0xE1042DEA,
+		0x34013C87, 0x986E2DBF, 0x6CDE1EF7, 0xC0B10FCF,
+		0x84BF7967, 0x28D0685F, 0xDC605B17, 0x700F4A2F,
+		0x766B79CD, 0xDA0468F5, 0x2EB45BBD, 0x82DB4A85,
+		0xC6D53C2D, 0x6ABA2D15, 0x9E0A1E5D, 0x32650F65,
+		0xE7601E08, 0x4B0F0F30, 0xBFBF3C78, 0x13D02D40,
+		0x57DE5BE8, 0xFBB14AD0, 0x0F017998, 0xA36E68A0,
+	},
+	{
+		0x00000000, 0x196B30EF, 0xC3A08CDB, 0xDACBBC34,
+		0x7737F5B2, 0x6E5CC55D, 0xB4977969, 0xADFC4986,
+		0x1F180660, 0x0673368F, 0xDCB88ABB, 0xC5D3BA54,
+		0x682FF3D2, 0x7144C33D, 0xAB8F7F09, 0xB2E44FE6,
+		0x3E300CC0, 0x275B3C2F, 0xFD90801B, 0xE4FBB0F4,
+		0x4907F972, 0x506CC99D, 0x8AA775A9, 0x93CC4546,
+		0x21280AA0, 0x38433A4F, 0xE288867B, 0xFBE3B694,
+		0x561FFF12, 0x4F74CFFD, 0x95BF73C9, 0x8CD44326,
+		0x8D16F485, 0x947DC46A, 0x4EB6785E, 0x57DD48B1,
+		0xFA210137, 0xE34A31D8, 0x39818DEC, 0x20EABD03,
+		0x920EF2E5, 0x8B65C20A, 0x51AE7E3E, 0x48C54ED1,
+		0xE5390757, 0xFC5237B8, 0x26998B8C, 0x3FF2BB63,
+		0xB326F845, 0xAA4DC8AA, 0x7086749E, 0x69ED4471,
+		0xC4110DF7, 0xDD7A3D18, 0x07B1812C, 0x1EDAB1C3,
+		0xAC3EFE25, 0xB555CECA, 0x6F9E72FE, 0x76F54211,
+		0xDB090B97, 0xC2623B78, 0x18A9874C, 0x01C2B7A3,
+		0xEB5B040E, 0xF23034E1, 0x28FB88D5, 0x3190B83A,
+		0x9C6CF1BC, 0x8507C153, 0x5FCC7D67, 0x46A74D88,
+		0xF443026E, 0xED283281, 0x37E38EB5, 0x2E88BE5A,
+		0x8374F7DC, 0x9A1FC733, 0x40D47B07, 0x59BF4BE8,
+		0xD56B08CE, 0xCC003821, 0x16CB8415, 0x0FA0B4FA,
+		0xA25CFD7C, 0xBB37CD93, 0x61FC71A7, 0x78974148,
+		0xCA730EAE, 0xD3183E41, 0x09D38275, 0x10B8B29A,
+		0xBD44FB1C, 0xA42FCBF3, 0x7EE477C7, 0x678F4728,
+		0x664DF08B, 0x7F26C064, 0xA5ED7C50, 0xBC864CBF,
+		0x117A0539, 0x081135D6, 0xD2DA89E2, 0xCBB1B90D,
+		0x7955F6EB, 0x603EC604, 0xBAF57A30, 0xA39E4ADF,
+		0x0E620359, 0x170933B6, 0xCDC28F82, 0xD4A9BF6D,
+		0x587DFC4B, 0x4116CCA4, 0x9BDD7090, 0x82B6407F,
+		0x2F4A09F9, 0x36213916, 0xECEA8522, 0xF581B5CD,
+		0x4765FA2B, 0x5E0ECAC4, 0x84C576F0, 0x9DAE461F,
+		0x30520F99, 0x29393F76, 0xF3F28342, 0xEA99B3AD,
+		0xD6B7081C, 0xCFDC38F3, 0x151784C7, 0x0C7CB428,
+		0xA180FDAE, 0xB8EBCD41, 0x62207175, 0x7B4B419A,
+		0xC9AF0E7C, 0xD0C43E93, 0x0A0F82A7, 0x1364B248,
+		0xBE98FBCE, 0xA7F3CB21, 0x7D387715, 0x645347FA,
+		0xE88704DC, 0xF1EC3433, 0x2B278807, 0x324CB8E8,
+		0x9FB0F16E, 0x86DBC181, 0x5C107DB5, 0x457B4D5A,
+		0xF79F02BC, 0xEEF43253, 0x343F8E67, 0x2D54BE88,
+		0x80A8F70E, 0x99C3C7E1, 0x43087BD5, 0x5A634B3A,
+		0x5BA1FC99, 0x42CACC76, 0x98017042, 0x816A40AD,
+		0x2C96092B, 0x35FD39C4, 0xEF3685F0, 0xF65DB51F,
+		0x44B9FAF9, 0x5DD2CA16, 0x87197622, 0x9E7246CD,
+		0x338E0F4B, 0x2AE53FA4, 0xF02E8390, 0xE945B37F,
+		0x6591F059, 0x7CFAC0B6, 0xA6317C82, 0xBF5A4C6D,
+		0x12A605EB, 0x0BCD3504, 0xD1068930, 0xC86DB9DF,
+		0x7A89F639, 0x63E2C6D6, 0xB9297AE2, 0xA0424A0D,
+		0x0DBE038B, 0x14D53364, 0xCE1E8F50, 0xD775BFBF,
+		0x3DEC0C12, 0x24873CFD, 0xFE4C80C9, 0xE727B026,
+		0x4ADBF9A0, 0x53B0C94F, 0x897B757B, 0x90104594,
+		0x22F40A72, 0x3B9F3A9D, 0xE15486A9, 0xF83FB646,
+		0x55C3FFC0, 0x4CA8CF2F, 0x9663731B, 0x8F0843F4,
+		0x03DC00D2, 0x1AB7303D, 0xC07C8C09, 0xD917BCE6,
+		0x74EBF560, 0x6D80C58F, 0xB74B79BB, 0xAE204954,
+		0x1CC406B2, 0x05AF365D, 0xDF648A69, 0xC60FBA86,
+		0x6BF3F300, 0x7298C3EF, 0xA8537FDB, 0xB1384F34,
+		0xB0FAF897, 0xA991C878, 0x735A744C, 0x6A3144A3,
+		0xC7CD0D25, 0xDEA63DCA, 0x046D81FE, 0x1D06B111,
+		0xAFE2FEF7, 0xB689CE18, 0x6C42722C, 0x752942C3,
+		0xD8D50B45, 0xC1BE3BAA, 0x1B75879E, 0x021EB771,
+		0x8ECAF457, 0x97A1C4B8, 0x4D6A788C, 0x54014863,
+		0xF9FD01E5, 0xE096310A, 0x3A5D8D3E, 0x2336BDD1,
+		0x91D2F237, 0x88B9C2D8, 0x52727EEC, 0x4B194E03,
+		0xE6E50785, 0xFF8E376A, 0x25458B5E, 0x3C2EBBB1,
+	},
+	{
+		0x00000000, 0xC82C0368, 0x905906D0, 0x587505B8,
+		0xD1C5E0A5, 0x19E9E3CD, 0x419CE675, 0x89B0E51D,
+		0x53FD2D4E, 0x9BD12E26, 0xC3A42B9E, 0x0B8828F6,
+		0x8238CDEB, 0x4A14CE83, 0x1261CB3B, 0xDA4DC853,
+		0xA6FA5B9C, 0x6ED658F4, 0x36A35D4C, 0xFE8F5E24,
+		0x773FBB39, 0xBF13B851, 0xE766BDE9, 0x2F4ABE81,
+		0xF50776D2, 0x3D2B75BA, 0x655E7002, 0xAD72736A,
+		0x24C29677, 0xECEE951F, 0xB49B90A7, 0x7CB793CF,
+		0xBD835B3D, 0x75AF5855, 0x2DDA5DED, 0xE5F65E85,
+		0x6C46BB98, 0xA46AB8F0, 0xFC1FBD48, 0x3433BE20,
+		0xEE7E7673, 0x2652751B, 0x7E2770A3, 0xB60B73CB,
+		0x3FBB96D6, 0xF79795BE, 0xAFE29006, 0x67CE936E,
+		0x1B7900A1, 0xD35503C9, 0x8B200671, 0x430C0519,
+		0xCABCE004, 0x0290E36C, 0x5AE5E6D4, 0x92C9E5BC,
+		0x48842DEF, 0x80A82E87, 0xD8DD2B3F, 0x10F12857,
+		0x9941CD4A, 0x516DCE22, 0x0918CB9A, 0xC134C8F2,
+		0x7A07B77A, 0xB22BB412, 0xEA5EB1AA, 0x2272B2C2,
+		0xABC257DF, 0x63EE54B7, 0x3B9B510F, 0xF3B75267,
+		0x29FA9A34, 0xE1D6995C, 0xB9A39CE4, 0x718F9F8C,
+		0xF83F7A91, 0x301379F9, 0x68667C41, 0xA04A7F29,
+		0xDCFDECE6, 0x14D1EF8E, 0x4CA4EA36, 0x8488E95E,
+		0x0D380C43, 0xC5140F2B, 0x9D610A93, 0x554D09FB,
+		0x8F00C1A8, 0x472CC2C0, 0x1F59C778, 0xD775C410,
+		0x5EC5210D, 0x96E92265, 0xCE9C27DD, 0x06B024B5,
+		0xC784EC47, 0x0FA8EF2F, 0x57DDEA97, 0x9FF1E9FF,
+		0x16410CE2, 0xDE6D0F8A, 0x86180A32, 0x4E34095A,
+		0x9479C109, 0x5C55C261, 0x0420C7D9, 0xCC0CC4B1,
+		0x45BC21AC, 0x8D9022C4, 0xD5E5277C, 0x1DC92414,
+		0x617EB7DB, 0xA952B4B3, 0xF127B10B, 0x390BB263,
+		0xB0BB577E, 0x78975416, 0x20E251AE, 0xE8CE52C6,
+		0x32839A95, 0xFAAF99FD, 0xA2DA9C45, 0x6AF69F2D,
+		0xE3467A30, 0x2B6A7958, 0x731F7CE0, 0xBB337F88,
+		0xF40E6EF5, 0x3C226D9D, 0x64576825, 0xAC7B6B4D,
+		0x25CB8E50, 0xEDE78D38, 0xB5928880, 0x7DBE8BE8,
+		0xA7F343BB, 0x6FDF40D3, 0x37AA456B, 0xFF864603,
+		0x7636A31E, 0xBE1AA076, 0xE66FA5CE, 0x2E43A6A6,
+		0x52F43569, 0x9AD83601, 0xC2AD33B9, 0x0A8130D1,
+		0x8331D5CC, 0x4B1DD6A4, 0x1368D31C, 0xDB44D074,
+		0x01091827, 0xC9251B4F, 0x91501EF7, 0x597C1D9F,
+		0xD0CCF882, 0x18E0FBEA, 0x4095FE52, 0x88B9FD3A,
+		0x498D35C8, 0x81A136A0, 0xD9D43318, 0x11F83070,
+		0x9848D56D, 0x5064D605, 0x0811D3BD, 0xC03DD0D5,
+		0x1A701886, 0xD25C1BEE, 0x8A291E56, 0x42051D3E,
+		0xCBB5F823, 0x0399FB4B, 0x5BECFEF3, 0x93C0FD9B,
+		0xEF776E54, 0x275B6D3C, 0x7F2E6884, 0xB7026BEC,
+		0x3EB28EF1, 0xF69E8D99, 0xAEEB8821, 0x66C78B49,
+		0xBC8A431A, 0x74A64072, 0x2CD345CA, 0xE4FF46A2,
+		0x6D4FA3BF, 0xA563A0D7, 0xFD16A56F, 0x353AA607,
+		0x8E09D98F, 0x4625DAE7, 0x1E50DF5F, 0xD67CDC37,
+		0x5FCC392A, 0x97E03A42, 0xCF953FFA, 0x07B93C92,
+		0xDDF4F4C1, 0x15D8F7A9, 0x4DADF211, 0x8581F179,
+		0x0C311464, 0xC41D170C, 0x9C6812B4, 0x544411DC,
+		0x28F38213, 0xE0DF817B, 0xB8AA84C3, 0x708687AB,
+		0xF93662B6, 0x311A61DE, 0x696F6466, 0xA143670E,
+		0x7B0EAF5D, 0xB322AC35, 0xEB57A98D, 0x237BAAE5,
+		0xAACB4FF8, 0x62E74C90, 0x3A924928, 0xF2BE4A40,
+		0x338A82B2, 0xFBA681DA, 0xA3D38462, 0x6BFF870A,
+		0xE24F6217, 0x2A63617F, 0x721664C7, 0xBA3A67AF,
+		0x6077AFFC, 0xA85BAC94, 0xF02EA92C, 0x3802AA44,
+		0xB1B24F59, 0x799E4C31, 0x21EB4989, 0xE9C74AE1,
+		0x9570D92E, 0x5D5CDA46, 0x0529DFFE, 0xCD05DC96,
+		0x44B5398B, 0x8C993AE3, 0xD4EC3F5B, 0x1CC03C33,
+		0xC68DF460, 0x0EA1F708, 0x56D4F2B0, 0x9EF8F1D8,
+		0x174814C5, 0xDF6417AD, 0x87111215, 0x4F3D117D,
+	},
+	{
+		0x00000000, 0x277D3C49, 0x4EFA7892, 0x698744DB,
+		0x6D821D21, 0x4AFF2168, 0x237865B3, 0x040559FA,
+		0xDA043B42, 0xFD79070B, 0x94FE43D0, 0xB3837F99,
+		0xB7862663, 0x90FB1A2A, 0xF97C5EF1, 0xDE0162B8,
+		0xB4097684, 0x93744ACD, 0xFAF30E16, 0xDD8E325F,
+		0xD98B6BA5, 0xFEF657EC, 0x97711337, 0xB00C2F7E,
+		0x6E0D4DC6, 0x4970718F, 0x20F73554, 0x078A091D,
+		0x038F50E7, 0x24F26CAE, 0x4D752875, 0x6A08143C,
+		0x9965000D, 0xBE183C44, 0xD79F789F, 0xF0E244D6,
+		0xF4E71D2C, 0xD39A2165, 0xBA1D65BE, 0x9D6059F7,
+		0x43613B4F, 0x641C0706, 0x0D9B43DD, 0x2AE67F94,
+		0x2EE3266E, 0x099E1A27, 0x60195EFC, 0x476462B5,
+		0x2D6C7689, 0x0A114AC0, 0x63960E1B, 0x44EB3252,
+		0x40EE6BA8, 0x679357E1, 0x0E14133A, 0x29692F73,
+		0xF7684DCB, 0xD0157182, 0xB9923559, 0x9EEF0910,
+		0x9AEA50EA, 0xBD976CA3, 0xD4102878, 0xF36D1431,
+		0x32CB001A, 0x15B63C53, 0x7C317888, 0x5B4C44C1,
+		0x5F491D3B, 0x78342172, 0x11B365A9, 0x36CE59E0,
+		0xE8CF3B58, 0xCFB20711, 0xA63543CA, 0x81487F83,
+		0x854D2679, 0xA2301A30, 0xCBB75EEB, 0xECCA62A2,
+		0x86C2769E, 0xA1BF4AD7, 0xC8380E0C, 0xEF453245,
+		0xEB406BBF, 0xCC3D57F6, 0xA5BA132D, 0x82C72F64,
+		0x5CC64DDC, 0x7BBB7195, 0x123C354E, 0x35410907,
+		0x314450FD, 0x16396CB4, 0x7FBE286F, 0x58C31426,
+		0xABAE0017, 0x8CD33C5E, 0xE5547885, 0xC22944CC,
+		0xC62C1D36, 0xE151217F, 0x88D665A4, 0xAFAB59ED,
+		0x71AA3B55, 0x56D7071C, 0x3F5043C7, 0x182D7F8E,
+		0x1C282674, 0x3B551A3D, 0x52D25EE6, 0x75AF62AF,
+		0x1FA77693, 0x38DA4ADA, 0x515D0E01, 0x76203248,
+		0x72256BB2, 0x555857FB, 0x3CDF1320, 0x1BA22F69,
+		0xC5A34DD1, 0xE2DE7198, 0x8B593543, 0xAC24090A,
+		0xA82150F0, 0x8F5C6CB9, 0xE6DB2862, 0xC1A6142B,
+		0x64960134, 0x43EB3D7D, 0x2A6C79A6, 0x0D1145EF,
+		0x09141C15, 0x2E69205C, 0x47EE6487, 0x609358CE,
+		0xBE923A76, 0x99EF063F, 0xF06842E4, 0xD7157EAD,
+		0xD3102757, 0xF46D1B1E, 0x9DEA5FC5, 0xBA97638C,
+		0xD09F77B0, 0xF7E24BF9, 0x9E650F22, 0xB918336B,
+		0xBD1D6A91, 0x9A6056D8, 0xF3E71203, 0xD49A2E4A,
+		0x0A9B4CF2, 0x2DE670BB, 0x44613460, 0x631C0829,
+		0x671951D3, 0x40646D9A, 0x29E32941, 0x0E9E1508,
+		0xFDF30139, 0xDA8E3D70, 0xB30979AB, 0x947445E2,
+		0x90711C18, 0xB70C2051, 0xDE8B648A, 0xF9F658C3,
+		0x27F73A7B, 0x008A0632, 0x690D42E9, 0x4E707EA0,
+		0x4A75275A, 0x6D081B13, 0x048F5FC8, 0x23F26381,
+		0x49FA77BD, 0x6E874BF4, 0x07000F2F, 0x207D3366,
+		0x24786A9C, 0x030556D5, 0x6A82120E, 0x4DFF2E47,
+		0x93FE4CFF, 0xB48370B6, 0xDD04346D, 0xFA790824,
+		0xFE7C51DE, 0xD9016D97, 0xB086294C, 0x97FB1505,
+		0x565D012E, 0x71203D67, 0x18A779BC, 0x3FDA45F5,
+		0x3BDF1C0F, 0x1CA22046, 0x7525649D, 0x525858D4,
+		0x8C593A6C, 0xAB240625, 0xC2A342FE, 0xE5DE7EB7,
+		0xE1DB274D, 0xC6A61B04, 0xAF215FDF, 0x885C6396,
+		0xE25477AA, 0xC5294BE3, 0xACAE0F38, 0x8BD33371,
+		0x8FD66A8B, 0xA8AB56C2, 0xC12C1219, 0xE6512E50,
+		0x38504CE8, 0x1F2D70A1, 0x76AA347A, 0x51D70833,
+		0x55D251C9, 0x72AF6D80, 0x1B28295B, 0x3C551512,
+		0xCF380123, 0xE8453D6A, 0x81C279B1, 0xA6BF45F8,
+		0xA2BA1C02, 0x85C7204B, 0xEC406490, 0xCB3D58D9,
+		0x153C3A61, 0x32410628, 0x5BC642F3, 0x7CBB7EBA,
+		0x78BE2740, 0x5FC31B09, 0x36445FD2, 0x1139639B,
+		0x7B3177A7, 0x5C4C4BEE, 0x35CB0F35, 0x12B6337C,
+		0x16B36A86, 0x31CE56CF, 0x58491214, 0x7F342E5D,
+		0xA1354CE5, 0x864870AC, 0xEFCF3477, 0xC8B2083E,
+		0xCCB751C4, 0xEBCA6D8D, 0x824D2956, 0xA530151F
+	}
+#endif
 };
 
 
@@ -96,7 +1176,6 @@ const uint32 pg_crc32c_table[256] = {
  * This table is based on the polynomial
  *	x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
  * (This is the same polynomial used in Ethernet checksums, for instance.)
- * It is for normal, not "reflected", in Williams' terms, CRC.
  */
 const uint32 pg_crc32_table[256] = {
 	0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
diff --git a/src/include/common/pg_crc.h b/src/include/common/pg_crc.h
index ea03dbf..eefc79a 100644
--- a/src/include/common/pg_crc.h
+++ b/src/include/common/pg_crc.h
@@ -41,17 +41,36 @@
 
 typedef uint32 pg_crc32;
 
+extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+
+#ifdef HAVE__BUILTIN_BSWAP32
+#define BSWAP32(x) __builtin_bswap32(x)
+#else
+#define BSWAP32(x) (((x << 24) & 0xff000000) | \
+					((x << 8) & 0x00ff0000) | \
+					((x >> 8) & 0x0000ff00) | \
+					((x >> 24) & 0x000000ff))
+#endif
+
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
  *
  * We use all-ones as the initial register contents and final bit inversion.
  * This is the same algorithm used e.g. in iSCSI. See RFC 3385 for more
  * details on the choice of polynomial.
+ *
+ * On big-endian systems, the intermediate value is kept in reverse byte
+ * order, to avoid byte-swapping during the calculation. FIN_CRC32C reverses
+ * the bytes to the final order.
  */
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
+#ifdef WORDS_BIGENDIAN
+#define FIN_CRC32C(crc)	((crc) = BSWAP32(crc) ^ 0xFFFFFFFF)
+#else
 #define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
+#endif
 #define COMP_CRC32C(crc, data, len)	\
-	COMP_CRC32_NORMAL_TABLE(crc, data, len, pg_crc32c_table)
+	((crc) = pg_comp_crc32c((crc), (char *) (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
 /*
@@ -115,7 +134,7 @@ do {															  \
 } while (0)
 
 /* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[];
+extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
 extern CRCDLLIMPORT const uint32 pg_crc32_table[];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 995fb65..ece57c8 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -663,6 +663,9 @@
 /* Define to 1 if you have the <winldap.h> header file. */
 #undef HAVE_WINLDAP_H
 
+/* Define to 1 if your compiler understands __builtin_bswap32. */
+#undef HAVE__BUILTIN_BSWAP32
+
 /* Define to 1 if your compiler understands __builtin_constant_p. */
 #undef HAVE__BUILTIN_CONSTANT_P
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 69d0e31..3f858c6 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -517,6 +517,9 @@
 /* Define to 1 if you have the <winldap.h> header file. */
 /* #undef HAVE_WINLDAP_H */
 
+/* Define to 1 if your compiler understands __builtin_bswap32. */
+/* #undef HAVE__BUILTIN_BSWAP32 */
+
 /* Define to 1 if your compiler understands __builtin_constant_p. */
 /* #undef HAVE__BUILTIN_CONSTANT_P */
 
#55Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#54)
Re: What exactly is our CRC algorithm?

At 2015-02-09 12:52:41 +0200, hlinnakangas@vmware.com wrote:

Ok, I've committed a patch that just moves the existing code to
common/pg_crc.c […]

Thanks, looks good.

Attached is a rebased version of the slicing-by-8 patch.

Looks OK too.

Do you have access to big-endian hardware to test this on?

Yes, I tested it on a Linux/ppc system. I wasn't speculating when I said
it "does make a noticeable difference", though I'm afraid I did not keep
the timings after submitting the revised patch. The speedup was some
double-digit percentage, IIRC.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#56Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#55)
Re: What exactly is our CRC algorithm?

On 02/09/2015 03:20 PM, Abhijit Menon-Sen wrote:

At 2015-02-09 12:52:41 +0200, hlinnakangas@vmware.com wrote:

Do you have access to big-endian hardware to test this on?

Yes, I tested it on a Linux/ppc system. I wasn't speculating when I said
it "does make a noticeable difference", though I'm afraid I did not keep
the timings after submitting the revised patch. The speedup was some
double-digit percentage, IIRC.

Ok, that's good enough for me.

Committed with a few more edits on comments and such. I'll start looking
at the second patch now.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#57Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#50)
1 attachment(s)
Re: What exactly is our CRC algorithm?

On 01/09/2015 10:32 AM, Abhijit Menon-Sen wrote:

2. The sse4.2 patch has only some minor compile fixes.

I have built and tested both patches individually on little-endian
(amd64) and big-endian (ppc) systems. I verified that the _sse is
chosen at startup on the former, and _sb8 on the latter, and that
both implementations function correctly with respect to HEAD.

I'd like to arrange this somewhat differently, to keep the really
low-level assembler blocks and such separate from the higher level
parts. Especially now that pg_crc.c is in src/common and src/port, it
doesn't seem appropriate to have assembler code in there. Also, some of
the high-level code can be reused if we later add support e.g. for the
ARMv8 CRC instructions.

I propose that we add a new header file in src/port, let's call it
crc_instructions.h. That file contains the very low-level stuff, the
pg_asm_crc32q() and pg_asm_crc32b() inline functions, which just contain
the single assembler instruction. Or the corresponding mnemomic or macro
depending on the compiler; the point of the crc_instructions.h header is
to hide the differences between compilers and architectures.

If the CRC instructions are available, crc_instructions.h defines
PG_HAVE_CRC32C_INSTRUCTIONS, as well as the pg_asm_crc32q() and
pg_asm_crc32b() macros/functions. It also defines
pg_crc32_instructions_runtime_check(), to perform the runtime check to
determine whether the instructions can be used on the current platform
(i.e. if you're running on a CPU with SSE 4.2 support). There's another
symbol PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK, which indicates
whether the runtime check is needed. That's currently always defined
when PG_HAVE_CRC32C_INSTRUCTIONS is, but conceivably you might want to
build a version that skips the runtime check altogether, and doesn't
therefore require the slicing-by-8 fallback implementation at all.
Gentoo users might like that ;-), as well as possible future
architectures that always have CRC32 instructions.

Attached is a patch along those lines. I haven't done much testing, but
it demonstrates the code structure I have in mind.

A couple of remarks on your original patch, which also apply to the
attached version:

+static inline pg_crc32
+pg_asm_crc32b(pg_crc32 crc, unsigned char data)
+{
+#if defined(__GNUC__) && defined(__x86_64__)
+	__asm__ ("crc32b %[data], %[crc]\n" : [crc] "+r" (crc) : [data] "rm" (data));
+	return crc;
+#elif defined(_MSC_VER)
+	return _mm_crc32_u8(crc, data);
+#else
+	/* Can't generate crc32b, but keep the compiler quiet. */
+	return 0;
+#endif

I believe the CRC instructions are also available in 32-bit mode, so the
check for __x86_64__ is not needed. Right? Any CPU recent enough to have
these instructions certainly supports the x86-64 instruction set, but
you might nevertheless have compiled and be running in i386 mode.

It would be nice to use GCC's builtin intrinsics, __builtin_ia32_crc32*
where available, but I guess those are only available if you build with
-msse4.2, and that would defeat the point of the runtime check.

I believe the _mm_* mnemonics would also work with the Intel compiler.

- Heikki

Attachments:

0001-Use-Intel-SSE4.2-CRC-instructions-where-available.patchapplication/x-patch; name=0001-Use-Intel-SSE4.2-CRC-instructions-where-available.patchDownload
From 7e16b0d5be39f832769da463f069c51afa04fb57 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Tue, 10 Feb 2015 14:26:24 +0200
Subject: [PATCH 1/1] Use Intel SSE4.2 CRC instructions where available.

On x86, perform a runtime check to see if we're running on a CPU that
supports SSE 4.2. If we are, we can use the special crc32b and crc32q
instructions for the CRC-32C calculations. That greatly speeds up CRC
calculation.

Abhijit Menon-Sen, reviewed by Andres Freund and me.
---
 configure                   |   2 +-
 configure.in                |   2 +-
 src/common/pg_crc.c         | 109 ++++++++++++++++++++++++++++++++++++++++----
 src/include/common/pg_crc.h |  12 ++++-
 src/include/pg_config.h.in  |   3 ++
 5 files changed, 114 insertions(+), 14 deletions(-)

diff --git a/configure b/configure
index fa271fe..c352128 100755
--- a/configure
+++ b/configure
@@ -9204,7 +9204,7 @@ fi
 done
 
 
-for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.in b/configure.in
index e6a49d1..588d626 100644
--- a/configure.in
+++ b/configure.in
@@ -1032,7 +1032,7 @@ AC_SUBST(UUID_LIBS)
 ##
 
 dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES
-AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.
diff --git a/src/common/pg_crc.c b/src/common/pg_crc.c
index eba32d3..b6db749 100644
--- a/src/common/pg_crc.c
+++ b/src/common/pg_crc.c
@@ -21,25 +21,113 @@
 
 #include "common/pg_crc.h"
 
-/* Accumulate one input byte */
-#ifdef WORDS_BIGENDIAN
-#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
+static pg_crc32 pg_comp_crc32c_hw(pg_crc32 crc, const void *data, size_t len);
+#endif
+
+#if !defined(PG_HAVE_CRC32C_INSTRUCTIONS) || defined(PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK)
+static pg_crc32 pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len);
+static const uint32 pg_crc32c_table[8][256];
+#endif
+
+#ifdef PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+/*
+ * When built with support for CRC instructions, but we need to perform a
+ * run-time check to determine whether we can actually use them,
+ * pg_comp_crc32c is a function pointer. It is initialized to
+ * pg_comp_crc32c_choose, which performs the runtime check, and changes the
+ * function pointer so that subsequent calls go directly to the hw-accelerated
+ * version, or the fallback slicing-by-8 version.
+ */
+static pg_crc32
+pg_comp_crc32c_choose(pg_crc32 crc, const void *data, size_t len)
+{
+	if (pg_crc32_instructions_runtime_check())
+		pg_comp_crc32c = pg_comp_crc32c_hw;
+	else
+		pg_comp_crc32c = pg_comp_crc32c_sb8;
+
+	return pg_comp_crc32c(crc, data, len);
+}
+
+pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_choose;
+
 #else
-#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+/*
+ * No need for a runtime check. Compile directly with the hw-accelerated
+ * or the slicing-by-8 version. (We trust that the compiler
+ * is smart enough to inline it here.)
+ */
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
+	return pg_comp_crc32c_hw(crc, data, len);
+#else
+	return pg_comp_crc32c_sb8(crc, data, len);
+#endif
+}
 #endif
 
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
 /*
- * This function computes a CRC using the slicing-by-8 algorithm, which
- * uses an 8*256 lookup table to operate on eight bytes in parallel and
- * recombine the results.
+ * This function computes CRC-32C using special-purpose CPU instructions.
+ */
+static pg_crc32
+pg_comp_crc32c_hw(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Process eight bytes of data at a time.
+	 *
+	 * NB: We do unaligned 8-byte accesses here. Currently, the only CRC
+	 * instructions supported are the ones on Intel SSE 4.2, and that works
+	 * and performs well with unaligned access. This may need to be changed
+	 * if we get support for more architectures.
+	 */
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = pg_asm_crc32q(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
+
+#endif /* PG_HAVE_CRC32C_INSTRUCTIONS */
+
+#if !defined(PG_HAVE_CRC32C_INSTRUCTIONS) || defined(PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK)
+/*
+ * Compute CRC-32C using slicing-by-8 algorithm.
  *
  * Michael E. Kounavis, Frank L. Berry,
  * "Novel Table Lookup-Based Algorithms for High-Performance CRC
  * Generation", IEEE Transactions on Computers, vol.57, no. 11,
  * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85
  */
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+
+/* Accumulate one input byte */
+#ifdef WORDS_BIGENDIAN
+#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+#else
+#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+#endif
+
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
 {
 	const unsigned char *p = data;
 	const uint32 *p4;
@@ -113,7 +201,7 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
  * order (IOW, the tables are stored in little-endian order even on big-endian
  * systems).
  */
-const uint32 pg_crc32c_table[8][256] = {
+static const uint32 pg_crc32c_table[8][256] = {
 #ifndef WORDS_BIGENDIAN
 	{
 		0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
@@ -1175,6 +1263,7 @@ const uint32 pg_crc32c_table[8][256] = {
 #endif /* WORDS_BIGENDIAN */
 };
 
+#endif
 
 /*
  * Lookup table for calculating CRC-32 using Sarwate's algorithm.
diff --git a/src/include/common/pg_crc.h b/src/include/common/pg_crc.h
index f496659..6806f6f 100644
--- a/src/include/common/pg_crc.h
+++ b/src/include/common/pg_crc.h
@@ -32,6 +32,8 @@
 #ifndef PG_CRC_H
 #define PG_CRC_H
 
+#include "port/crc_instructions.h"
+
 /* ugly hack to let this be used in frontend and backend code on Cygwin */
 #ifdef FRONTEND
 #define CRCDLLIMPORT
@@ -71,7 +73,11 @@ typedef uint32 pg_crc32;
 	((crc) = pg_comp_crc32c((crc), (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
+#ifdef PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);
+#else
 extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+#endif
 
 /*
  * CRC-32, the same used e.g. in Ethernet.
@@ -135,8 +141,10 @@ do {															  \
 	} \
 } while (0)
 
-/* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
+/*
+ * Constant table for the CRC-32 polynomial (the tables for CRC-32C are
+ * static in pg_crc.c)
+ */
 extern CRCDLLIMPORT const uint32 pg_crc32_table[256];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ece57c8..685ff81 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -96,6 +96,9 @@
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
-- 
2.1.4

#58Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#57)
Re: What exactly is our CRC algorithm?

At 2015-02-10 14:30:51 +0200, hlinnakangas@vmware.com wrote:

I propose that we add a new header file in src/port, let's call it
crc_instructions.h […] the point of the crc_instructions.h header
is to hide the differences between compilers and architectures.

Moving the assembly code/compiler intrinsics to a separate header is
fine with me, but I really don't like the proposed implementation at
all. Here are some comments:

1. I don't mind moving platform-specific tests for CRC32C instructions
to configure, but if we only define PG_HAVE_CRC32C_INSTRUCTIONS, we
would anyway have to reproduce all that platform-specific stuff in
the header file. To do it properly, I think we should generate the
right version of crc_instructions.h for the platform. Otherwise,
what's the point? Might as well have only the complicated header.

2. At this point, I think we should stick with the _sse function rather
than a generic _hw one to "drive" the platform-specific instructions.
The structure of that function (n/8*(8bytes)+n%8*(bytes)) is specific
to what works best for the SSE instructions. On another platform, we
may need something very similar, or very different.

With the proposed structure, _hw would inevitably become #ifdef'ed
non-trivially, e.g. to run a single-byte loop at the start to align
the main loop, but only for certain combinations of #defines.

I think we should consider what makes the most sense when someone
actually wants to add support for another platform/compiler, and
not before.

3. I dislike everything about pg_crc32_instructions_runtime_check()—the
name, the separate PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK #define,
the fact that you try to do the test "inline" rather than at startup…

Maybe you're trying to avoid checking separately at startup so that a
program that links with code from src/common doesn't need to do its
own test. But I don't think the results are worth it.

As for omitting the slicing-by-8 tables, if there's a more compelling
reason to do that than "Gentoo users might like that ;-)", I think it
should be done with a straightforward -DUSE_CRC_SSE style arrangement
rather than figuring out that you HAVE_CRC32C_INSTRUCTIONS but don't
NEED_RUNTIME_CHECK. If you want to build special-purpose binaries,
just pick whichever CRC implementation you like, done.

I believe the CRC instructions are also available in 32-bit mode, so
the check for __x86_64__ is not needed. Right?

I'm not sure, but I guess you're right.

It would be nice to use GCC's builtin intrinsics,
__builtin_ia32_crc32* where available, but I guess those are only
available if you build with -msse4.2, and that would defeat the
point of the runtime check.

Exactly.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#59Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#58)
Re: What exactly is our CRC algorithm?

On 02/11/2015 11:28 AM, Abhijit Menon-Sen wrote:

1. I don't mind moving platform-specific tests for CRC32C instructions
to configure, but if we only define PG_HAVE_CRC32C_INSTRUCTIONS, we
would anyway have to reproduce all that platform-specific stuff in
the header file. To do it properly, I think we should generate the
right version of crc_instructions.h for the platform. Otherwise,
what's the point? Might as well have only the complicated header.

I don't follow. I didn't change configure at all, compared to your patch.

2. At this point, I think we should stick with the _sse function rather
than a generic _hw one to "drive" the platform-specific instructions.
The structure of that function (n/8*(8bytes)+n%8*(bytes)) is specific
to what works best for the SSE instructions. On another platform, we
may need something very similar, or very different.

With the proposed structure, _hw would inevitably become #ifdef'ed
non-trivially, e.g. to run a single-byte loop at the start to align
the main loop, but only for certain combinations of #defines.

I think we should consider what makes the most sense when someone
actually wants to add support for another platform/compiler, and
not before.

Hmm, ok. The ARM CRC32C instruction is very similar to the SSE4.2 one,
but I presume it does require alignment.

3. I dislike everything about pg_crc32_instructions_runtime_check()—the
name, the separate PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK #define,
the fact that you try to do the test "inline" rather than at startup…

Maybe you're trying to avoid checking separately at startup so that a
program that links with code from src/common doesn't need to do its
own test. But I don't think the results are worth it.

As a case in point, with your patch pg_xlogdump would not have used the
CRC instruction, because it never called pg_choose_crc_impl(). "Choose
on first use" is much more convenient than requiring every program to
call a function.

As for omitting the slicing-by-8 tables, if there's a more compelling
reason to do that than "Gentoo users might like that ;-)", I think it
should be done with a straightforward -DUSE_CRC_SSE style arrangement
rather than figuring out that you HAVE_CRC32C_INSTRUCTIONS but don't
NEED_RUNTIME_CHECK. If you want to build special-purpose binaries,
just pick whichever CRC implementation you like, done.

I stopped short of actually allowing you to force the use of SSE, e.g.
with -DUSE_CRC_SSE, but my thinking was that that would force
PG_HAVE_CRC32C_INSTRUCTIONS to be set, and NEEDS_RUNTIME_CHECK to be
unset. I.e. those two #defines control what code is generated, but in
the header file. I think what you're suggesting is that we'd instead
have two mutually exclusive #defines, something like
"USE_CRC_SSE_ALWAYS" and "USE_CRC_SSE_WITH_RUNTIME_CHECK". It wouldn't
be much different, but would require some places to check for both.

It would be nice to use GCC's builtin intrinsics,
__builtin_ia32_crc32* where available, but I guess those are only
available if you build with -msse4.2, and that would defeat the
point of the runtime check.

Exactly.

Hmm. Perhaps we should check for the built-in functions, and if they're
available, use them and not set NEEDS_RUNTIME_CHECK. If you compile with
-msse4.2, the code won't run without SSE4.2 anyway (or at least isn't
guaranteed to run).

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#60Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#59)
Re: What exactly is our CRC algorithm?

At 2015-02-11 13:20:29 +0200, hlinnakangas@vmware.com wrote:

I don't follow. I didn't change configure at all, compared to your
patch.

OK, I extrapolated a little too much. Your patch didn't actually include
crc_instructions.h; from the name of the #define, I imagined you planned
to move the check to configure. But now I guess from your response that
PG_HAVE_CRC32C_INSTRUCTIONS would be #defined by the header (as you did
say it would be). So let's forget that part.

As a case in point, with your patch pg_xlogdump would not have used
the CRC instruction, because it never called pg_choose_crc_impl().
"Choose on first use" is much more convenient than requiring every
program to call a function.

I can see your point. I'm not fond of the code, but I guess it's not a
huge deal in the larger scheme of things.

I think what you're suggesting is that we'd instead have two mutually
exclusive #defines, something like "USE_CRC_SSE_ALWAYS" and
"USE_CRC_SSE_WITH_RUNTIME_CHECK".

I was thinking of only one knob: USE_CRC_SSE would (try to) build the
code to use the SSE instructions without any test. If it (or another
USE_CRC_XXX flag) isn't set, we'd build all applicable variants and
test at runtime to decide what to use.

Just give me a little while to think through what that would look like,
I'll post a patch.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#61Heikki Linnakangas
hlinnakangas@vmware.com
In reply to: Abhijit Menon-Sen (#60)
1 attachment(s)
Re: What exactly is our CRC algorithm?

On 02/11/2015 04:20 PM, Abhijit Menon-Sen wrote:

At 2015-02-11 13:20:29 +0200, hlinnakangas@vmware.com wrote:

I don't follow. I didn't change configure at all, compared to your
patch.

OK, I extrapolated a little too much. Your patch didn't actually include
crc_instructions.h;

Oh, I'm sorry. Here's the complete patch with crc_instructions.h
- Heikki

Attachments:

0001-Use-Intel-SSE4.2-CRC-instructions-where-available.patchapplication/x-patch; name=0001-Use-Intel-SSE4.2-CRC-instructions-where-available.patchDownload
From bd4a90d339e21cd6ac517d077fe3a76abb5ef37d Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Tue, 10 Feb 2015 14:26:24 +0200
Subject: [PATCH 1/1] Use Intel SSE4.2 CRC instructions where available.

On x86, perform a runtime check to see if we're running on a CPU that
supports SSE 4.2. If we are, we can use the special crc32b and crc32q
instructions for the CRC-32C calculations. That greatly speeds up CRC
calculation.

Abhijit Menon-Sen, reviewed by Andres Freund and me.
---
 configure                           |   2 +-
 configure.in                        |   2 +-
 src/common/pg_crc.c                 | 109 +++++++++++++++++++++++++++++---
 src/include/common/pg_crc.h         |  12 +++-
 src/include/pg_config.h.in          |   3 +
 src/include/port/crc_instructions.h | 121 ++++++++++++++++++++++++++++++++++++
 6 files changed, 235 insertions(+), 14 deletions(-)
 create mode 100644 src/include/port/crc_instructions.h

diff --git a/configure b/configure
index fa271fe..c352128 100755
--- a/configure
+++ b/configure
@@ -9204,7 +9204,7 @@ fi
 done
 
 
-for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.in b/configure.in
index e6a49d1..588d626 100644
--- a/configure.in
+++ b/configure.in
@@ -1032,7 +1032,7 @@ AC_SUBST(UUID_LIBS)
 ##
 
 dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES
-AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.
diff --git a/src/common/pg_crc.c b/src/common/pg_crc.c
index eba32d3..b6db749 100644
--- a/src/common/pg_crc.c
+++ b/src/common/pg_crc.c
@@ -21,25 +21,113 @@
 
 #include "common/pg_crc.h"
 
-/* Accumulate one input byte */
-#ifdef WORDS_BIGENDIAN
-#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
+static pg_crc32 pg_comp_crc32c_hw(pg_crc32 crc, const void *data, size_t len);
+#endif
+
+#if !defined(PG_HAVE_CRC32C_INSTRUCTIONS) || defined(PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK)
+static pg_crc32 pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len);
+static const uint32 pg_crc32c_table[8][256];
+#endif
+
+#ifdef PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+/*
+ * When built with support for CRC instructions, but we need to perform a
+ * run-time check to determine whether we can actually use them,
+ * pg_comp_crc32c is a function pointer. It is initialized to
+ * pg_comp_crc32c_choose, which performs the runtime check, and changes the
+ * function pointer so that subsequent calls go directly to the hw-accelerated
+ * version, or the fallback slicing-by-8 version.
+ */
+static pg_crc32
+pg_comp_crc32c_choose(pg_crc32 crc, const void *data, size_t len)
+{
+	if (pg_crc32_instructions_runtime_check())
+		pg_comp_crc32c = pg_comp_crc32c_hw;
+	else
+		pg_comp_crc32c = pg_comp_crc32c_sb8;
+
+	return pg_comp_crc32c(crc, data, len);
+}
+
+pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_choose;
+
 #else
-#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+/*
+ * No need for a runtime check. Compile directly with the hw-accelerated
+ * or the slicing-by-8 version. (We trust that the compiler
+ * is smart enough to inline it here.)
+ */
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
+	return pg_comp_crc32c_hw(crc, data, len);
+#else
+	return pg_comp_crc32c_sb8(crc, data, len);
+#endif
+}
 #endif
 
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
 /*
- * This function computes a CRC using the slicing-by-8 algorithm, which
- * uses an 8*256 lookup table to operate on eight bytes in parallel and
- * recombine the results.
+ * This function computes CRC-32C using special-purpose CPU instructions.
+ */
+static pg_crc32
+pg_comp_crc32c_hw(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Process eight bytes of data at a time.
+	 *
+	 * NB: We do unaligned 8-byte accesses here. Currently, the only CRC
+	 * instructions supported are the ones on Intel SSE 4.2, and that works
+	 * and performs well with unaligned access. This may need to be changed
+	 * if we get support for more architectures.
+	 */
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = pg_asm_crc32q(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
+
+#endif /* PG_HAVE_CRC32C_INSTRUCTIONS */
+
+#if !defined(PG_HAVE_CRC32C_INSTRUCTIONS) || defined(PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK)
+/*
+ * Compute CRC-32C using slicing-by-8 algorithm.
  *
  * Michael E. Kounavis, Frank L. Berry,
  * "Novel Table Lookup-Based Algorithms for High-Performance CRC
  * Generation", IEEE Transactions on Computers, vol.57, no. 11,
  * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85
  */
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+
+/* Accumulate one input byte */
+#ifdef WORDS_BIGENDIAN
+#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+#else
+#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+#endif
+
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
 {
 	const unsigned char *p = data;
 	const uint32 *p4;
@@ -113,7 +201,7 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
  * order (IOW, the tables are stored in little-endian order even on big-endian
  * systems).
  */
-const uint32 pg_crc32c_table[8][256] = {
+static const uint32 pg_crc32c_table[8][256] = {
 #ifndef WORDS_BIGENDIAN
 	{
 		0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
@@ -1175,6 +1263,7 @@ const uint32 pg_crc32c_table[8][256] = {
 #endif /* WORDS_BIGENDIAN */
 };
 
+#endif
 
 /*
  * Lookup table for calculating CRC-32 using Sarwate's algorithm.
diff --git a/src/include/common/pg_crc.h b/src/include/common/pg_crc.h
index f496659..6806f6f 100644
--- a/src/include/common/pg_crc.h
+++ b/src/include/common/pg_crc.h
@@ -32,6 +32,8 @@
 #ifndef PG_CRC_H
 #define PG_CRC_H
 
+#include "port/crc_instructions.h"
+
 /* ugly hack to let this be used in frontend and backend code on Cygwin */
 #ifdef FRONTEND
 #define CRCDLLIMPORT
@@ -71,7 +73,11 @@ typedef uint32 pg_crc32;
 	((crc) = pg_comp_crc32c((crc), (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
+#ifdef PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+extern pg_crc32 (*pg_comp_crc32c)(pg_crc32 crc, const void *data, size_t len);
+#else
 extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+#endif
 
 /*
  * CRC-32, the same used e.g. in Ethernet.
@@ -135,8 +141,10 @@ do {															  \
 	} \
 } while (0)
 
-/* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
+/*
+ * Constant table for the CRC-32 polynomial (the tables for CRC-32C are
+ * static in pg_crc.c)
+ */
 extern CRCDLLIMPORT const uint32 pg_crc32_table[256];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index ece57c8..685ff81 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -96,6 +96,9 @@
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
diff --git a/src/include/port/crc_instructions.h b/src/include/port/crc_instructions.h
new file mode 100644
index 0000000..85c9347
--- /dev/null
+++ b/src/include/port/crc_instructions.h
@@ -0,0 +1,121 @@
+/*-------------------------------------------------------------------------
+ *
+ * crc_instructions.h
+ *	  Hardware support for calculating CRCs.
+ *
+ * Some CPU architectures have special instructions for speeding up CRC
+ * calculations. This header files provides support for them in a
+ * reasonably platform and compiler independent way.
+ *
+ * This header file defines or no two preprocessor symbols, depending on
+ * the current platform:
+ *
+ * PG_HAVE_CRC32C_INSTRUCTIONS
+ *		Defined if this architecture has accelerated support for CRC32C
+ *		calculation.
+ *
+ * PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+ *		Defined if the architecture has accelerated support for CRC32C
+ *		calculation, but it's not available on all platforms that this
+ *		binary supports. A runtime check must be performed before
+ *		attempting to use the instructions, and a fallback implementation
+ *		is needed.
+ *
+ * If PG_HAVE_CRC32C_INSTRUCTIONS is defined, two inline functions or macros
+ * are also defined:
+ *
+ * uint32 pg_accumulate_crc32c_byte(uint32 crc, unsigned char data)
+ *		Add one byte to the current crc value.
+ *
+ * uint32 pg_accumulate_crc32c_uint64(uint32 crc, uint64 data)
+ *		Add eight bytes of data to the current crc value.
+ *
+ * If PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK is defined, there following
+ * inline function or macro is also defined:
+ *
+ * bool pg_crc32_instructions_runtime_check(void)
+ *		Returns 'true' if the CRC instructions can be used, 'false'
+ *		otherwise.
+ *
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/port/crc_instructions.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef CRC_INSTRUCTIONS_H
+#define CRC_INSTRUCTIONS_H
+
+#ifdef HAVE_CPUID_H
+#include <cpuid.h>
+#endif
+#ifdef _MSC_VER
+#include <intrin.h>
+#include <nmmintrin.h>
+#endif
+
+#if (defined(__GNUC__) && defined(__x86_64__) && defined(HAVE_CPUID_H))
+
+#define PG_HAVE_CRC32C_INSTRUCTIONS
+#define PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+
+static inline uint32
+pg_asm_crc32b(uint32 crc, unsigned char data)
+{
+	__asm__ (
+		"crc32b %[data], %[crc]\n"
+:		[crc] "+r" (crc)
+:		[data] "rm" (data));
+	return crc;
+}
+
+static inline uint32
+pg_asm_crc32q(uint32 crc, uint64 data)
+{
+	/*
+	 * For some strange reason, the crc32q instruction accepts and returns
+	 * the current crc value as a 64-bit integer, even though the upper 32
+	 * bits are always zeros.
+	 */
+	uint64 _crc = crc;
+	__asm__ (
+		"crc32q %[data], %[crc]\n"
+:		[crc] "+r" (_crc)
+:		[data] "rm" (data));
+	return (uint32) _crc;
+}
+
+static inline bool
+pg_crc32_instructions_runtime_check(void)
+{
+	unsigned int exx[4] = {0, 0, 0, 0};
+
+	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+	return true;
+
+	return (exx[2] & (1 << 20)); /* SSE 4.2 */
+}
+
+#elif defined(_MSC_VER)
+
+#define PG_HAVE_CRC32C_INSTRUCTIONS
+#define PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+
+#define pg_asm_crc32b(crc, data) _mm_crc32_u8(crc, data)
+#define pg_asm_crc32q(crc, data) ((uint32) _mm_crc32_u64(crc, data))
+
+static inline bool
+pg_crc32_instructions_runtime_check(void)
+{
+	unsigned int exx[4] = {0, 0, 0, 0};
+
+	__cpuid(exx, 1);
+
+	return (exx[2] & (1 << 20)); /* SSE 4.2 */
+}
+
+#endif
+
+#endif /* CRC_INSTRUCTIONS_H */
-- 
2.1.4

#62Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Heikki Linnakangas (#61)
1 attachment(s)
Re: What exactly is our CRC algorithm?

On 02/12/2015 09:26 PM, Heikki Linnakangas wrote:

On 02/11/2015 04:20 PM, Abhijit Menon-Sen wrote:

At 2015-02-11 13:20:29 +0200, hlinnakangas@vmware.com wrote:

I don't follow. I didn't change configure at all, compared to your
patch.

OK, I extrapolated a little too much. Your patch didn't actually include
crc_instructions.h;

Oh, I'm sorry. Here's the complete patch with crc_instructions.h

I was just about to commit the attached, which is the same as the
previous patch with just cosmetic comment changes, but then I realized
that this probably doesn't compile with Visual Studio 2005 or older. The
code does "#ifdef _MSC_VER", and then uses the _mm_crc32_u64 intrinsic,
but that intrinsic was added in Visual Studio 2008. I think we'll need a
version check there. Or better yet, a direct configure test to check if
the intrinsic exists - that way we get to also use it on Intel
compilers, which I believe also has the same intrinsics.

You want to write that or should I? How do you like this latest version
of the patch otherwise? You had some criticism earlier, but I had
forgotten to include the crc_instructions.h header file in that earlier
version.

- Heikki

Attachments:

v2-0001-Use-Intel-SSE4.2-CRC-instructions-where-available.patchapplication/x-patch; name=v2-0001-Use-Intel-SSE4.2-CRC-instructions-where-available.patchDownload
From f934cb017ad0270ded73feb4d3279e81a58a4149 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Wed, 25 Mar 2015 18:44:07 +0200
Subject: [PATCH v2 1/1] Use Intel SSE4.2 CRC instructions where available.

On x86, perform a runtime check to see if we're running on a CPU that
supports SSE 4.2. If we are, we can use the special crc32b and crc32q
instructions for the CRC-32C calculations. That greatly speeds up CRC
calculation.

Abhijit Menon-Sen, reviewed by Andres Freund and me.
---
 configure                           |   2 +-
 configure.in                        |   2 +-
 src/common/pg_crc.c                 | 113 +++++++++++++++++++++++++++----
 src/include/common/pg_crc.h         |  20 ++++--
 src/include/pg_config.h.in          |   3 +
 src/include/port/crc_instructions.h | 128 ++++++++++++++++++++++++++++++++++++
 6 files changed, 248 insertions(+), 20 deletions(-)
 create mode 100644 src/include/port/crc_instructions.h

diff --git a/configure b/configure
index 2c9b3a7..87ceb0b 100755
--- a/configure
+++ b/configure
@@ -9204,7 +9204,7 @@ fi
 done
 
 
-for ac_header in atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
+for ac_header in atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
diff --git a/configure.in b/configure.in
index b2c1ce7..bf604ea 100644
--- a/configure.in
+++ b/configure.in
@@ -1032,7 +1032,7 @@ AC_SUBST(UUID_LIBS)
 ##
 
 dnl sys/socket.h is required by AC_FUNC_ACCEPT_ARGTYPES
-AC_CHECK_HEADERS([atomic.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
+AC_CHECK_HEADERS([atomic.h cpuid.h crypt.h dld.h fp_class.h getopt.h ieeefp.h ifaddrs.h langinfo.h mbarrier.h poll.h pwd.h sys/ioctl.h sys/ipc.h sys/poll.h sys/pstat.h sys/resource.h sys/select.h sys/sem.h sys/shm.h sys/socket.h sys/sockio.h sys/tas.h sys/time.h sys/un.h termios.h ucred.h utime.h wchar.h wctype.h])
 
 # On BSD, test for net/if.h will fail unless sys/socket.h
 # is included first.
diff --git a/src/common/pg_crc.c b/src/common/pg_crc.c
index eba32d3..6675ae7 100644
--- a/src/common/pg_crc.c
+++ b/src/common/pg_crc.c
@@ -21,25 +21,113 @@
 
 #include "common/pg_crc.h"
 
-/* Accumulate one input byte */
-#ifdef WORDS_BIGENDIAN
-#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
+static pg_crc32 pg_comp_crc32c_hw(pg_crc32 crc, const void *data, size_t len);
+#endif
+
+#if !defined(PG_HAVE_CRC32C_INSTRUCTIONS) || defined(PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK)
+static pg_crc32 pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len);
+static const uint32 pg_crc32c_table[8][256];
+#endif
+
+#ifdef PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+/*
+ * When built with support for CRC instructions, but we need to perform a
+ * run-time check to determine whether we can actually use them,
+ * pg_comp_crc32c is a function pointer. It is initialized to
+ * pg_comp_crc32c_choose, which performs the runtime check, and changes the
+ * function pointer so that subsequent calls go directly to the hw-accelerated
+ * version, or the fallback slicing-by-8 version.
+ */
+static pg_crc32
+pg_comp_crc32c_choose(pg_crc32 crc, const void *data, size_t len)
+{
+	if (pg_crc32_instructions_runtime_check())
+		pg_comp_crc32c = pg_comp_crc32c_hw;
+	else
+		pg_comp_crc32c = pg_comp_crc32c_sb8;
+
+	return pg_comp_crc32c(crc, data, len);
+}
+
+pg_crc32	(*pg_comp_crc32c) (pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_choose;
+
 #else
-#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+/*
+ * No need for a runtime check. Compile directly with the hw-accelerated
+ * or the slicing-by-8 version. (We trust that the compiler
+ * is smart enough to inline it here.)
+ */
+pg_crc32
+pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+{
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
+	return pg_comp_crc32c_hw(crc, data, len);
+#else
+	return pg_comp_crc32c_sb8(crc, data, len);
+#endif
+}
 #endif
 
+#ifdef PG_HAVE_CRC32C_INSTRUCTIONS
 /*
- * This function computes a CRC using the slicing-by-8 algorithm, which
- * uses an 8*256 lookup table to operate on eight bytes in parallel and
- * recombine the results.
+ * This function computes CRC-32C using special-purpose CPU instructions.
+ */
+static pg_crc32
+pg_comp_crc32c_hw(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Process eight bytes of data at a time.
+	 *
+	 * NB: We do unaligned 8-byte accesses here. Currently, the only CRC
+	 * instructions supported are the ones on Intel SSE 4.2, and that works
+	 * and performs well with unaligned access. This may need to be changed if
+	 * we get support for more architectures.
+	 */
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = pg_asm_crc32q(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = pg_asm_crc32b(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
+
+#endif   /* PG_HAVE_CRC32C_INSTRUCTIONS */
+
+#if !defined(PG_HAVE_CRC32C_INSTRUCTIONS) || defined(PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK)
+/*
+ * Compute CRC-32C using slicing-by-8 algorithm.
  *
  * Michael E. Kounavis, Frank L. Berry,
  * "Novel Table Lookup-Based Algorithms for High-Performance CRC
  * Generation", IEEE Transactions on Computers, vol.57, no. 11,
  * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85
  */
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
+
+/* Accumulate one input byte */
+#ifdef WORDS_BIGENDIAN
+#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+#else
+#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+#endif
+
+static pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
 {
 	const unsigned char *p = data;
 	const uint32 *p4;
@@ -113,7 +201,7 @@ pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
  * order (IOW, the tables are stored in little-endian order even on big-endian
  * systems).
  */
-const uint32 pg_crc32c_table[8][256] = {
+static const uint32 pg_crc32c_table[8][256] = {
 #ifndef WORDS_BIGENDIAN
 	{
 		0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
@@ -643,7 +731,7 @@ const uint32 pg_crc32c_table[8][256] = {
 		0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
 		0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5
 	}
-#else		/* !WORDS_BIGENDIAN */
+#else							/* !WORDS_BIGENDIAN */
 	{
 		0x00000000, 0x03836BF2, 0xF7703BE1, 0xF4F35013,
 		0x1F979AC7, 0x1C14F135, 0xE8E7A126, 0xEB64CAD4,
@@ -1172,9 +1260,10 @@ const uint32 pg_crc32c_table[8][256] = {
 		0xA1354CE5, 0x864870AC, 0xEFCF3477, 0xC8B2083E,
 		0xCCB751C4, 0xEBCA6D8D, 0x824D2956, 0xA530151F
 	}
-#endif /* WORDS_BIGENDIAN */
+#endif   /* WORDS_BIGENDIAN */
 };
 
+#endif
 
 /*
  * Lookup table for calculating CRC-32 using Sarwate's algorithm.
diff --git a/src/include/common/pg_crc.h b/src/include/common/pg_crc.h
index f496659..de1ebdf 100644
--- a/src/include/common/pg_crc.h
+++ b/src/include/common/pg_crc.h
@@ -32,6 +32,8 @@
 #ifndef PG_CRC_H
 #define PG_CRC_H
 
+#include "port/crc_instructions.h"
+
 /* ugly hack to let this be used in frontend and backend code on Cygwin */
 #ifdef FRONTEND
 #define CRCDLLIMPORT
@@ -63,15 +65,19 @@ typedef uint32 pg_crc32;
  */
 #define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
 #ifdef WORDS_BIGENDIAN
-#define FIN_CRC32C(crc)	((crc) = BSWAP32(crc) ^ 0xFFFFFFFF)
+#define FIN_CRC32C(crc) ((crc) = BSWAP32(crc) ^ 0xFFFFFFFF)
 #else
-#define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
+#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
 #endif
-#define COMP_CRC32C(crc, data, len)	\
+#define COMP_CRC32C(crc, data, len) \
 	((crc) = pg_comp_crc32c((crc), (data), (len)))
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
+#ifdef PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+extern pg_crc32 (*pg_comp_crc32c) (pg_crc32 crc, const void *data, size_t len);
+#else
 extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
+#endif
 
 /*
  * CRC-32, the same used e.g. in Ethernet.
@@ -130,13 +136,15 @@ do {															  \
 \
 	while (__len-- > 0) \
 	{ \
-		int		__tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF;	\
+		int		__tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF; \
 		(crc) = table[__tab_index] ^ ((crc) << 8); \
 	} \
 } while (0)
 
-/* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
+/*
+ * Constant table for the CRC-32 polynomial (the tables for CRC-32C are
+ * static in pg_crc.c)
+ */
 extern CRCDLLIMPORT const uint32 pg_crc32_table[256];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 202c51a..129d9d0 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -96,6 +96,9 @@
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
+/* Define to 1 if you have the <cpuid.h> header file. */
+#undef HAVE_CPUID_H
+
 /* Define to 1 if you have the <crtdefs.h> header file. */
 #undef HAVE_CRTDEFS_H
 
diff --git a/src/include/port/crc_instructions.h b/src/include/port/crc_instructions.h
new file mode 100644
index 0000000..357890f
--- /dev/null
+++ b/src/include/port/crc_instructions.h
@@ -0,0 +1,128 @@
+/*-------------------------------------------------------------------------
+ *
+ * crc_instructions.h
+ *	  Hardware support for calculating CRCs.
+ *
+ * Some CPU architectures have special instructions for speeding up CRC
+ * calculations. This header files provides access to them in a reasonably
+ * platform and compiler independent way.
+ *
+ * This header file defines two preprocessor symbols, or not, depending on
+ * the current platform:
+ *
+ * PG_HAVE_CRC32C_INSTRUCTIONS
+ *		Defined if this architecture has a special instruction for CRC32C
+ *		calculation.
+ *
+ * PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+ *		Defined if the architecture has a special instruction for CRC32C
+ *		calculation, but it's not available on all platforms that this
+ *		binary supports. A runtime check must be performed before
+ *		attempting to use the instructions, and a fallback implementation
+ *		is needed.
+ *
+ * If PG_HAVE_CRC32C_INSTRUCTIONS is defined, two inline functions or macros
+ * are also defined:
+ *
+ * uint32 pg_accumulate_crc32c_byte(uint32 crc, unsigned char data)
+ *		Add one byte to the current crc value.
+ *
+ * uint32 pg_accumulate_crc32c_uint64(uint32 crc, uint64 data)
+ *		Add eight bytes of data to the current crc value.
+ *
+ * If PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK is defined, there following
+ * inline function or macro is also defined:
+ *
+ * bool pg_crc32_instructions_runtime_check(void)
+ *		Returns 'true' if the CRC instructions can be used, 'false'
+ *		otherwise.
+ *
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/port/crc_instructions.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef CRC_INSTRUCTIONS_H
+#define CRC_INSTRUCTIONS_H
+
+#ifdef HAVE_CPUID_H
+#include <cpuid.h>
+#endif
+#ifdef _MSC_VER
+#include <intrin.h>
+#include <nmmintrin.h>
+#endif
+
+
+/*
+ * Intel SSE 4.2 instructions, using GCC-style inline assembly
+ */
+#if (defined(__GNUC__) && defined(__x86_64__) && defined(HAVE_CPUID_H))
+
+#define PG_HAVE_CRC32C_INSTRUCTIONS
+#define PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+
+static inline uint32
+pg_asm_crc32b(uint32 crc, unsigned char data)
+{
+	__asm__(
+			"crc32b %[data], %[crc]\n"
+:			[crc] "+r"(crc)
+:			[data] "rm"(data));
+	return crc;
+}
+
+static inline uint32
+pg_asm_crc32q(uint32 crc, uint64 data)
+{
+	/*
+	 * For some strange reason, the crc32q instruction accepts and returns the
+	 * current crc value as a 64-bit integer, even though the upper 32 bits
+	 * are always zeros.
+	 */
+	uint64		_crc = crc;
+
+	__asm__(
+			"crc32q %[data], %[crc]\n"
+:			[crc] "+r"(_crc)
+:			[data] "rm"(data));
+	return (uint32) _crc;
+}
+
+static inline bool
+pg_crc32_instructions_runtime_check(void)
+{
+	unsigned int exx[4] = {0, 0, 0, 0};
+
+	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+
+	return (exx[2] & (1 << 20));	/* SSE 4.2 */
+}
+
+/*
+ * Intel SSE 4.2 instructions, using Microsoft intrinsics
+ */
+#elif defined(_MSC_VER)
+
+#define PG_HAVE_CRC32C_INSTRUCTIONS
+#define PG_CRC32C_INSTRUCTIONS_NEED_RUNTIME_CHECK
+
+#define pg_asm_crc32b(crc, data) _mm_crc32_u8(crc, data)
+#define pg_asm_crc32q(crc, data) ((uint32) _mm_crc32_u64(crc, data))
+
+static inline bool
+pg_crc32_instructions_runtime_check(void)
+{
+	unsigned int exx[4] = {0, 0, 0, 0};
+
+	__cpuid(exx, 1);
+
+	return (exx[2] & (1 << 20));	/* SSE 4.2 */
+}
+
+#endif   /* _MSC_VER */
+
+#endif   /* CRC_INSTRUCTIONS_H */
-- 
2.1.4

#63Andres Freund
andres@2ndquadrant.com
In reply to: Heikki Linnakangas (#62)
Re: What exactly is our CRC algorithm?

On 2015-03-25 19:18:51 +0200, Heikki Linnakangas wrote:

I was just about to commit the attached, which is the same as the previous
patch with just cosmetic comment changes, but then I realized that this
probably doesn't compile with Visual Studio 2005 or older. The code does
"#ifdef _MSC_VER", and then uses the _mm_crc32_u64 intrinsic, but that
intrinsic was added in Visual Studio 2008. I think we'll need a version
check there.

Good catch.

Or better yet, a direct configure test to check if the
intrinsic exists - that way we get to also use it on Intel compilers, which
I believe also has the same intrinsics.

Maybe I'm missing something, but configure isn't run for msvc?

Greetings,

Andres Freund

--
Andres Freund http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#64Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Andres Freund (#63)
Re: What exactly is our CRC algorithm?

On 03/25/2015 07:20 PM, Andres Freund wrote:

On 2015-03-25 19:18:51 +0200, Heikki Linnakangas wrote:

Or better yet, a direct configure test to check if the
intrinsic exists - that way we get to also use it on Intel compilers, which
I believe also has the same intrinsics.

Maybe I'm missing something, but configure isn't run for msvc?

Good point. On MSVC, we use the pre-built pg_config.h.win32 file
instead. There are already a couple of cases like this in it:

/* Define to 1 if you have the `rint' function. */
#if (_MSC_VER >= 1800)
#define HAVE_RINT 1
#endif

I think we should do that for the CRC32 intrinsic too.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#65Petr Jelinek
petr@2ndquadrant.com
In reply to: Heikki Linnakangas (#64)
Re: What exactly is our CRC algorithm?

On 25/03/15 18:24, Heikki Linnakangas wrote:

On 03/25/2015 07:20 PM, Andres Freund wrote:

On 2015-03-25 19:18:51 +0200, Heikki Linnakangas wrote:

Or better yet, a direct configure test to check if the
intrinsic exists - that way we get to also use it on Intel compilers,
which
I believe also has the same intrinsics.

Maybe I'm missing something, but configure isn't run for msvc?

Good point. On MSVC, we use the pre-built pg_config.h.win32 file
instead. There are already a couple of cases like this in it:

/* Define to 1 if you have the `rint' function. */
#if (_MSC_VER >= 1800)
#define HAVE_RINT 1
#endif

I think we should do that for the CRC32 intrinsic too.

Yeah, 1500 being MSVC 2008. But I think there is little point in putting
it in pg_config.h.win32 when it's only going to be used in 2 places in
single header file.

Do you plan to commit this otherwise as is?

--
Petr Jelinek http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#66Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#62)
Re: What exactly is our CRC algorithm?

At 2015-03-25 19:18:51 +0200, hlinnaka@iki.fi wrote:

I think we'll need a version check there. […]

You want to write that or should I?

I'm not familiar with MSVC at all, so it would be nice if you did it.

How do you like this latest version of the patch otherwise?

I'm sorry, but I'm still not especially fond of it.

Apart from removing the startup check so that client programs can also
use the best available CRC32C implementation without jumping through
hoops, I don't feel that the other changes buy us very much.

Also, assuming that the point is that people who don't care about CRCs
deeply should nevertheless be able to produce special-purpose binaries
with only the optimal implementation included, we should probably have
some instructions about how to do that.

Thinking about what you were trying to do, I would find an arrangement
roughly like the following to be clearer to follow in terms of adding
new implementations and so on:

#if defined(USE_CRC_SSE42) || …can build SSE4.2 CRC code…
#define HAVE_CRC_SSE42 1
pg_crc32c_sse42() { … }
bool sse42_crc32c_available() { … }
pg_comp_crc32c = pg_crc32c_sse42;
#elif defined(USE_CRC_ARM) || …can build ARM CRC code…
#define HAVE_CRC_ARM 1
pg_crc32c_arm() { … }
bool arm_crc32c_available() { … }
pg_comp_crc32c = pg_crc32c_arm;
#endif

#define CRC_SELECTION 1
#if defined(USE_CRC_SSE42) || defined(USE_CRC_ARM) || …
#undef CRC_SELECTION
#endif

#ifdef CRC_SELECTION
pg_crc32c_sb8() { … }

pg_comp_crc32c_choose(…)
{
pg_comp_crc32c = pg_crc32c_sb8;

#ifdef HAVE_CRC_SSE42
if (sse42_crc32c_available())
pg_comp_crc32c = pg_crc32c_sse42;
#elif …

#endif

return pg_comp_crc32c(…);
}

pg_comp_crc32c = pg_crc32c_choose;
#endif

Then someone who wants to force the building of (only) the SSE4.2
implementation can build with -DUSE_CRC_SSE42. And if you turn on
USE_CRC_ARM when you can't build ARM code, it won't build. (The
HAVE_CRC_xxx #defines could also move to configure tests.)

If you don't specify any USE_CRC_xxx explicitly, then it'll build
whichever (probably) one it can, and select it at runtime if it's
available.

All that said, I do recognise that there are all relatively cosmetic
concerns, and I don't object seriously to any of it. On the contrary,
thanks for taking the time to review and work on the patch. Nobody
else has expressed an opinion, so I'll leave it to you to decide whether
to commit as-is, or if you want me to pursue the above approach instead.

In the realm of very minor nitpicking, here are a couple of points I
noticed in crc_instructions.h:

1. I think «if (pg_crc32_instructions_runtime_check())» would read
better if the function were named crc32c_instructions_available or
pg_crc32c_is_hw_accelerated, or something like that.

2. It documents pg_accumulate_crc32c_byte and
pg_accumulate_crc32c_uint64, but actually defines pg_asm_crc32b and
pg_asm_crc32q. If you update the code rather than the documentation,
_update_ may be slightly preferable to _accumulate_, and maybe the
suffixes should be _uint8 and _uint64.

3. The descriptions (e.g. "Add one byte to the current crc value.")
should also probably read "Update the current crc value for the given
byte/eight bytes of data".

Thanks.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#67Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Abhijit Menon-Sen (#66)
Re: What exactly is our CRC algorithm?

On 04/02/2015 12:39 PM, Abhijit Menon-Sen wrote:

At 2015-03-25 19:18:51 +0200, hlinnaka@iki.fi wrote:

I think we'll need a version check there. […]

You want to write that or should I?

I'm not familiar with MSVC at all, so it would be nice if you did it.

Thinking more about the configure checks, I think the current approach
of using inline assembly on gcc is not quite right. We're only using
inline assembly to force producing SSE 4.2 code, even when -msse4.2 is
not used. That feels wrong.

And who's to say that the assembler supports the SSE instructions
anyway? At least we'd need a configure check for that too. We have a
buildfarm animal that still uses gcc 2.95.3, which was released in 2001.
I don't have a compiler of that vintage to test with, but I assume an
old enough assembler would not know about the crc32q instruction and
fail to compile.

I believe the GCC way to do this would be to put the SSE4.2-specific
code into a separate source file, and compile that file with "-msse4.2".
And when you compile with -msse4.2, gcc actually also supports the
_mm_crc32_u8/u64 intrinsics.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#68Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#67)
Re: What exactly is our CRC algorithm?

At 2015-04-02 17:58:23 +0300, hlinnaka@iki.fi wrote:

We're only using inline assembly to force producing SSE 4.2 code, even
when -msse4.2 is not used. That feels wrong.

Why? It feels OK to me (and to Andres, per earlier discussions about
exactly this topic). Doing it this way allows the binary to run on a
non-SSE4.2 platform (and not use the CRC instructions).

Also, -msse4.2 was added to the compiler later than support for the
instructions was added to the assembler.

We have a buildfarm animal that still uses gcc 2.95.3, which was
released in 2001. I don't have a compiler of that vintage to test
with, but I assume an old enough assembler would not know about the
crc32q instruction and fail to compile.

GCC from <2002 wouldn't support the symbolic operand names in inline
assembly. binutils from <2007 (IIRC) wouldn't support the assembler
instructions themselves.

We could work around the latter by using the appropriate sequence of
bytes. We could work around the former by using the old syntax for
operands.

I believe the GCC way to do this would be to put the SSE4.2-specific
code into a separate source file, and compile that file with
"-msse4.2". And when you compile with -msse4.2, gcc actually also
supports the _mm_crc32_u8/u64 intrinsics.

I have no objection to this.

Building only that file with -msse4.2 would resolve the problem of the
output binary requiring SSE4.2; and the only compilers to be excluded
are old enough to be uninteresting at least to me personally.

Have you done/are you doing this already, or do you want me to? I could
use advice on how to add build flags to only one file, since I don't
know of any precendent for that.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#69Andres Freund
andres@anarazel.de
In reply to: Abhijit Menon-Sen (#68)
Re: What exactly is our CRC algorithm?

On 2015-04-02 20:57:24 +0530, Abhijit Menon-Sen wrote:

At 2015-04-02 17:58:23 +0300, hlinnaka@iki.fi wrote:

We're only using inline assembly to force producing SSE 4.2 code, even
when -msse4.2 is not used. That feels wrong.

Why? It feels OK to me (and to Andres, per earlier discussions about
exactly this topic). Doing it this way allows the binary to run on a
non-SSE4.2 platform (and not use the CRC instructions).

Right. And SSE4.2 isn't that widespread yet.

I believe the GCC way to do this would be to put the SSE4.2-specific
code into a separate source file, and compile that file with
"-msse4.2". And when you compile with -msse4.2, gcc actually also
supports the _mm_crc32_u8/u64 intrinsics.

To me this seems like a somewhat pointless exercise. I actually think
from a performance POV it's better to have all the functions in one
source file, so the compiler can inline things into the trampoline if it
feels like it.

Greetings,

Andres Freund

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#70Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Abhijit Menon-Sen (#68)
1 attachment(s)
Re: What exactly is our CRC algorithm?

On 04/02/2015 06:27 PM, Abhijit Menon-Sen wrote:

At 2015-04-02 17:58:23 +0300, hlinnaka@iki.fi wrote:

We're only using inline assembly to force producing SSE 4.2 code, even
when -msse4.2 is not used. That feels wrong.

Why? It feels OK to me (and to Andres, per earlier discussions about
exactly this topic). Doing it this way allows the binary to run on a
non-SSE4.2 platform (and not use the CRC instructions).

Being able to run on non-SSE4.2 platforms is required, for sure.

Also, -msse4.2 was added to the compiler later than support for the
instructions was added to the assembler.

It was added in gcc 4.2. That's good enough for me.

We have a buildfarm animal that still uses gcc 2.95.3, which was
released in 2001. I don't have a compiler of that vintage to test
with, but I assume an old enough assembler would not know about the
crc32q instruction and fail to compile.

GCC from <2002 wouldn't support the symbolic operand names in inline
assembly. binutils from <2007 (IIRC) wouldn't support the assembler
instructions themselves.

We could work around the latter by using the appropriate sequence of
bytes. We could work around the former by using the old syntax for
operands.

I'm OK with not supporting the new instructions when building with an
old compiler/assembler. But the build shouldn't fail with an old
compiler/assembler. Using old syntax or raw bytes just to avoid failing
on an ancient compiler seems ugly.

I believe the GCC way to do this would be to put the SSE4.2-specific
code into a separate source file, and compile that file with
"-msse4.2". And when you compile with -msse4.2, gcc actually also
supports the _mm_crc32_u8/u64 intrinsics.

I have no objection to this.

Building only that file with -msse4.2 would resolve the problem of the
output binary requiring SSE4.2; and the only compilers to be excluded
are old enough to be uninteresting at least to me personally.

Have you done/are you doing this already, or do you want me to? I could
use advice on how to add build flags to only one file, since I don't
know of any precendent for that.

I came up with the attached. The SSE4.2 specific code is now in a
separate file, in src/port/pg_crc32c_sse42.c. The slicing-by-8
implementation is moved to src/port/pg_crc32c_sb8.c, and the function to
choose the implementation at runtime is in src/port/pg_crc32c_choose.c.
How does this look to you?

BTW, we might want to move the "traditional" and "legacy" crc32
implementations out of src/common. They are only used in backend code now.

- Heikki

Attachments:

v3-0001-Use-Intel-SSE4.2-CRC-instructions-where-available.patchapplication/x-patch; name=v3-0001-Use-Intel-SSE4.2-CRC-instructions-where-available.patchDownload
From 6ed14e6eff165ea155961b93e79d8d1f34a7715d Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Wed, 25 Mar 2015 18:44:07 +0200
Subject: [PATCH v3 1/1] Use Intel SSE4.2 CRC instructions where available.

On x86, perform a runtime check to see if we're running on a CPU that
supports SSE 4.2. If we are, we can use the special crc32b and crc32q
instructions for the CRC-32C calculations. That greatly speeds up CRC
calculation.

Abhijit Menon-Sen, reviewed by Andres Freund and me.
---
 configure                     |  157 ++++++
 configure.in                  |   63 +++
 src/Makefile.global.in        |    4 +
 src/common/pg_crc.c           | 1155 ----------------------------------------
 src/include/common/pg_crc.h   |   32 +-
 src/include/pg_config.h.in    |   13 +
 src/include/pg_config.h.win32 |   20 +-
 src/include/port/pg_crc32c.h  |   79 +++
 src/port/Makefile             |    7 +-
 src/port/pg_crc32c_choose.c   |   63 +++
 src/port/pg_crc32c_sb8.c      | 1169 +++++++++++++++++++++++++++++++++++++++++
 src/port/pg_crc32c_sse42.c    |   57 ++
 src/tools/msvc/Mkvcbuild.pm   |    9 +
 13 files changed, 1642 insertions(+), 1186 deletions(-)
 create mode 100644 src/include/port/pg_crc32c.h
 create mode 100644 src/port/pg_crc32c_choose.c
 create mode 100644 src/port/pg_crc32c_sb8.c
 create mode 100644 src/port/pg_crc32c_sse42.c

diff --git a/configure b/configure
index 2c9b3a7..97e7c7a 100755
--- a/configure
+++ b/configure
@@ -650,6 +650,8 @@ MSGMERGE
 MSGFMT_FLAGS
 MSGFMT
 HAVE_POSIX_SIGNALS
+PG_CRC32C_OBJS
+CFLAGS_SSE42
 LDAP_LIBS_BE
 LDAP_LIBS_FE
 PTHREAD_CFLAGS
@@ -14054,6 +14056,161 @@ $as_echo "#define HAVE_GCC__ATOMIC_INT64_CAS 1" >>confdefs.h
 
 fi
 
+
+# Check for x86 cpuid instruction
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __get_cpuid" >&5
+$as_echo_n "checking for __get_cpuid... " >&6; }
+if ${pgac_cv__get_cpuid+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <cpuid.h>
+int
+main ()
+{
+unsigned int exx[4] = {0, 0, 0, 0};
+  __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  pgac_cv__get_cpuid="yes"
+else
+  pgac_cv__get_cpuid="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__get_cpuid" >&5
+$as_echo "$pgac_cv__get_cpuid" >&6; }
+if test x"$pgac_cv__get_cpuid" = x"yes"; then
+
+$as_echo "#define HAVE__GET_CPUID 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __cpuid" >&5
+$as_echo_n "checking for __cpuid... " >&6; }
+if ${pgac_cv__cpuid+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <intrin.h>
+int
+main ()
+{
+unsigned int exx[4] = {0, 0, 0, 0};
+  __get_cpuid(exx[0], 1);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  pgac_cv__cpuid="yes"
+else
+  pgac_cv__cpuid="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv__cpuid" >&5
+$as_echo "$pgac_cv__cpuid" >&6; }
+if test x"$pgac_cv__cpuid" = x"yes"; then
+
+$as_echo "#define HAVE__CPUID 1" >>confdefs.h
+
+fi
+
+# Check for Intel SSE 4.2 intrinsics to do CRC calculations.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mm_crc32_u8 and _mm_crc32_u64 intrinsics" >&5
+$as_echo_n "checking for _mm_crc32_u8 and _mm_crc32_u64 intrinsics... " >&6; }
+if ${pgac_cv_mm_crc32_intrinsics+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <nmmintrin.h>
+int
+main ()
+{
+unsigned int crc; crc = _mm_crc32_u8(crc, 0); crc = (unsigned int) _mm_crc32_u64(crc, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  pgac_cv_mm_crc32_intrinsics="yes"
+else
+  pgac_cv_mm_crc32_intrinsics="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_mm_crc32_intrinsics" >&5
+$as_echo "$pgac_cv_mm_crc32_intrinsics" >&6; }
+
+if test x"$pgac_cv_mm_crc32_intrinsics" = x"yes"; then
+
+$as_echo "#define HAVE_MM_CRC32_INTRINSICS 1" >>confdefs.h
+
+  PG_CRC32C_OBJS="pg_crc32c_sse42.o"
+else
+  # Intrinsics don't work out of the box, check if adding -msse4.2 compiler
+  # option helps. But only support this if we the cpuid instruction is
+  # available, so that we can check at runtime that SSE4.2 is available.
+if test x"$pgac_cv__get_cpuid" = x"yes" || test x"$pgac_cv__cpuid"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _mm_crc32_u8 and _mm_crc32_u64 intrinsics with -msse4.2" >&5
+$as_echo_n "checking for _mm_crc32_u8 and _mm_crc32_u64 intrinsics with -msse4.2... " >&6; }
+if ${pgac_cv_mm_crc32_intrinsics_with_msse42+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  pgac_save_CFLAGS=$CFLAGS
+    CFLAGS="$pgac_save_CFLAGS -msse4.2"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <nmmintrin.h>
+int
+main ()
+{
+unsigned int crc; crc = _mm_crc32_u8(crc, 0); crc = (unsigned int) _mm_crc32_u64(crc, 0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  pgac_cv_mm_crc32_intrinsics_with_msse42="yes"
+else
+  pgac_cv_mm_crc32_intrinsics_with_msse42="no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+    CFLAGS="$pgac_save_CFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_mm_crc32_intrinsics_with_msse42" >&5
+$as_echo "$pgac_cv_mm_crc32_intrinsics_with_msse42" >&6; }
+
+  if test x"$pgac_cv_mm_crc32_intrinsics_with_msse42" = x"yes"; then
+
+$as_echo "#define HAVE_MM_CRC32_INTRINSICS_WITH_RUNTIME_CHECK 1" >>confdefs.h
+
+    CFLAGS_SSE42="-msse4.2"
+    PG_CRC32C_OBJS="pg_crc32c_sse42.o pg_crc32c_sb8.o pg_crc32c_choose.o"
+  else
+    PG_CRC32C_OBJS="pg_crc32c_sb8.o"
+  fi
+fi
+fi
+
+
+
+
+# Check that POSIX signals are available if thread safety is enabled.
 if test "$PORTNAME" != "win32"
 then
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for POSIX signal interface" >&5
diff --git a/configure.in b/configure.in
index b2c1ce7..fc5084f 100644
--- a/configure.in
+++ b/configure.in
@@ -1783,6 +1783,69 @@ PGAC_HAVE_GCC__SYNC_INT64_CAS
 PGAC_HAVE_GCC__ATOMIC_INT32_CAS
 PGAC_HAVE_GCC__ATOMIC_INT64_CAS
 
+
+# Check for x86 cpuid instruction
+AC_CACHE_CHECK([for __get_cpuid], [pgac_cv__get_cpuid],
+[AC_TRY_LINK([#include <cpuid.h>],
+  [unsigned int exx[4] = {0, 0, 0, 0};
+  __get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+],
+  [pgac_cv__get_cpuid="yes"],
+  [pgac_cv__get_cpuid="no"])])
+if test x"$pgac_cv__get_cpuid" = x"yes"; then
+  AC_DEFINE(HAVE__GET_CPUID, 1, [Define to 1 if you have __get_cpuid.])
+fi
+
+AC_CACHE_CHECK([for __cpuid], [pgac_cv__cpuid],
+[AC_TRY_LINK([#include <intrin.h>],
+  [unsigned int exx[4] = {0, 0, 0, 0};
+  __get_cpuid(exx[0], 1);
+],
+  [pgac_cv__cpuid="yes"],
+  [pgac_cv__cpuid="no"])])
+if test x"$pgac_cv__cpuid" = x"yes"; then
+  AC_DEFINE(HAVE__CPUID, 1, [Define to 1 if you have __cpuid.])
+fi
+
+# Check for Intel SSE 4.2 intrinsics to do CRC calculations.
+AC_CACHE_CHECK([for _mm_crc32_u8 and _mm_crc32_u64 intrinsics], [pgac_cv_mm_crc32_intrinsics],
+[AC_TRY_LINK([#include <nmmintrin.h>],
+  [unsigned int crc; crc = _mm_crc32_u8(crc, 0); crc = (unsigned int) _mm_crc32_u64(crc, 0); ],
+  [pgac_cv_mm_crc32_intrinsics="yes"],
+  [pgac_cv_mm_crc32_intrinsics="no"])])
+
+if test x"$pgac_cv_mm_crc32_intrinsics" = x"yes"; then
+  AC_DEFINE(HAVE_MM_CRC32_INTRINSICS, 1, [Define to 1 if you have _mm_crc32_u8() and _mm_crc32_u64().])
+  PG_CRC32C_OBJS="pg_crc32c_sse42.o"
+else
+  # Intrinsics don't work out of the box, check if adding -msse4.2 compiler
+  # option helps. But only support this if we the cpuid instruction is
+  # available, so that we can check at runtime that SSE4.2 is available.
+if test x"$pgac_cv__get_cpuid" = x"yes" || test x"$pgac_cv__cpuid"; then
+  AC_CACHE_CHECK([for _mm_crc32_u8 and _mm_crc32_u64 intrinsics with -msse4.2], [pgac_cv_mm_crc32_intrinsics_with_msse42],
+  [pgac_save_CFLAGS=$CFLAGS
+    CFLAGS="$pgac_save_CFLAGS -msse4.2"
+    AC_TRY_LINK([#include <nmmintrin.h>],
+      [unsigned int crc; crc = _mm_crc32_u8(crc, 0); crc = (unsigned int) _mm_crc32_u64(crc, 0);],
+      [pgac_cv_mm_crc32_intrinsics_with_msse42="yes"],
+      [pgac_cv_mm_crc32_intrinsics_with_msse42="no"])
+    CFLAGS="$pgac_save_CFLAGS"
+])
+
+  if test x"$pgac_cv_mm_crc32_intrinsics_with_msse42" = x"yes"; then
+    AC_DEFINE(HAVE_MM_CRC32_INTRINSICS_WITH_RUNTIME_CHECK, 1, [Define to 1 if you have _mm_crc32_u8() and _mm_crc32_u64(), but they need a runtime check.])
+    CFLAGS_SSE42="-msse4.2"
+    PG_CRC32C_OBJS="pg_crc32c_sse42.o pg_crc32c_sb8.o pg_crc32c_choose.o"
+  else
+    PG_CRC32C_OBJS="pg_crc32c_sb8.o"
+  fi
+fi
+fi
+AC_SUBST(CFLAGS_SSE42)
+AC_SUBST(PG_CRC32C_OBJS)
+
+
+# Check that POSIX signals are available if thread safety is enabled.
 if test "$PORTNAME" != "win32"
 then
 PGAC_FUNC_POSIX_SIGNALS
diff --git a/src/Makefile.global.in b/src/Makefile.global.in
index 7c39d82..4b06fc2 100644
--- a/src/Makefile.global.in
+++ b/src/Makefile.global.in
@@ -225,6 +225,7 @@ GCC = @GCC@
 SUN_STUDIO_CC = @SUN_STUDIO_CC@
 CFLAGS = @CFLAGS@
 CFLAGS_VECTOR = @CFLAGS_VECTOR@
+CFLAGS_SSE42 = @CFLAGS_SSE42@
 
 # Kind-of compilers
 
@@ -548,6 +549,9 @@ endif
 
 LIBOBJS = @LIBOBJS@
 
+# files needed for the chosen CRC-32C implementation
+PG_CRC32C_OBJS = @PG_CRC32C_OBJS@
+
 LIBS := -lpgcommon -lpgport $(LIBS)
 
 # to make ws2_32.lib the last library
diff --git a/src/common/pg_crc.c b/src/common/pg_crc.c
index eba32d3..6fc56c4 100644
--- a/src/common/pg_crc.c
+++ b/src/common/pg_crc.c
@@ -21,1161 +21,6 @@
 
 #include "common/pg_crc.h"
 
-/* Accumulate one input byte */
-#ifdef WORDS_BIGENDIAN
-#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
-#else
-#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
-#endif
-
-/*
- * This function computes a CRC using the slicing-by-8 algorithm, which
- * uses an 8*256 lookup table to operate on eight bytes in parallel and
- * recombine the results.
- *
- * Michael E. Kounavis, Frank L. Berry,
- * "Novel Table Lookup-Based Algorithms for High-Performance CRC
- * Generation", IEEE Transactions on Computers, vol.57, no. 11,
- * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85
- */
-pg_crc32
-pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len)
-{
-	const unsigned char *p = data;
-	const uint32 *p4;
-
-	/*
-	 * Handle 0-3 initial bytes one at a time, so that the loop below starts
-	 * with a pointer aligned to four bytes.
-	 */
-	while (len > 0 && ((uintptr_t) p & 3))
-	{
-		crc = CRC8(*p++);
-		len--;
-	}
-
-	/*
-	 * Process eight bytes of data at a time.
-	 */
-	p4 = (const uint32 *) p;
-	while (len >= 8)
-	{
-		uint32		a = *p4++ ^ crc;
-		uint32		b = *p4++;
-
-#ifdef WORDS_BIGENDIAN
-		const uint8 c0 = b;
-		const uint8 c1 = b >> 8;
-		const uint8 c2 = b >> 16;
-		const uint8 c3 = b >> 24;
-		const uint8 c4 = a;
-		const uint8 c5 = a >> 8;
-		const uint8 c6 = a >> 16;
-		const uint8 c7 = a >> 24;
-#else
-		const uint8 c0 = b >> 24;
-		const uint8 c1 = b >> 16;
-		const uint8 c2 = b >> 8;
-		const uint8 c3 = b;
-		const uint8 c4 = a >> 24;
-		const uint8 c5 = a >> 16;
-		const uint8 c6 = a >> 8;
-		const uint8 c7 = a;
-#endif
-
-		crc =
-			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
-			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
-			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
-			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
-
-		len -= 8;
-	}
-
-	/*
-	 * Handle any remaining bytes one at a time.
-	 */
-	p = (const unsigned char *) p4;
-	while (len > 0)
-	{
-		crc = CRC8(*p++);
-		len--;
-	}
-
-	return crc;
-}
-
-/*
- * Lookup tables for the slicing-by-8 algorithm, for the so-called Castagnoli
- * polynomial (the same that is used e.g. in iSCSI), 0x1EDC6F41. Using
- * Williams' terms, this is the "normal", not "reflected" version. However, on
- * big-endian systems the values in the tables are stored in byte-reversed
- * order (IOW, the tables are stored in little-endian order even on big-endian
- * systems).
- */
-const uint32 pg_crc32c_table[8][256] = {
-#ifndef WORDS_BIGENDIAN
-	{
-		0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
-		0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
-		0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
-		0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
-		0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
-		0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
-		0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
-		0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
-		0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
-		0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
-		0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
-		0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
-		0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
-		0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
-		0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
-		0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
-		0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
-		0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
-		0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
-		0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
-		0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
-		0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
-		0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
-		0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
-		0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
-		0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
-		0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
-		0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
-		0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
-		0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
-		0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
-		0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
-		0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
-		0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
-		0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
-		0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
-		0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
-		0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
-		0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
-		0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
-		0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
-		0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
-		0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
-		0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
-		0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
-		0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
-		0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
-		0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
-		0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
-		0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
-		0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
-		0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
-		0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
-		0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
-		0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
-		0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
-		0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
-		0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
-		0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
-		0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
-		0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
-		0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
-		0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
-		0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
-	},
-	{
-		0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
-		0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
-		0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
-		0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
-		0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
-		0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
-		0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
-		0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
-		0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
-		0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
-		0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
-		0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
-		0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
-		0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
-		0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
-		0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
-		0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
-		0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
-		0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
-		0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
-		0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
-		0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
-		0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
-		0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
-		0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
-		0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
-		0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
-		0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
-		0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
-		0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
-		0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
-		0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
-		0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
-		0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
-		0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
-		0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
-		0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
-		0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
-		0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
-		0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
-		0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
-		0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
-		0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
-		0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
-		0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
-		0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
-		0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
-		0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
-		0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
-		0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
-		0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
-		0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
-		0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
-		0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
-		0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
-		0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
-		0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
-		0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
-		0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
-		0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
-		0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
-		0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
-		0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
-		0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483
-	},
-	{
-		0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
-		0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
-		0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
-		0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
-		0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
-		0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
-		0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
-		0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
-		0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
-		0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
-		0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
-		0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
-		0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
-		0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
-		0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
-		0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
-		0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
-		0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
-		0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
-		0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
-		0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
-		0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
-		0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
-		0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
-		0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
-		0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
-		0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
-		0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
-		0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
-		0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
-		0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
-		0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
-		0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
-		0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
-		0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
-		0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
-		0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
-		0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
-		0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
-		0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
-		0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
-		0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
-		0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
-		0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
-		0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
-		0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
-		0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
-		0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
-		0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
-		0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
-		0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
-		0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
-		0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
-		0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
-		0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
-		0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
-		0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
-		0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
-		0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
-		0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
-		0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
-		0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
-		0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
-		0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8
-	},
-	{
-		0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
-		0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
-		0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
-		0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
-		0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
-		0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
-		0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
-		0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
-		0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
-		0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
-		0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
-		0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
-		0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
-		0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
-		0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
-		0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
-		0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
-		0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
-		0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
-		0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
-		0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
-		0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
-		0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
-		0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
-		0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
-		0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
-		0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
-		0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
-		0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
-		0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
-		0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
-		0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
-		0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
-		0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
-		0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
-		0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
-		0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
-		0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
-		0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
-		0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
-		0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
-		0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
-		0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
-		0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
-		0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
-		0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
-		0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
-		0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
-		0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
-		0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
-		0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
-		0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
-		0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
-		0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
-		0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
-		0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
-		0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
-		0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
-		0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
-		0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
-		0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
-		0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
-		0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
-		0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842
-	},
-	{
-		0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
-		0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
-		0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
-		0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
-		0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
-		0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
-		0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
-		0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
-		0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
-		0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
-		0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
-		0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
-		0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
-		0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
-		0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
-		0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
-		0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
-		0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
-		0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
-		0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
-		0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
-		0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
-		0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
-		0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
-		0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
-		0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
-		0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
-		0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
-		0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
-		0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
-		0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
-		0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
-		0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
-		0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
-		0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
-		0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
-		0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
-		0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
-		0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
-		0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
-		0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
-		0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
-		0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
-		0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
-		0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
-		0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
-		0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
-		0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
-		0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
-		0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
-		0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
-		0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
-		0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
-		0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
-		0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
-		0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
-		0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
-		0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
-		0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
-		0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
-		0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
-		0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
-		0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
-		0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3
-	},
-	{
-		0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
-		0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
-		0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
-		0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
-		0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
-		0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
-		0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
-		0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
-		0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
-		0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
-		0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
-		0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
-		0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
-		0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
-		0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
-		0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
-		0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
-		0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
-		0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
-		0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
-		0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
-		0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
-		0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
-		0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
-		0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
-		0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
-		0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
-		0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
-		0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
-		0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
-		0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
-		0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
-		0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
-		0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
-		0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
-		0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
-		0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
-		0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
-		0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
-		0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
-		0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
-		0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
-		0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
-		0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
-		0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
-		0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
-		0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
-		0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
-		0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
-		0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
-		0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
-		0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
-		0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
-		0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
-		0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
-		0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
-		0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
-		0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
-		0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
-		0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
-		0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
-		0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
-		0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
-		0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C
-	},
-	{
-		0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
-		0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
-		0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
-		0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
-		0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
-		0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
-		0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
-		0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
-		0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
-		0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
-		0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
-		0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
-		0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
-		0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
-		0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
-		0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
-		0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
-		0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
-		0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
-		0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
-		0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
-		0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
-		0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
-		0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
-		0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
-		0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
-		0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
-		0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
-		0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
-		0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
-		0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
-		0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
-		0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
-		0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
-		0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
-		0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
-		0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
-		0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
-		0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
-		0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
-		0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
-		0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
-		0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
-		0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
-		0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
-		0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
-		0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
-		0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
-		0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
-		0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
-		0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
-		0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
-		0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
-		0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
-		0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
-		0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
-		0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
-		0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
-		0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
-		0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
-		0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
-		0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
-		0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
-		0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F
-	},
-	{
-		0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
-		0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
-		0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
-		0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
-		0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
-		0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
-		0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
-		0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
-		0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
-		0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
-		0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
-		0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
-		0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
-		0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
-		0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
-		0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
-		0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
-		0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
-		0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
-		0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
-		0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
-		0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
-		0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
-		0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
-		0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
-		0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
-		0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
-		0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
-		0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
-		0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
-		0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
-		0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
-		0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
-		0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
-		0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
-		0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
-		0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
-		0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
-		0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
-		0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
-		0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
-		0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
-		0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
-		0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
-		0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
-		0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
-		0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
-		0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
-		0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
-		0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
-		0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
-		0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
-		0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
-		0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
-		0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
-		0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
-		0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
-		0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
-		0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
-		0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
-		0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
-		0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
-		0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
-		0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5
-	}
-#else		/* !WORDS_BIGENDIAN */
-	{
-		0x00000000, 0x03836BF2, 0xF7703BE1, 0xF4F35013,
-		0x1F979AC7, 0x1C14F135, 0xE8E7A126, 0xEB64CAD4,
-		0xCF58D98A, 0xCCDBB278, 0x3828E26B, 0x3BAB8999,
-		0xD0CF434D, 0xD34C28BF, 0x27BF78AC, 0x243C135E,
-		0x6FC75E10, 0x6C4435E2, 0x98B765F1, 0x9B340E03,
-		0x7050C4D7, 0x73D3AF25, 0x8720FF36, 0x84A394C4,
-		0xA09F879A, 0xA31CEC68, 0x57EFBC7B, 0x546CD789,
-		0xBF081D5D, 0xBC8B76AF, 0x487826BC, 0x4BFB4D4E,
-		0xDE8EBD20, 0xDD0DD6D2, 0x29FE86C1, 0x2A7DED33,
-		0xC11927E7, 0xC29A4C15, 0x36691C06, 0x35EA77F4,
-		0x11D664AA, 0x12550F58, 0xE6A65F4B, 0xE52534B9,
-		0x0E41FE6D, 0x0DC2959F, 0xF931C58C, 0xFAB2AE7E,
-		0xB149E330, 0xB2CA88C2, 0x4639D8D1, 0x45BAB323,
-		0xAEDE79F7, 0xAD5D1205, 0x59AE4216, 0x5A2D29E4,
-		0x7E113ABA, 0x7D925148, 0x8961015B, 0x8AE26AA9,
-		0x6186A07D, 0x6205CB8F, 0x96F69B9C, 0x9575F06E,
-		0xBC1D7B41, 0xBF9E10B3, 0x4B6D40A0, 0x48EE2B52,
-		0xA38AE186, 0xA0098A74, 0x54FADA67, 0x5779B195,
-		0x7345A2CB, 0x70C6C939, 0x8435992A, 0x87B6F2D8,
-		0x6CD2380C, 0x6F5153FE, 0x9BA203ED, 0x9821681F,
-		0xD3DA2551, 0xD0594EA3, 0x24AA1EB0, 0x27297542,
-		0xCC4DBF96, 0xCFCED464, 0x3B3D8477, 0x38BEEF85,
-		0x1C82FCDB, 0x1F019729, 0xEBF2C73A, 0xE871ACC8,
-		0x0315661C, 0x00960DEE, 0xF4655DFD, 0xF7E6360F,
-		0x6293C661, 0x6110AD93, 0x95E3FD80, 0x96609672,
-		0x7D045CA6, 0x7E873754, 0x8A746747, 0x89F70CB5,
-		0xADCB1FEB, 0xAE487419, 0x5ABB240A, 0x59384FF8,
-		0xB25C852C, 0xB1DFEEDE, 0x452CBECD, 0x46AFD53F,
-		0x0D549871, 0x0ED7F383, 0xFA24A390, 0xF9A7C862,
-		0x12C302B6, 0x11406944, 0xE5B33957, 0xE63052A5,
-		0xC20C41FB, 0xC18F2A09, 0x357C7A1A, 0x36FF11E8,
-		0xDD9BDB3C, 0xDE18B0CE, 0x2AEBE0DD, 0x29688B2F,
-		0x783BF682, 0x7BB89D70, 0x8F4BCD63, 0x8CC8A691,
-		0x67AC6C45, 0x642F07B7, 0x90DC57A4, 0x935F3C56,
-		0xB7632F08, 0xB4E044FA, 0x401314E9, 0x43907F1B,
-		0xA8F4B5CF, 0xAB77DE3D, 0x5F848E2E, 0x5C07E5DC,
-		0x17FCA892, 0x147FC360, 0xE08C9373, 0xE30FF881,
-		0x086B3255, 0x0BE859A7, 0xFF1B09B4, 0xFC986246,
-		0xD8A47118, 0xDB271AEA, 0x2FD44AF9, 0x2C57210B,
-		0xC733EBDF, 0xC4B0802D, 0x3043D03E, 0x33C0BBCC,
-		0xA6B54BA2, 0xA5362050, 0x51C57043, 0x52461BB1,
-		0xB922D165, 0xBAA1BA97, 0x4E52EA84, 0x4DD18176,
-		0x69ED9228, 0x6A6EF9DA, 0x9E9DA9C9, 0x9D1EC23B,
-		0x767A08EF, 0x75F9631D, 0x810A330E, 0x828958FC,
-		0xC97215B2, 0xCAF17E40, 0x3E022E53, 0x3D8145A1,
-		0xD6E58F75, 0xD566E487, 0x2195B494, 0x2216DF66,
-		0x062ACC38, 0x05A9A7CA, 0xF15AF7D9, 0xF2D99C2B,
-		0x19BD56FF, 0x1A3E3D0D, 0xEECD6D1E, 0xED4E06EC,
-		0xC4268DC3, 0xC7A5E631, 0x3356B622, 0x30D5DDD0,
-		0xDBB11704, 0xD8327CF6, 0x2CC12CE5, 0x2F424717,
-		0x0B7E5449, 0x08FD3FBB, 0xFC0E6FA8, 0xFF8D045A,
-		0x14E9CE8E, 0x176AA57C, 0xE399F56F, 0xE01A9E9D,
-		0xABE1D3D3, 0xA862B821, 0x5C91E832, 0x5F1283C0,
-		0xB4764914, 0xB7F522E6, 0x430672F5, 0x40851907,
-		0x64B90A59, 0x673A61AB, 0x93C931B8, 0x904A5A4A,
-		0x7B2E909E, 0x78ADFB6C, 0x8C5EAB7F, 0x8FDDC08D,
-		0x1AA830E3, 0x192B5B11, 0xEDD80B02, 0xEE5B60F0,
-		0x053FAA24, 0x06BCC1D6, 0xF24F91C5, 0xF1CCFA37,
-		0xD5F0E969, 0xD673829B, 0x2280D288, 0x2103B97A,
-		0xCA6773AE, 0xC9E4185C, 0x3D17484F, 0x3E9423BD,
-		0x756F6EF3, 0x76EC0501, 0x821F5512, 0x819C3EE0,
-		0x6AF8F434, 0x697B9FC6, 0x9D88CFD5, 0x9E0BA427,
-		0xBA37B779, 0xB9B4DC8B, 0x4D478C98, 0x4EC4E76A,
-		0xA5A02DBE, 0xA623464C, 0x52D0165F, 0x51537DAD,
-	},
-	{
-		0x00000000, 0x7798A213, 0xEE304527, 0x99A8E734,
-		0xDC618A4E, 0xABF9285D, 0x3251CF69, 0x45C96D7A,
-		0xB8C3149D, 0xCF5BB68E, 0x56F351BA, 0x216BF3A9,
-		0x64A29ED3, 0x133A3CC0, 0x8A92DBF4, 0xFD0A79E7,
-		0x81F1C53F, 0xF669672C, 0x6FC18018, 0x1859220B,
-		0x5D904F71, 0x2A08ED62, 0xB3A00A56, 0xC438A845,
-		0x3932D1A2, 0x4EAA73B1, 0xD7029485, 0xA09A3696,
-		0xE5535BEC, 0x92CBF9FF, 0x0B631ECB, 0x7CFBBCD8,
-		0x02E38B7F, 0x757B296C, 0xECD3CE58, 0x9B4B6C4B,
-		0xDE820131, 0xA91AA322, 0x30B24416, 0x472AE605,
-		0xBA209FE2, 0xCDB83DF1, 0x5410DAC5, 0x238878D6,
-		0x664115AC, 0x11D9B7BF, 0x8871508B, 0xFFE9F298,
-		0x83124E40, 0xF48AEC53, 0x6D220B67, 0x1ABAA974,
-		0x5F73C40E, 0x28EB661D, 0xB1438129, 0xC6DB233A,
-		0x3BD15ADD, 0x4C49F8CE, 0xD5E11FFA, 0xA279BDE9,
-		0xE7B0D093, 0x90287280, 0x098095B4, 0x7E1837A7,
-		0x04C617FF, 0x735EB5EC, 0xEAF652D8, 0x9D6EF0CB,
-		0xD8A79DB1, 0xAF3F3FA2, 0x3697D896, 0x410F7A85,
-		0xBC050362, 0xCB9DA171, 0x52354645, 0x25ADE456,
-		0x6064892C, 0x17FC2B3F, 0x8E54CC0B, 0xF9CC6E18,
-		0x8537D2C0, 0xF2AF70D3, 0x6B0797E7, 0x1C9F35F4,
-		0x5956588E, 0x2ECEFA9D, 0xB7661DA9, 0xC0FEBFBA,
-		0x3DF4C65D, 0x4A6C644E, 0xD3C4837A, 0xA45C2169,
-		0xE1954C13, 0x960DEE00, 0x0FA50934, 0x783DAB27,
-		0x06259C80, 0x71BD3E93, 0xE815D9A7, 0x9F8D7BB4,
-		0xDA4416CE, 0xADDCB4DD, 0x347453E9, 0x43ECF1FA,
-		0xBEE6881D, 0xC97E2A0E, 0x50D6CD3A, 0x274E6F29,
-		0x62870253, 0x151FA040, 0x8CB74774, 0xFB2FE567,
-		0x87D459BF, 0xF04CFBAC, 0x69E41C98, 0x1E7CBE8B,
-		0x5BB5D3F1, 0x2C2D71E2, 0xB58596D6, 0xC21D34C5,
-		0x3F174D22, 0x488FEF31, 0xD1270805, 0xA6BFAA16,
-		0xE376C76C, 0x94EE657F, 0x0D46824B, 0x7ADE2058,
-		0xF9FAC3FB, 0x8E6261E8, 0x17CA86DC, 0x605224CF,
-		0x259B49B5, 0x5203EBA6, 0xCBAB0C92, 0xBC33AE81,
-		0x4139D766, 0x36A17575, 0xAF099241, 0xD8913052,
-		0x9D585D28, 0xEAC0FF3B, 0x7368180F, 0x04F0BA1C,
-		0x780B06C4, 0x0F93A4D7, 0x963B43E3, 0xE1A3E1F0,
-		0xA46A8C8A, 0xD3F22E99, 0x4A5AC9AD, 0x3DC26BBE,
-		0xC0C81259, 0xB750B04A, 0x2EF8577E, 0x5960F56D,
-		0x1CA99817, 0x6B313A04, 0xF299DD30, 0x85017F23,
-		0xFB194884, 0x8C81EA97, 0x15290DA3, 0x62B1AFB0,
-		0x2778C2CA, 0x50E060D9, 0xC94887ED, 0xBED025FE,
-		0x43DA5C19, 0x3442FE0A, 0xADEA193E, 0xDA72BB2D,
-		0x9FBBD657, 0xE8237444, 0x718B9370, 0x06133163,
-		0x7AE88DBB, 0x0D702FA8, 0x94D8C89C, 0xE3406A8F,
-		0xA68907F5, 0xD111A5E6, 0x48B942D2, 0x3F21E0C1,
-		0xC22B9926, 0xB5B33B35, 0x2C1BDC01, 0x5B837E12,
-		0x1E4A1368, 0x69D2B17B, 0xF07A564F, 0x87E2F45C,
-		0xFD3CD404, 0x8AA47617, 0x130C9123, 0x64943330,
-		0x215D5E4A, 0x56C5FC59, 0xCF6D1B6D, 0xB8F5B97E,
-		0x45FFC099, 0x3267628A, 0xABCF85BE, 0xDC5727AD,
-		0x999E4AD7, 0xEE06E8C4, 0x77AE0FF0, 0x0036ADE3,
-		0x7CCD113B, 0x0B55B328, 0x92FD541C, 0xE565F60F,
-		0xA0AC9B75, 0xD7343966, 0x4E9CDE52, 0x39047C41,
-		0xC40E05A6, 0xB396A7B5, 0x2A3E4081, 0x5DA6E292,
-		0x186F8FE8, 0x6FF72DFB, 0xF65FCACF, 0x81C768DC,
-		0xFFDF5F7B, 0x8847FD68, 0x11EF1A5C, 0x6677B84F,
-		0x23BED535, 0x54267726, 0xCD8E9012, 0xBA163201,
-		0x471C4BE6, 0x3084E9F5, 0xA92C0EC1, 0xDEB4ACD2,
-		0x9B7DC1A8, 0xECE563BB, 0x754D848F, 0x02D5269C,
-		0x7E2E9A44, 0x09B63857, 0x901EDF63, 0xE7867D70,
-		0xA24F100A, 0xD5D7B219, 0x4C7F552D, 0x3BE7F73E,
-		0xC6ED8ED9, 0xB1752CCA, 0x28DDCBFE, 0x5F4569ED,
-		0x1A8C0497, 0x6D14A684, 0xF4BC41B0, 0x8324E3A3,
-	},
-	{
-		0x00000000, 0x7E9241A5, 0x0D526F4F, 0x73C02EEA,
-		0x1AA4DE9E, 0x64369F3B, 0x17F6B1D1, 0x6964F074,
-		0xC53E5138, 0xBBAC109D, 0xC86C3E77, 0xB6FE7FD2,
-		0xDF9A8FA6, 0xA108CE03, 0xD2C8E0E9, 0xAC5AA14C,
-		0x8A7DA270, 0xF4EFE3D5, 0x872FCD3F, 0xF9BD8C9A,
-		0x90D97CEE, 0xEE4B3D4B, 0x9D8B13A1, 0xE3195204,
-		0x4F43F348, 0x31D1B2ED, 0x42119C07, 0x3C83DDA2,
-		0x55E72DD6, 0x2B756C73, 0x58B54299, 0x2627033C,
-		0x14FB44E1, 0x6A690544, 0x19A92BAE, 0x673B6A0B,
-		0x0E5F9A7F, 0x70CDDBDA, 0x030DF530, 0x7D9FB495,
-		0xD1C515D9, 0xAF57547C, 0xDC977A96, 0xA2053B33,
-		0xCB61CB47, 0xB5F38AE2, 0xC633A408, 0xB8A1E5AD,
-		0x9E86E691, 0xE014A734, 0x93D489DE, 0xED46C87B,
-		0x8422380F, 0xFAB079AA, 0x89705740, 0xF7E216E5,
-		0x5BB8B7A9, 0x252AF60C, 0x56EAD8E6, 0x28789943,
-		0x411C6937, 0x3F8E2892, 0x4C4E0678, 0x32DC47DD,
-		0xD98065C7, 0xA7122462, 0xD4D20A88, 0xAA404B2D,
-		0xC324BB59, 0xBDB6FAFC, 0xCE76D416, 0xB0E495B3,
-		0x1CBE34FF, 0x622C755A, 0x11EC5BB0, 0x6F7E1A15,
-		0x061AEA61, 0x7888ABC4, 0x0B48852E, 0x75DAC48B,
-		0x53FDC7B7, 0x2D6F8612, 0x5EAFA8F8, 0x203DE95D,
-		0x49591929, 0x37CB588C, 0x440B7666, 0x3A9937C3,
-		0x96C3968F, 0xE851D72A, 0x9B91F9C0, 0xE503B865,
-		0x8C674811, 0xF2F509B4, 0x8135275E, 0xFFA766FB,
-		0xCD7B2126, 0xB3E96083, 0xC0294E69, 0xBEBB0FCC,
-		0xD7DFFFB8, 0xA94DBE1D, 0xDA8D90F7, 0xA41FD152,
-		0x0845701E, 0x76D731BB, 0x05171F51, 0x7B855EF4,
-		0x12E1AE80, 0x6C73EF25, 0x1FB3C1CF, 0x6121806A,
-		0x47068356, 0x3994C2F3, 0x4A54EC19, 0x34C6ADBC,
-		0x5DA25DC8, 0x23301C6D, 0x50F03287, 0x2E627322,
-		0x8238D26E, 0xFCAA93CB, 0x8F6ABD21, 0xF1F8FC84,
-		0x989C0CF0, 0xE60E4D55, 0x95CE63BF, 0xEB5C221A,
-		0x4377278B, 0x3DE5662E, 0x4E2548C4, 0x30B70961,
-		0x59D3F915, 0x2741B8B0, 0x5481965A, 0x2A13D7FF,
-		0x864976B3, 0xF8DB3716, 0x8B1B19FC, 0xF5895859,
-		0x9CEDA82D, 0xE27FE988, 0x91BFC762, 0xEF2D86C7,
-		0xC90A85FB, 0xB798C45E, 0xC458EAB4, 0xBACAAB11,
-		0xD3AE5B65, 0xAD3C1AC0, 0xDEFC342A, 0xA06E758F,
-		0x0C34D4C3, 0x72A69566, 0x0166BB8C, 0x7FF4FA29,
-		0x16900A5D, 0x68024BF8, 0x1BC26512, 0x655024B7,
-		0x578C636A, 0x291E22CF, 0x5ADE0C25, 0x244C4D80,
-		0x4D28BDF4, 0x33BAFC51, 0x407AD2BB, 0x3EE8931E,
-		0x92B23252, 0xEC2073F7, 0x9FE05D1D, 0xE1721CB8,
-		0x8816ECCC, 0xF684AD69, 0x85448383, 0xFBD6C226,
-		0xDDF1C11A, 0xA36380BF, 0xD0A3AE55, 0xAE31EFF0,
-		0xC7551F84, 0xB9C75E21, 0xCA0770CB, 0xB495316E,
-		0x18CF9022, 0x665DD187, 0x159DFF6D, 0x6B0FBEC8,
-		0x026B4EBC, 0x7CF90F19, 0x0F3921F3, 0x71AB6056,
-		0x9AF7424C, 0xE46503E9, 0x97A52D03, 0xE9376CA6,
-		0x80539CD2, 0xFEC1DD77, 0x8D01F39D, 0xF393B238,
-		0x5FC91374, 0x215B52D1, 0x529B7C3B, 0x2C093D9E,
-		0x456DCDEA, 0x3BFF8C4F, 0x483FA2A5, 0x36ADE300,
-		0x108AE03C, 0x6E18A199, 0x1DD88F73, 0x634ACED6,
-		0x0A2E3EA2, 0x74BC7F07, 0x077C51ED, 0x79EE1048,
-		0xD5B4B104, 0xAB26F0A1, 0xD8E6DE4B, 0xA6749FEE,
-		0xCF106F9A, 0xB1822E3F, 0xC24200D5, 0xBCD04170,
-		0x8E0C06AD, 0xF09E4708, 0x835E69E2, 0xFDCC2847,
-		0x94A8D833, 0xEA3A9996, 0x99FAB77C, 0xE768F6D9,
-		0x4B325795, 0x35A01630, 0x466038DA, 0x38F2797F,
-		0x5196890B, 0x2F04C8AE, 0x5CC4E644, 0x2256A7E1,
-		0x0471A4DD, 0x7AE3E578, 0x0923CB92, 0x77B18A37,
-		0x1ED57A43, 0x60473BE6, 0x1387150C, 0x6D1554A9,
-		0xC14FF5E5, 0xBFDDB440, 0xCC1D9AAA, 0xB28FDB0F,
-		0xDBEB2B7B, 0xA5796ADE, 0xD6B94434, 0xA82B0591,
-	},
-	{
-		0x00000000, 0xB8AA45DD, 0x812367BF, 0x39892262,
-		0xF331227B, 0x4B9B67A6, 0x721245C4, 0xCAB80019,
-		0xE66344F6, 0x5EC9012B, 0x67402349, 0xDFEA6694,
-		0x1552668D, 0xADF82350, 0x94710132, 0x2CDB44EF,
-		0x3DB164E9, 0x851B2134, 0xBC920356, 0x0438468B,
-		0xCE804692, 0x762A034F, 0x4FA3212D, 0xF70964F0,
-		0xDBD2201F, 0x637865C2, 0x5AF147A0, 0xE25B027D,
-		0x28E30264, 0x904947B9, 0xA9C065DB, 0x116A2006,
-		0x8B1425D7, 0x33BE600A, 0x0A374268, 0xB29D07B5,
-		0x782507AC, 0xC08F4271, 0xF9066013, 0x41AC25CE,
-		0x6D776121, 0xD5DD24FC, 0xEC54069E, 0x54FE4343,
-		0x9E46435A, 0x26EC0687, 0x1F6524E5, 0xA7CF6138,
-		0xB6A5413E, 0x0E0F04E3, 0x37862681, 0x8F2C635C,
-		0x45946345, 0xFD3E2698, 0xC4B704FA, 0x7C1D4127,
-		0x50C605C8, 0xE86C4015, 0xD1E56277, 0x694F27AA,
-		0xA3F727B3, 0x1B5D626E, 0x22D4400C, 0x9A7E05D1,
-		0xE75FA6AB, 0x5FF5E376, 0x667CC114, 0xDED684C9,
-		0x146E84D0, 0xACC4C10D, 0x954DE36F, 0x2DE7A6B2,
-		0x013CE25D, 0xB996A780, 0x801F85E2, 0x38B5C03F,
-		0xF20DC026, 0x4AA785FB, 0x732EA799, 0xCB84E244,
-		0xDAEEC242, 0x6244879F, 0x5BCDA5FD, 0xE367E020,
-		0x29DFE039, 0x9175A5E4, 0xA8FC8786, 0x1056C25B,
-		0x3C8D86B4, 0x8427C369, 0xBDAEE10B, 0x0504A4D6,
-		0xCFBCA4CF, 0x7716E112, 0x4E9FC370, 0xF63586AD,
-		0x6C4B837C, 0xD4E1C6A1, 0xED68E4C3, 0x55C2A11E,
-		0x9F7AA107, 0x27D0E4DA, 0x1E59C6B8, 0xA6F38365,
-		0x8A28C78A, 0x32828257, 0x0B0BA035, 0xB3A1E5E8,
-		0x7919E5F1, 0xC1B3A02C, 0xF83A824E, 0x4090C793,
-		0x51FAE795, 0xE950A248, 0xD0D9802A, 0x6873C5F7,
-		0xA2CBC5EE, 0x1A618033, 0x23E8A251, 0x9B42E78C,
-		0xB799A363, 0x0F33E6BE, 0x36BAC4DC, 0x8E108101,
-		0x44A88118, 0xFC02C4C5, 0xC58BE6A7, 0x7D21A37A,
-		0x3FC9A052, 0x8763E58F, 0xBEEAC7ED, 0x06408230,
-		0xCCF88229, 0x7452C7F4, 0x4DDBE596, 0xF571A04B,
-		0xD9AAE4A4, 0x6100A179, 0x5889831B, 0xE023C6C6,
-		0x2A9BC6DF, 0x92318302, 0xABB8A160, 0x1312E4BD,
-		0x0278C4BB, 0xBAD28166, 0x835BA304, 0x3BF1E6D9,
-		0xF149E6C0, 0x49E3A31D, 0x706A817F, 0xC8C0C4A2,
-		0xE41B804D, 0x5CB1C590, 0x6538E7F2, 0xDD92A22F,
-		0x172AA236, 0xAF80E7EB, 0x9609C589, 0x2EA38054,
-		0xB4DD8585, 0x0C77C058, 0x35FEE23A, 0x8D54A7E7,
-		0x47ECA7FE, 0xFF46E223, 0xC6CFC041, 0x7E65859C,
-		0x52BEC173, 0xEA1484AE, 0xD39DA6CC, 0x6B37E311,
-		0xA18FE308, 0x1925A6D5, 0x20AC84B7, 0x9806C16A,
-		0x896CE16C, 0x31C6A4B1, 0x084F86D3, 0xB0E5C30E,
-		0x7A5DC317, 0xC2F786CA, 0xFB7EA4A8, 0x43D4E175,
-		0x6F0FA59A, 0xD7A5E047, 0xEE2CC225, 0x568687F8,
-		0x9C3E87E1, 0x2494C23C, 0x1D1DE05E, 0xA5B7A583,
-		0xD89606F9, 0x603C4324, 0x59B56146, 0xE11F249B,
-		0x2BA72482, 0x930D615F, 0xAA84433D, 0x122E06E0,
-		0x3EF5420F, 0x865F07D2, 0xBFD625B0, 0x077C606D,
-		0xCDC46074, 0x756E25A9, 0x4CE707CB, 0xF44D4216,
-		0xE5276210, 0x5D8D27CD, 0x640405AF, 0xDCAE4072,
-		0x1616406B, 0xAEBC05B6, 0x973527D4, 0x2F9F6209,
-		0x034426E6, 0xBBEE633B, 0x82674159, 0x3ACD0484,
-		0xF075049D, 0x48DF4140, 0x71566322, 0xC9FC26FF,
-		0x5382232E, 0xEB2866F3, 0xD2A14491, 0x6A0B014C,
-		0xA0B30155, 0x18194488, 0x219066EA, 0x993A2337,
-		0xB5E167D8, 0x0D4B2205, 0x34C20067, 0x8C6845BA,
-		0x46D045A3, 0xFE7A007E, 0xC7F3221C, 0x7F5967C1,
-		0x6E3347C7, 0xD699021A, 0xEF102078, 0x57BA65A5,
-		0x9D0265BC, 0x25A82061, 0x1C210203, 0xA48B47DE,
-		0x88500331, 0x30FA46EC, 0x0973648E, 0xB1D92153,
-		0x7B61214A, 0xC3CB6497, 0xFA4246F5, 0x42E80328,
-	},
-	{
-		0x00000000, 0xAC6F1138, 0x58DF2270, 0xF4B03348,
-		0xB0BE45E0, 0x1CD154D8, 0xE8616790, 0x440E76A8,
-		0x910B67C5, 0x3D6476FD, 0xC9D445B5, 0x65BB548D,
-		0x21B52225, 0x8DDA331D, 0x796A0055, 0xD505116D,
-		0xD361228F, 0x7F0E33B7, 0x8BBE00FF, 0x27D111C7,
-		0x63DF676F, 0xCFB07657, 0x3B00451F, 0x976F5427,
-		0x426A454A, 0xEE055472, 0x1AB5673A, 0xB6DA7602,
-		0xF2D400AA, 0x5EBB1192, 0xAA0B22DA, 0x066433E2,
-		0x57B5A81B, 0xFBDAB923, 0x0F6A8A6B, 0xA3059B53,
-		0xE70BEDFB, 0x4B64FCC3, 0xBFD4CF8B, 0x13BBDEB3,
-		0xC6BECFDE, 0x6AD1DEE6, 0x9E61EDAE, 0x320EFC96,
-		0x76008A3E, 0xDA6F9B06, 0x2EDFA84E, 0x82B0B976,
-		0x84D48A94, 0x28BB9BAC, 0xDC0BA8E4, 0x7064B9DC,
-		0x346ACF74, 0x9805DE4C, 0x6CB5ED04, 0xC0DAFC3C,
-		0x15DFED51, 0xB9B0FC69, 0x4D00CF21, 0xE16FDE19,
-		0xA561A8B1, 0x090EB989, 0xFDBE8AC1, 0x51D19BF9,
-		0xAE6A5137, 0x0205400F, 0xF6B57347, 0x5ADA627F,
-		0x1ED414D7, 0xB2BB05EF, 0x460B36A7, 0xEA64279F,
-		0x3F6136F2, 0x930E27CA, 0x67BE1482, 0xCBD105BA,
-		0x8FDF7312, 0x23B0622A, 0xD7005162, 0x7B6F405A,
-		0x7D0B73B8, 0xD1646280, 0x25D451C8, 0x89BB40F0,
-		0xCDB53658, 0x61DA2760, 0x956A1428, 0x39050510,
-		0xEC00147D, 0x406F0545, 0xB4DF360D, 0x18B02735,
-		0x5CBE519D, 0xF0D140A5, 0x046173ED, 0xA80E62D5,
-		0xF9DFF92C, 0x55B0E814, 0xA100DB5C, 0x0D6FCA64,
-		0x4961BCCC, 0xE50EADF4, 0x11BE9EBC, 0xBDD18F84,
-		0x68D49EE9, 0xC4BB8FD1, 0x300BBC99, 0x9C64ADA1,
-		0xD86ADB09, 0x7405CA31, 0x80B5F979, 0x2CDAE841,
-		0x2ABEDBA3, 0x86D1CA9B, 0x7261F9D3, 0xDE0EE8EB,
-		0x9A009E43, 0x366F8F7B, 0xC2DFBC33, 0x6EB0AD0B,
-		0xBBB5BC66, 0x17DAAD5E, 0xE36A9E16, 0x4F058F2E,
-		0x0B0BF986, 0xA764E8BE, 0x53D4DBF6, 0xFFBBCACE,
-		0x5CD5A26E, 0xF0BAB356, 0x040A801E, 0xA8659126,
-		0xEC6BE78E, 0x4004F6B6, 0xB4B4C5FE, 0x18DBD4C6,
-		0xCDDEC5AB, 0x61B1D493, 0x9501E7DB, 0x396EF6E3,
-		0x7D60804B, 0xD10F9173, 0x25BFA23B, 0x89D0B303,
-		0x8FB480E1, 0x23DB91D9, 0xD76BA291, 0x7B04B3A9,
-		0x3F0AC501, 0x9365D439, 0x67D5E771, 0xCBBAF649,
-		0x1EBFE724, 0xB2D0F61C, 0x4660C554, 0xEA0FD46C,
-		0xAE01A2C4, 0x026EB3FC, 0xF6DE80B4, 0x5AB1918C,
-		0x0B600A75, 0xA70F1B4D, 0x53BF2805, 0xFFD0393D,
-		0xBBDE4F95, 0x17B15EAD, 0xE3016DE5, 0x4F6E7CDD,
-		0x9A6B6DB0, 0x36047C88, 0xC2B44FC0, 0x6EDB5EF8,
-		0x2AD52850, 0x86BA3968, 0x720A0A20, 0xDE651B18,
-		0xD80128FA, 0x746E39C2, 0x80DE0A8A, 0x2CB11BB2,
-		0x68BF6D1A, 0xC4D07C22, 0x30604F6A, 0x9C0F5E52,
-		0x490A4F3F, 0xE5655E07, 0x11D56D4F, 0xBDBA7C77,
-		0xF9B40ADF, 0x55DB1BE7, 0xA16B28AF, 0x0D043997,
-		0xF2BFF359, 0x5ED0E261, 0xAA60D129, 0x060FC011,
-		0x4201B6B9, 0xEE6EA781, 0x1ADE94C9, 0xB6B185F1,
-		0x63B4949C, 0xCFDB85A4, 0x3B6BB6EC, 0x9704A7D4,
-		0xD30AD17C, 0x7F65C044, 0x8BD5F30C, 0x27BAE234,
-		0x21DED1D6, 0x8DB1C0EE, 0x7901F3A6, 0xD56EE29E,
-		0x91609436, 0x3D0F850E, 0xC9BFB646, 0x65D0A77E,
-		0xB0D5B613, 0x1CBAA72B, 0xE80A9463, 0x4465855B,
-		0x006BF3F3, 0xAC04E2CB, 0x58B4D183, 0xF4DBC0BB,
-		0xA50A5B42, 0x09654A7A, 0xFDD57932, 0x51BA680A,
-		0x15B41EA2, 0xB9DB0F9A, 0x4D6B3CD2, 0xE1042DEA,
-		0x34013C87, 0x986E2DBF, 0x6CDE1EF7, 0xC0B10FCF,
-		0x84BF7967, 0x28D0685F, 0xDC605B17, 0x700F4A2F,
-		0x766B79CD, 0xDA0468F5, 0x2EB45BBD, 0x82DB4A85,
-		0xC6D53C2D, 0x6ABA2D15, 0x9E0A1E5D, 0x32650F65,
-		0xE7601E08, 0x4B0F0F30, 0xBFBF3C78, 0x13D02D40,
-		0x57DE5BE8, 0xFBB14AD0, 0x0F017998, 0xA36E68A0,
-	},
-	{
-		0x00000000, 0x196B30EF, 0xC3A08CDB, 0xDACBBC34,
-		0x7737F5B2, 0x6E5CC55D, 0xB4977969, 0xADFC4986,
-		0x1F180660, 0x0673368F, 0xDCB88ABB, 0xC5D3BA54,
-		0x682FF3D2, 0x7144C33D, 0xAB8F7F09, 0xB2E44FE6,
-		0x3E300CC0, 0x275B3C2F, 0xFD90801B, 0xE4FBB0F4,
-		0x4907F972, 0x506CC99D, 0x8AA775A9, 0x93CC4546,
-		0x21280AA0, 0x38433A4F, 0xE288867B, 0xFBE3B694,
-		0x561FFF12, 0x4F74CFFD, 0x95BF73C9, 0x8CD44326,
-		0x8D16F485, 0x947DC46A, 0x4EB6785E, 0x57DD48B1,
-		0xFA210137, 0xE34A31D8, 0x39818DEC, 0x20EABD03,
-		0x920EF2E5, 0x8B65C20A, 0x51AE7E3E, 0x48C54ED1,
-		0xE5390757, 0xFC5237B8, 0x26998B8C, 0x3FF2BB63,
-		0xB326F845, 0xAA4DC8AA, 0x7086749E, 0x69ED4471,
-		0xC4110DF7, 0xDD7A3D18, 0x07B1812C, 0x1EDAB1C3,
-		0xAC3EFE25, 0xB555CECA, 0x6F9E72FE, 0x76F54211,
-		0xDB090B97, 0xC2623B78, 0x18A9874C, 0x01C2B7A3,
-		0xEB5B040E, 0xF23034E1, 0x28FB88D5, 0x3190B83A,
-		0x9C6CF1BC, 0x8507C153, 0x5FCC7D67, 0x46A74D88,
-		0xF443026E, 0xED283281, 0x37E38EB5, 0x2E88BE5A,
-		0x8374F7DC, 0x9A1FC733, 0x40D47B07, 0x59BF4BE8,
-		0xD56B08CE, 0xCC003821, 0x16CB8415, 0x0FA0B4FA,
-		0xA25CFD7C, 0xBB37CD93, 0x61FC71A7, 0x78974148,
-		0xCA730EAE, 0xD3183E41, 0x09D38275, 0x10B8B29A,
-		0xBD44FB1C, 0xA42FCBF3, 0x7EE477C7, 0x678F4728,
-		0x664DF08B, 0x7F26C064, 0xA5ED7C50, 0xBC864CBF,
-		0x117A0539, 0x081135D6, 0xD2DA89E2, 0xCBB1B90D,
-		0x7955F6EB, 0x603EC604, 0xBAF57A30, 0xA39E4ADF,
-		0x0E620359, 0x170933B6, 0xCDC28F82, 0xD4A9BF6D,
-		0x587DFC4B, 0x4116CCA4, 0x9BDD7090, 0x82B6407F,
-		0x2F4A09F9, 0x36213916, 0xECEA8522, 0xF581B5CD,
-		0x4765FA2B, 0x5E0ECAC4, 0x84C576F0, 0x9DAE461F,
-		0x30520F99, 0x29393F76, 0xF3F28342, 0xEA99B3AD,
-		0xD6B7081C, 0xCFDC38F3, 0x151784C7, 0x0C7CB428,
-		0xA180FDAE, 0xB8EBCD41, 0x62207175, 0x7B4B419A,
-		0xC9AF0E7C, 0xD0C43E93, 0x0A0F82A7, 0x1364B248,
-		0xBE98FBCE, 0xA7F3CB21, 0x7D387715, 0x645347FA,
-		0xE88704DC, 0xF1EC3433, 0x2B278807, 0x324CB8E8,
-		0x9FB0F16E, 0x86DBC181, 0x5C107DB5, 0x457B4D5A,
-		0xF79F02BC, 0xEEF43253, 0x343F8E67, 0x2D54BE88,
-		0x80A8F70E, 0x99C3C7E1, 0x43087BD5, 0x5A634B3A,
-		0x5BA1FC99, 0x42CACC76, 0x98017042, 0x816A40AD,
-		0x2C96092B, 0x35FD39C4, 0xEF3685F0, 0xF65DB51F,
-		0x44B9FAF9, 0x5DD2CA16, 0x87197622, 0x9E7246CD,
-		0x338E0F4B, 0x2AE53FA4, 0xF02E8390, 0xE945B37F,
-		0x6591F059, 0x7CFAC0B6, 0xA6317C82, 0xBF5A4C6D,
-		0x12A605EB, 0x0BCD3504, 0xD1068930, 0xC86DB9DF,
-		0x7A89F639, 0x63E2C6D6, 0xB9297AE2, 0xA0424A0D,
-		0x0DBE038B, 0x14D53364, 0xCE1E8F50, 0xD775BFBF,
-		0x3DEC0C12, 0x24873CFD, 0xFE4C80C9, 0xE727B026,
-		0x4ADBF9A0, 0x53B0C94F, 0x897B757B, 0x90104594,
-		0x22F40A72, 0x3B9F3A9D, 0xE15486A9, 0xF83FB646,
-		0x55C3FFC0, 0x4CA8CF2F, 0x9663731B, 0x8F0843F4,
-		0x03DC00D2, 0x1AB7303D, 0xC07C8C09, 0xD917BCE6,
-		0x74EBF560, 0x6D80C58F, 0xB74B79BB, 0xAE204954,
-		0x1CC406B2, 0x05AF365D, 0xDF648A69, 0xC60FBA86,
-		0x6BF3F300, 0x7298C3EF, 0xA8537FDB, 0xB1384F34,
-		0xB0FAF897, 0xA991C878, 0x735A744C, 0x6A3144A3,
-		0xC7CD0D25, 0xDEA63DCA, 0x046D81FE, 0x1D06B111,
-		0xAFE2FEF7, 0xB689CE18, 0x6C42722C, 0x752942C3,
-		0xD8D50B45, 0xC1BE3BAA, 0x1B75879E, 0x021EB771,
-		0x8ECAF457, 0x97A1C4B8, 0x4D6A788C, 0x54014863,
-		0xF9FD01E5, 0xE096310A, 0x3A5D8D3E, 0x2336BDD1,
-		0x91D2F237, 0x88B9C2D8, 0x52727EEC, 0x4B194E03,
-		0xE6E50785, 0xFF8E376A, 0x25458B5E, 0x3C2EBBB1,
-	},
-	{
-		0x00000000, 0xC82C0368, 0x905906D0, 0x587505B8,
-		0xD1C5E0A5, 0x19E9E3CD, 0x419CE675, 0x89B0E51D,
-		0x53FD2D4E, 0x9BD12E26, 0xC3A42B9E, 0x0B8828F6,
-		0x8238CDEB, 0x4A14CE83, 0x1261CB3B, 0xDA4DC853,
-		0xA6FA5B9C, 0x6ED658F4, 0x36A35D4C, 0xFE8F5E24,
-		0x773FBB39, 0xBF13B851, 0xE766BDE9, 0x2F4ABE81,
-		0xF50776D2, 0x3D2B75BA, 0x655E7002, 0xAD72736A,
-		0x24C29677, 0xECEE951F, 0xB49B90A7, 0x7CB793CF,
-		0xBD835B3D, 0x75AF5855, 0x2DDA5DED, 0xE5F65E85,
-		0x6C46BB98, 0xA46AB8F0, 0xFC1FBD48, 0x3433BE20,
-		0xEE7E7673, 0x2652751B, 0x7E2770A3, 0xB60B73CB,
-		0x3FBB96D6, 0xF79795BE, 0xAFE29006, 0x67CE936E,
-		0x1B7900A1, 0xD35503C9, 0x8B200671, 0x430C0519,
-		0xCABCE004, 0x0290E36C, 0x5AE5E6D4, 0x92C9E5BC,
-		0x48842DEF, 0x80A82E87, 0xD8DD2B3F, 0x10F12857,
-		0x9941CD4A, 0x516DCE22, 0x0918CB9A, 0xC134C8F2,
-		0x7A07B77A, 0xB22BB412, 0xEA5EB1AA, 0x2272B2C2,
-		0xABC257DF, 0x63EE54B7, 0x3B9B510F, 0xF3B75267,
-		0x29FA9A34, 0xE1D6995C, 0xB9A39CE4, 0x718F9F8C,
-		0xF83F7A91, 0x301379F9, 0x68667C41, 0xA04A7F29,
-		0xDCFDECE6, 0x14D1EF8E, 0x4CA4EA36, 0x8488E95E,
-		0x0D380C43, 0xC5140F2B, 0x9D610A93, 0x554D09FB,
-		0x8F00C1A8, 0x472CC2C0, 0x1F59C778, 0xD775C410,
-		0x5EC5210D, 0x96E92265, 0xCE9C27DD, 0x06B024B5,
-		0xC784EC47, 0x0FA8EF2F, 0x57DDEA97, 0x9FF1E9FF,
-		0x16410CE2, 0xDE6D0F8A, 0x86180A32, 0x4E34095A,
-		0x9479C109, 0x5C55C261, 0x0420C7D9, 0xCC0CC4B1,
-		0x45BC21AC, 0x8D9022C4, 0xD5E5277C, 0x1DC92414,
-		0x617EB7DB, 0xA952B4B3, 0xF127B10B, 0x390BB263,
-		0xB0BB577E, 0x78975416, 0x20E251AE, 0xE8CE52C6,
-		0x32839A95, 0xFAAF99FD, 0xA2DA9C45, 0x6AF69F2D,
-		0xE3467A30, 0x2B6A7958, 0x731F7CE0, 0xBB337F88,
-		0xF40E6EF5, 0x3C226D9D, 0x64576825, 0xAC7B6B4D,
-		0x25CB8E50, 0xEDE78D38, 0xB5928880, 0x7DBE8BE8,
-		0xA7F343BB, 0x6FDF40D3, 0x37AA456B, 0xFF864603,
-		0x7636A31E, 0xBE1AA076, 0xE66FA5CE, 0x2E43A6A6,
-		0x52F43569, 0x9AD83601, 0xC2AD33B9, 0x0A8130D1,
-		0x8331D5CC, 0x4B1DD6A4, 0x1368D31C, 0xDB44D074,
-		0x01091827, 0xC9251B4F, 0x91501EF7, 0x597C1D9F,
-		0xD0CCF882, 0x18E0FBEA, 0x4095FE52, 0x88B9FD3A,
-		0x498D35C8, 0x81A136A0, 0xD9D43318, 0x11F83070,
-		0x9848D56D, 0x5064D605, 0x0811D3BD, 0xC03DD0D5,
-		0x1A701886, 0xD25C1BEE, 0x8A291E56, 0x42051D3E,
-		0xCBB5F823, 0x0399FB4B, 0x5BECFEF3, 0x93C0FD9B,
-		0xEF776E54, 0x275B6D3C, 0x7F2E6884, 0xB7026BEC,
-		0x3EB28EF1, 0xF69E8D99, 0xAEEB8821, 0x66C78B49,
-		0xBC8A431A, 0x74A64072, 0x2CD345CA, 0xE4FF46A2,
-		0x6D4FA3BF, 0xA563A0D7, 0xFD16A56F, 0x353AA607,
-		0x8E09D98F, 0x4625DAE7, 0x1E50DF5F, 0xD67CDC37,
-		0x5FCC392A, 0x97E03A42, 0xCF953FFA, 0x07B93C92,
-		0xDDF4F4C1, 0x15D8F7A9, 0x4DADF211, 0x8581F179,
-		0x0C311464, 0xC41D170C, 0x9C6812B4, 0x544411DC,
-		0x28F38213, 0xE0DF817B, 0xB8AA84C3, 0x708687AB,
-		0xF93662B6, 0x311A61DE, 0x696F6466, 0xA143670E,
-		0x7B0EAF5D, 0xB322AC35, 0xEB57A98D, 0x237BAAE5,
-		0xAACB4FF8, 0x62E74C90, 0x3A924928, 0xF2BE4A40,
-		0x338A82B2, 0xFBA681DA, 0xA3D38462, 0x6BFF870A,
-		0xE24F6217, 0x2A63617F, 0x721664C7, 0xBA3A67AF,
-		0x6077AFFC, 0xA85BAC94, 0xF02EA92C, 0x3802AA44,
-		0xB1B24F59, 0x799E4C31, 0x21EB4989, 0xE9C74AE1,
-		0x9570D92E, 0x5D5CDA46, 0x0529DFFE, 0xCD05DC96,
-		0x44B5398B, 0x8C993AE3, 0xD4EC3F5B, 0x1CC03C33,
-		0xC68DF460, 0x0EA1F708, 0x56D4F2B0, 0x9EF8F1D8,
-		0x174814C5, 0xDF6417AD, 0x87111215, 0x4F3D117D,
-	},
-	{
-		0x00000000, 0x277D3C49, 0x4EFA7892, 0x698744DB,
-		0x6D821D21, 0x4AFF2168, 0x237865B3, 0x040559FA,
-		0xDA043B42, 0xFD79070B, 0x94FE43D0, 0xB3837F99,
-		0xB7862663, 0x90FB1A2A, 0xF97C5EF1, 0xDE0162B8,
-		0xB4097684, 0x93744ACD, 0xFAF30E16, 0xDD8E325F,
-		0xD98B6BA5, 0xFEF657EC, 0x97711337, 0xB00C2F7E,
-		0x6E0D4DC6, 0x4970718F, 0x20F73554, 0x078A091D,
-		0x038F50E7, 0x24F26CAE, 0x4D752875, 0x6A08143C,
-		0x9965000D, 0xBE183C44, 0xD79F789F, 0xF0E244D6,
-		0xF4E71D2C, 0xD39A2165, 0xBA1D65BE, 0x9D6059F7,
-		0x43613B4F, 0x641C0706, 0x0D9B43DD, 0x2AE67F94,
-		0x2EE3266E, 0x099E1A27, 0x60195EFC, 0x476462B5,
-		0x2D6C7689, 0x0A114AC0, 0x63960E1B, 0x44EB3252,
-		0x40EE6BA8, 0x679357E1, 0x0E14133A, 0x29692F73,
-		0xF7684DCB, 0xD0157182, 0xB9923559, 0x9EEF0910,
-		0x9AEA50EA, 0xBD976CA3, 0xD4102878, 0xF36D1431,
-		0x32CB001A, 0x15B63C53, 0x7C317888, 0x5B4C44C1,
-		0x5F491D3B, 0x78342172, 0x11B365A9, 0x36CE59E0,
-		0xE8CF3B58, 0xCFB20711, 0xA63543CA, 0x81487F83,
-		0x854D2679, 0xA2301A30, 0xCBB75EEB, 0xECCA62A2,
-		0x86C2769E, 0xA1BF4AD7, 0xC8380E0C, 0xEF453245,
-		0xEB406BBF, 0xCC3D57F6, 0xA5BA132D, 0x82C72F64,
-		0x5CC64DDC, 0x7BBB7195, 0x123C354E, 0x35410907,
-		0x314450FD, 0x16396CB4, 0x7FBE286F, 0x58C31426,
-		0xABAE0017, 0x8CD33C5E, 0xE5547885, 0xC22944CC,
-		0xC62C1D36, 0xE151217F, 0x88D665A4, 0xAFAB59ED,
-		0x71AA3B55, 0x56D7071C, 0x3F5043C7, 0x182D7F8E,
-		0x1C282674, 0x3B551A3D, 0x52D25EE6, 0x75AF62AF,
-		0x1FA77693, 0x38DA4ADA, 0x515D0E01, 0x76203248,
-		0x72256BB2, 0x555857FB, 0x3CDF1320, 0x1BA22F69,
-		0xC5A34DD1, 0xE2DE7198, 0x8B593543, 0xAC24090A,
-		0xA82150F0, 0x8F5C6CB9, 0xE6DB2862, 0xC1A6142B,
-		0x64960134, 0x43EB3D7D, 0x2A6C79A6, 0x0D1145EF,
-		0x09141C15, 0x2E69205C, 0x47EE6487, 0x609358CE,
-		0xBE923A76, 0x99EF063F, 0xF06842E4, 0xD7157EAD,
-		0xD3102757, 0xF46D1B1E, 0x9DEA5FC5, 0xBA97638C,
-		0xD09F77B0, 0xF7E24BF9, 0x9E650F22, 0xB918336B,
-		0xBD1D6A91, 0x9A6056D8, 0xF3E71203, 0xD49A2E4A,
-		0x0A9B4CF2, 0x2DE670BB, 0x44613460, 0x631C0829,
-		0x671951D3, 0x40646D9A, 0x29E32941, 0x0E9E1508,
-		0xFDF30139, 0xDA8E3D70, 0xB30979AB, 0x947445E2,
-		0x90711C18, 0xB70C2051, 0xDE8B648A, 0xF9F658C3,
-		0x27F73A7B, 0x008A0632, 0x690D42E9, 0x4E707EA0,
-		0x4A75275A, 0x6D081B13, 0x048F5FC8, 0x23F26381,
-		0x49FA77BD, 0x6E874BF4, 0x07000F2F, 0x207D3366,
-		0x24786A9C, 0x030556D5, 0x6A82120E, 0x4DFF2E47,
-		0x93FE4CFF, 0xB48370B6, 0xDD04346D, 0xFA790824,
-		0xFE7C51DE, 0xD9016D97, 0xB086294C, 0x97FB1505,
-		0x565D012E, 0x71203D67, 0x18A779BC, 0x3FDA45F5,
-		0x3BDF1C0F, 0x1CA22046, 0x7525649D, 0x525858D4,
-		0x8C593A6C, 0xAB240625, 0xC2A342FE, 0xE5DE7EB7,
-		0xE1DB274D, 0xC6A61B04, 0xAF215FDF, 0x885C6396,
-		0xE25477AA, 0xC5294BE3, 0xACAE0F38, 0x8BD33371,
-		0x8FD66A8B, 0xA8AB56C2, 0xC12C1219, 0xE6512E50,
-		0x38504CE8, 0x1F2D70A1, 0x76AA347A, 0x51D70833,
-		0x55D251C9, 0x72AF6D80, 0x1B28295B, 0x3C551512,
-		0xCF380123, 0xE8453D6A, 0x81C279B1, 0xA6BF45F8,
-		0xA2BA1C02, 0x85C7204B, 0xEC406490, 0xCB3D58D9,
-		0x153C3A61, 0x32410628, 0x5BC642F3, 0x7CBB7EBA,
-		0x78BE2740, 0x5FC31B09, 0x36445FD2, 0x1139639B,
-		0x7B3177A7, 0x5C4C4BEE, 0x35CB0F35, 0x12B6337C,
-		0x16B36A86, 0x31CE56CF, 0x58491214, 0x7F342E5D,
-		0xA1354CE5, 0x864870AC, 0xEFCF3477, 0xC8B2083E,
-		0xCCB751C4, 0xEBCA6D8D, 0x824D2956, 0xA530151F
-	}
-#endif /* WORDS_BIGENDIAN */
-};
-
-
 /*
  * Lookup table for calculating CRC-32 using Sarwate's algorithm.
  *
diff --git a/src/include/common/pg_crc.h b/src/include/common/pg_crc.h
index f496659..72faeab 100644
--- a/src/include/common/pg_crc.h
+++ b/src/include/common/pg_crc.h
@@ -32,6 +32,8 @@
 #ifndef PG_CRC_H
 #define PG_CRC_H
 
+#include "port/pg_crc32c.h"
+
 /* ugly hack to let this be used in frontend and backend code on Cygwin */
 #ifdef FRONTEND
 #define CRCDLLIMPORT
@@ -39,39 +41,16 @@
 #define CRCDLLIMPORT PGDLLIMPORT
 #endif
 
-typedef uint32 pg_crc32;
-
-#ifdef HAVE__BUILTIN_BSWAP32
-#define BSWAP32(x) __builtin_bswap32(x)
-#else
-#define BSWAP32(x) (((x << 24) & 0xff000000) | \
-					((x << 8) & 0x00ff0000) | \
-					((x >> 8) & 0x0000ff00) | \
-					((x >> 24) & 0x000000ff))
-#endif
-
 /*
  * CRC calculation using the CRC-32C (Castagnoli) polynomial.
  *
  * We use all-ones as the initial register contents and final bit inversion.
  * This is the same algorithm used e.g. in iSCSI. See RFC 3385 for more
  * details on the choice of polynomial.
- *
- * On big-endian systems, the intermediate value is kept in reverse byte
- * order, to avoid byte-swapping during the calculation. FIN_CRC32C reverses
- * the bytes to the final order.
  */
-#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
-#ifdef WORDS_BIGENDIAN
-#define FIN_CRC32C(crc)	((crc) = BSWAP32(crc) ^ 0xFFFFFFFF)
-#else
-#define FIN_CRC32C(crc)	((crc) ^= 0xFFFFFFFF)
-#endif
-#define COMP_CRC32C(crc, data, len)	\
-	((crc) = pg_comp_crc32c((crc), (data), (len)))
+/* INIT_CRC32C, COMP_CRC32C and FIN_CRC32C are defined in port/pg_crc32c.h */
 #define EQ_CRC32C(c1, c2) ((c1) == (c2))
 
-extern pg_crc32 pg_comp_crc32c(pg_crc32 crc, const void *data, size_t len);
 
 /*
  * CRC-32, the same used e.g. in Ethernet.
@@ -130,13 +109,12 @@ do {															  \
 \
 	while (__len-- > 0) \
 	{ \
-		int		__tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF;	\
+		int		__tab_index = ((int) ((crc) >> 24) ^ *__data++) & 0xFF; \
 		(crc) = table[__tab_index] ^ ((crc) << 8); \
 	} \
 } while (0)
 
-/* Constant tables for CRC-32C and CRC-32 polynomials */
-extern CRCDLLIMPORT const uint32 pg_crc32c_table[8][256];
+/* Constant table for the CRC-32 polynomial */
 extern CRCDLLIMPORT const uint32 pg_crc32_table[256];
 
 #endif   /* PG_CRC_H */
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index 202c51a..91b0f0e 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -355,6 +355,13 @@
 /* Define to 1 if you have the `mkdtemp' function. */
 #undef HAVE_MKDTEMP
 
+/* Define to 1 if you have _mm_crc32_u8() and _mm_crc32_u64(). */
+#undef HAVE_MM_CRC32_INTRINSICS
+
+/* Define to 1 if you have _mm_crc32_u8() and _mm_crc32_u64(), but it needs a
+   runtime check. */
+#undef HAVE_MM_CRC32_INTRINSICS_WITH_RUNTIME_CHECK
+
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #undef HAVE_NETINET_IN_H
 
@@ -675,6 +682,12 @@
 /* Define to 1 if your compiler understands __builtin_unreachable. */
 #undef HAVE__BUILTIN_UNREACHABLE
 
+/* Define to 1 if you have __cpuid. */
+#undef HAVE__CPUID
+
+/* Define to 1 if you have __get_cpuid. */
+#undef HAVE__GET_CPUID
+
 /* Define to 1 if your compiler understands _Static_assert. */
 #undef HAVE__STATIC_ASSERT
 
diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32
index 1baf64f..1d00c53 100644
--- a/src/include/pg_config.h.win32
+++ b/src/include/pg_config.h.win32
@@ -5,9 +5,9 @@
  * changes to be valid for Visual C++ (and compatible):
  *
  * HAVE_CBRT, HAVE_FUNCNAME_FUNC, HAVE_GETOPT, HAVE_GETOPT_H, HAVE_INTTYPES_H,
- * HAVE_GETOPT_LONG, HAVE_LOCALE_T, HAVE_RINT, HAVE_STRINGS_H, HAVE_STRTOLL,
- * HAVE_STRTOULL, HAVE_STRUCT_OPTION, ENABLE_THREAD_SAFETY,
- * PG_USE_INLINE, inline
+ * HAVE_GETOPT_LONG, HAVE_LOCALE_T, HAVE_MM_CRC32_INTRINSICS_WITH_RUNTIME_CHECK,
+ * HAVE_RINT, HAVE_STRINGS_H, HAVE_STRTOLL, HAVE_STRTOULL, HAVE_STRUCT_OPTION,
+ * ENABLE_THREAD_SAFETY, PG_USE_INLINE, inline
  */
 
 /* Define to the type of arg 1 of 'accept' */
@@ -249,6 +249,14 @@
 /* Define to 1 if you have the `mkdtemp' function. */
 /* #undef HAVE_MKDTEMP */
 
+/* Define to 1 if you have _mm_crc32_u8() and _mm_crc32_u64(). */
+/* #undef HAVE_MM_CRC32_INTRINSICS */
+
+/* Define to 1 if you have _mm_crc32_u8() and _mm_crc32_u64() but they need a runtime check. */
+#if (_MSC_VER >= 1500)
+#define HAVE_MM_CRC32_INTRINSICS_WITH_RUNTIME_CHECK
+#endif
+
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #define HAVE_NETINET_IN_H 1
 
@@ -529,6 +537,12 @@
 /* Define to 1 if your compiler understands __builtin_unreachable. */
 /* #undef HAVE__BUILTIN_UNREACHABLE */
 
+/* Define to 1 if you have __cpuid. */
+#define HAVE__CPUID 1
+
+/* Define to 1 if you have __get_cpuid. */
+#undef HAVE__GET_CPUID
+
 /* Define to 1 if your compiler understands _Static_assert. */
 /* #undef HAVE__STATIC_ASSERT */
 
diff --git a/src/include/port/pg_crc32c.h b/src/include/port/pg_crc32c.h
new file mode 100644
index 0000000..94687b6
--- /dev/null
+++ b/src/include/port/pg_crc32c.h
@@ -0,0 +1,79 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_crc32c.h
+ *	  Support for computing CRC-32C.
+ *
+ * Some CPU architectures have special instructions for speeding up CRC
+ * calculations. This header files provides access to them in a reasonably
+ * platform and compiler independent way.
+ *
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/port/pg_crc32c.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef PG_CRC32C_H
+#define PG_CRC32C_H
+
+typedef uint32 pg_crc32;
+
+#if defined(HAVE_MM_CRC32_INTRINSICS)
+/* Use SSE4.2 instructions */
+
+extern pg_crc32 pg_comp_crc32c_sse42(pg_crc32 crc, const void *data, size_t len);
+
+#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
+#define COMP_CRC32C(crc, data, len) \
+	((crc) = pg_comp_crc32c_sse42((crc), (data), (len)))
+#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
+
+#elif defined(HAVE_MM_CRC32_INTRINSICS_WITH_RUNTIME_CHECK)
+/*
+ * Use SSE4.2 instructions, but perform a runtime check first to check that
+ * they are available
+ */
+
+extern pg_crc32 pg_comp_crc32c_sse42(pg_crc32 crc, const void *data, size_t len);
+extern pg_crc32 pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len);
+extern pg_crc32 (*pg_comp_crc32c) (pg_crc32 crc, const void *data, size_t len);
+
+#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
+#define COMP_CRC32C(crc, data, len) \
+	((crc) = pg_comp_crc32c((crc), (data), (len)))
+#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
+
+#else
+/*
+ * Use slicing-by-8 algorithm.
+ *
+ * On big-endian systems, the intermediate value is kept in reverse byte
+ * order, to avoid byte-swapping during the calculation. FIN_CRC32C reverses
+ * the bytes to the final order.
+ */
+extern pg_crc32 pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len);
+
+#define INIT_CRC32C(crc) ((crc) = 0xFFFFFFFF)
+#define COMP_CRC32C(crc, data, len) \
+	((crc) = pg_comp_crc32c_sb8((crc), (data), (len)))
+#ifdef WORDS_BIGENDIAN
+
+#ifdef HAVE__BUILTIN_BSWAP32
+#define BSWAP32(x) __builtin_bswap32(x)
+#else
+#define BSWAP32(x) (((x << 24) & 0xff000000) | \
+					((x << 8) & 0x00ff0000) | \
+					((x >> 8) & 0x0000ff00) | \
+					((x >> 24) & 0x000000ff))
+#endif
+
+#define FIN_CRC32C(crc) ((crc) = BSWAP32(crc) ^ 0xFFFFFFFF)
+#else
+#define FIN_CRC32C(crc) ((crc) ^= 0xFFFFFFFF)
+#endif
+
+#endif
+
+#endif /* PG_CRC32C_H */
diff --git a/src/port/Makefile b/src/port/Makefile
index abc42a2..b3d5177 100644
--- a/src/port/Makefile
+++ b/src/port/Makefile
@@ -30,7 +30,7 @@ include $(top_builddir)/src/Makefile.global
 override CPPFLAGS := -I$(top_builddir)/src/port -DFRONTEND $(CPPFLAGS)
 LIBS += $(PTHREAD_LIBS)
 
-OBJS = $(LIBOBJS) chklocale.o erand48.o inet_net_ntop.o \
+OBJS = $(LIBOBJS) $(PG_CRC32C_OBJS) chklocale.o erand48.o inet_net_ntop.o \
 	noblock.o path.o pgcheckdir.o pgmkdirp.o pgsleep.o \
 	pgstrcasecmp.o pqsignal.o \
 	qsort.o qsort_arg.o quotes.o sprompt.o tar.o thread.o
@@ -57,6 +57,11 @@ libpgport.a: $(OBJS)
 # thread.o needs PTHREAD_CFLAGS (but thread_srv.o does not)
 thread.o: CFLAGS+=$(PTHREAD_CFLAGS)
 
+# pg_crc32c_sse42.o and its _src.o version need CFLAGS_SSE42
+pg_crc32c_sse42.o: CFLAGS+=$(CFLAGS_SSE42)
+pg_crc32c_sse42_srv.o: CFLAGS+=$(CFLAGS_SSE42)
+
+
 #
 # Server versions of object files
 #
diff --git a/src/port/pg_crc32c_choose.c b/src/port/pg_crc32c_choose.c
new file mode 100644
index 0000000..ff0f05d
--- /dev/null
+++ b/src/port/pg_crc32c_choose.c
@@ -0,0 +1,63 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_crc32c_choose.c
+ *	  Choose which CRC-32C implementation to use, at runtime.
+ *
+ * Try to the special CRC instructions introduced in Intel SSE 4.2,
+ * if available on the platform we're running on, but fall back to the
+ * slicing-by-8 implementation otherwise.
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/port/pg_crc32c_choose.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "c.h"
+
+#ifdef HAVE__GET_CPUID
+#include <cpuid.h>
+#endif
+
+#ifdef HAVE__CPUID
+#include <intrin.h>
+#endif
+
+#include "port/pg_crc32c.h"
+
+static bool
+pg_crc32c_sse42_available(void)
+{
+	unsigned int exx[4] = {0, 0, 0, 0};
+
+#if defined(HAVE__GET_CPUID)
+	__get_cpuid(1, &exx[0], &exx[1], &exx[2], &exx[3]);
+#elif defined(HAVE__CPUID)
+	__cpuid(exx, 1);
+#else
+#error cpuid instruction not available
+#endif
+
+	return (exx[2] & (1 << 20)) != 0;    /* SSE 4.2 */
+}
+
+/*
+ * This gets called on the first call. It replaces the function pointer
+ * so that subsequent calls are routed directly to the chosen implementation.
+ */
+static pg_crc32
+pg_comp_crc32c_choose(pg_crc32 crc, const void *data, size_t len)
+{
+	if (pg_crc32c_sse42_available())
+		pg_comp_crc32c = pg_comp_crc32c_sse42;
+	else
+		pg_comp_crc32c = pg_comp_crc32c_sb8;
+
+	return pg_comp_crc32c(crc, data, len);
+}
+
+pg_crc32       (*pg_comp_crc32c) (pg_crc32 crc, const void *data, size_t len) = pg_comp_crc32c_choose;
diff --git a/src/port/pg_crc32c_sb8.c b/src/port/pg_crc32c_sb8.c
new file mode 100644
index 0000000..ace8e96
--- /dev/null
+++ b/src/port/pg_crc32c_sb8.c
@@ -0,0 +1,1169 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_crc32c_sb8.c
+ *	  Compute CRC-32C checksum using slicing-by-8 algorithm.
+ *
+ * Michael E. Kounavis, Frank L. Berry,
+ * "Novel Table Lookup-Based Algorithms for High-Performance CRC
+ * Generation", IEEE Transactions on Computers, vol.57, no. 11,
+ * pp. 1550-1560, November 2008, doi:10.1109/TC.2008.85
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/port/pg_crc32c_sb8.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "c.h"
+
+#include "common/pg_crc.h"
+
+static const uint32 pg_crc32c_table[8][256];
+
+/* Accumulate one input byte */
+#ifdef WORDS_BIGENDIAN
+#define CRC8(x) pg_crc32c_table[0][((crc >> 24) ^ (x)) & 0xFF] ^ (crc << 8)
+#else
+#define CRC8(x) pg_crc32c_table[0][(crc ^ (x)) & 0xFF] ^ (crc >> 8)
+#endif
+
+pg_crc32
+pg_comp_crc32c_sb8(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint32 *p4;
+
+	/*
+	 * Handle 0-3 initial bytes one at a time, so that the loop below starts
+	 * with a pointer aligned to four bytes.
+	 */
+	while (len > 0 && ((uintptr_t) p & 3))
+	{
+		crc = CRC8(*p++);
+		len--;
+	}
+
+	/*
+	 * Process eight bytes of data at a time.
+	 */
+	p4 = (const uint32 *) p;
+	while (len >= 8)
+	{
+		uint32		a = *p4++ ^ crc;
+		uint32		b = *p4++;
+
+#ifdef WORDS_BIGENDIAN
+		const uint8 c0 = b;
+		const uint8 c1 = b >> 8;
+		const uint8 c2 = b >> 16;
+		const uint8 c3 = b >> 24;
+		const uint8 c4 = a;
+		const uint8 c5 = a >> 8;
+		const uint8 c6 = a >> 16;
+		const uint8 c7 = a >> 24;
+#else
+		const uint8 c0 = b >> 24;
+		const uint8 c1 = b >> 16;
+		const uint8 c2 = b >> 8;
+		const uint8 c3 = b;
+		const uint8 c4 = a >> 24;
+		const uint8 c5 = a >> 16;
+		const uint8 c6 = a >> 8;
+		const uint8 c7 = a;
+#endif
+
+		crc =
+			pg_crc32c_table[0][c0] ^ pg_crc32c_table[1][c1] ^
+			pg_crc32c_table[2][c2] ^ pg_crc32c_table[3][c3] ^
+			pg_crc32c_table[4][c4] ^ pg_crc32c_table[5][c5] ^
+			pg_crc32c_table[6][c6] ^ pg_crc32c_table[7][c7];
+
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+	p = (const unsigned char *) p4;
+	while (len > 0)
+	{
+		crc = CRC8(*p++);
+		len--;
+	}
+
+	return crc;
+}
+
+/*
+ * Lookup tables for the slicing-by-8 algorithm, for the so-called Castagnoli
+ * polynomial (the same that is used e.g. in iSCSI), 0x1EDC6F41. Using
+ * Williams' terms, this is the "normal", not "reflected" version. However, on
+ * big-endian systems the values in the tables are stored in byte-reversed
+ * order (IOW, the tables are stored in little-endian order even on big-endian
+ * systems).
+ */
+static const uint32 pg_crc32c_table[8][256] = {
+#ifndef WORDS_BIGENDIAN
+	{
+		0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
+		0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
+		0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
+		0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
+		0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
+		0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
+		0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
+		0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
+		0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
+		0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
+		0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
+		0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
+		0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
+		0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
+		0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
+		0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
+		0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
+		0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
+		0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
+		0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
+		0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
+		0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
+		0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
+		0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
+		0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
+		0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
+		0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
+		0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
+		0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
+		0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
+		0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
+		0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
+		0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
+		0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
+		0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
+		0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
+		0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
+		0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
+		0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
+		0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
+		0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
+		0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
+		0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
+		0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
+		0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
+		0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
+		0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
+		0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
+		0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
+		0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
+		0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
+		0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
+		0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
+		0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
+		0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
+		0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
+		0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
+		0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
+		0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
+		0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
+		0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
+		0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
+		0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
+		0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
+	},
+	{
+		0x00000000, 0x13A29877, 0x274530EE, 0x34E7A899,
+		0x4E8A61DC, 0x5D28F9AB, 0x69CF5132, 0x7A6DC945,
+		0x9D14C3B8, 0x8EB65BCF, 0xBA51F356, 0xA9F36B21,
+		0xD39EA264, 0xC03C3A13, 0xF4DB928A, 0xE7790AFD,
+		0x3FC5F181, 0x2C6769F6, 0x1880C16F, 0x0B225918,
+		0x714F905D, 0x62ED082A, 0x560AA0B3, 0x45A838C4,
+		0xA2D13239, 0xB173AA4E, 0x859402D7, 0x96369AA0,
+		0xEC5B53E5, 0xFFF9CB92, 0xCB1E630B, 0xD8BCFB7C,
+		0x7F8BE302, 0x6C297B75, 0x58CED3EC, 0x4B6C4B9B,
+		0x310182DE, 0x22A31AA9, 0x1644B230, 0x05E62A47,
+		0xE29F20BA, 0xF13DB8CD, 0xC5DA1054, 0xD6788823,
+		0xAC154166, 0xBFB7D911, 0x8B507188, 0x98F2E9FF,
+		0x404E1283, 0x53EC8AF4, 0x670B226D, 0x74A9BA1A,
+		0x0EC4735F, 0x1D66EB28, 0x298143B1, 0x3A23DBC6,
+		0xDD5AD13B, 0xCEF8494C, 0xFA1FE1D5, 0xE9BD79A2,
+		0x93D0B0E7, 0x80722890, 0xB4958009, 0xA737187E,
+		0xFF17C604, 0xECB55E73, 0xD852F6EA, 0xCBF06E9D,
+		0xB19DA7D8, 0xA23F3FAF, 0x96D89736, 0x857A0F41,
+		0x620305BC, 0x71A19DCB, 0x45463552, 0x56E4AD25,
+		0x2C896460, 0x3F2BFC17, 0x0BCC548E, 0x186ECCF9,
+		0xC0D23785, 0xD370AFF2, 0xE797076B, 0xF4359F1C,
+		0x8E585659, 0x9DFACE2E, 0xA91D66B7, 0xBABFFEC0,
+		0x5DC6F43D, 0x4E646C4A, 0x7A83C4D3, 0x69215CA4,
+		0x134C95E1, 0x00EE0D96, 0x3409A50F, 0x27AB3D78,
+		0x809C2506, 0x933EBD71, 0xA7D915E8, 0xB47B8D9F,
+		0xCE1644DA, 0xDDB4DCAD, 0xE9537434, 0xFAF1EC43,
+		0x1D88E6BE, 0x0E2A7EC9, 0x3ACDD650, 0x296F4E27,
+		0x53028762, 0x40A01F15, 0x7447B78C, 0x67E52FFB,
+		0xBF59D487, 0xACFB4CF0, 0x981CE469, 0x8BBE7C1E,
+		0xF1D3B55B, 0xE2712D2C, 0xD69685B5, 0xC5341DC2,
+		0x224D173F, 0x31EF8F48, 0x050827D1, 0x16AABFA6,
+		0x6CC776E3, 0x7F65EE94, 0x4B82460D, 0x5820DE7A,
+		0xFBC3FAF9, 0xE861628E, 0xDC86CA17, 0xCF245260,
+		0xB5499B25, 0xA6EB0352, 0x920CABCB, 0x81AE33BC,
+		0x66D73941, 0x7575A136, 0x419209AF, 0x523091D8,
+		0x285D589D, 0x3BFFC0EA, 0x0F186873, 0x1CBAF004,
+		0xC4060B78, 0xD7A4930F, 0xE3433B96, 0xF0E1A3E1,
+		0x8A8C6AA4, 0x992EF2D3, 0xADC95A4A, 0xBE6BC23D,
+		0x5912C8C0, 0x4AB050B7, 0x7E57F82E, 0x6DF56059,
+		0x1798A91C, 0x043A316B, 0x30DD99F2, 0x237F0185,
+		0x844819FB, 0x97EA818C, 0xA30D2915, 0xB0AFB162,
+		0xCAC27827, 0xD960E050, 0xED8748C9, 0xFE25D0BE,
+		0x195CDA43, 0x0AFE4234, 0x3E19EAAD, 0x2DBB72DA,
+		0x57D6BB9F, 0x447423E8, 0x70938B71, 0x63311306,
+		0xBB8DE87A, 0xA82F700D, 0x9CC8D894, 0x8F6A40E3,
+		0xF50789A6, 0xE6A511D1, 0xD242B948, 0xC1E0213F,
+		0x26992BC2, 0x353BB3B5, 0x01DC1B2C, 0x127E835B,
+		0x68134A1E, 0x7BB1D269, 0x4F567AF0, 0x5CF4E287,
+		0x04D43CFD, 0x1776A48A, 0x23910C13, 0x30339464,
+		0x4A5E5D21, 0x59FCC556, 0x6D1B6DCF, 0x7EB9F5B8,
+		0x99C0FF45, 0x8A626732, 0xBE85CFAB, 0xAD2757DC,
+		0xD74A9E99, 0xC4E806EE, 0xF00FAE77, 0xE3AD3600,
+		0x3B11CD7C, 0x28B3550B, 0x1C54FD92, 0x0FF665E5,
+		0x759BACA0, 0x663934D7, 0x52DE9C4E, 0x417C0439,
+		0xA6050EC4, 0xB5A796B3, 0x81403E2A, 0x92E2A65D,
+		0xE88F6F18, 0xFB2DF76F, 0xCFCA5FF6, 0xDC68C781,
+		0x7B5FDFFF, 0x68FD4788, 0x5C1AEF11, 0x4FB87766,
+		0x35D5BE23, 0x26772654, 0x12908ECD, 0x013216BA,
+		0xE64B1C47, 0xF5E98430, 0xC10E2CA9, 0xD2ACB4DE,
+		0xA8C17D9B, 0xBB63E5EC, 0x8F844D75, 0x9C26D502,
+		0x449A2E7E, 0x5738B609, 0x63DF1E90, 0x707D86E7,
+		0x0A104FA2, 0x19B2D7D5, 0x2D557F4C, 0x3EF7E73B,
+		0xD98EEDC6, 0xCA2C75B1, 0xFECBDD28, 0xED69455F,
+		0x97048C1A, 0x84A6146D, 0xB041BCF4, 0xA3E32483
+	},
+	{
+		0x00000000, 0xA541927E, 0x4F6F520D, 0xEA2EC073,
+		0x9EDEA41A, 0x3B9F3664, 0xD1B1F617, 0x74F06469,
+		0x38513EC5, 0x9D10ACBB, 0x773E6CC8, 0xD27FFEB6,
+		0xA68F9ADF, 0x03CE08A1, 0xE9E0C8D2, 0x4CA15AAC,
+		0x70A27D8A, 0xD5E3EFF4, 0x3FCD2F87, 0x9A8CBDF9,
+		0xEE7CD990, 0x4B3D4BEE, 0xA1138B9D, 0x045219E3,
+		0x48F3434F, 0xEDB2D131, 0x079C1142, 0xA2DD833C,
+		0xD62DE755, 0x736C752B, 0x9942B558, 0x3C032726,
+		0xE144FB14, 0x4405696A, 0xAE2BA919, 0x0B6A3B67,
+		0x7F9A5F0E, 0xDADBCD70, 0x30F50D03, 0x95B49F7D,
+		0xD915C5D1, 0x7C5457AF, 0x967A97DC, 0x333B05A2,
+		0x47CB61CB, 0xE28AF3B5, 0x08A433C6, 0xADE5A1B8,
+		0x91E6869E, 0x34A714E0, 0xDE89D493, 0x7BC846ED,
+		0x0F382284, 0xAA79B0FA, 0x40577089, 0xE516E2F7,
+		0xA9B7B85B, 0x0CF62A25, 0xE6D8EA56, 0x43997828,
+		0x37691C41, 0x92288E3F, 0x78064E4C, 0xDD47DC32,
+		0xC76580D9, 0x622412A7, 0x880AD2D4, 0x2D4B40AA,
+		0x59BB24C3, 0xFCFAB6BD, 0x16D476CE, 0xB395E4B0,
+		0xFF34BE1C, 0x5A752C62, 0xB05BEC11, 0x151A7E6F,
+		0x61EA1A06, 0xC4AB8878, 0x2E85480B, 0x8BC4DA75,
+		0xB7C7FD53, 0x12866F2D, 0xF8A8AF5E, 0x5DE93D20,
+		0x29195949, 0x8C58CB37, 0x66760B44, 0xC337993A,
+		0x8F96C396, 0x2AD751E8, 0xC0F9919B, 0x65B803E5,
+		0x1148678C, 0xB409F5F2, 0x5E273581, 0xFB66A7FF,
+		0x26217BCD, 0x8360E9B3, 0x694E29C0, 0xCC0FBBBE,
+		0xB8FFDFD7, 0x1DBE4DA9, 0xF7908DDA, 0x52D11FA4,
+		0x1E704508, 0xBB31D776, 0x511F1705, 0xF45E857B,
+		0x80AEE112, 0x25EF736C, 0xCFC1B31F, 0x6A802161,
+		0x56830647, 0xF3C29439, 0x19EC544A, 0xBCADC634,
+		0xC85DA25D, 0x6D1C3023, 0x8732F050, 0x2273622E,
+		0x6ED23882, 0xCB93AAFC, 0x21BD6A8F, 0x84FCF8F1,
+		0xF00C9C98, 0x554D0EE6, 0xBF63CE95, 0x1A225CEB,
+		0x8B277743, 0x2E66E53D, 0xC448254E, 0x6109B730,
+		0x15F9D359, 0xB0B84127, 0x5A968154, 0xFFD7132A,
+		0xB3764986, 0x1637DBF8, 0xFC191B8B, 0x595889F5,
+		0x2DA8ED9C, 0x88E97FE2, 0x62C7BF91, 0xC7862DEF,
+		0xFB850AC9, 0x5EC498B7, 0xB4EA58C4, 0x11ABCABA,
+		0x655BAED3, 0xC01A3CAD, 0x2A34FCDE, 0x8F756EA0,
+		0xC3D4340C, 0x6695A672, 0x8CBB6601, 0x29FAF47F,
+		0x5D0A9016, 0xF84B0268, 0x1265C21B, 0xB7245065,
+		0x6A638C57, 0xCF221E29, 0x250CDE5A, 0x804D4C24,
+		0xF4BD284D, 0x51FCBA33, 0xBBD27A40, 0x1E93E83E,
+		0x5232B292, 0xF77320EC, 0x1D5DE09F, 0xB81C72E1,
+		0xCCEC1688, 0x69AD84F6, 0x83834485, 0x26C2D6FB,
+		0x1AC1F1DD, 0xBF8063A3, 0x55AEA3D0, 0xF0EF31AE,
+		0x841F55C7, 0x215EC7B9, 0xCB7007CA, 0x6E3195B4,
+		0x2290CF18, 0x87D15D66, 0x6DFF9D15, 0xC8BE0F6B,
+		0xBC4E6B02, 0x190FF97C, 0xF321390F, 0x5660AB71,
+		0x4C42F79A, 0xE90365E4, 0x032DA597, 0xA66C37E9,
+		0xD29C5380, 0x77DDC1FE, 0x9DF3018D, 0x38B293F3,
+		0x7413C95F, 0xD1525B21, 0x3B7C9B52, 0x9E3D092C,
+		0xEACD6D45, 0x4F8CFF3B, 0xA5A23F48, 0x00E3AD36,
+		0x3CE08A10, 0x99A1186E, 0x738FD81D, 0xD6CE4A63,
+		0xA23E2E0A, 0x077FBC74, 0xED517C07, 0x4810EE79,
+		0x04B1B4D5, 0xA1F026AB, 0x4BDEE6D8, 0xEE9F74A6,
+		0x9A6F10CF, 0x3F2E82B1, 0xD50042C2, 0x7041D0BC,
+		0xAD060C8E, 0x08479EF0, 0xE2695E83, 0x4728CCFD,
+		0x33D8A894, 0x96993AEA, 0x7CB7FA99, 0xD9F668E7,
+		0x9557324B, 0x3016A035, 0xDA386046, 0x7F79F238,
+		0x0B899651, 0xAEC8042F, 0x44E6C45C, 0xE1A75622,
+		0xDDA47104, 0x78E5E37A, 0x92CB2309, 0x378AB177,
+		0x437AD51E, 0xE63B4760, 0x0C158713, 0xA954156D,
+		0xE5F54FC1, 0x40B4DDBF, 0xAA9A1DCC, 0x0FDB8FB2,
+		0x7B2BEBDB, 0xDE6A79A5, 0x3444B9D6, 0x91052BA8
+	},
+	{
+		0x00000000, 0xDD45AAB8, 0xBF672381, 0x62228939,
+		0x7B2231F3, 0xA6679B4B, 0xC4451272, 0x1900B8CA,
+		0xF64463E6, 0x2B01C95E, 0x49234067, 0x9466EADF,
+		0x8D665215, 0x5023F8AD, 0x32017194, 0xEF44DB2C,
+		0xE964B13D, 0x34211B85, 0x560392BC, 0x8B463804,
+		0x924680CE, 0x4F032A76, 0x2D21A34F, 0xF06409F7,
+		0x1F20D2DB, 0xC2657863, 0xA047F15A, 0x7D025BE2,
+		0x6402E328, 0xB9474990, 0xDB65C0A9, 0x06206A11,
+		0xD725148B, 0x0A60BE33, 0x6842370A, 0xB5079DB2,
+		0xAC072578, 0x71428FC0, 0x136006F9, 0xCE25AC41,
+		0x2161776D, 0xFC24DDD5, 0x9E0654EC, 0x4343FE54,
+		0x5A43469E, 0x8706EC26, 0xE524651F, 0x3861CFA7,
+		0x3E41A5B6, 0xE3040F0E, 0x81268637, 0x5C632C8F,
+		0x45639445, 0x98263EFD, 0xFA04B7C4, 0x27411D7C,
+		0xC805C650, 0x15406CE8, 0x7762E5D1, 0xAA274F69,
+		0xB327F7A3, 0x6E625D1B, 0x0C40D422, 0xD1057E9A,
+		0xABA65FE7, 0x76E3F55F, 0x14C17C66, 0xC984D6DE,
+		0xD0846E14, 0x0DC1C4AC, 0x6FE34D95, 0xB2A6E72D,
+		0x5DE23C01, 0x80A796B9, 0xE2851F80, 0x3FC0B538,
+		0x26C00DF2, 0xFB85A74A, 0x99A72E73, 0x44E284CB,
+		0x42C2EEDA, 0x9F874462, 0xFDA5CD5B, 0x20E067E3,
+		0x39E0DF29, 0xE4A57591, 0x8687FCA8, 0x5BC25610,
+		0xB4868D3C, 0x69C32784, 0x0BE1AEBD, 0xD6A40405,
+		0xCFA4BCCF, 0x12E11677, 0x70C39F4E, 0xAD8635F6,
+		0x7C834B6C, 0xA1C6E1D4, 0xC3E468ED, 0x1EA1C255,
+		0x07A17A9F, 0xDAE4D027, 0xB8C6591E, 0x6583F3A6,
+		0x8AC7288A, 0x57828232, 0x35A00B0B, 0xE8E5A1B3,
+		0xF1E51979, 0x2CA0B3C1, 0x4E823AF8, 0x93C79040,
+		0x95E7FA51, 0x48A250E9, 0x2A80D9D0, 0xF7C57368,
+		0xEEC5CBA2, 0x3380611A, 0x51A2E823, 0x8CE7429B,
+		0x63A399B7, 0xBEE6330F, 0xDCC4BA36, 0x0181108E,
+		0x1881A844, 0xC5C402FC, 0xA7E68BC5, 0x7AA3217D,
+		0x52A0C93F, 0x8FE56387, 0xEDC7EABE, 0x30824006,
+		0x2982F8CC, 0xF4C75274, 0x96E5DB4D, 0x4BA071F5,
+		0xA4E4AAD9, 0x79A10061, 0x1B838958, 0xC6C623E0,
+		0xDFC69B2A, 0x02833192, 0x60A1B8AB, 0xBDE41213,
+		0xBBC47802, 0x6681D2BA, 0x04A35B83, 0xD9E6F13B,
+		0xC0E649F1, 0x1DA3E349, 0x7F816A70, 0xA2C4C0C8,
+		0x4D801BE4, 0x90C5B15C, 0xF2E73865, 0x2FA292DD,
+		0x36A22A17, 0xEBE780AF, 0x89C50996, 0x5480A32E,
+		0x8585DDB4, 0x58C0770C, 0x3AE2FE35, 0xE7A7548D,
+		0xFEA7EC47, 0x23E246FF, 0x41C0CFC6, 0x9C85657E,
+		0x73C1BE52, 0xAE8414EA, 0xCCA69DD3, 0x11E3376B,
+		0x08E38FA1, 0xD5A62519, 0xB784AC20, 0x6AC10698,
+		0x6CE16C89, 0xB1A4C631, 0xD3864F08, 0x0EC3E5B0,
+		0x17C35D7A, 0xCA86F7C2, 0xA8A47EFB, 0x75E1D443,
+		0x9AA50F6F, 0x47E0A5D7, 0x25C22CEE, 0xF8878656,
+		0xE1873E9C, 0x3CC29424, 0x5EE01D1D, 0x83A5B7A5,
+		0xF90696D8, 0x24433C60, 0x4661B559, 0x9B241FE1,
+		0x8224A72B, 0x5F610D93, 0x3D4384AA, 0xE0062E12,
+		0x0F42F53E, 0xD2075F86, 0xB025D6BF, 0x6D607C07,
+		0x7460C4CD, 0xA9256E75, 0xCB07E74C, 0x16424DF4,
+		0x106227E5, 0xCD278D5D, 0xAF050464, 0x7240AEDC,
+		0x6B401616, 0xB605BCAE, 0xD4273597, 0x09629F2F,
+		0xE6264403, 0x3B63EEBB, 0x59416782, 0x8404CD3A,
+		0x9D0475F0, 0x4041DF48, 0x22635671, 0xFF26FCC9,
+		0x2E238253, 0xF36628EB, 0x9144A1D2, 0x4C010B6A,
+		0x5501B3A0, 0x88441918, 0xEA669021, 0x37233A99,
+		0xD867E1B5, 0x05224B0D, 0x6700C234, 0xBA45688C,
+		0xA345D046, 0x7E007AFE, 0x1C22F3C7, 0xC167597F,
+		0xC747336E, 0x1A0299D6, 0x782010EF, 0xA565BA57,
+		0xBC65029D, 0x6120A825, 0x0302211C, 0xDE478BA4,
+		0x31035088, 0xEC46FA30, 0x8E647309, 0x5321D9B1,
+		0x4A21617B, 0x9764CBC3, 0xF54642FA, 0x2803E842
+	},
+	{
+		0x00000000, 0x38116FAC, 0x7022DF58, 0x4833B0F4,
+		0xE045BEB0, 0xD854D11C, 0x906761E8, 0xA8760E44,
+		0xC5670B91, 0xFD76643D, 0xB545D4C9, 0x8D54BB65,
+		0x2522B521, 0x1D33DA8D, 0x55006A79, 0x6D1105D5,
+		0x8F2261D3, 0xB7330E7F, 0xFF00BE8B, 0xC711D127,
+		0x6F67DF63, 0x5776B0CF, 0x1F45003B, 0x27546F97,
+		0x4A456A42, 0x725405EE, 0x3A67B51A, 0x0276DAB6,
+		0xAA00D4F2, 0x9211BB5E, 0xDA220BAA, 0xE2336406,
+		0x1BA8B557, 0x23B9DAFB, 0x6B8A6A0F, 0x539B05A3,
+		0xFBED0BE7, 0xC3FC644B, 0x8BCFD4BF, 0xB3DEBB13,
+		0xDECFBEC6, 0xE6DED16A, 0xAEED619E, 0x96FC0E32,
+		0x3E8A0076, 0x069B6FDA, 0x4EA8DF2E, 0x76B9B082,
+		0x948AD484, 0xAC9BBB28, 0xE4A80BDC, 0xDCB96470,
+		0x74CF6A34, 0x4CDE0598, 0x04EDB56C, 0x3CFCDAC0,
+		0x51EDDF15, 0x69FCB0B9, 0x21CF004D, 0x19DE6FE1,
+		0xB1A861A5, 0x89B90E09, 0xC18ABEFD, 0xF99BD151,
+		0x37516AAE, 0x0F400502, 0x4773B5F6, 0x7F62DA5A,
+		0xD714D41E, 0xEF05BBB2, 0xA7360B46, 0x9F2764EA,
+		0xF236613F, 0xCA270E93, 0x8214BE67, 0xBA05D1CB,
+		0x1273DF8F, 0x2A62B023, 0x625100D7, 0x5A406F7B,
+		0xB8730B7D, 0x806264D1, 0xC851D425, 0xF040BB89,
+		0x5836B5CD, 0x6027DA61, 0x28146A95, 0x10050539,
+		0x7D1400EC, 0x45056F40, 0x0D36DFB4, 0x3527B018,
+		0x9D51BE5C, 0xA540D1F0, 0xED736104, 0xD5620EA8,
+		0x2CF9DFF9, 0x14E8B055, 0x5CDB00A1, 0x64CA6F0D,
+		0xCCBC6149, 0xF4AD0EE5, 0xBC9EBE11, 0x848FD1BD,
+		0xE99ED468, 0xD18FBBC4, 0x99BC0B30, 0xA1AD649C,
+		0x09DB6AD8, 0x31CA0574, 0x79F9B580, 0x41E8DA2C,
+		0xA3DBBE2A, 0x9BCAD186, 0xD3F96172, 0xEBE80EDE,
+		0x439E009A, 0x7B8F6F36, 0x33BCDFC2, 0x0BADB06E,
+		0x66BCB5BB, 0x5EADDA17, 0x169E6AE3, 0x2E8F054F,
+		0x86F90B0B, 0xBEE864A7, 0xF6DBD453, 0xCECABBFF,
+		0x6EA2D55C, 0x56B3BAF0, 0x1E800A04, 0x269165A8,
+		0x8EE76BEC, 0xB6F60440, 0xFEC5B4B4, 0xC6D4DB18,
+		0xABC5DECD, 0x93D4B161, 0xDBE70195, 0xE3F66E39,
+		0x4B80607D, 0x73910FD1, 0x3BA2BF25, 0x03B3D089,
+		0xE180B48F, 0xD991DB23, 0x91A26BD7, 0xA9B3047B,
+		0x01C50A3F, 0x39D46593, 0x71E7D567, 0x49F6BACB,
+		0x24E7BF1E, 0x1CF6D0B2, 0x54C56046, 0x6CD40FEA,
+		0xC4A201AE, 0xFCB36E02, 0xB480DEF6, 0x8C91B15A,
+		0x750A600B, 0x4D1B0FA7, 0x0528BF53, 0x3D39D0FF,
+		0x954FDEBB, 0xAD5EB117, 0xE56D01E3, 0xDD7C6E4F,
+		0xB06D6B9A, 0x887C0436, 0xC04FB4C2, 0xF85EDB6E,
+		0x5028D52A, 0x6839BA86, 0x200A0A72, 0x181B65DE,
+		0xFA2801D8, 0xC2396E74, 0x8A0ADE80, 0xB21BB12C,
+		0x1A6DBF68, 0x227CD0C4, 0x6A4F6030, 0x525E0F9C,
+		0x3F4F0A49, 0x075E65E5, 0x4F6DD511, 0x777CBABD,
+		0xDF0AB4F9, 0xE71BDB55, 0xAF286BA1, 0x9739040D,
+		0x59F3BFF2, 0x61E2D05E, 0x29D160AA, 0x11C00F06,
+		0xB9B60142, 0x81A76EEE, 0xC994DE1A, 0xF185B1B6,
+		0x9C94B463, 0xA485DBCF, 0xECB66B3B, 0xD4A70497,
+		0x7CD10AD3, 0x44C0657F, 0x0CF3D58B, 0x34E2BA27,
+		0xD6D1DE21, 0xEEC0B18D, 0xA6F30179, 0x9EE26ED5,
+		0x36946091, 0x0E850F3D, 0x46B6BFC9, 0x7EA7D065,
+		0x13B6D5B0, 0x2BA7BA1C, 0x63940AE8, 0x5B856544,
+		0xF3F36B00, 0xCBE204AC, 0x83D1B458, 0xBBC0DBF4,
+		0x425B0AA5, 0x7A4A6509, 0x3279D5FD, 0x0A68BA51,
+		0xA21EB415, 0x9A0FDBB9, 0xD23C6B4D, 0xEA2D04E1,
+		0x873C0134, 0xBF2D6E98, 0xF71EDE6C, 0xCF0FB1C0,
+		0x6779BF84, 0x5F68D028, 0x175B60DC, 0x2F4A0F70,
+		0xCD796B76, 0xF56804DA, 0xBD5BB42E, 0x854ADB82,
+		0x2D3CD5C6, 0x152DBA6A, 0x5D1E0A9E, 0x650F6532,
+		0x081E60E7, 0x300F0F4B, 0x783CBFBF, 0x402DD013,
+		0xE85BDE57, 0xD04AB1FB, 0x9879010F, 0xA0686EA3
+	},
+	{
+		0x00000000, 0xEF306B19, 0xDB8CA0C3, 0x34BCCBDA,
+		0xB2F53777, 0x5DC55C6E, 0x697997B4, 0x8649FCAD,
+		0x6006181F, 0x8F367306, 0xBB8AB8DC, 0x54BAD3C5,
+		0xD2F32F68, 0x3DC34471, 0x097F8FAB, 0xE64FE4B2,
+		0xC00C303E, 0x2F3C5B27, 0x1B8090FD, 0xF4B0FBE4,
+		0x72F90749, 0x9DC96C50, 0xA975A78A, 0x4645CC93,
+		0xA00A2821, 0x4F3A4338, 0x7B8688E2, 0x94B6E3FB,
+		0x12FF1F56, 0xFDCF744F, 0xC973BF95, 0x2643D48C,
+		0x85F4168D, 0x6AC47D94, 0x5E78B64E, 0xB148DD57,
+		0x370121FA, 0xD8314AE3, 0xEC8D8139, 0x03BDEA20,
+		0xE5F20E92, 0x0AC2658B, 0x3E7EAE51, 0xD14EC548,
+		0x570739E5, 0xB83752FC, 0x8C8B9926, 0x63BBF23F,
+		0x45F826B3, 0xAAC84DAA, 0x9E748670, 0x7144ED69,
+		0xF70D11C4, 0x183D7ADD, 0x2C81B107, 0xC3B1DA1E,
+		0x25FE3EAC, 0xCACE55B5, 0xFE729E6F, 0x1142F576,
+		0x970B09DB, 0x783B62C2, 0x4C87A918, 0xA3B7C201,
+		0x0E045BEB, 0xE13430F2, 0xD588FB28, 0x3AB89031,
+		0xBCF16C9C, 0x53C10785, 0x677DCC5F, 0x884DA746,
+		0x6E0243F4, 0x813228ED, 0xB58EE337, 0x5ABE882E,
+		0xDCF77483, 0x33C71F9A, 0x077BD440, 0xE84BBF59,
+		0xCE086BD5, 0x213800CC, 0x1584CB16, 0xFAB4A00F,
+		0x7CFD5CA2, 0x93CD37BB, 0xA771FC61, 0x48419778,
+		0xAE0E73CA, 0x413E18D3, 0x7582D309, 0x9AB2B810,
+		0x1CFB44BD, 0xF3CB2FA4, 0xC777E47E, 0x28478F67,
+		0x8BF04D66, 0x64C0267F, 0x507CEDA5, 0xBF4C86BC,
+		0x39057A11, 0xD6351108, 0xE289DAD2, 0x0DB9B1CB,
+		0xEBF65579, 0x04C63E60, 0x307AF5BA, 0xDF4A9EA3,
+		0x5903620E, 0xB6330917, 0x828FC2CD, 0x6DBFA9D4,
+		0x4BFC7D58, 0xA4CC1641, 0x9070DD9B, 0x7F40B682,
+		0xF9094A2F, 0x16392136, 0x2285EAEC, 0xCDB581F5,
+		0x2BFA6547, 0xC4CA0E5E, 0xF076C584, 0x1F46AE9D,
+		0x990F5230, 0x763F3929, 0x4283F2F3, 0xADB399EA,
+		0x1C08B7D6, 0xF338DCCF, 0xC7841715, 0x28B47C0C,
+		0xAEFD80A1, 0x41CDEBB8, 0x75712062, 0x9A414B7B,
+		0x7C0EAFC9, 0x933EC4D0, 0xA7820F0A, 0x48B26413,
+		0xCEFB98BE, 0x21CBF3A7, 0x1577387D, 0xFA475364,
+		0xDC0487E8, 0x3334ECF1, 0x0788272B, 0xE8B84C32,
+		0x6EF1B09F, 0x81C1DB86, 0xB57D105C, 0x5A4D7B45,
+		0xBC029FF7, 0x5332F4EE, 0x678E3F34, 0x88BE542D,
+		0x0EF7A880, 0xE1C7C399, 0xD57B0843, 0x3A4B635A,
+		0x99FCA15B, 0x76CCCA42, 0x42700198, 0xAD406A81,
+		0x2B09962C, 0xC439FD35, 0xF08536EF, 0x1FB55DF6,
+		0xF9FAB944, 0x16CAD25D, 0x22761987, 0xCD46729E,
+		0x4B0F8E33, 0xA43FE52A, 0x90832EF0, 0x7FB345E9,
+		0x59F09165, 0xB6C0FA7C, 0x827C31A6, 0x6D4C5ABF,
+		0xEB05A612, 0x0435CD0B, 0x308906D1, 0xDFB96DC8,
+		0x39F6897A, 0xD6C6E263, 0xE27A29B9, 0x0D4A42A0,
+		0x8B03BE0D, 0x6433D514, 0x508F1ECE, 0xBFBF75D7,
+		0x120CEC3D, 0xFD3C8724, 0xC9804CFE, 0x26B027E7,
+		0xA0F9DB4A, 0x4FC9B053, 0x7B757B89, 0x94451090,
+		0x720AF422, 0x9D3A9F3B, 0xA98654E1, 0x46B63FF8,
+		0xC0FFC355, 0x2FCFA84C, 0x1B736396, 0xF443088F,
+		0xD200DC03, 0x3D30B71A, 0x098C7CC0, 0xE6BC17D9,
+		0x60F5EB74, 0x8FC5806D, 0xBB794BB7, 0x544920AE,
+		0xB206C41C, 0x5D36AF05, 0x698A64DF, 0x86BA0FC6,
+		0x00F3F36B, 0xEFC39872, 0xDB7F53A8, 0x344F38B1,
+		0x97F8FAB0, 0x78C891A9, 0x4C745A73, 0xA344316A,
+		0x250DCDC7, 0xCA3DA6DE, 0xFE816D04, 0x11B1061D,
+		0xF7FEE2AF, 0x18CE89B6, 0x2C72426C, 0xC3422975,
+		0x450BD5D8, 0xAA3BBEC1, 0x9E87751B, 0x71B71E02,
+		0x57F4CA8E, 0xB8C4A197, 0x8C786A4D, 0x63480154,
+		0xE501FDF9, 0x0A3196E0, 0x3E8D5D3A, 0xD1BD3623,
+		0x37F2D291, 0xD8C2B988, 0xEC7E7252, 0x034E194B,
+		0x8507E5E6, 0x6A378EFF, 0x5E8B4525, 0xB1BB2E3C
+	},
+	{
+		0x00000000, 0x68032CC8, 0xD0065990, 0xB8057558,
+		0xA5E0C5D1, 0xCDE3E919, 0x75E69C41, 0x1DE5B089,
+		0x4E2DFD53, 0x262ED19B, 0x9E2BA4C3, 0xF628880B,
+		0xEBCD3882, 0x83CE144A, 0x3BCB6112, 0x53C84DDA,
+		0x9C5BFAA6, 0xF458D66E, 0x4C5DA336, 0x245E8FFE,
+		0x39BB3F77, 0x51B813BF, 0xE9BD66E7, 0x81BE4A2F,
+		0xD27607F5, 0xBA752B3D, 0x02705E65, 0x6A7372AD,
+		0x7796C224, 0x1F95EEEC, 0xA7909BB4, 0xCF93B77C,
+		0x3D5B83BD, 0x5558AF75, 0xED5DDA2D, 0x855EF6E5,
+		0x98BB466C, 0xF0B86AA4, 0x48BD1FFC, 0x20BE3334,
+		0x73767EEE, 0x1B755226, 0xA370277E, 0xCB730BB6,
+		0xD696BB3F, 0xBE9597F7, 0x0690E2AF, 0x6E93CE67,
+		0xA100791B, 0xC90355D3, 0x7106208B, 0x19050C43,
+		0x04E0BCCA, 0x6CE39002, 0xD4E6E55A, 0xBCE5C992,
+		0xEF2D8448, 0x872EA880, 0x3F2BDDD8, 0x5728F110,
+		0x4ACD4199, 0x22CE6D51, 0x9ACB1809, 0xF2C834C1,
+		0x7AB7077A, 0x12B42BB2, 0xAAB15EEA, 0xC2B27222,
+		0xDF57C2AB, 0xB754EE63, 0x0F519B3B, 0x6752B7F3,
+		0x349AFA29, 0x5C99D6E1, 0xE49CA3B9, 0x8C9F8F71,
+		0x917A3FF8, 0xF9791330, 0x417C6668, 0x297F4AA0,
+		0xE6ECFDDC, 0x8EEFD114, 0x36EAA44C, 0x5EE98884,
+		0x430C380D, 0x2B0F14C5, 0x930A619D, 0xFB094D55,
+		0xA8C1008F, 0xC0C22C47, 0x78C7591F, 0x10C475D7,
+		0x0D21C55E, 0x6522E996, 0xDD279CCE, 0xB524B006,
+		0x47EC84C7, 0x2FEFA80F, 0x97EADD57, 0xFFE9F19F,
+		0xE20C4116, 0x8A0F6DDE, 0x320A1886, 0x5A09344E,
+		0x09C17994, 0x61C2555C, 0xD9C72004, 0xB1C40CCC,
+		0xAC21BC45, 0xC422908D, 0x7C27E5D5, 0x1424C91D,
+		0xDBB77E61, 0xB3B452A9, 0x0BB127F1, 0x63B20B39,
+		0x7E57BBB0, 0x16549778, 0xAE51E220, 0xC652CEE8,
+		0x959A8332, 0xFD99AFFA, 0x459CDAA2, 0x2D9FF66A,
+		0x307A46E3, 0x58796A2B, 0xE07C1F73, 0x887F33BB,
+		0xF56E0EF4, 0x9D6D223C, 0x25685764, 0x4D6B7BAC,
+		0x508ECB25, 0x388DE7ED, 0x808892B5, 0xE88BBE7D,
+		0xBB43F3A7, 0xD340DF6F, 0x6B45AA37, 0x034686FF,
+		0x1EA33676, 0x76A01ABE, 0xCEA56FE6, 0xA6A6432E,
+		0x6935F452, 0x0136D89A, 0xB933ADC2, 0xD130810A,
+		0xCCD53183, 0xA4D61D4B, 0x1CD36813, 0x74D044DB,
+		0x27180901, 0x4F1B25C9, 0xF71E5091, 0x9F1D7C59,
+		0x82F8CCD0, 0xEAFBE018, 0x52FE9540, 0x3AFDB988,
+		0xC8358D49, 0xA036A181, 0x1833D4D9, 0x7030F811,
+		0x6DD54898, 0x05D66450, 0xBDD31108, 0xD5D03DC0,
+		0x8618701A, 0xEE1B5CD2, 0x561E298A, 0x3E1D0542,
+		0x23F8B5CB, 0x4BFB9903, 0xF3FEEC5B, 0x9BFDC093,
+		0x546E77EF, 0x3C6D5B27, 0x84682E7F, 0xEC6B02B7,
+		0xF18EB23E, 0x998D9EF6, 0x2188EBAE, 0x498BC766,
+		0x1A438ABC, 0x7240A674, 0xCA45D32C, 0xA246FFE4,
+		0xBFA34F6D, 0xD7A063A5, 0x6FA516FD, 0x07A63A35,
+		0x8FD9098E, 0xE7DA2546, 0x5FDF501E, 0x37DC7CD6,
+		0x2A39CC5F, 0x423AE097, 0xFA3F95CF, 0x923CB907,
+		0xC1F4F4DD, 0xA9F7D815, 0x11F2AD4D, 0x79F18185,
+		0x6414310C, 0x0C171DC4, 0xB412689C, 0xDC114454,
+		0x1382F328, 0x7B81DFE0, 0xC384AAB8, 0xAB878670,
+		0xB66236F9, 0xDE611A31, 0x66646F69, 0x0E6743A1,
+		0x5DAF0E7B, 0x35AC22B3, 0x8DA957EB, 0xE5AA7B23,
+		0xF84FCBAA, 0x904CE762, 0x2849923A, 0x404ABEF2,
+		0xB2828A33, 0xDA81A6FB, 0x6284D3A3, 0x0A87FF6B,
+		0x17624FE2, 0x7F61632A, 0xC7641672, 0xAF673ABA,
+		0xFCAF7760, 0x94AC5BA8, 0x2CA92EF0, 0x44AA0238,
+		0x594FB2B1, 0x314C9E79, 0x8949EB21, 0xE14AC7E9,
+		0x2ED97095, 0x46DA5C5D, 0xFEDF2905, 0x96DC05CD,
+		0x8B39B544, 0xE33A998C, 0x5B3FECD4, 0x333CC01C,
+		0x60F48DC6, 0x08F7A10E, 0xB0F2D456, 0xD8F1F89E,
+		0xC5144817, 0xAD1764DF, 0x15121187, 0x7D113D4F
+	},
+	{
+		0x00000000, 0x493C7D27, 0x9278FA4E, 0xDB448769,
+		0x211D826D, 0x6821FF4A, 0xB3657823, 0xFA590504,
+		0x423B04DA, 0x0B0779FD, 0xD043FE94, 0x997F83B3,
+		0x632686B7, 0x2A1AFB90, 0xF15E7CF9, 0xB86201DE,
+		0x847609B4, 0xCD4A7493, 0x160EF3FA, 0x5F328EDD,
+		0xA56B8BD9, 0xEC57F6FE, 0x37137197, 0x7E2F0CB0,
+		0xC64D0D6E, 0x8F717049, 0x5435F720, 0x1D098A07,
+		0xE7508F03, 0xAE6CF224, 0x7528754D, 0x3C14086A,
+		0x0D006599, 0x443C18BE, 0x9F789FD7, 0xD644E2F0,
+		0x2C1DE7F4, 0x65219AD3, 0xBE651DBA, 0xF759609D,
+		0x4F3B6143, 0x06071C64, 0xDD439B0D, 0x947FE62A,
+		0x6E26E32E, 0x271A9E09, 0xFC5E1960, 0xB5626447,
+		0x89766C2D, 0xC04A110A, 0x1B0E9663, 0x5232EB44,
+		0xA86BEE40, 0xE1579367, 0x3A13140E, 0x732F6929,
+		0xCB4D68F7, 0x827115D0, 0x593592B9, 0x1009EF9E,
+		0xEA50EA9A, 0xA36C97BD, 0x782810D4, 0x31146DF3,
+		0x1A00CB32, 0x533CB615, 0x8878317C, 0xC1444C5B,
+		0x3B1D495F, 0x72213478, 0xA965B311, 0xE059CE36,
+		0x583BCFE8, 0x1107B2CF, 0xCA4335A6, 0x837F4881,
+		0x79264D85, 0x301A30A2, 0xEB5EB7CB, 0xA262CAEC,
+		0x9E76C286, 0xD74ABFA1, 0x0C0E38C8, 0x453245EF,
+		0xBF6B40EB, 0xF6573DCC, 0x2D13BAA5, 0x642FC782,
+		0xDC4DC65C, 0x9571BB7B, 0x4E353C12, 0x07094135,
+		0xFD504431, 0xB46C3916, 0x6F28BE7F, 0x2614C358,
+		0x1700AEAB, 0x5E3CD38C, 0x857854E5, 0xCC4429C2,
+		0x361D2CC6, 0x7F2151E1, 0xA465D688, 0xED59ABAF,
+		0x553BAA71, 0x1C07D756, 0xC743503F, 0x8E7F2D18,
+		0x7426281C, 0x3D1A553B, 0xE65ED252, 0xAF62AF75,
+		0x9376A71F, 0xDA4ADA38, 0x010E5D51, 0x48322076,
+		0xB26B2572, 0xFB575855, 0x2013DF3C, 0x692FA21B,
+		0xD14DA3C5, 0x9871DEE2, 0x4335598B, 0x0A0924AC,
+		0xF05021A8, 0xB96C5C8F, 0x6228DBE6, 0x2B14A6C1,
+		0x34019664, 0x7D3DEB43, 0xA6796C2A, 0xEF45110D,
+		0x151C1409, 0x5C20692E, 0x8764EE47, 0xCE589360,
+		0x763A92BE, 0x3F06EF99, 0xE44268F0, 0xAD7E15D7,
+		0x572710D3, 0x1E1B6DF4, 0xC55FEA9D, 0x8C6397BA,
+		0xB0779FD0, 0xF94BE2F7, 0x220F659E, 0x6B3318B9,
+		0x916A1DBD, 0xD856609A, 0x0312E7F3, 0x4A2E9AD4,
+		0xF24C9B0A, 0xBB70E62D, 0x60346144, 0x29081C63,
+		0xD3511967, 0x9A6D6440, 0x4129E329, 0x08159E0E,
+		0x3901F3FD, 0x703D8EDA, 0xAB7909B3, 0xE2457494,
+		0x181C7190, 0x51200CB7, 0x8A648BDE, 0xC358F6F9,
+		0x7B3AF727, 0x32068A00, 0xE9420D69, 0xA07E704E,
+		0x5A27754A, 0x131B086D, 0xC85F8F04, 0x8163F223,
+		0xBD77FA49, 0xF44B876E, 0x2F0F0007, 0x66337D20,
+		0x9C6A7824, 0xD5560503, 0x0E12826A, 0x472EFF4D,
+		0xFF4CFE93, 0xB67083B4, 0x6D3404DD, 0x240879FA,
+		0xDE517CFE, 0x976D01D9, 0x4C2986B0, 0x0515FB97,
+		0x2E015D56, 0x673D2071, 0xBC79A718, 0xF545DA3F,
+		0x0F1CDF3B, 0x4620A21C, 0x9D642575, 0xD4585852,
+		0x6C3A598C, 0x250624AB, 0xFE42A3C2, 0xB77EDEE5,
+		0x4D27DBE1, 0x041BA6C6, 0xDF5F21AF, 0x96635C88,
+		0xAA7754E2, 0xE34B29C5, 0x380FAEAC, 0x7133D38B,
+		0x8B6AD68F, 0xC256ABA8, 0x19122CC1, 0x502E51E6,
+		0xE84C5038, 0xA1702D1F, 0x7A34AA76, 0x3308D751,
+		0xC951D255, 0x806DAF72, 0x5B29281B, 0x1215553C,
+		0x230138CF, 0x6A3D45E8, 0xB179C281, 0xF845BFA6,
+		0x021CBAA2, 0x4B20C785, 0x906440EC, 0xD9583DCB,
+		0x613A3C15, 0x28064132, 0xF342C65B, 0xBA7EBB7C,
+		0x4027BE78, 0x091BC35F, 0xD25F4436, 0x9B633911,
+		0xA777317B, 0xEE4B4C5C, 0x350FCB35, 0x7C33B612,
+		0x866AB316, 0xCF56CE31, 0x14124958, 0x5D2E347F,
+		0xE54C35A1, 0xAC704886, 0x7734CFEF, 0x3E08B2C8,
+		0xC451B7CC, 0x8D6DCAEB, 0x56294D82, 0x1F1530A5
+	}
+#else							/* !WORDS_BIGENDIAN */
+	{
+		0x00000000, 0x03836BF2, 0xF7703BE1, 0xF4F35013,
+		0x1F979AC7, 0x1C14F135, 0xE8E7A126, 0xEB64CAD4,
+		0xCF58D98A, 0xCCDBB278, 0x3828E26B, 0x3BAB8999,
+		0xD0CF434D, 0xD34C28BF, 0x27BF78AC, 0x243C135E,
+		0x6FC75E10, 0x6C4435E2, 0x98B765F1, 0x9B340E03,
+		0x7050C4D7, 0x73D3AF25, 0x8720FF36, 0x84A394C4,
+		0xA09F879A, 0xA31CEC68, 0x57EFBC7B, 0x546CD789,
+		0xBF081D5D, 0xBC8B76AF, 0x487826BC, 0x4BFB4D4E,
+		0xDE8EBD20, 0xDD0DD6D2, 0x29FE86C1, 0x2A7DED33,
+		0xC11927E7, 0xC29A4C15, 0x36691C06, 0x35EA77F4,
+		0x11D664AA, 0x12550F58, 0xE6A65F4B, 0xE52534B9,
+		0x0E41FE6D, 0x0DC2959F, 0xF931C58C, 0xFAB2AE7E,
+		0xB149E330, 0xB2CA88C2, 0x4639D8D1, 0x45BAB323,
+		0xAEDE79F7, 0xAD5D1205, 0x59AE4216, 0x5A2D29E4,
+		0x7E113ABA, 0x7D925148, 0x8961015B, 0x8AE26AA9,
+		0x6186A07D, 0x6205CB8F, 0x96F69B9C, 0x9575F06E,
+		0xBC1D7B41, 0xBF9E10B3, 0x4B6D40A0, 0x48EE2B52,
+		0xA38AE186, 0xA0098A74, 0x54FADA67, 0x5779B195,
+		0x7345A2CB, 0x70C6C939, 0x8435992A, 0x87B6F2D8,
+		0x6CD2380C, 0x6F5153FE, 0x9BA203ED, 0x9821681F,
+		0xD3DA2551, 0xD0594EA3, 0x24AA1EB0, 0x27297542,
+		0xCC4DBF96, 0xCFCED464, 0x3B3D8477, 0x38BEEF85,
+		0x1C82FCDB, 0x1F019729, 0xEBF2C73A, 0xE871ACC8,
+		0x0315661C, 0x00960DEE, 0xF4655DFD, 0xF7E6360F,
+		0x6293C661, 0x6110AD93, 0x95E3FD80, 0x96609672,
+		0x7D045CA6, 0x7E873754, 0x8A746747, 0x89F70CB5,
+		0xADCB1FEB, 0xAE487419, 0x5ABB240A, 0x59384FF8,
+		0xB25C852C, 0xB1DFEEDE, 0x452CBECD, 0x46AFD53F,
+		0x0D549871, 0x0ED7F383, 0xFA24A390, 0xF9A7C862,
+		0x12C302B6, 0x11406944, 0xE5B33957, 0xE63052A5,
+		0xC20C41FB, 0xC18F2A09, 0x357C7A1A, 0x36FF11E8,
+		0xDD9BDB3C, 0xDE18B0CE, 0x2AEBE0DD, 0x29688B2F,
+		0x783BF682, 0x7BB89D70, 0x8F4BCD63, 0x8CC8A691,
+		0x67AC6C45, 0x642F07B7, 0x90DC57A4, 0x935F3C56,
+		0xB7632F08, 0xB4E044FA, 0x401314E9, 0x43907F1B,
+		0xA8F4B5CF, 0xAB77DE3D, 0x5F848E2E, 0x5C07E5DC,
+		0x17FCA892, 0x147FC360, 0xE08C9373, 0xE30FF881,
+		0x086B3255, 0x0BE859A7, 0xFF1B09B4, 0xFC986246,
+		0xD8A47118, 0xDB271AEA, 0x2FD44AF9, 0x2C57210B,
+		0xC733EBDF, 0xC4B0802D, 0x3043D03E, 0x33C0BBCC,
+		0xA6B54BA2, 0xA5362050, 0x51C57043, 0x52461BB1,
+		0xB922D165, 0xBAA1BA97, 0x4E52EA84, 0x4DD18176,
+		0x69ED9228, 0x6A6EF9DA, 0x9E9DA9C9, 0x9D1EC23B,
+		0x767A08EF, 0x75F9631D, 0x810A330E, 0x828958FC,
+		0xC97215B2, 0xCAF17E40, 0x3E022E53, 0x3D8145A1,
+		0xD6E58F75, 0xD566E487, 0x2195B494, 0x2216DF66,
+		0x062ACC38, 0x05A9A7CA, 0xF15AF7D9, 0xF2D99C2B,
+		0x19BD56FF, 0x1A3E3D0D, 0xEECD6D1E, 0xED4E06EC,
+		0xC4268DC3, 0xC7A5E631, 0x3356B622, 0x30D5DDD0,
+		0xDBB11704, 0xD8327CF6, 0x2CC12CE5, 0x2F424717,
+		0x0B7E5449, 0x08FD3FBB, 0xFC0E6FA8, 0xFF8D045A,
+		0x14E9CE8E, 0x176AA57C, 0xE399F56F, 0xE01A9E9D,
+		0xABE1D3D3, 0xA862B821, 0x5C91E832, 0x5F1283C0,
+		0xB4764914, 0xB7F522E6, 0x430672F5, 0x40851907,
+		0x64B90A59, 0x673A61AB, 0x93C931B8, 0x904A5A4A,
+		0x7B2E909E, 0x78ADFB6C, 0x8C5EAB7F, 0x8FDDC08D,
+		0x1AA830E3, 0x192B5B11, 0xEDD80B02, 0xEE5B60F0,
+		0x053FAA24, 0x06BCC1D6, 0xF24F91C5, 0xF1CCFA37,
+		0xD5F0E969, 0xD673829B, 0x2280D288, 0x2103B97A,
+		0xCA6773AE, 0xC9E4185C, 0x3D17484F, 0x3E9423BD,
+		0x756F6EF3, 0x76EC0501, 0x821F5512, 0x819C3EE0,
+		0x6AF8F434, 0x697B9FC6, 0x9D88CFD5, 0x9E0BA427,
+		0xBA37B779, 0xB9B4DC8B, 0x4D478C98, 0x4EC4E76A,
+		0xA5A02DBE, 0xA623464C, 0x52D0165F, 0x51537DAD,
+	},
+	{
+		0x00000000, 0x7798A213, 0xEE304527, 0x99A8E734,
+		0xDC618A4E, 0xABF9285D, 0x3251CF69, 0x45C96D7A,
+		0xB8C3149D, 0xCF5BB68E, 0x56F351BA, 0x216BF3A9,
+		0x64A29ED3, 0x133A3CC0, 0x8A92DBF4, 0xFD0A79E7,
+		0x81F1C53F, 0xF669672C, 0x6FC18018, 0x1859220B,
+		0x5D904F71, 0x2A08ED62, 0xB3A00A56, 0xC438A845,
+		0x3932D1A2, 0x4EAA73B1, 0xD7029485, 0xA09A3696,
+		0xE5535BEC, 0x92CBF9FF, 0x0B631ECB, 0x7CFBBCD8,
+		0x02E38B7F, 0x757B296C, 0xECD3CE58, 0x9B4B6C4B,
+		0xDE820131, 0xA91AA322, 0x30B24416, 0x472AE605,
+		0xBA209FE2, 0xCDB83DF1, 0x5410DAC5, 0x238878D6,
+		0x664115AC, 0x11D9B7BF, 0x8871508B, 0xFFE9F298,
+		0x83124E40, 0xF48AEC53, 0x6D220B67, 0x1ABAA974,
+		0x5F73C40E, 0x28EB661D, 0xB1438129, 0xC6DB233A,
+		0x3BD15ADD, 0x4C49F8CE, 0xD5E11FFA, 0xA279BDE9,
+		0xE7B0D093, 0x90287280, 0x098095B4, 0x7E1837A7,
+		0x04C617FF, 0x735EB5EC, 0xEAF652D8, 0x9D6EF0CB,
+		0xD8A79DB1, 0xAF3F3FA2, 0x3697D896, 0x410F7A85,
+		0xBC050362, 0xCB9DA171, 0x52354645, 0x25ADE456,
+		0x6064892C, 0x17FC2B3F, 0x8E54CC0B, 0xF9CC6E18,
+		0x8537D2C0, 0xF2AF70D3, 0x6B0797E7, 0x1C9F35F4,
+		0x5956588E, 0x2ECEFA9D, 0xB7661DA9, 0xC0FEBFBA,
+		0x3DF4C65D, 0x4A6C644E, 0xD3C4837A, 0xA45C2169,
+		0xE1954C13, 0x960DEE00, 0x0FA50934, 0x783DAB27,
+		0x06259C80, 0x71BD3E93, 0xE815D9A7, 0x9F8D7BB4,
+		0xDA4416CE, 0xADDCB4DD, 0x347453E9, 0x43ECF1FA,
+		0xBEE6881D, 0xC97E2A0E, 0x50D6CD3A, 0x274E6F29,
+		0x62870253, 0x151FA040, 0x8CB74774, 0xFB2FE567,
+		0x87D459BF, 0xF04CFBAC, 0x69E41C98, 0x1E7CBE8B,
+		0x5BB5D3F1, 0x2C2D71E2, 0xB58596D6, 0xC21D34C5,
+		0x3F174D22, 0x488FEF31, 0xD1270805, 0xA6BFAA16,
+		0xE376C76C, 0x94EE657F, 0x0D46824B, 0x7ADE2058,
+		0xF9FAC3FB, 0x8E6261E8, 0x17CA86DC, 0x605224CF,
+		0x259B49B5, 0x5203EBA6, 0xCBAB0C92, 0xBC33AE81,
+		0x4139D766, 0x36A17575, 0xAF099241, 0xD8913052,
+		0x9D585D28, 0xEAC0FF3B, 0x7368180F, 0x04F0BA1C,
+		0x780B06C4, 0x0F93A4D7, 0x963B43E3, 0xE1A3E1F0,
+		0xA46A8C8A, 0xD3F22E99, 0x4A5AC9AD, 0x3DC26BBE,
+		0xC0C81259, 0xB750B04A, 0x2EF8577E, 0x5960F56D,
+		0x1CA99817, 0x6B313A04, 0xF299DD30, 0x85017F23,
+		0xFB194884, 0x8C81EA97, 0x15290DA3, 0x62B1AFB0,
+		0x2778C2CA, 0x50E060D9, 0xC94887ED, 0xBED025FE,
+		0x43DA5C19, 0x3442FE0A, 0xADEA193E, 0xDA72BB2D,
+		0x9FBBD657, 0xE8237444, 0x718B9370, 0x06133163,
+		0x7AE88DBB, 0x0D702FA8, 0x94D8C89C, 0xE3406A8F,
+		0xA68907F5, 0xD111A5E6, 0x48B942D2, 0x3F21E0C1,
+		0xC22B9926, 0xB5B33B35, 0x2C1BDC01, 0x5B837E12,
+		0x1E4A1368, 0x69D2B17B, 0xF07A564F, 0x87E2F45C,
+		0xFD3CD404, 0x8AA47617, 0x130C9123, 0x64943330,
+		0x215D5E4A, 0x56C5FC59, 0xCF6D1B6D, 0xB8F5B97E,
+		0x45FFC099, 0x3267628A, 0xABCF85BE, 0xDC5727AD,
+		0x999E4AD7, 0xEE06E8C4, 0x77AE0FF0, 0x0036ADE3,
+		0x7CCD113B, 0x0B55B328, 0x92FD541C, 0xE565F60F,
+		0xA0AC9B75, 0xD7343966, 0x4E9CDE52, 0x39047C41,
+		0xC40E05A6, 0xB396A7B5, 0x2A3E4081, 0x5DA6E292,
+		0x186F8FE8, 0x6FF72DFB, 0xF65FCACF, 0x81C768DC,
+		0xFFDF5F7B, 0x8847FD68, 0x11EF1A5C, 0x6677B84F,
+		0x23BED535, 0x54267726, 0xCD8E9012, 0xBA163201,
+		0x471C4BE6, 0x3084E9F5, 0xA92C0EC1, 0xDEB4ACD2,
+		0x9B7DC1A8, 0xECE563BB, 0x754D848F, 0x02D5269C,
+		0x7E2E9A44, 0x09B63857, 0x901EDF63, 0xE7867D70,
+		0xA24F100A, 0xD5D7B219, 0x4C7F552D, 0x3BE7F73E,
+		0xC6ED8ED9, 0xB1752CCA, 0x28DDCBFE, 0x5F4569ED,
+		0x1A8C0497, 0x6D14A684, 0xF4BC41B0, 0x8324E3A3,
+	},
+	{
+		0x00000000, 0x7E9241A5, 0x0D526F4F, 0x73C02EEA,
+		0x1AA4DE9E, 0x64369F3B, 0x17F6B1D1, 0x6964F074,
+		0xC53E5138, 0xBBAC109D, 0xC86C3E77, 0xB6FE7FD2,
+		0xDF9A8FA6, 0xA108CE03, 0xD2C8E0E9, 0xAC5AA14C,
+		0x8A7DA270, 0xF4EFE3D5, 0x872FCD3F, 0xF9BD8C9A,
+		0x90D97CEE, 0xEE4B3D4B, 0x9D8B13A1, 0xE3195204,
+		0x4F43F348, 0x31D1B2ED, 0x42119C07, 0x3C83DDA2,
+		0x55E72DD6, 0x2B756C73, 0x58B54299, 0x2627033C,
+		0x14FB44E1, 0x6A690544, 0x19A92BAE, 0x673B6A0B,
+		0x0E5F9A7F, 0x70CDDBDA, 0x030DF530, 0x7D9FB495,
+		0xD1C515D9, 0xAF57547C, 0xDC977A96, 0xA2053B33,
+		0xCB61CB47, 0xB5F38AE2, 0xC633A408, 0xB8A1E5AD,
+		0x9E86E691, 0xE014A734, 0x93D489DE, 0xED46C87B,
+		0x8422380F, 0xFAB079AA, 0x89705740, 0xF7E216E5,
+		0x5BB8B7A9, 0x252AF60C, 0x56EAD8E6, 0x28789943,
+		0x411C6937, 0x3F8E2892, 0x4C4E0678, 0x32DC47DD,
+		0xD98065C7, 0xA7122462, 0xD4D20A88, 0xAA404B2D,
+		0xC324BB59, 0xBDB6FAFC, 0xCE76D416, 0xB0E495B3,
+		0x1CBE34FF, 0x622C755A, 0x11EC5BB0, 0x6F7E1A15,
+		0x061AEA61, 0x7888ABC4, 0x0B48852E, 0x75DAC48B,
+		0x53FDC7B7, 0x2D6F8612, 0x5EAFA8F8, 0x203DE95D,
+		0x49591929, 0x37CB588C, 0x440B7666, 0x3A9937C3,
+		0x96C3968F, 0xE851D72A, 0x9B91F9C0, 0xE503B865,
+		0x8C674811, 0xF2F509B4, 0x8135275E, 0xFFA766FB,
+		0xCD7B2126, 0xB3E96083, 0xC0294E69, 0xBEBB0FCC,
+		0xD7DFFFB8, 0xA94DBE1D, 0xDA8D90F7, 0xA41FD152,
+		0x0845701E, 0x76D731BB, 0x05171F51, 0x7B855EF4,
+		0x12E1AE80, 0x6C73EF25, 0x1FB3C1CF, 0x6121806A,
+		0x47068356, 0x3994C2F3, 0x4A54EC19, 0x34C6ADBC,
+		0x5DA25DC8, 0x23301C6D, 0x50F03287, 0x2E627322,
+		0x8238D26E, 0xFCAA93CB, 0x8F6ABD21, 0xF1F8FC84,
+		0x989C0CF0, 0xE60E4D55, 0x95CE63BF, 0xEB5C221A,
+		0x4377278B, 0x3DE5662E, 0x4E2548C4, 0x30B70961,
+		0x59D3F915, 0x2741B8B0, 0x5481965A, 0x2A13D7FF,
+		0x864976B3, 0xF8DB3716, 0x8B1B19FC, 0xF5895859,
+		0x9CEDA82D, 0xE27FE988, 0x91BFC762, 0xEF2D86C7,
+		0xC90A85FB, 0xB798C45E, 0xC458EAB4, 0xBACAAB11,
+		0xD3AE5B65, 0xAD3C1AC0, 0xDEFC342A, 0xA06E758F,
+		0x0C34D4C3, 0x72A69566, 0x0166BB8C, 0x7FF4FA29,
+		0x16900A5D, 0x68024BF8, 0x1BC26512, 0x655024B7,
+		0x578C636A, 0x291E22CF, 0x5ADE0C25, 0x244C4D80,
+		0x4D28BDF4, 0x33BAFC51, 0x407AD2BB, 0x3EE8931E,
+		0x92B23252, 0xEC2073F7, 0x9FE05D1D, 0xE1721CB8,
+		0x8816ECCC, 0xF684AD69, 0x85448383, 0xFBD6C226,
+		0xDDF1C11A, 0xA36380BF, 0xD0A3AE55, 0xAE31EFF0,
+		0xC7551F84, 0xB9C75E21, 0xCA0770CB, 0xB495316E,
+		0x18CF9022, 0x665DD187, 0x159DFF6D, 0x6B0FBEC8,
+		0x026B4EBC, 0x7CF90F19, 0x0F3921F3, 0x71AB6056,
+		0x9AF7424C, 0xE46503E9, 0x97A52D03, 0xE9376CA6,
+		0x80539CD2, 0xFEC1DD77, 0x8D01F39D, 0xF393B238,
+		0x5FC91374, 0x215B52D1, 0x529B7C3B, 0x2C093D9E,
+		0x456DCDEA, 0x3BFF8C4F, 0x483FA2A5, 0x36ADE300,
+		0x108AE03C, 0x6E18A199, 0x1DD88F73, 0x634ACED6,
+		0x0A2E3EA2, 0x74BC7F07, 0x077C51ED, 0x79EE1048,
+		0xD5B4B104, 0xAB26F0A1, 0xD8E6DE4B, 0xA6749FEE,
+		0xCF106F9A, 0xB1822E3F, 0xC24200D5, 0xBCD04170,
+		0x8E0C06AD, 0xF09E4708, 0x835E69E2, 0xFDCC2847,
+		0x94A8D833, 0xEA3A9996, 0x99FAB77C, 0xE768F6D9,
+		0x4B325795, 0x35A01630, 0x466038DA, 0x38F2797F,
+		0x5196890B, 0x2F04C8AE, 0x5CC4E644, 0x2256A7E1,
+		0x0471A4DD, 0x7AE3E578, 0x0923CB92, 0x77B18A37,
+		0x1ED57A43, 0x60473BE6, 0x1387150C, 0x6D1554A9,
+		0xC14FF5E5, 0xBFDDB440, 0xCC1D9AAA, 0xB28FDB0F,
+		0xDBEB2B7B, 0xA5796ADE, 0xD6B94434, 0xA82B0591,
+	},
+	{
+		0x00000000, 0xB8AA45DD, 0x812367BF, 0x39892262,
+		0xF331227B, 0x4B9B67A6, 0x721245C4, 0xCAB80019,
+		0xE66344F6, 0x5EC9012B, 0x67402349, 0xDFEA6694,
+		0x1552668D, 0xADF82350, 0x94710132, 0x2CDB44EF,
+		0x3DB164E9, 0x851B2134, 0xBC920356, 0x0438468B,
+		0xCE804692, 0x762A034F, 0x4FA3212D, 0xF70964F0,
+		0xDBD2201F, 0x637865C2, 0x5AF147A0, 0xE25B027D,
+		0x28E30264, 0x904947B9, 0xA9C065DB, 0x116A2006,
+		0x8B1425D7, 0x33BE600A, 0x0A374268, 0xB29D07B5,
+		0x782507AC, 0xC08F4271, 0xF9066013, 0x41AC25CE,
+		0x6D776121, 0xD5DD24FC, 0xEC54069E, 0x54FE4343,
+		0x9E46435A, 0x26EC0687, 0x1F6524E5, 0xA7CF6138,
+		0xB6A5413E, 0x0E0F04E3, 0x37862681, 0x8F2C635C,
+		0x45946345, 0xFD3E2698, 0xC4B704FA, 0x7C1D4127,
+		0x50C605C8, 0xE86C4015, 0xD1E56277, 0x694F27AA,
+		0xA3F727B3, 0x1B5D626E, 0x22D4400C, 0x9A7E05D1,
+		0xE75FA6AB, 0x5FF5E376, 0x667CC114, 0xDED684C9,
+		0x146E84D0, 0xACC4C10D, 0x954DE36F, 0x2DE7A6B2,
+		0x013CE25D, 0xB996A780, 0x801F85E2, 0x38B5C03F,
+		0xF20DC026, 0x4AA785FB, 0x732EA799, 0xCB84E244,
+		0xDAEEC242, 0x6244879F, 0x5BCDA5FD, 0xE367E020,
+		0x29DFE039, 0x9175A5E4, 0xA8FC8786, 0x1056C25B,
+		0x3C8D86B4, 0x8427C369, 0xBDAEE10B, 0x0504A4D6,
+		0xCFBCA4CF, 0x7716E112, 0x4E9FC370, 0xF63586AD,
+		0x6C4B837C, 0xD4E1C6A1, 0xED68E4C3, 0x55C2A11E,
+		0x9F7AA107, 0x27D0E4DA, 0x1E59C6B8, 0xA6F38365,
+		0x8A28C78A, 0x32828257, 0x0B0BA035, 0xB3A1E5E8,
+		0x7919E5F1, 0xC1B3A02C, 0xF83A824E, 0x4090C793,
+		0x51FAE795, 0xE950A248, 0xD0D9802A, 0x6873C5F7,
+		0xA2CBC5EE, 0x1A618033, 0x23E8A251, 0x9B42E78C,
+		0xB799A363, 0x0F33E6BE, 0x36BAC4DC, 0x8E108101,
+		0x44A88118, 0xFC02C4C5, 0xC58BE6A7, 0x7D21A37A,
+		0x3FC9A052, 0x8763E58F, 0xBEEAC7ED, 0x06408230,
+		0xCCF88229, 0x7452C7F4, 0x4DDBE596, 0xF571A04B,
+		0xD9AAE4A4, 0x6100A179, 0x5889831B, 0xE023C6C6,
+		0x2A9BC6DF, 0x92318302, 0xABB8A160, 0x1312E4BD,
+		0x0278C4BB, 0xBAD28166, 0x835BA304, 0x3BF1E6D9,
+		0xF149E6C0, 0x49E3A31D, 0x706A817F, 0xC8C0C4A2,
+		0xE41B804D, 0x5CB1C590, 0x6538E7F2, 0xDD92A22F,
+		0x172AA236, 0xAF80E7EB, 0x9609C589, 0x2EA38054,
+		0xB4DD8585, 0x0C77C058, 0x35FEE23A, 0x8D54A7E7,
+		0x47ECA7FE, 0xFF46E223, 0xC6CFC041, 0x7E65859C,
+		0x52BEC173, 0xEA1484AE, 0xD39DA6CC, 0x6B37E311,
+		0xA18FE308, 0x1925A6D5, 0x20AC84B7, 0x9806C16A,
+		0x896CE16C, 0x31C6A4B1, 0x084F86D3, 0xB0E5C30E,
+		0x7A5DC317, 0xC2F786CA, 0xFB7EA4A8, 0x43D4E175,
+		0x6F0FA59A, 0xD7A5E047, 0xEE2CC225, 0x568687F8,
+		0x9C3E87E1, 0x2494C23C, 0x1D1DE05E, 0xA5B7A583,
+		0xD89606F9, 0x603C4324, 0x59B56146, 0xE11F249B,
+		0x2BA72482, 0x930D615F, 0xAA84433D, 0x122E06E0,
+		0x3EF5420F, 0x865F07D2, 0xBFD625B0, 0x077C606D,
+		0xCDC46074, 0x756E25A9, 0x4CE707CB, 0xF44D4216,
+		0xE5276210, 0x5D8D27CD, 0x640405AF, 0xDCAE4072,
+		0x1616406B, 0xAEBC05B6, 0x973527D4, 0x2F9F6209,
+		0x034426E6, 0xBBEE633B, 0x82674159, 0x3ACD0484,
+		0xF075049D, 0x48DF4140, 0x71566322, 0xC9FC26FF,
+		0x5382232E, 0xEB2866F3, 0xD2A14491, 0x6A0B014C,
+		0xA0B30155, 0x18194488, 0x219066EA, 0x993A2337,
+		0xB5E167D8, 0x0D4B2205, 0x34C20067, 0x8C6845BA,
+		0x46D045A3, 0xFE7A007E, 0xC7F3221C, 0x7F5967C1,
+		0x6E3347C7, 0xD699021A, 0xEF102078, 0x57BA65A5,
+		0x9D0265BC, 0x25A82061, 0x1C210203, 0xA48B47DE,
+		0x88500331, 0x30FA46EC, 0x0973648E, 0xB1D92153,
+		0x7B61214A, 0xC3CB6497, 0xFA4246F5, 0x42E80328,
+	},
+	{
+		0x00000000, 0xAC6F1138, 0x58DF2270, 0xF4B03348,
+		0xB0BE45E0, 0x1CD154D8, 0xE8616790, 0x440E76A8,
+		0x910B67C5, 0x3D6476FD, 0xC9D445B5, 0x65BB548D,
+		0x21B52225, 0x8DDA331D, 0x796A0055, 0xD505116D,
+		0xD361228F, 0x7F0E33B7, 0x8BBE00FF, 0x27D111C7,
+		0x63DF676F, 0xCFB07657, 0x3B00451F, 0x976F5427,
+		0x426A454A, 0xEE055472, 0x1AB5673A, 0xB6DA7602,
+		0xF2D400AA, 0x5EBB1192, 0xAA0B22DA, 0x066433E2,
+		0x57B5A81B, 0xFBDAB923, 0x0F6A8A6B, 0xA3059B53,
+		0xE70BEDFB, 0x4B64FCC3, 0xBFD4CF8B, 0x13BBDEB3,
+		0xC6BECFDE, 0x6AD1DEE6, 0x9E61EDAE, 0x320EFC96,
+		0x76008A3E, 0xDA6F9B06, 0x2EDFA84E, 0x82B0B976,
+		0x84D48A94, 0x28BB9BAC, 0xDC0BA8E4, 0x7064B9DC,
+		0x346ACF74, 0x9805DE4C, 0x6CB5ED04, 0xC0DAFC3C,
+		0x15DFED51, 0xB9B0FC69, 0x4D00CF21, 0xE16FDE19,
+		0xA561A8B1, 0x090EB989, 0xFDBE8AC1, 0x51D19BF9,
+		0xAE6A5137, 0x0205400F, 0xF6B57347, 0x5ADA627F,
+		0x1ED414D7, 0xB2BB05EF, 0x460B36A7, 0xEA64279F,
+		0x3F6136F2, 0x930E27CA, 0x67BE1482, 0xCBD105BA,
+		0x8FDF7312, 0x23B0622A, 0xD7005162, 0x7B6F405A,
+		0x7D0B73B8, 0xD1646280, 0x25D451C8, 0x89BB40F0,
+		0xCDB53658, 0x61DA2760, 0x956A1428, 0x39050510,
+		0xEC00147D, 0x406F0545, 0xB4DF360D, 0x18B02735,
+		0x5CBE519D, 0xF0D140A5, 0x046173ED, 0xA80E62D5,
+		0xF9DFF92C, 0x55B0E814, 0xA100DB5C, 0x0D6FCA64,
+		0x4961BCCC, 0xE50EADF4, 0x11BE9EBC, 0xBDD18F84,
+		0x68D49EE9, 0xC4BB8FD1, 0x300BBC99, 0x9C64ADA1,
+		0xD86ADB09, 0x7405CA31, 0x80B5F979, 0x2CDAE841,
+		0x2ABEDBA3, 0x86D1CA9B, 0x7261F9D3, 0xDE0EE8EB,
+		0x9A009E43, 0x366F8F7B, 0xC2DFBC33, 0x6EB0AD0B,
+		0xBBB5BC66, 0x17DAAD5E, 0xE36A9E16, 0x4F058F2E,
+		0x0B0BF986, 0xA764E8BE, 0x53D4DBF6, 0xFFBBCACE,
+		0x5CD5A26E, 0xF0BAB356, 0x040A801E, 0xA8659126,
+		0xEC6BE78E, 0x4004F6B6, 0xB4B4C5FE, 0x18DBD4C6,
+		0xCDDEC5AB, 0x61B1D493, 0x9501E7DB, 0x396EF6E3,
+		0x7D60804B, 0xD10F9173, 0x25BFA23B, 0x89D0B303,
+		0x8FB480E1, 0x23DB91D9, 0xD76BA291, 0x7B04B3A9,
+		0x3F0AC501, 0x9365D439, 0x67D5E771, 0xCBBAF649,
+		0x1EBFE724, 0xB2D0F61C, 0x4660C554, 0xEA0FD46C,
+		0xAE01A2C4, 0x026EB3FC, 0xF6DE80B4, 0x5AB1918C,
+		0x0B600A75, 0xA70F1B4D, 0x53BF2805, 0xFFD0393D,
+		0xBBDE4F95, 0x17B15EAD, 0xE3016DE5, 0x4F6E7CDD,
+		0x9A6B6DB0, 0x36047C88, 0xC2B44FC0, 0x6EDB5EF8,
+		0x2AD52850, 0x86BA3968, 0x720A0A20, 0xDE651B18,
+		0xD80128FA, 0x746E39C2, 0x80DE0A8A, 0x2CB11BB2,
+		0x68BF6D1A, 0xC4D07C22, 0x30604F6A, 0x9C0F5E52,
+		0x490A4F3F, 0xE5655E07, 0x11D56D4F, 0xBDBA7C77,
+		0xF9B40ADF, 0x55DB1BE7, 0xA16B28AF, 0x0D043997,
+		0xF2BFF359, 0x5ED0E261, 0xAA60D129, 0x060FC011,
+		0x4201B6B9, 0xEE6EA781, 0x1ADE94C9, 0xB6B185F1,
+		0x63B4949C, 0xCFDB85A4, 0x3B6BB6EC, 0x9704A7D4,
+		0xD30AD17C, 0x7F65C044, 0x8BD5F30C, 0x27BAE234,
+		0x21DED1D6, 0x8DB1C0EE, 0x7901F3A6, 0xD56EE29E,
+		0x91609436, 0x3D0F850E, 0xC9BFB646, 0x65D0A77E,
+		0xB0D5B613, 0x1CBAA72B, 0xE80A9463, 0x4465855B,
+		0x006BF3F3, 0xAC04E2CB, 0x58B4D183, 0xF4DBC0BB,
+		0xA50A5B42, 0x09654A7A, 0xFDD57932, 0x51BA680A,
+		0x15B41EA2, 0xB9DB0F9A, 0x4D6B3CD2, 0xE1042DEA,
+		0x34013C87, 0x986E2DBF, 0x6CDE1EF7, 0xC0B10FCF,
+		0x84BF7967, 0x28D0685F, 0xDC605B17, 0x700F4A2F,
+		0x766B79CD, 0xDA0468F5, 0x2EB45BBD, 0x82DB4A85,
+		0xC6D53C2D, 0x6ABA2D15, 0x9E0A1E5D, 0x32650F65,
+		0xE7601E08, 0x4B0F0F30, 0xBFBF3C78, 0x13D02D40,
+		0x57DE5BE8, 0xFBB14AD0, 0x0F017998, 0xA36E68A0,
+	},
+	{
+		0x00000000, 0x196B30EF, 0xC3A08CDB, 0xDACBBC34,
+		0x7737F5B2, 0x6E5CC55D, 0xB4977969, 0xADFC4986,
+		0x1F180660, 0x0673368F, 0xDCB88ABB, 0xC5D3BA54,
+		0x682FF3D2, 0x7144C33D, 0xAB8F7F09, 0xB2E44FE6,
+		0x3E300CC0, 0x275B3C2F, 0xFD90801B, 0xE4FBB0F4,
+		0x4907F972, 0x506CC99D, 0x8AA775A9, 0x93CC4546,
+		0x21280AA0, 0x38433A4F, 0xE288867B, 0xFBE3B694,
+		0x561FFF12, 0x4F74CFFD, 0x95BF73C9, 0x8CD44326,
+		0x8D16F485, 0x947DC46A, 0x4EB6785E, 0x57DD48B1,
+		0xFA210137, 0xE34A31D8, 0x39818DEC, 0x20EABD03,
+		0x920EF2E5, 0x8B65C20A, 0x51AE7E3E, 0x48C54ED1,
+		0xE5390757, 0xFC5237B8, 0x26998B8C, 0x3FF2BB63,
+		0xB326F845, 0xAA4DC8AA, 0x7086749E, 0x69ED4471,
+		0xC4110DF7, 0xDD7A3D18, 0x07B1812C, 0x1EDAB1C3,
+		0xAC3EFE25, 0xB555CECA, 0x6F9E72FE, 0x76F54211,
+		0xDB090B97, 0xC2623B78, 0x18A9874C, 0x01C2B7A3,
+		0xEB5B040E, 0xF23034E1, 0x28FB88D5, 0x3190B83A,
+		0x9C6CF1BC, 0x8507C153, 0x5FCC7D67, 0x46A74D88,
+		0xF443026E, 0xED283281, 0x37E38EB5, 0x2E88BE5A,
+		0x8374F7DC, 0x9A1FC733, 0x40D47B07, 0x59BF4BE8,
+		0xD56B08CE, 0xCC003821, 0x16CB8415, 0x0FA0B4FA,
+		0xA25CFD7C, 0xBB37CD93, 0x61FC71A7, 0x78974148,
+		0xCA730EAE, 0xD3183E41, 0x09D38275, 0x10B8B29A,
+		0xBD44FB1C, 0xA42FCBF3, 0x7EE477C7, 0x678F4728,
+		0x664DF08B, 0x7F26C064, 0xA5ED7C50, 0xBC864CBF,
+		0x117A0539, 0x081135D6, 0xD2DA89E2, 0xCBB1B90D,
+		0x7955F6EB, 0x603EC604, 0xBAF57A30, 0xA39E4ADF,
+		0x0E620359, 0x170933B6, 0xCDC28F82, 0xD4A9BF6D,
+		0x587DFC4B, 0x4116CCA4, 0x9BDD7090, 0x82B6407F,
+		0x2F4A09F9, 0x36213916, 0xECEA8522, 0xF581B5CD,
+		0x4765FA2B, 0x5E0ECAC4, 0x84C576F0, 0x9DAE461F,
+		0x30520F99, 0x29393F76, 0xF3F28342, 0xEA99B3AD,
+		0xD6B7081C, 0xCFDC38F3, 0x151784C7, 0x0C7CB428,
+		0xA180FDAE, 0xB8EBCD41, 0x62207175, 0x7B4B419A,
+		0xC9AF0E7C, 0xD0C43E93, 0x0A0F82A7, 0x1364B248,
+		0xBE98FBCE, 0xA7F3CB21, 0x7D387715, 0x645347FA,
+		0xE88704DC, 0xF1EC3433, 0x2B278807, 0x324CB8E8,
+		0x9FB0F16E, 0x86DBC181, 0x5C107DB5, 0x457B4D5A,
+		0xF79F02BC, 0xEEF43253, 0x343F8E67, 0x2D54BE88,
+		0x80A8F70E, 0x99C3C7E1, 0x43087BD5, 0x5A634B3A,
+		0x5BA1FC99, 0x42CACC76, 0x98017042, 0x816A40AD,
+		0x2C96092B, 0x35FD39C4, 0xEF3685F0, 0xF65DB51F,
+		0x44B9FAF9, 0x5DD2CA16, 0x87197622, 0x9E7246CD,
+		0x338E0F4B, 0x2AE53FA4, 0xF02E8390, 0xE945B37F,
+		0x6591F059, 0x7CFAC0B6, 0xA6317C82, 0xBF5A4C6D,
+		0x12A605EB, 0x0BCD3504, 0xD1068930, 0xC86DB9DF,
+		0x7A89F639, 0x63E2C6D6, 0xB9297AE2, 0xA0424A0D,
+		0x0DBE038B, 0x14D53364, 0xCE1E8F50, 0xD775BFBF,
+		0x3DEC0C12, 0x24873CFD, 0xFE4C80C9, 0xE727B026,
+		0x4ADBF9A0, 0x53B0C94F, 0x897B757B, 0x90104594,
+		0x22F40A72, 0x3B9F3A9D, 0xE15486A9, 0xF83FB646,
+		0x55C3FFC0, 0x4CA8CF2F, 0x9663731B, 0x8F0843F4,
+		0x03DC00D2, 0x1AB7303D, 0xC07C8C09, 0xD917BCE6,
+		0x74EBF560, 0x6D80C58F, 0xB74B79BB, 0xAE204954,
+		0x1CC406B2, 0x05AF365D, 0xDF648A69, 0xC60FBA86,
+		0x6BF3F300, 0x7298C3EF, 0xA8537FDB, 0xB1384F34,
+		0xB0FAF897, 0xA991C878, 0x735A744C, 0x6A3144A3,
+		0xC7CD0D25, 0xDEA63DCA, 0x046D81FE, 0x1D06B111,
+		0xAFE2FEF7, 0xB689CE18, 0x6C42722C, 0x752942C3,
+		0xD8D50B45, 0xC1BE3BAA, 0x1B75879E, 0x021EB771,
+		0x8ECAF457, 0x97A1C4B8, 0x4D6A788C, 0x54014863,
+		0xF9FD01E5, 0xE096310A, 0x3A5D8D3E, 0x2336BDD1,
+		0x91D2F237, 0x88B9C2D8, 0x52727EEC, 0x4B194E03,
+		0xE6E50785, 0xFF8E376A, 0x25458B5E, 0x3C2EBBB1,
+	},
+	{
+		0x00000000, 0xC82C0368, 0x905906D0, 0x587505B8,
+		0xD1C5E0A5, 0x19E9E3CD, 0x419CE675, 0x89B0E51D,
+		0x53FD2D4E, 0x9BD12E26, 0xC3A42B9E, 0x0B8828F6,
+		0x8238CDEB, 0x4A14CE83, 0x1261CB3B, 0xDA4DC853,
+		0xA6FA5B9C, 0x6ED658F4, 0x36A35D4C, 0xFE8F5E24,
+		0x773FBB39, 0xBF13B851, 0xE766BDE9, 0x2F4ABE81,
+		0xF50776D2, 0x3D2B75BA, 0x655E7002, 0xAD72736A,
+		0x24C29677, 0xECEE951F, 0xB49B90A7, 0x7CB793CF,
+		0xBD835B3D, 0x75AF5855, 0x2DDA5DED, 0xE5F65E85,
+		0x6C46BB98, 0xA46AB8F0, 0xFC1FBD48, 0x3433BE20,
+		0xEE7E7673, 0x2652751B, 0x7E2770A3, 0xB60B73CB,
+		0x3FBB96D6, 0xF79795BE, 0xAFE29006, 0x67CE936E,
+		0x1B7900A1, 0xD35503C9, 0x8B200671, 0x430C0519,
+		0xCABCE004, 0x0290E36C, 0x5AE5E6D4, 0x92C9E5BC,
+		0x48842DEF, 0x80A82E87, 0xD8DD2B3F, 0x10F12857,
+		0x9941CD4A, 0x516DCE22, 0x0918CB9A, 0xC134C8F2,
+		0x7A07B77A, 0xB22BB412, 0xEA5EB1AA, 0x2272B2C2,
+		0xABC257DF, 0x63EE54B7, 0x3B9B510F, 0xF3B75267,
+		0x29FA9A34, 0xE1D6995C, 0xB9A39CE4, 0x718F9F8C,
+		0xF83F7A91, 0x301379F9, 0x68667C41, 0xA04A7F29,
+		0xDCFDECE6, 0x14D1EF8E, 0x4CA4EA36, 0x8488E95E,
+		0x0D380C43, 0xC5140F2B, 0x9D610A93, 0x554D09FB,
+		0x8F00C1A8, 0x472CC2C0, 0x1F59C778, 0xD775C410,
+		0x5EC5210D, 0x96E92265, 0xCE9C27DD, 0x06B024B5,
+		0xC784EC47, 0x0FA8EF2F, 0x57DDEA97, 0x9FF1E9FF,
+		0x16410CE2, 0xDE6D0F8A, 0x86180A32, 0x4E34095A,
+		0x9479C109, 0x5C55C261, 0x0420C7D9, 0xCC0CC4B1,
+		0x45BC21AC, 0x8D9022C4, 0xD5E5277C, 0x1DC92414,
+		0x617EB7DB, 0xA952B4B3, 0xF127B10B, 0x390BB263,
+		0xB0BB577E, 0x78975416, 0x20E251AE, 0xE8CE52C6,
+		0x32839A95, 0xFAAF99FD, 0xA2DA9C45, 0x6AF69F2D,
+		0xE3467A30, 0x2B6A7958, 0x731F7CE0, 0xBB337F88,
+		0xF40E6EF5, 0x3C226D9D, 0x64576825, 0xAC7B6B4D,
+		0x25CB8E50, 0xEDE78D38, 0xB5928880, 0x7DBE8BE8,
+		0xA7F343BB, 0x6FDF40D3, 0x37AA456B, 0xFF864603,
+		0x7636A31E, 0xBE1AA076, 0xE66FA5CE, 0x2E43A6A6,
+		0x52F43569, 0x9AD83601, 0xC2AD33B9, 0x0A8130D1,
+		0x8331D5CC, 0x4B1DD6A4, 0x1368D31C, 0xDB44D074,
+		0x01091827, 0xC9251B4F, 0x91501EF7, 0x597C1D9F,
+		0xD0CCF882, 0x18E0FBEA, 0x4095FE52, 0x88B9FD3A,
+		0x498D35C8, 0x81A136A0, 0xD9D43318, 0x11F83070,
+		0x9848D56D, 0x5064D605, 0x0811D3BD, 0xC03DD0D5,
+		0x1A701886, 0xD25C1BEE, 0x8A291E56, 0x42051D3E,
+		0xCBB5F823, 0x0399FB4B, 0x5BECFEF3, 0x93C0FD9B,
+		0xEF776E54, 0x275B6D3C, 0x7F2E6884, 0xB7026BEC,
+		0x3EB28EF1, 0xF69E8D99, 0xAEEB8821, 0x66C78B49,
+		0xBC8A431A, 0x74A64072, 0x2CD345CA, 0xE4FF46A2,
+		0x6D4FA3BF, 0xA563A0D7, 0xFD16A56F, 0x353AA607,
+		0x8E09D98F, 0x4625DAE7, 0x1E50DF5F, 0xD67CDC37,
+		0x5FCC392A, 0x97E03A42, 0xCF953FFA, 0x07B93C92,
+		0xDDF4F4C1, 0x15D8F7A9, 0x4DADF211, 0x8581F179,
+		0x0C311464, 0xC41D170C, 0x9C6812B4, 0x544411DC,
+		0x28F38213, 0xE0DF817B, 0xB8AA84C3, 0x708687AB,
+		0xF93662B6, 0x311A61DE, 0x696F6466, 0xA143670E,
+		0x7B0EAF5D, 0xB322AC35, 0xEB57A98D, 0x237BAAE5,
+		0xAACB4FF8, 0x62E74C90, 0x3A924928, 0xF2BE4A40,
+		0x338A82B2, 0xFBA681DA, 0xA3D38462, 0x6BFF870A,
+		0xE24F6217, 0x2A63617F, 0x721664C7, 0xBA3A67AF,
+		0x6077AFFC, 0xA85BAC94, 0xF02EA92C, 0x3802AA44,
+		0xB1B24F59, 0x799E4C31, 0x21EB4989, 0xE9C74AE1,
+		0x9570D92E, 0x5D5CDA46, 0x0529DFFE, 0xCD05DC96,
+		0x44B5398B, 0x8C993AE3, 0xD4EC3F5B, 0x1CC03C33,
+		0xC68DF460, 0x0EA1F708, 0x56D4F2B0, 0x9EF8F1D8,
+		0x174814C5, 0xDF6417AD, 0x87111215, 0x4F3D117D,
+	},
+	{
+		0x00000000, 0x277D3C49, 0x4EFA7892, 0x698744DB,
+		0x6D821D21, 0x4AFF2168, 0x237865B3, 0x040559FA,
+		0xDA043B42, 0xFD79070B, 0x94FE43D0, 0xB3837F99,
+		0xB7862663, 0x90FB1A2A, 0xF97C5EF1, 0xDE0162B8,
+		0xB4097684, 0x93744ACD, 0xFAF30E16, 0xDD8E325F,
+		0xD98B6BA5, 0xFEF657EC, 0x97711337, 0xB00C2F7E,
+		0x6E0D4DC6, 0x4970718F, 0x20F73554, 0x078A091D,
+		0x038F50E7, 0x24F26CAE, 0x4D752875, 0x6A08143C,
+		0x9965000D, 0xBE183C44, 0xD79F789F, 0xF0E244D6,
+		0xF4E71D2C, 0xD39A2165, 0xBA1D65BE, 0x9D6059F7,
+		0x43613B4F, 0x641C0706, 0x0D9B43DD, 0x2AE67F94,
+		0x2EE3266E, 0x099E1A27, 0x60195EFC, 0x476462B5,
+		0x2D6C7689, 0x0A114AC0, 0x63960E1B, 0x44EB3252,
+		0x40EE6BA8, 0x679357E1, 0x0E14133A, 0x29692F73,
+		0xF7684DCB, 0xD0157182, 0xB9923559, 0x9EEF0910,
+		0x9AEA50EA, 0xBD976CA3, 0xD4102878, 0xF36D1431,
+		0x32CB001A, 0x15B63C53, 0x7C317888, 0x5B4C44C1,
+		0x5F491D3B, 0x78342172, 0x11B365A9, 0x36CE59E0,
+		0xE8CF3B58, 0xCFB20711, 0xA63543CA, 0x81487F83,
+		0x854D2679, 0xA2301A30, 0xCBB75EEB, 0xECCA62A2,
+		0x86C2769E, 0xA1BF4AD7, 0xC8380E0C, 0xEF453245,
+		0xEB406BBF, 0xCC3D57F6, 0xA5BA132D, 0x82C72F64,
+		0x5CC64DDC, 0x7BBB7195, 0x123C354E, 0x35410907,
+		0x314450FD, 0x16396CB4, 0x7FBE286F, 0x58C31426,
+		0xABAE0017, 0x8CD33C5E, 0xE5547885, 0xC22944CC,
+		0xC62C1D36, 0xE151217F, 0x88D665A4, 0xAFAB59ED,
+		0x71AA3B55, 0x56D7071C, 0x3F5043C7, 0x182D7F8E,
+		0x1C282674, 0x3B551A3D, 0x52D25EE6, 0x75AF62AF,
+		0x1FA77693, 0x38DA4ADA, 0x515D0E01, 0x76203248,
+		0x72256BB2, 0x555857FB, 0x3CDF1320, 0x1BA22F69,
+		0xC5A34DD1, 0xE2DE7198, 0x8B593543, 0xAC24090A,
+		0xA82150F0, 0x8F5C6CB9, 0xE6DB2862, 0xC1A6142B,
+		0x64960134, 0x43EB3D7D, 0x2A6C79A6, 0x0D1145EF,
+		0x09141C15, 0x2E69205C, 0x47EE6487, 0x609358CE,
+		0xBE923A76, 0x99EF063F, 0xF06842E4, 0xD7157EAD,
+		0xD3102757, 0xF46D1B1E, 0x9DEA5FC5, 0xBA97638C,
+		0xD09F77B0, 0xF7E24BF9, 0x9E650F22, 0xB918336B,
+		0xBD1D6A91, 0x9A6056D8, 0xF3E71203, 0xD49A2E4A,
+		0x0A9B4CF2, 0x2DE670BB, 0x44613460, 0x631C0829,
+		0x671951D3, 0x40646D9A, 0x29E32941, 0x0E9E1508,
+		0xFDF30139, 0xDA8E3D70, 0xB30979AB, 0x947445E2,
+		0x90711C18, 0xB70C2051, 0xDE8B648A, 0xF9F658C3,
+		0x27F73A7B, 0x008A0632, 0x690D42E9, 0x4E707EA0,
+		0x4A75275A, 0x6D081B13, 0x048F5FC8, 0x23F26381,
+		0x49FA77BD, 0x6E874BF4, 0x07000F2F, 0x207D3366,
+		0x24786A9C, 0x030556D5, 0x6A82120E, 0x4DFF2E47,
+		0x93FE4CFF, 0xB48370B6, 0xDD04346D, 0xFA790824,
+		0xFE7C51DE, 0xD9016D97, 0xB086294C, 0x97FB1505,
+		0x565D012E, 0x71203D67, 0x18A779BC, 0x3FDA45F5,
+		0x3BDF1C0F, 0x1CA22046, 0x7525649D, 0x525858D4,
+		0x8C593A6C, 0xAB240625, 0xC2A342FE, 0xE5DE7EB7,
+		0xE1DB274D, 0xC6A61B04, 0xAF215FDF, 0x885C6396,
+		0xE25477AA, 0xC5294BE3, 0xACAE0F38, 0x8BD33371,
+		0x8FD66A8B, 0xA8AB56C2, 0xC12C1219, 0xE6512E50,
+		0x38504CE8, 0x1F2D70A1, 0x76AA347A, 0x51D70833,
+		0x55D251C9, 0x72AF6D80, 0x1B28295B, 0x3C551512,
+		0xCF380123, 0xE8453D6A, 0x81C279B1, 0xA6BF45F8,
+		0xA2BA1C02, 0x85C7204B, 0xEC406490, 0xCB3D58D9,
+		0x153C3A61, 0x32410628, 0x5BC642F3, 0x7CBB7EBA,
+		0x78BE2740, 0x5FC31B09, 0x36445FD2, 0x1139639B,
+		0x7B3177A7, 0x5C4C4BEE, 0x35CB0F35, 0x12B6337C,
+		0x16B36A86, 0x31CE56CF, 0x58491214, 0x7F342E5D,
+		0xA1354CE5, 0x864870AC, 0xEFCF3477, 0xC8B2083E,
+		0xCCB751C4, 0xEBCA6D8D, 0x824D2956, 0xA530151F
+	}
+#endif   /* WORDS_BIGENDIAN */
+};
diff --git a/src/port/pg_crc32c_sse42.c b/src/port/pg_crc32c_sse42.c
new file mode 100644
index 0000000..b253ee4
--- /dev/null
+++ b/src/port/pg_crc32c_sse42.c
@@ -0,0 +1,57 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_crc32c_sse42.c
+ *	  Compute CRC-32C checksum using Intel SSE 4.2 instructions.
+ *
+ * See Ross Williams' excellent introduction
+ * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from
+ * http://www.ross.net/crc/download/crc_v3.txt or several other net sites.
+ *
+ * Portions Copyright (c) 1996-2015, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *	  src/port/pg_crc32c_sse42.c
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "c.h"
+
+#include "port/pg_crc32c.h"
+
+#include <nmmintrin.h>
+
+pg_crc32
+pg_comp_crc32c_sse42(pg_crc32 crc, const void *data, size_t len)
+{
+	const unsigned char *p = data;
+	const uint64 *p8;
+
+	/*
+	 * Process eight bytes of data at a time.
+	 *
+	 * NB: We do unaligned 8-byte accesses here. Currently, the only CRC
+	 * instructions supported are the ones on Intel SSE 4.2, and that works
+	 * and performs well with unaligned access. This may need to be changed if
+	 * we get support for more architectures.
+	 */
+	p8 = (const uint64 *) p;
+	while (len >= 8)
+	{
+		crc = (uint32) _mm_crc32_u64(crc, *p8++);
+		len -= 8;
+	}
+
+	/*
+	 * Handle any remaining bytes one at a time.
+	 */
+	p = (const unsigned char *) p8;
+	while (len > 0)
+	{
+		crc = _mm_crc32_u8(crc, *p++);
+		len--;
+	}
+
+	return crc;
+}
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index 7f319df..21caecc 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -91,6 +91,15 @@ sub mkvcbuild
 
 	push(@pgportfiles, 'rint.c') if ($vsVersion < '12.00');
 
+	if ($vsVersion >= '9.00')
+	{
+		push(@pgportfiles, 'pg_crc32c_choose.c pg_crc32_sse42.c pg_crc32_sb8.c')
+	}
+	else
+	{
+		push(@pgportfiles, 'pg_crc32_sb8.c')
+	}
+
 	our @pgcommonallfiles = qw(
 	  exec.c pg_crc.c pg_lzcompress.c pgfnames.c psprintf.c relpath.c rmtree.c
 	  string.c username.c wait_error.c);
-- 
2.1.4

#71Robert Haas
robertmhaas@gmail.com
In reply to: Heikki Linnakangas (#70)
Re: What exactly is our CRC algorithm?

On Thu, Apr 2, 2015 at 5:33 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:

It was added in gcc 4.2. That's good enough for me.

I think it's fine to have optional optimizations that require gcc >=
4.2, as long as older platforms don't break outright.

We have a buildfarm animal that still uses gcc 2.95.3, which was
released in 2001. I don't have a compiler of that vintage to test
with, but I assume an old enough assembler would not know about the
crc32q instruction and fail to compile.

GCC from <2002 wouldn't support the symbolic operand names in inline
assembly. binutils from <2007 (IIRC) wouldn't support the assembler
instructions themselves.

We could work around the latter by using the appropriate sequence of
bytes. We could work around the former by using the old syntax for
operands.

I'm OK with not supporting the new instructions when building with an old
compiler/assembler. But the build shouldn't fail with an old
compiler/assembler. Using old syntax or raw bytes just to avoid failing on
an ancient compiler seems ugly.

I dunno about old syntax, but raw bytes seems like a bad idea, for sure.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#72Abhijit Menon-Sen
ams@2ndQuadrant.com
In reply to: Heikki Linnakangas (#70)
Re: What exactly is our CRC algorithm?

At 2015-04-03 00:33:10 +0300, hlinnaka@iki.fi wrote:

I came up with the attached.

I like it very much.

src/port/Makefile has (note src/srv):

    +# pg_crc32c_sse42.o and its _src.o version need CFLAGS_SSE42
    +pg_crc32c_sse42.o: CFLAGS+=$(CFLAGS_SSE42)
    +pg_crc32c_sse42_srv.o: CFLAGS+=$(CFLAGS_SSE42)

Other than that, this looks great. Thank you.

BTW, we might want to move the "traditional" and "legacy" crc32
implementations out of src/common. They are only used in backend
code now.

I agree.

-- Abhijit

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

#73Heikki Linnakangas
hlinnaka@iki.fi
In reply to: Abhijit Menon-Sen (#72)
Re: What exactly is our CRC algorithm?

On 04/03/2015 05:28 AM, Abhijit Menon-Sen wrote:

At 2015-04-03 00:33:10 +0300, hlinnaka@iki.fi wrote:

I came up with the attached.

I like it very much.

src/port/Makefile has (note src/srv):

+# pg_crc32c_sse42.o and its _src.o version need CFLAGS_SSE42
+pg_crc32c_sse42.o: CFLAGS+=$(CFLAGS_SSE42)
+pg_crc32c_sse42_srv.o: CFLAGS+=$(CFLAGS_SSE42)

Other than that, this looks great. Thank you.

BTW, we might want to move the "traditional" and "legacy" crc32
implementations out of src/common. They are only used in backend
code now.

I agree.

Committed this now, after some further cleanup and reorganizing the
autoconf stuff.

- Heikki

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers