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