From: Julian Seward Date: Wed, 11 Apr 2012 07:12:32 +0000 (+0000) Subject: Add a test re conversions of QNaNs between 64- and 80-bit FP X-Git-Tag: svn/VALGRIND_3_8_0~363 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cfd1bdd20b328c9e7eed3232853094fd4e8ee090;p=thirdparty%2Fvalgrind.git Add a test re conversions of QNaNs between 64- and 80-bit FP formats. Related to Mozilla bug #738117. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12497 --- diff --git a/none/tests/amd64/Makefile.am b/none/tests/amd64/Makefile.am index ac69bff637..03a4b393b8 100644 --- a/none/tests/amd64/Makefile.am +++ b/none/tests/amd64/Makefile.am @@ -51,6 +51,7 @@ EXTRA_DIST = \ looper.stderr.exp looper.stdout.exp looper.vgtest \ loopnel.stderr.exp loopnel.stdout.exp loopnel.vgtest \ lzcnt64.stderr.exp lzcnt64.stdout.exp lzcnt64.vgtest \ + nan80and64.stderr.exp nan80and64.stdout.exp nan80and64.vgtest \ nibz_bennee_mmap.stderr.exp nibz_bennee_mmap.stdout.exp \ nibz_bennee_mmap.vgtest \ pcmpstr64.stderr.exp pcmpstr64.stdout.exp \ @@ -83,6 +84,7 @@ check_PROGRAMS = \ clc \ cmpxchg \ $(INSN_TESTS) \ + nan80and64 \ rcl-amd64 \ redundantRexW \ smc1 \ diff --git a/none/tests/amd64/nan80and64.c b/none/tests/amd64/nan80and64.c new file mode 100644 index 0000000000..6fa46c3d15 --- /dev/null +++ b/none/tests/amd64/nan80and64.c @@ -0,0 +1,140 @@ + +/* Test conversions between 64- and 80- bit quiet NaNs. Uses + "canonical forms" for qNaNs. It also tests sNaNs but it's not + clear what the canonical form of them should be, so the results are + pretty much irrelevant. Failure to do this right is the cause + of https://bugzilla.mozilla.org/show_bug.cgi?id=738117 +*/ + +#include +#include +#include +#include + +typedef unsigned char UChar; + + +void do_64_to_80 ( UChar* dst, UChar* src ) +{ + __asm__ __volatile__( + "fldl (%0); fstpt (%1)" + : : "r"(src), "r"(dst) : "memory" + ); +} + +void do_80_to_64 ( UChar* dst, UChar* src ) +{ + __asm__ __volatile__( + "fldt (%0); fstpl (%1)" + : : "r"(src), "r"(dst) : "memory" + ); +} + +void print80 ( char* s, UChar* v ) +{ + int i; + printf("%s", s); + for (i = 9; i >= 0; i--) + printf("%02x", (unsigned int)v[i]); + printf("\n"); +} + +void print64 ( char* s, UChar* v ) +{ + int i; + printf("%s", s); + for (i = 7; i >= 0; i--) { + printf("%02x", (unsigned int)v[i]); + } + printf("\n"); +} + +#if 0 +void gen_qnan_64 ( UChar* dst ) +{ + +} +#endif + +#define SWAPC(_xx,_yy) { UChar tmp = _xx; _xx = _yy; _yy = tmp; } + +static void rev64 ( UChar* f64 ) +{ + SWAPC( f64[0], f64[7] ); + SWAPC( f64[1], f64[6] ); + SWAPC( f64[2], f64[5] ); + SWAPC( f64[3], f64[4] ); +} + +static void rev80 ( UChar* f80 ) +{ + SWAPC( f80[0], f80[9] ); + SWAPC( f80[1], f80[8] ); + SWAPC( f80[2], f80[7] ); + SWAPC( f80[3], f80[6] ); + SWAPC( f80[4], f80[5] ); +} + +#undef SWAPC + +int main ( void ) +{ + UChar ref_qnan64[8] + = { 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + UChar ref_snan64[8] + = { 0x7f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + UChar ref_qnan80[10] + = { 0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + UChar ref_snan80[10] + = { 0x7f, 0xff, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + rev64( ref_qnan64 ); + rev64( ref_snan64 ); + rev80( ref_qnan80 ); + rev80( ref_snan80 ); + + UChar* res = malloc(10); +#define ZAP memset(res, 0x55, 10) + + + int pass; + for (pass = 1; pass <= 2; pass++) { + + ZAP; do_64_to_80( res, ref_qnan64 ); + print64( "src = qnan64: ", ref_qnan64 ); + print80( "dst = qnan80: ", res ); + printf("\n"); + + ZAP; do_64_to_80( res, ref_snan64 ); + print64( "src = snan64: ", ref_snan64 ); + print80( "dst = snan80: ", res ); + printf("\n"); + + ZAP; do_80_to_64( res, ref_qnan80 ); + print80( "src = qnan80: ", ref_qnan80 ); + print64( "dst = qnan64: ", res ); + printf("\n"); + + ZAP; do_80_to_64( res, ref_snan80 ); + print80( "src = snan80: ", ref_snan80 ); + print64( "dst = snan64: ", res ); + printf("\n"); + + /* now make all the reference inputs negative and do it again */ + + ref_qnan64[7] ^= 0x80; + ref_snan64[7] ^= 0x80; + + ref_qnan80[9] ^= 0x80; + ref_snan80[9] ^= 0x80; + + } + +#undef ZAP + + free(res); + return 0; +} diff --git a/none/tests/amd64/nan80and64.stderr.exp b/none/tests/amd64/nan80and64.stderr.exp new file mode 100644 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/amd64/nan80and64.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/amd64/nan80and64.stdout.exp b/none/tests/amd64/nan80and64.stdout.exp new file mode 100644 index 0000000000..aa108070ef --- /dev/null +++ b/none/tests/amd64/nan80and64.stdout.exp @@ -0,0 +1,24 @@ +src = qnan64: 7ff8000000000000 +dst = qnan80: 7fffc000000000000000 + +src = snan64: 7ff4000000000000 +dst = snan80: 7fffbfffffffffffffff + +src = qnan80: 7fffc000000000000000 +dst = qnan64: 7ff8000000000000 + +src = snan80: 7fffa000000000000000 +dst = snan64: 7ff7ffffffffffff + +src = qnan64: fff8000000000000 +dst = qnan80: ffffc000000000000000 + +src = snan64: fff4000000000000 +dst = snan80: ffffbfffffffffffffff + +src = qnan80: ffffc000000000000000 +dst = qnan64: fff8000000000000 + +src = snan80: ffffa000000000000000 +dst = snan64: fff7ffffffffffff + diff --git a/none/tests/amd64/nan80and64.vgtest b/none/tests/amd64/nan80and64.vgtest new file mode 100644 index 0000000000..8047e20033 --- /dev/null +++ b/none/tests/amd64/nan80and64.vgtest @@ -0,0 +1 @@ +prog: nan80and64