Add test cases for out-of-range argument handling for x87 instructions
FSIN, FCOS, FSINCOS and FPTAN. Mozilla bug 995564.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13921 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/none/tests/amd64/Makefile.am b/none/tests/amd64/Makefile.am
index 99a8d33..d7ec56a 100644
--- a/none/tests/amd64/Makefile.am
+++ b/none/tests/amd64/Makefile.am
@@ -80,6 +80,7 @@
slahf-amd64.stderr.exp slahf-amd64.stdout.exp \
slahf-amd64.vgtest \
tm1.vgtest tm1.stderr.exp tm1.stdout.exp \
+ x87trigOOR.vgtest x87trigOOR.stderr.exp x87trigOOR.stdout.exp \
xacq_xrel.stderr.exp xacq_xrel.stdout.exp xacq_xrel.vgtest \
xadd.stderr.exp xadd.stdout.exp xadd.vgtest
@@ -96,6 +97,7 @@
smc1 \
sbbmisc \
nibz_bennee_mmap \
+ x87trigOOR \
xadd
if BUILD_ADDR32_TESTS
check_PROGRAMS += asorep
diff --git a/none/tests/amd64/x87trigOOR.c b/none/tests/amd64/x87trigOOR.c
new file mode 120000
index 0000000..64f32e6
--- /dev/null
+++ b/none/tests/amd64/x87trigOOR.c
@@ -0,0 +1 @@
+../x86/x87trigOOR.c
\ No newline at end of file
diff --git a/none/tests/amd64/x87trigOOR.stderr.exp b/none/tests/amd64/x87trigOOR.stderr.exp
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/none/tests/amd64/x87trigOOR.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/amd64/x87trigOOR.stdout.exp b/none/tests/amd64/x87trigOOR.stdout.exp
new file mode 100644
index 0000000..46e889b
--- /dev/null
+++ b/none/tests/amd64/x87trigOOR.stdout.exp
@@ -0,0 +1,72 @@
+fsin 0.000000e+00 --> 0.000000e+00 3.141593e+00 0000
+fsin 1.230000e-01 --> 1.226901e-01 3.141593e+00 0000
+fsin -4.560000e-01 --> -4.403604e-01 3.141593e+00 0000
+fsin 3.700000e+01 --> -6.435381e-01 3.141593e+00 0000
+fsin -5.300000e+01 --> -3.959252e-01 3.141593e+00 0000
+
+fsin 8.301035e+18 --> -1.249775e-01 3.141593e+00 0000
+fsin 9.223363e+18 --> 2.344065e-01 3.141593e+00 0000
+fsin 9.223372e+18 --> 9.223372e+18 3.141593e+00 0400
+fsin 9.223381e+18 --> 9.223381e+18 3.141593e+00 0400
+fsin 1.014571e+19 --> 1.014571e+19 3.141593e+00 0400
+
+fsin -8.301035e+18 --> 1.249775e-01 3.141593e+00 0000
+fsin -9.223363e+18 --> -2.344065e-01 3.141593e+00 0000
+fsin -9.223372e+18 --> -9.223372e+18 3.141593e+00 0400
+fsin -9.223381e+18 --> -9.223381e+18 3.141593e+00 0400
+fsin -1.014571e+19 --> -1.014571e+19 3.141593e+00 0400
+
+fcos 0.000000e+00 --> 1.000000e+00 3.141593e+00 0000
+fcos 1.230000e-01 --> 9.924450e-01 3.141593e+00 0000
+fcos -4.560000e-01 --> 8.978211e-01 3.141593e+00 0000
+fcos 3.700000e+01 --> 7.654141e-01 3.141593e+00 0000
+fcos -5.300000e+01 --> -9.182828e-01 3.141593e+00 0000
+
+fcos 8.301035e+18 --> -9.921596e-01 3.141593e+00 0000
+fcos 9.223363e+18 --> 9.721387e-01 3.141593e+00 0000
+fcos 9.223372e+18 --> 9.223372e+18 3.141593e+00 0400
+fcos 9.223381e+18 --> 9.223381e+18 3.141593e+00 0400
+fcos 1.014571e+19 --> 1.014571e+19 3.141593e+00 0400
+
+fcos -8.301035e+18 --> -9.921596e-01 3.141593e+00 0000
+fcos -9.223363e+18 --> 9.721387e-01 3.141593e+00 0000
+fcos -9.223372e+18 --> -9.223372e+18 3.141593e+00 0400
+fcos -9.223381e+18 --> -9.223381e+18 3.141593e+00 0400
+fcos -1.014571e+19 --> -1.014571e+19 3.141593e+00 0400
+
+fsincos 0.000000e+00 --> 1.000000e+00 0.000000e+00 0000
+fsincos 1.230000e-01 --> 9.924450e-01 1.226901e-01 0000
+fsincos -4.560000e-01 --> 8.978211e-01 -4.403604e-01 0000
+fsincos 3.700000e+01 --> 7.654141e-01 -6.435381e-01 0000
+fsincos -5.300000e+01 --> -9.182828e-01 -3.959252e-01 0000
+
+fsincos 8.301035e+18 --> -9.921596e-01 -1.249775e-01 0000
+fsincos 9.223363e+18 --> 9.721387e-01 2.344065e-01 0000
+fsincos 9.223372e+18 --> 9.223372e+18 3.141593e+00 0400
+fsincos 9.223381e+18 --> 9.223381e+18 3.141593e+00 0400
+fsincos 1.014571e+19 --> 1.014571e+19 3.141593e+00 0400
+
+fsincos -8.301035e+18 --> -9.921596e-01 1.249775e-01 0000
+fsincos -9.223363e+18 --> 9.721387e-01 -2.344065e-01 0000
+fsincos -9.223372e+18 --> -9.223372e+18 3.141593e+00 0400
+fsincos -9.223381e+18 --> -9.223381e+18 3.141593e+00 0400
+fsincos -1.014571e+19 --> -1.014571e+19 3.141593e+00 0400
+
+fptan 0.000000e+00 --> 1.000000e+00 0.000000e+00 0000
+fptan 1.230000e-01 --> 1.000000e+00 1.236241e-01 0000
+fptan -4.560000e-01 --> 1.000000e+00 -4.904767e-01 0000
+fptan 3.700000e+01 --> 1.000000e+00 -8.407713e-01 0000
+fptan -5.300000e+01 --> 1.000000e+00 4.311582e-01 0000
+
+fptan 8.301035e+18 --> 1.000000e+00 1.259651e-01 0000
+fptan 9.223363e+18 --> 1.000000e+00 2.411246e-01 0000
+fptan 9.223372e+18 --> 9.223372e+18 3.141593e+00 0400
+fptan 9.223381e+18 --> 9.223381e+18 3.141593e+00 0400
+fptan 1.014571e+19 --> 1.014571e+19 3.141593e+00 0400
+
+fptan -8.301035e+18 --> 1.000000e+00 -1.259651e-01 0000
+fptan -9.223363e+18 --> 1.000000e+00 -2.411246e-01 0000
+fptan -9.223372e+18 --> -9.223372e+18 3.141593e+00 0400
+fptan -9.223381e+18 --> -9.223381e+18 3.141593e+00 0400
+fptan -1.014571e+19 --> -1.014571e+19 3.141593e+00 0400
+
diff --git a/none/tests/amd64/x87trigOOR.vgtest b/none/tests/amd64/x87trigOOR.vgtest
new file mode 100644
index 0000000..1ff5fd7
--- /dev/null
+++ b/none/tests/amd64/x87trigOOR.vgtest
@@ -0,0 +1 @@
+prog: x87trigOOR
diff --git a/none/tests/x86/Makefile.am b/none/tests/x86/Makefile.am
index 0ed86e5..bab84b6 100644
--- a/none/tests/x86/Makefile.am
+++ b/none/tests/x86/Makefile.am
@@ -61,6 +61,7 @@
ssse3_misaligned.stderr.exp ssse3_misaligned.stdout.exp \
ssse3_misaligned.vgtest ssse3_misaligned.c \
x86locked.vgtest x86locked.stdout.exp x86locked.stderr.exp \
+ x87trigOOR.vgtest x87trigOOR.stdout.exp x87trigOOR.stderr.exp \
yield.stderr.exp yield.stdout.exp yield.disabled \
xadd.stdout.exp xadd.stderr.exp xadd.vgtest
@@ -94,6 +95,7 @@
shift_ndep \
smc1 \
x86locked \
+ x87trigOOR \
yield \
xadd
if BUILD_SSSE3_TESTS
diff --git a/none/tests/x86/x87trigOOR.c b/none/tests/x86/x87trigOOR.c
new file mode 100644
index 0000000..0485559
--- /dev/null
+++ b/none/tests/x86/x87trigOOR.c
@@ -0,0 +1,159 @@
+
+/* Tests out of range handling for FSIN, FCOS, FSINCOS and FPTAN. Be
+ careful with the inline assembly -- this program is compiled as
+ both a 32-bit and 64-bit test. */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+typedef unsigned short int UShort;
+typedef unsigned int UInt;
+typedef double Double;
+typedef unsigned long long int ULong;
+
+typedef struct { Double arg; Double st0; Double st1; UShort fpusw; } Res;
+
+#define SHIFT_C3 14
+#define SHIFT_C2 10
+#define SHIFT_C1 9
+#define SHIFT_C0 8
+
+
+#define my_offsetof(type,memb) ((int)(unsigned long int)&((type*)0)->memb)
+
+void do_fsin ( /*OUT*/Res* r, double d )
+{
+ assert(my_offsetof(Res,arg) == 0);
+ assert(my_offsetof(Res,st0) == 8);
+ assert(my_offsetof(Res,st1) == 16);
+ assert(my_offsetof(Res,fpusw) == 24);
+ memset(r, 0, sizeof(*r));
+ r->arg = d;
+ __asm__ __volatile__(
+ "finit" "\n\t"
+ "fldpi" "\n\t"
+ "fldl 0(%0)" "\n\t" // .arg
+ "fsin" "\n\t"
+ "fstsw %%ax" "\n\t"
+ "fstpl 8(%0)" "\n\t" // .st0
+ "fstpl 16(%0)" "\n\t" // .st1
+ "movw %%ax, 24(%0)" "\n\t" // .fpusw
+ "finit" "\n"
+ : : "r"(r) : "eax","cc","memory"
+ );
+}
+
+void do_fcos ( /*OUT*/Res* r, double d )
+{
+ assert(my_offsetof(Res,arg) == 0);
+ assert(my_offsetof(Res,st0) == 8);
+ assert(my_offsetof(Res,st1) == 16);
+ assert(my_offsetof(Res,fpusw) == 24);
+ memset(r, 0, sizeof(*r));
+ r->arg = d;
+ __asm__ __volatile__(
+ "finit" "\n\t"
+ "fldpi" "\n\t"
+ "fldl 0(%0)" "\n\t" // .arg
+ "fcos" "\n\t"
+ "fstsw %%ax" "\n\t"
+ "fstpl 8(%0)" "\n\t" // .st0
+ "fstpl 16(%0)" "\n\t" // .st1
+ "movw %%ax, 24(%0)" "\n\t" // .fpusw
+ "finit" "\n"
+ : : "r"(r) : "eax","cc","memory"
+ );
+}
+
+void do_fsincos ( /*OUT*/Res* r, double d )
+{
+ assert(my_offsetof(Res,arg) == 0);
+ assert(my_offsetof(Res,st0) == 8);
+ assert(my_offsetof(Res,st1) == 16);
+ assert(my_offsetof(Res,fpusw) == 24);
+ memset(r, 0, sizeof(*r));
+ r->arg = d;
+ __asm__ __volatile__(
+ "finit" "\n\t"
+ "fldpi" "\n\t"
+ "fldl 0(%0)" "\n\t" // .arg
+ "fsincos" "\n\t"
+ "fstsw %%ax" "\n\t"
+ "fstpl 8(%0)" "\n\t" // .st0
+ "fstpl 16(%0)" "\n\t" // .st1
+ "movw %%ax, 24(%0)" "\n\t" // .fpusw
+ "finit" "\n"
+ : : "r"(r) : "eax","cc","memory"
+ );
+}
+
+void do_fptan ( /*OUT*/Res* r, double d )
+{
+ assert(my_offsetof(Res,arg) == 0);
+ assert(my_offsetof(Res,st0) == 8);
+ assert(my_offsetof(Res,st1) == 16);
+ assert(my_offsetof(Res,fpusw) == 24);
+ memset(r, 0, sizeof(*r));
+ r->arg = d;
+ __asm__ __volatile__(
+ "finit" "\n\t"
+ "fldpi" "\n\t"
+ "fldl 0(%0)" "\n\t" // .arg
+ "fptan" "\n\t"
+ "fstsw %%ax" "\n\t"
+ "fstpl 8(%0)" "\n\t" // .st0
+ "fstpl 16(%0)" "\n\t" // .st1
+ "movw %%ax, 24(%0)" "\n\t" // .fpusw
+ "finit" "\n"
+ : : "r"(r) : "eax","cc","memory"
+ );
+}
+
+
+void try ( char* name, void(*fn)(Res*,double), double d )
+{
+ Res r;
+ fn(&r, d);
+ // Mask out all except C2 (range)
+ r.fpusw &= (1 << SHIFT_C2);
+ printf("%s %16e --> %16e %16e %04x\n",
+ name, r.arg, r.st0, r.st1, (UInt)r.fpusw);
+}
+
+int main ( void )
+{
+ Double limit = 9223372036854775808.0; // 2^63
+
+ char* names[4] = { "fsin ", "fcos ", "fsincos", "fptan " };
+ void(*fns[4])(Res*,double) = { do_fsin, do_fcos, do_fsincos, do_fptan };
+
+ int i;
+ for (i = 0; i < 4; i++) {
+ char* name = names[i];
+ void (*fn)(Res*,double) = fns[i];
+
+ try( name, fn, 0.0 );
+ try( name, fn, 0.123 );
+ try( name, fn, -0.456 );
+ try( name, fn, 37.0 );
+ try( name, fn, -53.0 );
+ printf("\n");
+
+ try( name, fn, limit * 0.900000 );
+ try( name, fn, limit * 0.999999 );
+ try( name, fn, limit * 1.000000 );
+ try( name, fn, limit * 1.000001 );
+ try( name, fn, limit * 1.100000 );
+ printf("\n");
+
+ try( name, fn, -limit * 0.900000 );
+ try( name, fn, -limit * 0.999999 );
+ try( name, fn, -limit * 1.000000 );
+ try( name, fn, -limit * 1.000001 );
+ try( name, fn, -limit * 1.100000 );
+ printf("\n");
+ }
+
+ return 0;
+}
diff --git a/none/tests/x86/x87trigOOR.stderr.exp b/none/tests/x86/x87trigOOR.stderr.exp
new file mode 100644
index 0000000..139597f
--- /dev/null
+++ b/none/tests/x86/x87trigOOR.stderr.exp
@@ -0,0 +1,2 @@
+
+
diff --git a/none/tests/x86/x87trigOOR.stdout.exp b/none/tests/x86/x87trigOOR.stdout.exp
new file mode 100644
index 0000000..46e889b
--- /dev/null
+++ b/none/tests/x86/x87trigOOR.stdout.exp
@@ -0,0 +1,72 @@
+fsin 0.000000e+00 --> 0.000000e+00 3.141593e+00 0000
+fsin 1.230000e-01 --> 1.226901e-01 3.141593e+00 0000
+fsin -4.560000e-01 --> -4.403604e-01 3.141593e+00 0000
+fsin 3.700000e+01 --> -6.435381e-01 3.141593e+00 0000
+fsin -5.300000e+01 --> -3.959252e-01 3.141593e+00 0000
+
+fsin 8.301035e+18 --> -1.249775e-01 3.141593e+00 0000
+fsin 9.223363e+18 --> 2.344065e-01 3.141593e+00 0000
+fsin 9.223372e+18 --> 9.223372e+18 3.141593e+00 0400
+fsin 9.223381e+18 --> 9.223381e+18 3.141593e+00 0400
+fsin 1.014571e+19 --> 1.014571e+19 3.141593e+00 0400
+
+fsin -8.301035e+18 --> 1.249775e-01 3.141593e+00 0000
+fsin -9.223363e+18 --> -2.344065e-01 3.141593e+00 0000
+fsin -9.223372e+18 --> -9.223372e+18 3.141593e+00 0400
+fsin -9.223381e+18 --> -9.223381e+18 3.141593e+00 0400
+fsin -1.014571e+19 --> -1.014571e+19 3.141593e+00 0400
+
+fcos 0.000000e+00 --> 1.000000e+00 3.141593e+00 0000
+fcos 1.230000e-01 --> 9.924450e-01 3.141593e+00 0000
+fcos -4.560000e-01 --> 8.978211e-01 3.141593e+00 0000
+fcos 3.700000e+01 --> 7.654141e-01 3.141593e+00 0000
+fcos -5.300000e+01 --> -9.182828e-01 3.141593e+00 0000
+
+fcos 8.301035e+18 --> -9.921596e-01 3.141593e+00 0000
+fcos 9.223363e+18 --> 9.721387e-01 3.141593e+00 0000
+fcos 9.223372e+18 --> 9.223372e+18 3.141593e+00 0400
+fcos 9.223381e+18 --> 9.223381e+18 3.141593e+00 0400
+fcos 1.014571e+19 --> 1.014571e+19 3.141593e+00 0400
+
+fcos -8.301035e+18 --> -9.921596e-01 3.141593e+00 0000
+fcos -9.223363e+18 --> 9.721387e-01 3.141593e+00 0000
+fcos -9.223372e+18 --> -9.223372e+18 3.141593e+00 0400
+fcos -9.223381e+18 --> -9.223381e+18 3.141593e+00 0400
+fcos -1.014571e+19 --> -1.014571e+19 3.141593e+00 0400
+
+fsincos 0.000000e+00 --> 1.000000e+00 0.000000e+00 0000
+fsincos 1.230000e-01 --> 9.924450e-01 1.226901e-01 0000
+fsincos -4.560000e-01 --> 8.978211e-01 -4.403604e-01 0000
+fsincos 3.700000e+01 --> 7.654141e-01 -6.435381e-01 0000
+fsincos -5.300000e+01 --> -9.182828e-01 -3.959252e-01 0000
+
+fsincos 8.301035e+18 --> -9.921596e-01 -1.249775e-01 0000
+fsincos 9.223363e+18 --> 9.721387e-01 2.344065e-01 0000
+fsincos 9.223372e+18 --> 9.223372e+18 3.141593e+00 0400
+fsincos 9.223381e+18 --> 9.223381e+18 3.141593e+00 0400
+fsincos 1.014571e+19 --> 1.014571e+19 3.141593e+00 0400
+
+fsincos -8.301035e+18 --> -9.921596e-01 1.249775e-01 0000
+fsincos -9.223363e+18 --> 9.721387e-01 -2.344065e-01 0000
+fsincos -9.223372e+18 --> -9.223372e+18 3.141593e+00 0400
+fsincos -9.223381e+18 --> -9.223381e+18 3.141593e+00 0400
+fsincos -1.014571e+19 --> -1.014571e+19 3.141593e+00 0400
+
+fptan 0.000000e+00 --> 1.000000e+00 0.000000e+00 0000
+fptan 1.230000e-01 --> 1.000000e+00 1.236241e-01 0000
+fptan -4.560000e-01 --> 1.000000e+00 -4.904767e-01 0000
+fptan 3.700000e+01 --> 1.000000e+00 -8.407713e-01 0000
+fptan -5.300000e+01 --> 1.000000e+00 4.311582e-01 0000
+
+fptan 8.301035e+18 --> 1.000000e+00 1.259651e-01 0000
+fptan 9.223363e+18 --> 1.000000e+00 2.411246e-01 0000
+fptan 9.223372e+18 --> 9.223372e+18 3.141593e+00 0400
+fptan 9.223381e+18 --> 9.223381e+18 3.141593e+00 0400
+fptan 1.014571e+19 --> 1.014571e+19 3.141593e+00 0400
+
+fptan -8.301035e+18 --> 1.000000e+00 -1.259651e-01 0000
+fptan -9.223363e+18 --> 1.000000e+00 -2.411246e-01 0000
+fptan -9.223372e+18 --> -9.223372e+18 3.141593e+00 0400
+fptan -9.223381e+18 --> -9.223381e+18 3.141593e+00 0400
+fptan -1.014571e+19 --> -1.014571e+19 3.141593e+00 0400
+
diff --git a/none/tests/x86/x87trigOOR.vgtest b/none/tests/x86/x87trigOOR.vgtest
new file mode 100644
index 0000000..1ff5fd7
--- /dev/null
+++ b/none/tests/x86/x87trigOOR.vgtest
@@ -0,0 +1 @@
+prog: x87trigOOR