From: Julian Seward Date: Thu, 29 Jul 2010 15:55:09 +0000 (+0000) Subject: Test cases for LZCNT instruction support. Not wired up yet. X-Git-Tag: svn/VALGRIND_3_6_0~206 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c97c366f1066461983429694c50fcdcecd4f28e9;p=thirdparty%2Fvalgrind.git Test cases for LZCNT instruction support. Not wired up yet. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11242 --- diff --git a/none/tests/amd64/test_lzcnt64.c b/none/tests/amd64/test_lzcnt64.c new file mode 100644 index 0000000000..22fa353b8d --- /dev/null +++ b/none/tests/amd64/test_lzcnt64.c @@ -0,0 +1,93 @@ + +#include + +typedef unsigned long long int ULong; +typedef unsigned int UInt; + +__attribute__((noinline)) +void do_lzcnt64 ( /*OUT*/UInt* flags, /*OUT*/ULong* res, ULong arg ) +{ + ULong block[3] = { arg, 0ULL, 0ULL }; + __asm__ __volatile__( + "movabsq $0x5555555555555555, %%r11" "\n\t" + "lzcntq 0(%0), %%r11" "\n\t" + "movq %%r11, 8(%0)" "\n\t" + "pushfq" "\n\t" + "popq %%r11" "\n\t" + "movq %%r11, 16(%0)" "\n" + : : "r"(&block[0]) : "r11","cc","memory" + ); + *res = block[1]; + *flags = block[2] & 0x8d5; +} + +__attribute__((noinline)) +void do_lzcnt32 ( /*OUT*/UInt* flags, /*OUT*/ULong* res, ULong arg ) +{ + ULong block[3] = { arg, 0ULL, 0ULL }; + __asm__ __volatile__( + "movabsq $0x5555555555555555, %%r11" "\n\t" + "lzcntl 0(%0), %%r11d" "\n\t" + "movq %%r11, 8(%0)" "\n\t" + "pushfq" "\n\t" + "popq %%r11" "\n\t" + "movq %%r11, 16(%0)" "\n" + : : "r"(&block[0]) : "r11","cc","memory" + ); + *res = block[1]; + *flags = block[2] & 0x8d5; +} + +__attribute__((noinline)) +void do_lzcnt16 ( /*OUT*/UInt* flags, /*OUT*/ULong* res, ULong arg ) +{ + ULong block[3] = { arg, 0ULL, 0ULL }; + __asm__ __volatile__( + "movabsq $0x5555555555555555, %%r11" "\n\t" + "lzcntw 0(%0), %%r11w" "\n\t" + "movq %%r11, 8(%0)" "\n\t" + "pushfq" "\n\t" + "popq %%r11" "\n\t" + "movq %%r11, 16(%0)" "\n" + : : "r"(&block[0]) : "r11","cc","memory" + ); + *res = block[1]; + *flags = block[2] & 0x8d5; +} + +int main ( void ) +{ + ULong w; + + w = 0xFEDC192837475675ULL; + while (1) { + ULong res; + UInt flags; + do_lzcnt64(&flags, &res, w); + printf("lzcntq %016llx -> %016llx %04x\n", w, res, flags); + if (w == 0) break; + w = ((w >> 2) | (w >> 1)) + (w / 17ULL); + } + + w = 0xFEDC192837475675ULL; + while (1) { + ULong res; + UInt flags; + do_lzcnt32(&flags, &res, w); + printf("lzcntl %016llx -> %016llx %04x\n", w, res, flags); + if (w == 0) break; + w = ((w >> 2) | (w >> 1)) + (w / 17ULL); + } + + w = 0xFEDC192837475675ULL; + while (1) { + ULong res; + UInt flags; + do_lzcnt16(&flags, &res, w); + printf("lzcntw %016llx -> %016llx %04x\n", w, res, flags); + if (w == 0) break; + w = ((w >> 2) | (w >> 1)) + (w / 17ULL); + } + + return 0; +} diff --git a/none/tests/x86/test_lzcnt32.c b/none/tests/x86/test_lzcnt32.c new file mode 100644 index 0000000000..107a25d64e --- /dev/null +++ b/none/tests/x86/test_lzcnt32.c @@ -0,0 +1,66 @@ + +#include + +typedef unsigned long long int ULong; +typedef unsigned int UInt; + +__attribute__((noinline)) +void do_lzcnt32 ( /*OUT*/UInt* flags, /*OUT*/UInt* res, UInt arg ) +{ + UInt block[3] = { arg, 0, 0 }; + __asm__ __volatile__( + "movl $0x55555555, %%esi" "\n\t" + "lzcntl 0(%0), %%esi" "\n\t" + "movl %%esi, 4(%0)" "\n\t" + "pushfl" "\n\t" + "popl %%esi" "\n\t" + "movl %%esi, 8(%0)" "\n" + : : "r"(&block[0]) : "esi","cc","memory" + ); + *res = block[1]; + *flags = block[2] & 0x8d5; +} + +__attribute__((noinline)) +void do_lzcnt16 ( /*OUT*/UInt* flags, /*OUT*/UInt* res, UInt arg ) +{ + UInt block[3] = { arg, 0, 0 }; + __asm__ __volatile__( + "movl $0x55555555, %%esi" "\n\t" + "lzcntw 0(%0), %%si" "\n\t" + "movl %%esi, 4(%0)" "\n\t" + "pushfl" "\n\t" + "popl %%esi" "\n\t" + "movl %%esi, 8(%0)" "\n" + : : "r"(&block[0]) : "esi","cc","memory" + ); + *res = block[1]; + *flags = block[2] & 0x8d5; +} + +int main ( void ) +{ + UInt w; + + w = 0xFEDC1928; + while (1) { + UInt res; + UInt flags; + do_lzcnt32(&flags, &res, w); + printf("lzcntl %08x -> %08x %04x\n", w, res, flags); + if (w == 0) break; + w = ((w >> 2) | (w >> 1)) + (w / 17); + } + + w = 0xFEDC1928; + while (1) { + UInt res; + UInt flags; + do_lzcnt16(&flags, &res, w); + printf("lzcntw %08x -> %08x %04x\n", w, res, flags); + if (w == 0) break; + w = ((w >> 2) | (w >> 1)) + (w / 17); + } + + return 0; +}