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
16unsigned long long res64 = -1;
17unsigned int res32 = -1;
18unsigned short res16 = -1;
19
20int 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
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
111void sighandler(int sig)
112{
113 printf("[FAIL]\tGot signal %d, exiting\n", sig);
114 exit(1);
115}
116
117int main(int argc, char **argv, char **envp)
118{
119 int err = 0;
120
121
122
123
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}
138