]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add a test re conversions of QNaNs between 64- and 80-bit FP
authorJulian Seward <jseward@acm.org>
Wed, 11 Apr 2012 07:12:32 +0000 (07:12 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 11 Apr 2012 07:12:32 +0000 (07:12 +0000)
formats.  Related to Mozilla bug #738117.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12497

none/tests/amd64/Makefile.am
none/tests/amd64/nan80and64.c [new file with mode: 0644]
none/tests/amd64/nan80and64.stderr.exp [new file with mode: 0644]
none/tests/amd64/nan80and64.stdout.exp [new file with mode: 0644]
none/tests/amd64/nan80and64.vgtest [new file with mode: 0644]

index ac69bff637f8450e3ecbf570d9607820981e770e..03a4b393b882181cbdb41107f4138b8f6513d727 100644 (file)
@@ -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 (file)
index 0000000..6fa46c3
--- /dev/null
@@ -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 <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+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 (file)
index 0000000..139597f
--- /dev/null
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/amd64/nan80and64.stdout.exp b/none/tests/amd64/nan80and64.stdout.exp
new file mode 100644 (file)
index 0000000..aa10807
--- /dev/null
@@ -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 (file)
index 0000000..8047e20
--- /dev/null
@@ -0,0 +1 @@
+prog: nan80and64