b8e61a047f6ba1bcc566cfeef3cfed219467ad5d
[sfrench/cifs-2.6.git] / tools / testing / selftests / x86 / test_FISTTP.c
1 #undef _GNU_SOURCE
2 #define _GNU_SOURCE 1
3 #undef __USE_GNU
4 #define __USE_GNU 1
5 #include <unistd.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <signal.h>
10 #include <sys/types.h>
11 #include <sys/select.h>
12 #include <sys/time.h>
13 #include <sys/wait.h>
14 #include <fenv.h>
15
16 unsigned long long res64 = -1;
17 unsigned int res32 = -1;
18 unsigned short res16 = -1;
19
20 int test(void)
21 {
22         int ex;
23
24         feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
25         asm volatile ("\n"
26         "       fld1""\n"
27         "       fisttp  res16""\n"
28         "       fld1""\n"
29         "       fisttpl res32""\n"
30         "       fld1""\n"
31         "       fisttpll res64""\n"
32         : : : "memory"
33         );
34         if (res16 != 1 || res32 != 1 || res64 != 1) {
35                 printf("[BAD]\tfisttp 1\n");
36                 return 1;
37         }
38         ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
39         if (ex != 0) {
40                 printf("[BAD]\tfisttp 1: wrong exception state\n");
41                 return 1;
42         }
43
44         feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
45         asm volatile ("\n"
46         "       fldpi""\n"
47         "       fisttp  res16""\n"
48         "       fldpi""\n"
49         "       fisttpl res32""\n"
50         "       fldpi""\n"
51         "       fisttpll res64""\n"
52         : : : "memory"
53         );
54         if (res16 != 3 || res32 != 3 || res64 != 3) {
55                 printf("[BAD]\tfisttp pi\n");
56                 return 1;
57         }
58         ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
59         if (ex != FE_INEXACT) {
60                 printf("[BAD]\tfisttp pi: wrong exception state\n");
61                 return 1;
62         }
63
64         feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
65         asm volatile ("\n"
66         "       fldpi""\n"
67         "       fchs""\n"
68         "       fisttp  res16""\n"
69         "       fldpi""\n"
70         "       fchs""\n"
71         "       fisttpl res32""\n"
72         "       fldpi""\n"
73         "       fchs""\n"
74         "       fisttpll res64""\n"
75         : : : "memory"
76         );
77         if (res16 != 0xfffd || res32 != 0xfffffffd || res64 != 0xfffffffffffffffdULL) {
78                 printf("[BAD]\tfisttp -pi\n");
79                 return 1;
80         }
81         ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
82         if (ex != FE_INEXACT) {
83                 printf("[BAD]\tfisttp -pi: wrong exception state\n");
84                 return 1;
85         }
86
87         feclearexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
88         asm volatile ("\n"
89         "       fldln2""\n"
90         "       fisttp  res16""\n"
91         "       fldln2""\n"
92         "       fisttpl res32""\n"
93         "       fldln2""\n"
94         "       fisttpll res64""\n"
95         : : : "memory"
96         );
97         /* Test truncation to zero (round-to-nearest would give 1 here) */
98         if (res16 != 0 || res32 != 0 || res64 != 0) {
99                 printf("[BAD]\tfisttp ln2\n");
100                 return 1;
101         }
102         ex = fetestexcept(FE_DIVBYZERO|FE_INEXACT|FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW);
103         if (ex != FE_INEXACT) {
104                 printf("[BAD]\tfisttp ln2: wrong exception state\n");
105                 return 1;
106         }
107
108         return 0;
109 }
110
111 void sighandler(int sig)
112 {
113         printf("[FAIL]\tGot signal %d, exiting\n", sig);
114         exit(1);
115 }
116
117 int main(int argc, char **argv, char **envp)
118 {
119         int err = 0;
120
121         /* SIGILL triggers on 32-bit kernels w/o fisttp emulation
122          * when run with "no387 nofxsr". Other signals are caught
123          * just in case.
124          */
125         signal(SIGILL, sighandler);
126         signal(SIGFPE, sighandler);
127         signal(SIGSEGV, sighandler);
128
129         printf("[RUN]\tTesting fisttp instructions\n");
130         err |= test();
131         if (!err)
132                 printf("[OK]\tfisttp\n");
133         else
134                 printf("[FAIL]\tfisttp errors: %d\n", err);
135
136         return err;
137 }