lzcnt32.c revision 9bea4c13fca0e3bb4b719dcb3ed63d47d479294e
1
2#include <stdio.h>
3
4typedef  unsigned long long int  ULong;
5typedef  unsigned int            UInt;
6
7__attribute__((noinline))
8void 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))
25void 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
41int 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