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 
     68 #include <stdio.h>
     69 
     70 typedef  unsigned long long int  ULong;
     71 typedef  unsigned int            UInt;
     72 
     73 __attribute__((noinline))
     74 void do_lzcnt32 ( /*OUT*/UInt* flags, /*OUT*/UInt* res, UInt arg )
     75 {
     76   UInt block[3] = { arg, 0, 0 };
     77   __asm__ __volatile__(
     78     "movl $0x55555555, %%esi" "\n\t"
     79     "lzcntl 0(%0), %%esi"     "\n\t"
     80     "movl %%esi, 4(%0)"       "\n\t"
     81     "pushfl"                  "\n\t"
     82     "popl %%esi"              "\n\t"
     83     "movl %%esi, 8(%0)"       "\n"
     84     : : "r"(&block[0]) : "esi","cc","memory"
     85   );
     86   *res = block[1];
     87   *flags = block[2] & 0x8d5;
     88 }
     89 
     90 __attribute__((noinline))
     91 void do_lzcnt16 ( /*OUT*/UInt* flags, /*OUT*/UInt* res, UInt arg )
     92 {
     93   UInt block[3] = { arg, 0, 0 };
     94   __asm__ __volatile__(
     95     "movl $0x55555555, %%esi" "\n\t"
     96     "lzcntw 0(%0), %%si"      "\n\t"
     97     "movl %%esi, 4(%0)"       "\n\t"
     98     "pushfl"                  "\n\t"
     99     "popl %%esi"              "\n\t"
    100     "movl %%esi, 8(%0)"       "\n"
    101     : : "r"(&block[0]) : "esi","cc","memory"
    102   );
    103   *res = block[1];
    104   *flags = block[2] & 0x8d5;
    105 }
    106 
    107 int main ( void )
    108 {
    109    UInt w;
    110 
    111    w = 0xFEDC1928;
    112    while (1) {
    113       UInt res;
    114       UInt flags;
    115       do_lzcnt32(&flags, &res, w);
    116       printf("lzcntl %08x -> %08x %04x\n", w, res, flags);
    117       if (w == 0) break;
    118       w = ((w >> 2) | (w >> 1)) + (w / 17);
    119    }
    120 
    121    w = 0xFEDC1928;
    122    while (1) {
    123       UInt res;
    124       UInt flags;
    125       do_lzcnt16(&flags, &res, w);
    126       printf("lzcntw %08x -> %08x %04x\n", w, res, flags);
    127       if (w == 0) break;
    128       w = ((w >> 2) | (w >> 1)) + (w / 17);
    129    }
    130 
    131    return 0;
    132 }
    133