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