Home | History | Annotate | Download | only in x86
      1 
      2 #include <stdio.h>
      3 
      4 typedef  unsigned long long int  ULong;
      5 typedef  unsigned int            UInt;
      6 
      7 __attribute__((noinline))
      8 void do_lzcnt32 ( /*OUT*/UInt* flags, /*OUT*/UInt* res, UInt arg )
      9 {
     10   UInt block[3] = { arg, 0, 0 };
     11   __asm__ __volatile__(
     12     "movl $0x55555555, %%esi" "\n\t"
     13     "lzcntl 0(%0), %%esi"     "\n\t"
     14     "movl %%esi, 4(%0)"       "\n\t"
     15     "pushfl"                  "\n\t"
     16     "popl %%esi"              "\n\t"
     17     "movl %%esi, 8(%0)"       "\n"
     18     : : "r"(&block[0]) : "esi","cc","memory"
     19   );
     20   *res = block[1];
     21   *flags = block[2] & 0x8d5;
     22 }
     23 
     24 __attribute__((noinline))
     25 void do_lzcnt16 ( /*OUT*/UInt* flags, /*OUT*/UInt* res, UInt arg )
     26 {
     27   UInt block[3] = { arg, 0, 0 };
     28   __asm__ __volatile__(
     29     "movl $0x55555555, %%esi" "\n\t"
     30     "lzcntw 0(%0), %%si"      "\n\t"
     31     "movl %%esi, 4(%0)"       "\n\t"
     32     "pushfl"                  "\n\t"
     33     "popl %%esi"              "\n\t"
     34     "movl %%esi, 8(%0)"       "\n"
     35     : : "r"(&block[0]) : "esi","cc","memory"
     36   );
     37   *res = block[1];
     38   *flags = block[2] & 0x8d5;
     39 }
     40 
     41 int main ( void )
     42 {
     43    UInt w;
     44 
     45    w = 0xFEDC1928;
     46    while (1) {
     47       UInt res;
     48       UInt flags;
     49       do_lzcnt32(&flags, &res, w);
     50       printf("lzcntl %08x -> %08x %04x\n", w, res, flags);
     51       if (w == 0) break;
     52       w = ((w >> 2) | (w >> 1)) + (w / 17);
     53    }
     54 
     55    w = 0xFEDC1928;
     56    while (1) {
     57       UInt res;
     58       UInt flags;
     59       do_lzcnt16(&flags, &res, w);
     60       printf("lzcntw %08x -> %08x %04x\n", w, res, flags);
     61       if (w == 0) break;
     62       w = ((w >> 2) | (w >> 1)) + (w / 17);
     63    }
     64 
     65    return 0;
     66 }
     67