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