lzcnt32.c revision b32f58018498ea2225959b0ba11c18f0c433deef
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 68#include <stdio.h> 69 70typedef unsigned long long int ULong; 71typedef unsigned int UInt; 72 73__attribute__((noinline)) 74void 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)) 91void 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 107int 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