]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Yet more x86 instruction tests, mostly aimed at wierd/transcendental
authorJulian Seward <jseward@acm.org>
Sat, 4 Feb 2006 15:26:11 +0000 (15:26 +0000)
committerJulian Seward <jseward@acm.org>
Sat, 4 Feb 2006 15:26:11 +0000 (15:26 +0000)
x87 insns.

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

memcheck/tests/x86/Makefile.am
memcheck/tests/x86/fprem.c [new file with mode: 0644]
memcheck/tests/x86/fprem.stderr.exp [new file with mode: 0644]
memcheck/tests/x86/fprem.stdout.exp [new file with mode: 0644]
memcheck/tests/x86/fprem.vgtest [new file with mode: 0644]
memcheck/tests/x86/more_x86_fp.c [new file with mode: 0644]
memcheck/tests/x86/more_x86_fp.stderr.exp [new file with mode: 0644]
memcheck/tests/x86/more_x86_fp.stdout.exp [new file with mode: 0644]
memcheck/tests/x86/more_x86_fp.vgtest [new file with mode: 0644]

index dbbce96dc102a76e3b3a34cc01492c219ac36a61..9564b005c94861a9529fa4474a90f5abc5fc3ece 100644 (file)
@@ -19,11 +19,14 @@ EXTRA_DIST = $(noinst_SCRIPTS) \
        scalar_vfork.stderr.exp scalar_vfork.vgtest \
        sse1_memory.stderr.exp sse1_memory.stdout.exp sse1_memory.vgtest \
        sse2_memory.stderr.exp sse2_memory.stdout.exp sse2_memory.vgtest \
-       tronical.stderr.exp tronical.vgtest
+       tronical.stderr.exp tronical.vgtest \
+       more_x86_fp.stderr.exp more_x86_fp.stdout.exp more_x86_fp.vgtest \
+       fprem.stderr.exp fprem.stdout.exp fprem.vgtest
 
 check_PROGRAMS = \
        scalar_exit_group scalar_fork scalar_supp scalar_vfork \
-       fpeflags pushfpopf scalar sse_memory tronical
+       fpeflags pushfpopf scalar sse_memory tronical \
+       more_x86_fp fprem
 
 AM_CPPFLAGS  = -I$(top_srcdir)/include
 AM_CFLAGS    = $(WERROR) @FLAG_M32@ -Winline -Wall -Wshadow -g \
@@ -36,3 +39,4 @@ fpeflags_CFLAGS               = $(AM_CFLAGS) -march=i686
 pushfpopf_SOURCES      = pushfpopf_c.c pushfpopf_s.s
 tronical_SOURCES       = tronical.S
 
