14a12423d8c9cf8853332483f653d27913eb27f3esewardj
24a12423d8c9cf8853332483f653d27913eb27f3esewardj#include <stdlib.h>
34a12423d8c9cf8853332483f653d27913eb27f3esewardj#include <stdio.h>
44a12423d8c9cf8853332483f653d27913eb27f3esewardj
54a12423d8c9cf8853332483f653d27913eb27f3esewardjtypedef  unsigned int            UInt;
64a12423d8c9cf8853332483f653d27913eb27f3esewardjtypedef  unsigned long long int  ULong;
74a12423d8c9cf8853332483f653d27913eb27f3esewardjtypedef  unsigned char           UChar;
84a12423d8c9cf8853332483f653d27913eb27f3esewardjtypedef  unsigned short int      UShort;
94a12423d8c9cf8853332483f653d27913eb27f3esewardj
104a12423d8c9cf8853332483f653d27913eb27f3esewardj
114a12423d8c9cf8853332483f653d27913eb27f3esewardj/////////////////////////////////////////////////////////////////
124a12423d8c9cf8853332483f653d27913eb27f3esewardj
134a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_s_crc32b ( UInt crcIn, UChar b )
144a12423d8c9cf8853332483f653d27913eb27f3esewardj{
154a12423d8c9cf8853332483f653d27913eb27f3esewardj   UInt i, crc = (b & 0xFF) ^ crcIn;
164a12423d8c9cf8853332483f653d27913eb27f3esewardj   for (i = 0; i < 8; i++)
174a12423d8c9cf8853332483f653d27913eb27f3esewardj      crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
184a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crc;
194a12423d8c9cf8853332483f653d27913eb27f3esewardj}
204a12423d8c9cf8853332483f653d27913eb27f3esewardj
214a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_s_crc32w ( UInt crcIn, UShort w )
224a12423d8c9cf8853332483f653d27913eb27f3esewardj{
234a12423d8c9cf8853332483f653d27913eb27f3esewardj   UInt i, crc = (w & 0xFFFF) ^ crcIn;
244a12423d8c9cf8853332483f653d27913eb27f3esewardj   for (i = 0; i < 16; i++)
254a12423d8c9cf8853332483f653d27913eb27f3esewardj      crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
264a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crc;
274a12423d8c9cf8853332483f653d27913eb27f3esewardj}
284a12423d8c9cf8853332483f653d27913eb27f3esewardj
294a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_s_crc32l ( UInt crcIn, UInt l )
304a12423d8c9cf8853332483f653d27913eb27f3esewardj{
314a12423d8c9cf8853332483f653d27913eb27f3esewardj   UInt i, crc = l ^ crcIn;
324a12423d8c9cf8853332483f653d27913eb27f3esewardj   for (i = 0; i < 32; i++)
334a12423d8c9cf8853332483f653d27913eb27f3esewardj      crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
344a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crc;
354a12423d8c9cf8853332483f653d27913eb27f3esewardj}
364a12423d8c9cf8853332483f653d27913eb27f3esewardj
374a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_s_crc32q ( UInt crcIn, ULong q )
384a12423d8c9cf8853332483f653d27913eb27f3esewardj{
394a12423d8c9cf8853332483f653d27913eb27f3esewardj   UInt crc = do_s_crc32l(crcIn, (UInt)q);
404a12423d8c9cf8853332483f653d27913eb27f3esewardj   return do_s_crc32l(crc, (UInt)(q >> 32));
414a12423d8c9cf8853332483f653d27913eb27f3esewardj}
424a12423d8c9cf8853332483f653d27913eb27f3esewardj
434a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_h_crc32b ( UInt crcIn, UChar b )
444a12423d8c9cf8853332483f653d27913eb27f3esewardj{
454a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
464a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32b %%cl,%%esi\n\t"
474a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=S"(crcIn) : "0"(crcIn), "c"(b)
484a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
494a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crcIn;
504a12423d8c9cf8853332483f653d27913eb27f3esewardj}
514a12423d8c9cf8853332483f653d27913eb27f3esewardj
524a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_h_crc32w ( UInt crcIn, UShort w )
534a12423d8c9cf8853332483f653d27913eb27f3esewardj{
544a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
554a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32w %%cx,%%esi\n\t"
564a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=S"(crcIn) : "0"(crcIn), "c"(w)
574a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
584a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crcIn;
594a12423d8c9cf8853332483f653d27913eb27f3esewardj}
604a12423d8c9cf8853332483f653d27913eb27f3esewardj
614a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_h_crc32l ( UInt crcIn, UInt l )
624a12423d8c9cf8853332483f653d27913eb27f3esewardj{
634a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
644a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32l %%ecx,%%esi\n\t"
654a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=S"(crcIn) : "0"(crcIn), "c"(l)
664a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
674a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crcIn;
684a12423d8c9cf8853332483f653d27913eb27f3esewardj}
694a12423d8c9cf8853332483f653d27913eb27f3esewardj
704a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_h_crc32q ( UInt crcIn, ULong q )
714a12423d8c9cf8853332483f653d27913eb27f3esewardj{
724a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
734a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32q %%rcx,%%rsi\n\t"
744a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=S"(crcIn) : "0"(crcIn), "c"(q)
754a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
764a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crcIn;
774a12423d8c9cf8853332483f653d27913eb27f3esewardj}
784a12423d8c9cf8853332483f653d27913eb27f3esewardj
794a12423d8c9cf8853332483f653d27913eb27f3esewardj////////////////
804a12423d8c9cf8853332483f653d27913eb27f3esewardj
814a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_h_crc32b_mem ( UInt crcIn, UChar* a )
824a12423d8c9cf8853332483f653d27913eb27f3esewardj{
834a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
844a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32b (%2),%%esi\n\t"
854a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=S"(crcIn) : "0"(crcIn), "r"(a)
864a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
874a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crcIn;
884a12423d8c9cf8853332483f653d27913eb27f3esewardj}
894a12423d8c9cf8853332483f653d27913eb27f3esewardj
904a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_h_crc32w_mem ( UInt crcIn, UShort* a )
914a12423d8c9cf8853332483f653d27913eb27f3esewardj{
924a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
934a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32w (%2),%%esi\n\t"
944a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=S"(crcIn) : "0"(crcIn), "r"(a)
954a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
964a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crcIn;
974a12423d8c9cf8853332483f653d27913eb27f3esewardj}
984a12423d8c9cf8853332483f653d27913eb27f3esewardj
994a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_h_crc32l_mem ( UInt crcIn, UInt* a )
1004a12423d8c9cf8853332483f653d27913eb27f3esewardj{
1014a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
1024a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32l (%2),%%esi\n\t"
1034a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=S"(crcIn) : "0"(crcIn), "r"(a)
1044a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
1054a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crcIn;
1064a12423d8c9cf8853332483f653d27913eb27f3esewardj}
1074a12423d8c9cf8853332483f653d27913eb27f3esewardj
1084a12423d8c9cf8853332483f653d27913eb27f3esewardjUInt do_h_crc32q_mem ( UInt crcIn, ULong* a )
1094a12423d8c9cf8853332483f653d27913eb27f3esewardj{
1104a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
1114a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32q (%2),%%rsi\n\t"
1124a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=S"(crcIn) : "0"(crcIn), "r"(a)
1134a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
1144a12423d8c9cf8853332483f653d27913eb27f3esewardj   return crcIn;
1154a12423d8c9cf8853332483f653d27913eb27f3esewardj}
1164a12423d8c9cf8853332483f653d27913eb27f3esewardj
1174a12423d8c9cf8853332483f653d27913eb27f3esewardjvoid try_simple ( void )
1184a12423d8c9cf8853332483f653d27913eb27f3esewardj{
1194a12423d8c9cf8853332483f653d27913eb27f3esewardj   UInt c0 = 0xFFFFFFFF;
1204a12423d8c9cf8853332483f653d27913eb27f3esewardj   UChar c = 0x42;
1214a12423d8c9cf8853332483f653d27913eb27f3esewardj
1224a12423d8c9cf8853332483f653d27913eb27f3esewardj   UInt cs = do_s_crc32b(c0, c);
1234a12423d8c9cf8853332483f653d27913eb27f3esewardj   UInt ch = do_h_crc32b(c0, c);
1244a12423d8c9cf8853332483f653d27913eb27f3esewardj   printf("b  %08x %08x\n", cs, ch);
1254a12423d8c9cf8853332483f653d27913eb27f3esewardj
1264a12423d8c9cf8853332483f653d27913eb27f3esewardj   UShort w = 0xed78;;
1274a12423d8c9cf8853332483f653d27913eb27f3esewardj   cs = do_s_crc32w(c0, w);
1284a12423d8c9cf8853332483f653d27913eb27f3esewardj   ch = do_h_crc32w(c0, w);
1294a12423d8c9cf8853332483f653d27913eb27f3esewardj   printf("w  %08x %08x\n", cs, ch);
1304a12423d8c9cf8853332483f653d27913eb27f3esewardj
1314a12423d8c9cf8853332483f653d27913eb27f3esewardj   UInt i = 0xCAFEBABE;
1324a12423d8c9cf8853332483f653d27913eb27f3esewardj   cs = do_s_crc32l(c0, i);
1334a12423d8c9cf8853332483f653d27913eb27f3esewardj   ch = do_h_crc32l(c0, i);
1344a12423d8c9cf8853332483f653d27913eb27f3esewardj   printf("l  %08x %08x\n", cs, ch);
1354a12423d8c9cf8853332483f653d27913eb27f3esewardj
1364a12423d8c9cf8853332483f653d27913eb27f3esewardj   ULong q = 0x0ddC0ffeeBadF00d;
1374a12423d8c9cf8853332483f653d27913eb27f3esewardj   cs = do_s_crc32q(c0, q);
1384a12423d8c9cf8853332483f653d27913eb27f3esewardj   ch = do_h_crc32q(c0, q);
1394a12423d8c9cf8853332483f653d27913eb27f3esewardj   printf("q  %08x %08x\n", cs, ch);
1404a12423d8c9cf8853332483f653d27913eb27f3esewardj}
1414a12423d8c9cf8853332483f653d27913eb27f3esewardj
1424a12423d8c9cf8853332483f653d27913eb27f3esewardj#define NMEM 1000
1434a12423d8c9cf8853332483f653d27913eb27f3esewardjvoid try_mem ( void )
1444a12423d8c9cf8853332483f653d27913eb27f3esewardj{
1454a12423d8c9cf8853332483f653d27913eb27f3esewardj  UInt al, i;
1464a12423d8c9cf8853332483f653d27913eb27f3esewardj  UChar* b = malloc(NMEM);
1474a12423d8c9cf8853332483f653d27913eb27f3esewardj  for (i = 0; i < NMEM; i++)
1484a12423d8c9cf8853332483f653d27913eb27f3esewardj     b[i] = (UChar)(i % 177);
1494a12423d8c9cf8853332483f653d27913eb27f3esewardj
1504a12423d8c9cf8853332483f653d27913eb27f3esewardj  for (al = 0; al < 1; al++) {
1514a12423d8c9cf8853332483f653d27913eb27f3esewardj     UInt crc = 0xFFFFFFFF;
1524a12423d8c9cf8853332483f653d27913eb27f3esewardj     for (i = 0; i <= 1000-1-al; i += 1)
1534a12423d8c9cf8853332483f653d27913eb27f3esewardj        crc = do_h_crc32b_mem( crc, &b[i+al] );
1544a12423d8c9cf8853332483f653d27913eb27f3esewardj     printf("mem b misalign %d = %08x\n", al, crc);
1554a12423d8c9cf8853332483f653d27913eb27f3esewardj  }
1564a12423d8c9cf8853332483f653d27913eb27f3esewardj
1574a12423d8c9cf8853332483f653d27913eb27f3esewardj  for (al = 0; al < 2; al++) {
1584a12423d8c9cf8853332483f653d27913eb27f3esewardj     UInt crc = 0xFFFFFFFF;
1594a12423d8c9cf8853332483f653d27913eb27f3esewardj     for (i = 0; i <= 1000-2-al; i += 2)
1604a12423d8c9cf8853332483f653d27913eb27f3esewardj       crc = do_h_crc32w_mem( crc, (UShort*)&b[i+al] );
1614a12423d8c9cf8853332483f653d27913eb27f3esewardj     printf("mem w misalign %d = %08x\n", al, crc);
1624a12423d8c9cf8853332483f653d27913eb27f3esewardj  }
1634a12423d8c9cf8853332483f653d27913eb27f3esewardj
1644a12423d8c9cf8853332483f653d27913eb27f3esewardj  for (al = 0; al < 4; al++) {
1654a12423d8c9cf8853332483f653d27913eb27f3esewardj     UInt crc = 0xFFFFFFFF;
1664a12423d8c9cf8853332483f653d27913eb27f3esewardj     for (i = 0; i <= 1000-4-al; i += 4)
1674a12423d8c9cf8853332483f653d27913eb27f3esewardj       crc = do_h_crc32l_mem( crc, (UInt*)&b[i+al] );
1684a12423d8c9cf8853332483f653d27913eb27f3esewardj     printf("mem l misalign %d = %08x\n", al, crc);
1694a12423d8c9cf8853332483f653d27913eb27f3esewardj  }
1704a12423d8c9cf8853332483f653d27913eb27f3esewardj
1714a12423d8c9cf8853332483f653d27913eb27f3esewardj  for (al = 0; al < 8; al++) {
1724a12423d8c9cf8853332483f653d27913eb27f3esewardj     UInt crc = 0xFFFFFFFF;
1734a12423d8c9cf8853332483f653d27913eb27f3esewardj     for (i = 0; i <= 1000-8-al; i += 8)
1744a12423d8c9cf8853332483f653d27913eb27f3esewardj       crc = do_h_crc32q_mem( crc, (ULong*)&b[i+al] );
1754a12423d8c9cf8853332483f653d27913eb27f3esewardj     printf("mem q misalign %d = %08x\n", al, crc);
1764a12423d8c9cf8853332483f653d27913eb27f3esewardj  }
1774a12423d8c9cf8853332483f653d27913eb27f3esewardj
1784a12423d8c9cf8853332483f653d27913eb27f3esewardj  free(b);
1794a12423d8c9cf8853332483f653d27913eb27f3esewardj}
1804a12423d8c9cf8853332483f653d27913eb27f3esewardj
1814a12423d8c9cf8853332483f653d27913eb27f3esewardjvoid try_misc ( void )
1824a12423d8c9cf8853332483f653d27913eb27f3esewardj{
1834a12423d8c9cf8853332483f653d27913eb27f3esewardj   ULong res = 0xAAAAAAAAAAAAAAAAULL;
1844a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
1854a12423d8c9cf8853332483f653d27913eb27f3esewardj      "movabsq $0x5555555555555555, %%rax"  "\n\t"
1864a12423d8c9cf8853332483f653d27913eb27f3esewardj      "movabsq $042, %%rbx"  "\n\t"
1874a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32b %%bl,%%rax"  "\n\t"
1884a12423d8c9cf8853332483f653d27913eb27f3esewardj      "movq %%rax, %0"  "\n"
1894a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=r"(res) : : "rax","rbx"
1904a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
1914a12423d8c9cf8853332483f653d27913eb27f3esewardj   printf("try_misc 64bit-dst 0x%016llx\n", res);
1924a12423d8c9cf8853332483f653d27913eb27f3esewardj
1934a12423d8c9cf8853332483f653d27913eb27f3esewardj   __asm__ __volatile__(
1944a12423d8c9cf8853332483f653d27913eb27f3esewardj      "movabsq $0x5555555555555555, %%rax"  "\n\t"
1954a12423d8c9cf8853332483f653d27913eb27f3esewardj      "movabsq $042, %%rbx"  "\n\t"
1964a12423d8c9cf8853332483f653d27913eb27f3esewardj      "crc32b %%bl,%%eax"  "\n\t"
1974a12423d8c9cf8853332483f653d27913eb27f3esewardj      "movq %%rax, %0"  "\n"
1984a12423d8c9cf8853332483f653d27913eb27f3esewardj      : "=r"(res) : : "rax","rbx"
1994a12423d8c9cf8853332483f653d27913eb27f3esewardj   );
2004a12423d8c9cf8853332483f653d27913eb27f3esewardj   printf("try_misc 32bit-dst 0x%016llx\n", res);
2014a12423d8c9cf8853332483f653d27913eb27f3esewardj}
2024a12423d8c9cf8853332483f653d27913eb27f3esewardj
2034a12423d8c9cf8853332483f653d27913eb27f3esewardj/////////////////////////////////////////////////////////////////
2044a12423d8c9cf8853332483f653d27913eb27f3esewardj
2054a12423d8c9cf8853332483f653d27913eb27f3esewardj
2064a12423d8c9cf8853332483f653d27913eb27f3esewardj
2074a12423d8c9cf8853332483f653d27913eb27f3esewardjint main ( int argc, char** argv )
2084a12423d8c9cf8853332483f653d27913eb27f3esewardj{
2094a12423d8c9cf8853332483f653d27913eb27f3esewardj   try_simple();
2104a12423d8c9cf8853332483f653d27913eb27f3esewardj   try_mem();
2114a12423d8c9cf8853332483f653d27913eb27f3esewardj   try_misc();
2124a12423d8c9cf8853332483f653d27913eb27f3esewardj   return 0;
2134a12423d8c9cf8853332483f653d27913eb27f3esewardj}
214