1
2 #include <stdio.h>
3
4 typedef unsigned long long int ULong;
5 typedef unsigned int UInt;
6
7 __attribute__((noinline))
do_lzcnt32(UInt * flags,UInt * res,UInt arg)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))
do_lzcnt16(UInt * flags,UInt * res,UInt arg)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
main(void)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))
do_lzcnt32(UInt * flags,UInt * res,UInt arg)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))
do_lzcnt16(UInt * flags,UInt * res,UInt arg)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
main(void)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