+more_x86_fp_LDADD      = -lm
diff --git a/memcheck/tests/x86/fprem.c b/memcheck/tests/x86/fprem.c
new file mode 100644 (file)
index 0000000..d48b49a
--- /dev/null
@@ -0,0 +1,42 @@
+
+/* Marginally test fprem/fprem1; these are hard to check otherwise */
+
+#include <stdio.h>
+
+double do_fprem ( void )
+{
+  double res;
+  __asm__ __volatile__(
+    "ffree %%st(0)\n\t"
+    "ffree %%st(1)\n\t"
+    "fldpi\n\t"
+    "fldln2\n\t"
+    "fprem\n\t"
+    "fstpl 0(%0)"
+    : : "r"(&res)  
+  );
+  return res;
+}
+
+double do_fprem1 ( void )
+{
+  double res;
+  __asm__ __volatile__(
+    "ffree %%st(0)\n\t"
+    "ffree %%st(1)\n\t"
+    "fldpi\n\t"
+    "fldln2\n\t"
+    "fprem1\n\t"
+    "fstpl 0(%0)"
+    : : "r"(&res)  
+  );
+  return res;
+}
+
+int main ( void )
+{
+  __asm__ __volatile__("finit");
+  printf("fprem  %f\n", do_fprem());
+  printf("fprem1 %f\n", do_fprem1());
+  return 0;
+}
diff --git a/memcheck/tests/x86/fprem.stderr.exp b/memcheck/tests/x86/fprem.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/x86/fprem.stdout.exp b/memcheck/tests/x86/fprem.stdout.exp
new file mode 100644 (file)
index 0000000..5ba92bf
--- /dev/null
@@ -0,0 +1,2 @@
+fprem  0.693147
+fprem1 0.693147
diff --git a/memcheck/tests/x86/fprem.vgtest b/memcheck/tests/x86/fprem.vgtest
new file mode 100644 (file)
index 0000000..94a0a0d
--- /dev/null
@@ -0,0 +1,2 @@
+vgopts: -q
+prog: fprem
diff --git a/memcheck/tests/x86/more_x86_fp.c b/memcheck/tests/x86/more_x86_fp.c
new file mode 100644 (file)
index 0000000..fbbd957
--- /dev/null
@@ -0,0 +1,263 @@
+
+/* Derived from: */
+
+/*
+ *  x86 CPU test
+ *
+ *  Copyright (c) 2003 Fabrice Bellard
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <math.h>
+
+/**********************************************/
+
+void test_fops(double a, double b)
+{
+    printf("a=%f b=%f a+b=%f\n", a, b, a + b);
+    printf("a=%f b=%f a-b=%f\n", a, b, a - b);
+    printf("a=%f b=%f a*b=%f\n", a, b, a * b);
+    printf("a=%f b=%f a/b=%f\n", a, b, a / b);
+    printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
+    printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
+    printf("a=%f sin(a)=%f\n", a, sin(a));
+    printf("a=%f cos(a)=%f\n", a, cos(a));
+    printf("a=%f tan(a)=%f\n", a, tan(a));
+    printf("a=%f log(a)=%f\n", a, log(a));
+    printf("a=%f exp(a)=%f\n", a, exp(a));
+    printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
+    /* just to test some op combining */
+    printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
+    printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
+    printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
+}
+#define CC_C    0x0001
+#define CC_P    0x0004
+#define CC_A    0x0010
+#define CC_Z    0x0040
+#define CC_S    0x0080
+#define CC_O    0x0800
+
+
+void test_fcmp(double a, double b)
+{
+    printf("(%f<%f)=%d\n",
+           a, b, a < b);
+    printf("(%f<=%f)=%d\n",
+           a, b, a <= b);
+    printf("(%f==%f)=%d\n",
+           a, b, a == b);
+    printf("(%f>%f)=%d\n",
+           a, b, a > b);
+    printf("(%f<=%f)=%d\n",
+           a, b, a >= b);
+    {
+        unsigned int eflags;
+        /* test f(u)comi instruction */
+        asm("fcomi %2, %1\n"
+            "pushf\n"
+            "pop %0\n"
+            : "=r" (eflags)
+            : "t" (a), "u" (b));
+        printf("fcomi(%f %f)=%08x\n", a, b, eflags & (CC_Z | CC_P | CC_C));
+    }
+}
+
+void test_fcvt(double a)
+{
+    float fa;
+    long double la;
+    int16_t fpuc;
+    int i;
+    int64_t lla;
+    int ia;
+    int16_t wa;
+    double ra;
+
+    fa = a;
+    la = a;
+    printf("(float)%f = %f\n", a, fa);
+    printf("(long double)%f = %Lf\n", a, la);
+    printf("a=%016Lx\n", *(long long *)&a);
+    printf("la=%016Lx %04x\n", *(long long *)&la, 
+           *(unsigned short *)((char *)(&la) + 8));
+
+    /* test all roundings */
+    asm volatile ("fstcw %0" : "=m" (fpuc));
+    for(i=0;i<4;i++) {
+      int16_t tmp = (fpuc & ~0x0c00) | (i << 10);
+        asm volatile ("fldcw %0" : : "m" (tmp));
+        asm volatile ("fist %0" : "=m" (wa) : "t" (a));
+        asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
+        asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
+        asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
+        asm volatile ("fldcw %0" : : "m" (fpuc));
+        printf("(short)a = %d\n", wa);
+        printf("(int)a = %d\n", ia);
+        printf("(int64_t)a = %Ld\n", lla);
+        printf("rint(a) = %f\n", ra);
+    }
+}
+
+#define TEST(N) \
+    asm("fld" #N : "=t" (a)); \
+    printf("fld" #N "= %f\n", a);
+
+void test_fconst(void)
+{
+    double a;
+    TEST(1);
+    TEST(l2t);
+    TEST(l2e);
+    TEST(pi);
+    TEST(lg2);
+    TEST(ln2);
+    TEST(z);
+}
+
+void test_fbcd(double a)
+{
+    unsigned short bcd[5];
+    double b;
+
+    asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
+    asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
+    printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n", 
+           a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
+}
+
+#define TEST_ENV(env, save, restore)\
+{\
+    memset((env), 0xaa, sizeof(*(env)));\
+    for(i=0;i<5;i++)\
+        asm volatile ("fldl %0" : : "m" (dtab[i]));\
+    asm(save " %0\n" : : "m" (*(env)));\
+    asm(restore " %0\n": : "m" (*(env)));\
+    for(i=0;i<5;i++)\
+        asm volatile ("fstpl %0" : "=m" (rtab[i]));\
+    for(i=0;i<5;i++)\
+        printf("res[%d]=%f\n", i, rtab[i]);\
+    printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
+           (env)->fpuc,\
+           (env)->fpus & 0xff00,\
+           (env)->fptag);\
+}
+
+void test_fenv(void)
+{
+    struct __attribute__((packed)) {
+        uint16_t fpuc;
+        uint16_t dummy1;
+        uint16_t fpus;
+        uint16_t dummy2;
+        uint16_t fptag;
+        uint16_t dummy3;
+        uint32_t ignored[4];
+        long double fpregs[8];
+    } float_env32;
+    struct __attribute__((packed)) {
+        uint16_t fpuc;
+        uint16_t fpus;
+        uint16_t fptag;
+        uint16_t ignored[4];
+        long double fpregs[8];
+    } float_env16;
+    double dtab[8];
+    double rtab[8];
+    int i;
+
+    for(i=0;i<8;i++)
+        dtab[i] = i + 1;
+
+    TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
+    TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
+    TEST_ENV(&float_env32, "fnstenv", "fldenv");
+    TEST_ENV(&float_env32, "fnsave", "frstor");
+
+    /* test for ffree */
+    for(i=0;i<5;i++)
+        asm volatile ("fldl %0" : : "m" (dtab[i]));
+    asm volatile("ffree %st(2)");
+    asm volatile ("fnstenv %0\n" : : "m" (float_env32));
+    asm volatile ("fninit");
+    printf("fptag=%04x\n", float_env32.fptag);
+}
+
+
+#define TEST_FCMOV(a, b, eflags, CC)\
+{\
+    double res;\
+    asm("push %3\n"\
+        "popf\n"\
+        "fcmov" CC " %2, %0\n"\
+        : "=t" (res)\
+        : "0" (a), "u" (b), "g" (eflags));\
+    printf("fcmov%s eflags=0x%04x-> %f\n", \
+           CC, eflags, res);\
+}
+
+void test_fcmov(void)
+{
+    double a, b;
+    int eflags, i;
+
+    a = 1.0;
+    b = 2.0;
+    for(i = 0; i < 4; i++) {
+        eflags = 0;
+        if (i & 1)
+            eflags |= CC_C;
+        if (i & 2)
+            eflags |= CC_Z;
+        TEST_FCMOV(a, b, eflags, "b");
+        TEST_FCMOV(a, b, eflags, "e");
+        TEST_FCMOV(a, b, eflags, "be");
+        TEST_FCMOV(a, b, eflags, "nb");
+        TEST_FCMOV(a, b, eflags, "ne");
+        TEST_FCMOV(a, b, eflags, "nbe");
+    }
+    TEST_FCMOV(a, b, 0, "u");
+    TEST_FCMOV(a, b, CC_P, "u");
+    TEST_FCMOV(a, b, 0, "nu");
+    TEST_FCMOV(a, b, CC_P, "nu");
+}
+
+void test_floats(void)
+{
+    test_fops(2, 3);
+    test_fops(1.4, -5);
+    test_fcmp(2, -1);
+    test_fcmp(2, 2);
+    test_fcmp(2, 3);
+    test_fcvt(0.5);
+    test_fcvt(-0.5);
+    test_fcvt(1.0/7.0);
+    test_fcvt(-1.0/9.0);
+    test_fcvt(32768);
+    test_fcvt(-1e20);
+    test_fconst();
+}
+
+int main ( void )
+{
+  test_floats();
+  return 0;
+}
diff --git a/memcheck/tests/x86/more_x86_fp.stderr.exp b/memcheck/tests/x86/more_x86_fp.stderr.exp
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/memcheck/tests/x86/more_x86_fp.stdout.exp b/memcheck/tests/x86/more_x86_fp.stdout.exp
new file mode 100644 (file)
index 0000000..4810929
--- /dev/null
@@ -0,0 +1,175 @@
+a=2.000000 b=3.000000 a+b=5.000000
+a=2.000000 b=3.000000 a-b=-1.000000
+a=2.000000 b=3.000000 a*b=6.000000
+a=2.000000 b=3.000000 a/b=0.666667
+a=2.000000 b=3.000000 fmod(a, b)=2.000000
+a=2.000000 sqrt(a)=1.414214
+a=2.000000 sin(a)=0.909297
+a=2.000000 cos(a)=-0.416147
+a=2.000000 tan(a)=-2.185040
+a=2.000000 log(a)=0.693147
+a=2.000000 exp(a)=7.389056
+a=2.000000 b=3.000000 atan2(a, b)=0.588003
+a=2.000000 asin(sin(a))=1.141593
+a=2.000000 acos(cos(a))=2.000000
+a=2.000000 atan(tan(a))=-1.141593
+a=1.400000 b=-5.000000 a+b=-3.600000
+a=1.400000 b=-5.000000 a-b=6.400000
+a=1.400000 b=-5.000000 a*b=-7.000000
+a=1.400000 b=-5.000000 a/b=-0.280000
+a=1.400000 b=-5.000000 fmod(a, b)=1.400000
+a=1.400000 sqrt(a)=1.183216
+a=1.400000 sin(a)=0.985450
+a=1.400000 cos(a)=0.169967
+a=1.400000 tan(a)=5.797884
+a=1.400000 log(a)=0.336472
+a=1.400000 exp(a)=4.055200
+a=1.400000 b=-5.000000 atan2(a, b)=2.868584
+a=1.400000 asin(sin(a))=1.400000
+a=1.400000 acos(cos(a))=1.400000
+a=1.400000 atan(tan(a))=1.400000
+(2.000000<-1.000000)=0
+(2.000000<=-1.000000)=0
+(2.000000==-1.000000)=0
+(2.000000>-1.000000)=1
+(2.000000<=-1.000000)=1
+fcomi(2.000000 -1.000000)=00000000
+(2.000000<2.000000)=0
+(2.000000<=2.000000)=1
+(2.000000==2.000000)=1
+(2.000000>2.000000)=0
+(2.000000<=2.000000)=1
+fcomi(2.000000 2.000000)=00000040
+(2.000000<3.000000)=1
+(2.000000<=3.000000)=1
+(2.000000==3.000000)=0
+(2.000000>3.000000)=0
+(2.000000<=3.000000)=0
+fcomi(2.000000 3.000000)=00000001
+(float)0.500000 = 0.500000
+(long double)0.500000 = 0.500000
+a=3fe0000000000000
+la=8000000000000000 3ffe
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = 0.000000
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = 0.000000
+(short)a = 1
+(int)a = 1
+(int64_t)a = 1
+rint(a) = 1.000000
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = 0.000000
+(float)-0.500000 = -0.500000
+(long double)-0.500000 = -0.500000
+a=bfe0000000000000
+la=8000000000000000 bffe
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = -0.000000
+(short)a = -1
+(int)a = -1
+(int64_t)a = -1
+rint(a) = -1.000000
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = -0.000000
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = -0.000000
+(float)0.142857 = 0.142857
+(long double)0.142857 = 0.142857
+a=3fc2492492492492
+la=9249249249249000 3ffc
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = 0.000000
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = 0.000000
+(short)a = 1
+(int)a = 1
+(int64_t)a = 1
+rint(a) = 1.000000
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = 0.000000
+(float)-0.111111 = -0.111111
+(long double)-0.111111 = -0.111111
+a=bfbc71c71c71c71c
+la=e38e38e38e38e000 bffb
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = -0.000000
+(short)a = -1
+(int)a = -1
+(int64_t)a = -1
+rint(a) = -1.000000
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = -0.000000
+(short)a = 0
+(int)a = 0
+(int64_t)a = 0
+rint(a) = -0.000000
+(float)32768.000000 = 32768.000000
+(long double)32768.000000 = 32768.000000
+a=40e0000000000000
+la=8000000000000000 400e
+(short)a = -32768
+(int)a = 32768
+(int64_t)a = 32768
+rint(a) = 32768.000000
+(short)a = -32768
+(int)a = 32768
+(int64_t)a = 32768
+rint(a) = 32768.000000
+(short)a = -32768
+(int)a = 32768
+(int64_t)a = 32768
+rint(a) = 32768.000000
+(short)a = -32768
+(int)a = 32768
+(int64_t)a = 32768
+rint(a) = 32768.000000
+(float)-100000000000000000000.000000 = -100000002004087734272.000000
+(long double)-100000000000000000000.000000 = -100000000000000000000.000000
+a=c415af1d78b58c40
+la=ad78ebc5ac620000 c041
+(short)a = -32768
+(int)a = -2147483648
+(int64_t)a = -9223372036854775808
+rint(a) = -100000000000000000000.000000
+(short)a = -32768
+(int)a = -2147483648
+(int64_t)a = -9223372036854775808
+rint(a) = -100000000000000000000.000000
+(short)a = -32768
+(int)a = -2147483648
+(int64_t)a = -9223372036854775808
+rint(a) = -100000000000000000000.000000
+(short)a = -32768
+(int)a = -2147483648
+(int64_t)a = -9223372036854775808
+rint(a) = -100000000000000000000.000000
+fld1= 1.000000
+fldl2t= 3.321928
+fldl2e= 1.442695
+fldpi= 3.141593
+fldlg2= 0.301030
+fldln2= 0.693147
+fldz= 0.000000
diff --git a/memcheck/tests/x86/more_x86_fp.vgtest b/memcheck/tests/x86/more_x86_fp.vgtest
new file mode 100644 (file)
index 0000000..9cf90f3
--- /dev/null
@@ -0,0 +1,2 @@
+vgopts: -q
+prog: more_x86_fp