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