--- /dev/null
+
+#include <stdlib.h>
+#include <stdio.h>
+
+typedef signed int Int;
+typedef unsigned int UInt;
+typedef unsigned char UChar;
+typedef unsigned short int UShort;
+typedef unsigned long long int ULong;
+
+
+static inline UChar randUChar ( void )
+{
+ static UInt seed = 80021;
+ seed = 1103515245 * seed + 12345;
+ return (seed >> 17) & 0xFF;
+}
+
+
+static inline ULong randULong ( void )
+{
+ Int i;
+ ULong r = 0;
+ for (i = 0; i < 8; i++) {
+ r = (r << 8) | (ULong)(0xFF & randUChar());
+ }
+ return r;
+}
+
+static inline UInt randUInt ( void )
+{
+ Int i;
+ UInt r = 0;
+ for (i = 0; i < 4; i++) {
+ r = (r << 8) | (UInt)(0xFF & randUChar());
+ }
+ return r;
+}
+
+/////////////////////////////////////////////////////////////////
+
+UInt do_s_crc32b ( UInt crcIn, UChar b )
+{
+ UInt i, crc = (b & 0xFF) ^ crcIn;
+ for (i = 0; i < 8; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
+ return crc;
+}
+
+UInt do_s_crc32w ( UInt crcIn, UShort w )
+{
+ UInt i, crc = (w & 0xFFFF) ^ crcIn;
+ for (i = 0; i < 16; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
+ return crc;
+}
+
+UInt do_s_crc32l ( UInt crcIn, UInt l )
+{
+ UInt i, crc = l ^ crcIn;
+ for (i = 0; i < 32; i++)
+ crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
+ return crc;
+}
+
+UInt do_h_crc32b ( UInt crcIn, UChar b )
+{
+ __asm__ __volatile__(
+ "crc32b %%cl,%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "c"(b)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32w ( UInt crcIn, UShort w )
+{
+ __asm__ __volatile__(
+ "crc32w %%cx,%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "c"(w)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32l ( UInt crcIn, UInt l )
+{
+ __asm__ __volatile__(
+ "crc32l %%ecx,%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "c"(l)
+ );
+ return crcIn;
+}
+
+////////////////
+
+UInt do_h_crc32b_mem ( UInt crcIn, UChar* a )
+{
+ __asm__ __volatile__(
+ "crc32b (%2),%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "r"(a)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32w_mem ( UInt crcIn, UShort* a )
+{
+ __asm__ __volatile__(
+ "crc32w (%2),%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "r"(a)
+ );
+ return crcIn;
+}
+
+UInt do_h_crc32l_mem ( UInt crcIn, UInt* a )
+{
+ __asm__ __volatile__(
+ "crc32l (%2),%%esi\n\t"
+ : "=S"(crcIn) : "0"(crcIn), "r"(a)
+ );
+ return crcIn;
+}
+
+void try_simple ( void )
+{
+ UInt c0 = 0xFFFFFFFF;
+ UChar c = 0x42;
+
+ UInt cs = do_s_crc32b(c0, c);
+ UInt ch = do_h_crc32b(c0, c);
+ printf("b %08x %08x\n", cs, ch);
+
+ UShort w = 0xed78;;
+ cs = do_s_crc32w(c0, w);
+ ch = do_h_crc32w(c0, w);
+ printf("w %08x %08x\n", cs, ch);
+
+ UInt i = 0xCAFEBABE;
+ cs = do_s_crc32l(c0, i);
+ ch = do_h_crc32l(c0, i);
+ printf("l %08x %08x\n", cs, ch);
+}
+
+#define NMEM 1000
+void try_mem ( void )
+{
+ UInt al, i;
+ UChar* b = malloc(NMEM);
+ for (i = 0; i < NMEM; i++)
+ b[i] = (UChar)(i % 177);
+
+ for (al = 0; al < 1; al++) {
+ UInt crc = 0xFFFFFFFF;
+ for (i = 0; i <= 1000-1-al; i += 1)
+ crc = do_h_crc32b_mem( crc, &b[i+al] );
+ printf("mem b misalign %d = %08x\n", al, crc);
+ }
+
+ for (al = 0; al < 2; al++) {
+ UInt crc = 0xFFFFFFFF;
+ for (i = 0; i <= 1000-2-al; i += 2)
+ crc = do_h_crc32w_mem( crc, (UShort*)&b[i+al] );
+ printf("mem w misalign %d = %08x\n", al, crc);
+ }
+
+ for (al = 0; al < 4; al++) {
+ UInt crc = 0xFFFFFFFF;
+ for (i = 0; i <= 1000-4-al; i += 4)
+ crc = do_h_crc32l_mem( crc, (UInt*)&b[i+al] );
+ printf("mem l misalign %d = %08x\n", al, crc);
+ }
+
+ free(b);
+}
+
+void try_misc ( void )
+{
+ UInt res = 0xAAAAAAAAU;
+ __asm__ __volatile__(
+ "movl $0x55555555, %%eax" "\n\t"
+ "movl $042, %%ebx" "\n\t"
+ "crc32b %%bl,%%eax" "\n\t"
+ "movl %%eax, %0" "\n"
+ : "=r"(res) : : "eax","ebx"
+ );
+ printf("try_misc 32bit-dst 0x%08x\n", res);
+}
+
+/////////////////////////////////////////////////////////////////
+
+void test_CRC32_U8_x86 ( void )
+{
+ UInt block[4];
+ Int i;
+ UInt oszacp_mask = 0x8D5;
+ for (i = 0; i < 10; i++) {
+ block[0] = i == 0 ? 0 : (UInt)randUInt();
+ block[1] = (UInt)randUInt();
+ block[2] = (UInt)randUInt();
+ block[3] = (UInt)randUInt();
+ __asm__ __volatile__(
+ "movl %0, %%eax" "\n\t"
+ "movl 0(%%eax), %%edi" "\n\t"
+ "movl 4(%%eax), %%ecx" "\n\t"
+ "crc32 %%dl, %%ecx" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "pushf" "\n\t"
+ "popl %%edx" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n"
+ : /*out*/
+ : /*in*/"r"(&block[0])
+ : /*trash*/ "cc", "memory", "edi", "ecx", "edx"
+ );
+ printf("r crc32_u8 %08x %08x %08x %08x\n",
+ block[0], block[1], block[2], block[3] & oszacp_mask);
+
+ block[0] = i == 0 ? 0 : (UInt)randUInt();
+ block[1] = (UInt)randUInt();
+ block[2] = (UInt)randUInt();
+ block[3] = (UInt)randUInt();
+ __asm__ __volatile__(
+ "movl %0, %%eax" "\n\t"
+ "movl 4(%%eax), %%ecx" "\n\t"
+ "crc32b 0(%%eax), %%ecx" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "pushf" "\n\t"
+ "popl %%edx" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n"
+ : /*out*/
+ : /*in*/"r"(&block[0])
+ : /*trash*/ "cc", "memory", "ecx", "edx"
+ );
+ printf("m crc32_u8 %08x %08x %08x %08x\n",
+ block[0], block[1], block[2], block[3] & oszacp_mask);
+ }
+}
+
+void test_CRC32_U16_x86 ( void )
+{
+ UInt block[4];
+ Int i;
+ UInt oszacp_mask = 0x8D5;
+ for (i = 0; i < 10; i++) {
+ block[0] = i == 0 ? 0 : (UInt)randUInt();
+ block[1] = (UInt)randUInt();
+ block[2] = (UInt)randUInt();
+ block[3] = (UInt)randUInt();
+ __asm__ __volatile__(
+ "movl %0, %%eax" "\n\t"
+ "movl 0(%%eax), %%edi" "\n\t"
+ "movl 4(%%eax), %%ecx" "\n\t"
+ "crc32 %%di, %%ecx" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "pushf" "\n\t"
+ "popl %%edx" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n"
+ : /*out*/
+ : /*in*/"r"(&block[0])
+ : /*trash*/ "cc", "memory", "edi", "ecx", "edx"
+ );
+ printf("r crc32_u16 %08x %08x %08x %08x\n",
+ block[0], block[1], block[2], block[3] & oszacp_mask);
+
+ block[0] = i == 0 ? 0 : (UInt)randUInt();
+ block[1] = (UInt)randUInt();
+ block[2] = (UInt)randUInt();
+ block[3] = (UInt)randUInt();
+ __asm__ __volatile__(
+ "movl %0, %%eax" "\n\t"
+ "movl 4(%%eax), %%ecx" "\n\t"
+ "crc32w 0(%%eax), %%ecx" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "pushf" "\n\t"
+ "popl %%edx" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n"
+ : /*out*/
+ : /*in*/"r"(&block[0])
+ : /*trash*/ "cc", "memory", "ecx", "edx"
+ );
+ printf("m crc32_u16 %08x %08x %08x %08x\n",
+ block[0], block[1], block[2], block[3] & oszacp_mask);
+ }
+}
+
+void test_CRC32_U32_x86 ( void )
+{
+ UInt block[4];
+ Int i;
+ UInt oszacp_mask = 0x8D5;
+ for (i = 0; i < 10; i++) {
+ block[0] = i == 0 ? 0 : (UInt)randUInt();
+ block[1] = (UInt)randUInt();
+ block[2] = (UInt)randUInt();
+ block[3] = (UInt)randUInt();
+ __asm__ __volatile__(
+ "movl %0, %%eax" "\n\t"
+ "movl 0(%%eax), %%edi" "\n\t"
+ "movl 4(%%eax), %%ecx" "\n\t"
+ "crc32 %%edi, %%ecx" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "pushf" "\n\t"
+ "popl %%edx" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n"
+ : /*out*/
+ : /*in*/"r"(&block[0])
+ : /*trash*/ "cc", "memory", "edi", "ecx", "edx"
+ );
+ printf("r crc32_u32 %08x %08x %08x %08x\n",
+ block[0], block[1], block[2], block[3] & oszacp_mask);
+
+ block[0] = i == 0 ? 0 : (UInt)randUInt();
+ block[1] = (UInt)randUInt();
+ block[2] = (UInt)randUInt();
+ block[3] = (UInt)randUInt();
+ __asm__ __volatile__(
+ "movl %0, %%eax" "\n\t"
+ "movl 4(%%eax), %%ecx" "\n\t"
+ "crc32 0(%%eax), %%ecx" "\n\t"
+ "movl %%ecx, 8(%%eax)" "\n\t"
+ "pushf" "\n\t"
+ "popl %%edx" "\n\t"
+ "movl %%edx, 12(%%eax)" "\n"
+ : /*out*/
+ : /*in*/"r"(&block[0])
+ : /*trash*/ "cc", "memory", "ecx", "edx"
+ );
+ printf("m crc32_u32 %08x %08x %08x %08x\n",
+ block[0], block[1], block[2], block[3] & oszacp_mask);
+ }
+}
+
+/////////////////////////////////////////////////////////////////
+
+int main ( int argc, char** argv )
+{
+ try_simple();
+ try_mem();
+ try_misc();
+ test_CRC32_U8_x86();
+ test_CRC32_U16_x86();
+ test_CRC32_U32_x86();
+ return 0;
+}
--- /dev/null
+b 0dc2c1e5 0dc2c1e5
+w 70cb7bdb 70cb7bdb
+l 9ca98638 9ca98638
+mem b misalign 0 = f502c278
+mem w misalign 0 = f502c278
+mem w misalign 1 = 0a72a365
+mem l misalign 0 = f502c278
+mem l misalign 1 = 246088f7
+mem l misalign 2 = bcf12db3
+mem l misalign 3 = 00d2a6af
+try_misc 32bit-dst 0xa50765b3
+r crc32_u8 00000000 00571784 456cfb70 00000000
+m crc32_u8 00000000 9de37551 a3d3baa5 00000000
+r crc32_u8 0d6a95fa c528657d ce7530bb 00000000
+m crc32_u8 84c4457d 8560b160 aff3eb0d 00000000
+r crc32_u8 2751bca7 5afbd2b6 94ee6ef3 00000000
+m crc32_u8 fd673a5c 2148a319 74ab4103 00000000
+r crc32_u8 6b3e625d 19775d06 26b890b5 00000000
+m crc32_u8 36ed3550 df9899d8 08f0fb2e 00000000
+r crc32_u8 856c13b8 709950cb 5a7414af 00000000
+m crc32_u8 db93c0f8 294addf9 f242c9de 00000000
+r crc32_u8 1f195c53 c95bf85f 0fffbd0f 00000000
+m crc32_u8 979569ee 6d5cbcd8 162ff2e5 00000000
+r crc32_u8 e87fc9cb 92bba120 202f357f 00000000
+m crc32_u8 172ebcce 16c982d1 4e5b32c9 00000000
+r crc32_u8 8adae4bb 36b59768 eb297e3a 00000000
+m crc32_u8 069b4435 908d7b40 44f9cd6a 00000000
+r crc32_u8 b2683bbf 21432695 a778ab2d 00000000
+m crc32_u8 11188dbe 47a5f281 6eb7d067 00000000
+r crc32_u8 0b635974 bf639901 f2d4e09a 00000000
+m crc32_u8 e4e02305 a70c35f0 c638775c 00000000
+r crc32_u16 00000000 4208cb75 b875e2db 00000000
+m crc32_u16 00000000 d5e7ca54 26378d42 00000000
+r crc32_u16 6efeebb0 fcde6db7 de3ae90b 00000000
+m crc32_u16 92a7705a 2d5b324d e5e878d4 00000000
+r crc32_u16 f3807c72 37dd6262 83e3be14 00000000
+m crc32_u16 e5f1216d 47c3a621 7ab57c30 00000000
+r crc32_u16 1e41d09e eb4d0896 c41e9191 00000000
+m crc32_u16 b4985c39 0f9bf2ac 971df7c9 00000000
+r crc32_u16 1cfdf650 03ac2d2e 01d80f31 00000000
+m crc32_u16 2b582ed8 725fe2c9 a2a9f2bd 00000000
+r crc32_u16 1870f7a3 6a759b08 013e441d 00000000
+m crc32_u16 77eca266 5a8c4256 a37ee015 00000000
+r crc32_u16 3f55e1b3 0e241fff 739fba16 00000000
+m crc32_u16 c411c4ff b49ddd2d 74b855ac 00000000
+r crc32_u16 bc68bf9d da3685ee d0bfc7a1 00000000
+m crc32_u16 3d83a1c1 6d0e812c 9bde063c 00000000
+r crc32_u16 bc679d7d ba2599b3 3795834d 00000000
+m crc32_u16 0ffd44c5 6f5bf82e 2dfa669c 00000000
+r crc32_u16 6b0c886e 9a6f2728 6a8084db 00000000
+m crc32_u16 663cba29 a8010f0e 8202e493 00000000
+r crc32_u32 00000000 f4148b8c c3257ae8 00000000
+m crc32_u32 00000000 5eb678f0 868ad750 00000000
+r crc32_u32 8d0bf37d 096a4357 5295b427 00000000
+m crc32_u32 e7e79284 496dce65 ad8f4c49 00000000
+r crc32_u32 23a9d13a 3e4f30f5 a3e3d675 00000000
+m crc32_u32 e9c893a3 6480e4c5 c5684927 00000000
+r crc32_u32 3c9d19a2 984fc36e 463bfd3e 00000000
+m crc32_u32 845f04fa 19ed086d b5033247 00000000
+r crc32_u32 85265650 84674a1c ee3337d7 00000000
+m crc32_u32 65e87126 d6ae84b9 8526f245 00000000
+r crc32_u32 aa7e15e1 6c920f5d abf69369 00000000
+m crc32_u32 389f65c3 05c2a505 fe247bc4 00000000
+r crc32_u32 56e2e1f0 becc5f8b 1019a8dc 00000000
+m crc32_u32 a9bf6c6c 1422b7ac 1e9eed0f 00000000
+r crc32_u32 368e461a e5128604 403c8c70 00000000
+m crc32_u32 638612bd 6ecb050c 35f56f16 00000000
+r crc32_u32 f5bdd1fa 4c5ecf22 fa7b2f38 00000000
+m crc32_u32 122de453 7ebadd80 ec581a76 00000000
+r crc32_u32 40ad0d2c 61ae8842 180bde9b 00000000
+m crc32_u32 63f36dc9 b2ea8964 76b5456b 00000000