Home | History | Annotate | Download | only in amd64
      1 
      2 #include <stdlib.h>
      3 #include <stdio.h>
      4 
      5 typedef  unsigned int            UInt;
      6 typedef  unsigned long long int  ULong;
      7 typedef  unsigned char           UChar;
      8 typedef  unsigned short int      UShort;
      9 
     10 
     11 /////////////////////////////////////////////////////////////////
     12 
     13 UInt do_s_crc32b ( UInt crcIn, UChar b )
     14 {
     15    UInt i, crc = (b & 0xFF) ^ crcIn;
     16    for (i = 0; i < 8; i++)
     17       crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
     18    return crc;
     19 }
     20 
     21 UInt do_s_crc32w ( UInt crcIn, UShort w )
     22 {
     23    UInt i, crc = (w & 0xFFFF) ^ crcIn;
     24    for (i = 0; i < 16; i++)
     25       crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
     26    return crc;
     27 }
     28 
     29 UInt do_s_crc32l ( UInt crcIn, UInt l )
     30 {
     31    UInt i, crc = l ^ crcIn;
     32    for (i = 0; i < 32; i++)
     33       crc = (crc >> 1) ^ ((crc & 1) ? 0x82f63b78 : 0);
     34    return crc;
     35 }
     36 
     37 UInt do_s_crc32q ( UInt crcIn, ULong q )
     38 {
     39    UInt crc = do_s_crc32l(crcIn, (UInt)q);
     40    return do_s_crc32l(crc, (UInt)(q >> 32));
     41 }
     42 
     43 UInt do_h_crc32b ( UInt crcIn, UChar b )
     44 {
     45    __asm__ __volatile__(
     46       "crc32b %%cl,%%esi\n\t"
     47       : "=S"(crcIn) : "0"(crcIn), "c"(b)
     48    );
     49    return crcIn;
     50 }
     51 
     52 UInt do_h_crc32w ( UInt crcIn, UShort w )
     53 {
     54    __asm__ __volatile__(
     55       "crc32w %%cx,%%esi\n\t"
     56       : "=S"(crcIn) : "0"(crcIn), "c"(w)
     57    );
     58    return crcIn;
     59 }
     60 
     61 UInt do_h_crc32l ( UInt crcIn, UInt l )
     62 {
     63    __asm__ __volatile__(
     64       "crc32l %%ecx,%%esi\n\t"
     65       : "=S"(crcIn) : "0"(crcIn), "c"(l)
     66    );
     67    return crcIn;
     68 }
     69 
     70 UInt do_h_crc32q ( UInt crcIn, ULong q )
     71 {
     72    __asm__ __volatile__(
     73       "crc32q %%rcx,%%rsi\n\t"
     74       : "=S"(crcIn) : "0"(crcIn), "c"(q)
     75    );
     76    return crcIn;
     77 }
     78 
     79 ////////////////
     80 
     81 UInt do_h_crc32b_mem ( UInt crcIn, UChar* a )
     82 {
     83    __asm__ __volatile__(
     84       "crc32b (%2),%%esi\n\t"
     85       : "=S"(crcIn) : "0"(crcIn), "r"(a)
     86    );
     87    return crcIn;
     88 }
     89 
     90 UInt do_h_crc32w_mem ( UInt crcIn, UShort* a )
     91 {
     92    __asm__ __volatile__(
     93       "crc32w (%2),%%esi\n\t"
     94       : "=S"(crcIn) : "0"(crcIn), "r"(a)
     95    );
     96    return crcIn;
     97 }
     98 
     99 UInt do_h_crc32l_mem ( UInt crcIn, UInt* a )
    100 {
    101    __asm__ __volatile__(
    102       "crc32l (%2),%%esi\n\t"
    103       : "=S"(crcIn) : "0"(crcIn), "r"(a)
    104    );
    105    return crcIn;
    106 }
    107 
    108 UInt do_h_crc32q_mem ( UInt crcIn, ULong* a )
    109 {
    110    __asm__ __volatile__(
    111       "crc32q (%2),%%rsi\n\t"
    112       : "=S"(crcIn) : "0"(crcIn), "r"(a)
    113    );
    114    return crcIn;
    115 }
    116 
    117 void try_simple ( void )
    118 {
    119    UInt c0 = 0xFFFFFFFF;
    120    UChar c = 0x42;
    121 
    122    UInt cs = do_s_crc32b(c0, c);
    123    UInt ch = do_h_crc32b(c0, c);
    124    printf("b  %08x %08x\n", cs, ch);
    125 
    126    UShort w = 0xed78;;
    127    cs = do_s_crc32w(c0, w);
    128    ch = do_h_crc32w(c0, w);
    129    printf("w  %08x %08x\n", cs, ch);
    130 
    131    UInt i = 0xCAFEBABE;
    132    cs = do_s_crc32l(c0, i);
    133    ch = do_h_crc32l(c0, i);
    134    printf("l  %08x %08x\n", cs, ch);
    135 
    136    ULong q = 0x0ddC0ffeeBadF00d;
    137    cs = do_s_crc32q(c0, q);
    138    ch = do_h_crc32q(c0, q);
    139    printf("q  %08x %08x\n", cs, ch);
    140 }
    141 
    142 #define NMEM 1000
    143 void try_mem ( void )
    144 {
    145   UInt al, i;
    146   UChar* b = malloc(NMEM);
    147   for (i = 0; i < NMEM; i++)
    148      b[i] = (UChar)(i % 177);
    149 
    150   for (al = 0; al < 1; al++) {
    151      UInt crc = 0xFFFFFFFF;
    152      for (i = 0; i <= 1000-1-al; i += 1)
    153         crc = do_h_crc32b_mem( crc, &b[i+al] );
    154      printf("mem b misalign %d = %08x\n", al, crc);
    155   }
    156 
    157   for (al = 0; al < 2; al++) {
    158      UInt crc = 0xFFFFFFFF;
    159      for (i = 0; i <= 1000-2-al; i += 2)
    160        crc = do_h_crc32w_mem( crc, (UShort*)&b[i+al] );
    161      printf("mem w misalign %d = %08x\n", al, crc);
    162   }
    163 
    164   for (al = 0; al < 4; al++) {
    165      UInt crc = 0xFFFFFFFF;
    166      for (i = 0; i <= 1000-4-al; i += 4)
    167        crc = do_h_crc32l_mem( crc, (UInt*)&b[i+al] );
    168      printf("mem l misalign %d = %08x\n", al, crc);
    169   }
    170 
    171   for (al = 0; al < 8; al++) {
    172      UInt crc = 0xFFFFFFFF;
    173      for (i = 0; i <= 1000-8-al; i += 8)
    174        crc = do_h_crc32q_mem( crc, (ULong*)&b[i+al] );
    175      printf("mem q misalign %d = %08x\n", al, crc);
    176   }
    177 
    178   free(b);
    179 }
    180 
    181 void try_misc ( void )
    182 {
    183    ULong res = 0xAAAAAAAAAAAAAAAAULL;
    184    __asm__ __volatile__(
    185       "movabsq $0x5555555555555555, %%rax"  "\n\t"
    186       "movabsq $042, %%rbx"  "\n\t"
    187       "crc32b %%bl,%%rax"  "\n\t"
    188       "movq %%rax, %0"  "\n"
    189       : "=r"(res) : : "rax","rbx"
    190    );
    191    printf("try_misc 64bit-dst 0x%016llx\n", res);
    192 
    193    __asm__ __volatile__(
    194       "movabsq $0x5555555555555555, %%rax"  "\n\t"
    195       "movabsq $042, %%rbx"  "\n\t"
    196       "crc32b %%bl,%%eax"  "\n\t"
    197       "movq %%rax, %0"  "\n"
    198       : "=r"(res) : : "rax","rbx"
    199    );
    200    printf("try_misc 32bit-dst 0x%016llx\n", res);
    201 }
    202 
    203 /////////////////////////////////////////////////////////////////
    204 
    205 
    206 
    207 int main ( int argc, char** argv )
    208 {
    209    try_simple();
    210    try_mem();
    211    try_misc();
    212    return 0;
    213 }
    214