Add missing zstd.h to coregrind Makefile.am noinst_HEADERS
[valgrind.git] / memcheck / tests / amd64 / more_x87_fp.c
blobb809b664f54e24933174735c6dbd81201d45e0c4
2 /* On amd64, to exercise x87, compile with
3 gcc4 -ffast-math -mfpmath=387 -mfancy-math-387
5 gcc4 really does generate all the sin cos tan stuff as
6 x87 insns inline. gcc 3.3 doesn't, which makes the test
7 pretty useless, but it should still pass. To be on the safe
8 side we need to link with -lm to handle the gcc 3.3 behaviour.
9 */
11 /* Derived from: */
14 * x86 CPU test
16 * Copyright (c) 2003 Fabrice Bellard
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, see <http://www.gnu.org/licenses/>.
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <inttypes.h>
37 #include <math.h>
39 /**********************************************/
41 void test_fops(double a, double b)
43 printf("a=%f b=%f a+b=%f\n", a, b, a + b);
44 printf("a=%f b=%f a-b=%f\n", a, b, a - b);
45 printf("a=%f b=%f a*b=%f\n", a, b, a * b);
46 printf("a=%f b=%f a/b=%f\n", a, b, a / b);
47 // requires fprem/fprem1 -- not done
48 //printf("a=%f b=%f fmod(a, b)=%f\n", a, b, fmod(a, b));
49 printf("a=%f sqrt(a)=%f\n", a, sqrt(a));
50 printf("a=%f sin(a)=%f\n", a, sin(a));
51 printf("a=%f cos(a)=%f\n", a, cos(a));
52 printf("a=%f tan(a)=%f\n", a, tan(a));
53 printf("a=%f log(a)=%f\n", a, log(a));
54 printf("a=%f exp(a)=%f\n", a, exp(a));
55 printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
56 /* just to test some op combining */
57 printf("a=%f asin(sin(a))=%f\n", a, asin(sin(a)));
58 printf("a=%f acos(cos(a))=%f\n", a, acos(cos(a)));
59 printf("a=%f atan(tan(a))=%f\n", a, atan(tan(a)));
61 #define CC_C 0x0001
62 #define CC_P 0x0004
63 #define CC_A 0x0010
64 #define CC_Z 0x0040
65 #define CC_S 0x0080
66 #define CC_O 0x0800
69 void test_fcmp(double a, double b)
71 printf("(%f<%f)=%d\n",
72 a, b, a < b);
73 printf("(%f<=%f)=%d\n",
74 a, b, a <= b);
75 printf("(%f==%f)=%d\n",
76 a, b, a == b);
77 printf("(%f>%f)=%d\n",
78 a, b, a > b);
79 printf("(%f<=%f)=%d\n",
80 a, b, a >= b);
82 unsigned long long int eflags;
83 /* test f(u)comi instruction */
84 asm("fcomi %2, %1\n"
85 "pushfq\n"
86 "popq %0\n"
87 : "=r" (eflags)
88 : "t" (a), "u" (b));
89 printf("fcomi(%f %f)=%08llx\n", a, b, eflags & (CC_Z | CC_P | CC_C));
93 void test_fcvt(double a)
95 float fa;
96 long double la;
97 int16_t fpuc;
98 int i;
99 int64_t lla;
100 int ia;
101 int16_t wa;
102 double ra;
104 fa = a;
105 la = a;
106 printf("(float)%e = %e\n", a, fa);
107 printf("(long double)%f = %Lf\n", a, la);
108 printf("a=%016llx\n", *(long long *)&a);
109 printf("la=%016llx %04x\n", *(long long *)&la,
110 *(unsigned short *)((char *)(&la) + 8));
112 /* test all roundings */
113 asm volatile ("fstcw %0" : "=m" (fpuc));
114 for(i=0;i<4;i++) {
115 int16_t tmp = (fpuc & ~0x0c00) | (i << 10);
116 asm volatile ("fldcw %0" : : "m" (tmp));
117 wa=0;//asm volatile ("fist %0" : "=m" (wa) : "t" (a));
118 asm volatile ("fistl %0" : "=m" (ia) : "t" (a));
119 asm volatile ("fistpll %0" : "=m" (lla) : "t" (a) : "st");
120 asm volatile ("frndint ; fstl %0" : "=m" (ra) : "t" (a));
121 asm volatile ("fldcw %0" : : "m" (fpuc));
122 printf("(short)a = %d\n", wa);
123 printf("(int)a = %d\n", ia);
124 printf("(int64_t)a = %lld\n", (long long int)lla);
125 printf("rint(a) = %f\n", ra);
129 #define TEST(N) \
130 asm("fld" #N : "=t" (a)); \
131 printf("fld" #N "= %f\n", a);
133 void test_fconst(void)
135 double a;
136 TEST(1);
137 TEST(l2t);
138 TEST(l2e);
139 TEST(pi);
140 TEST(lg2);
141 TEST(ln2);
142 TEST(z);
145 void test_fbcd(double a)
147 unsigned short bcd[5];
148 double b;
150 asm("fbstp %0" : "=m" (bcd[0]) : "t" (a) : "st");
151 asm("fbld %1" : "=t" (b) : "m" (bcd[0]));
152 printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
153 a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b);
156 #define TEST_ENV(env, save, restore)\
158 memset((env), 0xaa, sizeof(*(env)));\
159 for(i=0;i<5;i++)\
160 asm volatile ("fldl %0" : : "m" (dtab[i]));\
161 asm(save " %0\n" : : "m" (*(env)));\
162 asm(restore " %0\n": : "m" (*(env)));\
163 for(i=0;i<5;i++)\
164 asm volatile ("fstpl %0" : "=m" (rtab[i]));\
165 for(i=0;i<5;i++)\
166 printf("res[%d]=%f\n", i, rtab[i]);\
167 printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
168 (env)->fpuc,\
169 (env)->fpus & 0xff00,\
170 (env)->fptag);\
173 void test_fenv(void)
175 struct __attribute__((packed)) {
176 uint16_t fpuc;
177 uint16_t dummy1;
178 uint16_t fpus;
179 uint16_t dummy2;
180 uint16_t fptag;
181 uint16_t dummy3;
182 uint32_t ignored[4];
183 long double fpregs[8];
184 } float_env32;
185 struct __attribute__((packed)) {
186 uint16_t fpuc;
187 uint16_t fpus;
188 uint16_t fptag;
189 uint16_t ignored[4];
190 long double fpregs[8];
191 } float_env16;
192 double dtab[8];
193 double rtab[8];
194 int i;
196 for(i=0;i<8;i++)
197 dtab[i] = i + 1;
199 TEST_ENV(&float_env16, "data16 fnstenv", "data16 fldenv");
200 TEST_ENV(&float_env16, "data16 fnsave", "data16 frstor");
201 TEST_ENV(&float_env32, "fnstenv", "fldenv");
202 TEST_ENV(&float_env32, "fnsave", "frstor");
204 /* test for ffree */
205 for(i=0;i<5;i++)
206 asm volatile ("fldl %0" : : "m" (dtab[i]));
207 asm volatile("ffree %st(2)");
208 asm volatile ("fnstenv %0\n" : : "m" (float_env32));
209 asm volatile ("fninit");
210 printf("fptag=%04x\n", float_env32.fptag);
214 #define TEST_FCMOV(a, b, eflags, CC)\
216 double res;\
217 asm("pushq %3\n"\
218 "popfq\n"\
219 "fcmov" CC " %2, %0\n"\
220 : "=t" (res)\
221 : "0" (a), "u" (b), "g" ((long long int)eflags));\
222 printf("fcmov%s eflags=0x%04llx-> %f\n", \
223 CC, (long long int)eflags, res);\
226 void test_fcmov(void)
228 double a, b;
229 long long int eflags, i;
231 a = 1.0;
232 b = 2.0;
233 for(i = 0; i < 4; i++) {
234 eflags = 0;
235 if (i & 1)
236 eflags |= CC_C;
237 if (i & 2)
238 eflags |= CC_Z;
239 TEST_FCMOV(a, b, eflags, "b");
240 TEST_FCMOV(a, b, eflags, "e");
241 TEST_FCMOV(a, b, eflags, "be");
242 TEST_FCMOV(a, b, eflags, "nb");
243 TEST_FCMOV(a, b, eflags, "ne");
244 TEST_FCMOV(a, b, eflags, "nbe");
246 TEST_FCMOV(a, b, 0, "u");
247 TEST_FCMOV(a, b, CC_P, "u");
248 TEST_FCMOV(a, b, 0, "nu");
249 TEST_FCMOV(a, b, CC_P, "nu");
252 void test_floats(void)
254 test_fops(2, 3);
255 test_fops(1.4, -5);
256 test_fcmp(2, -1);
257 test_fcmp(2, 2);
258 test_fcmp(2, 3);
259 test_fcvt(0.5);
260 test_fcvt(-0.5);
261 test_fcvt(1.0/7.0);
262 test_fcvt(-1.0/9.0);
263 test_fcvt(32768);
264 test_fcvt(-1e20);
265 test_fconst();
268 int main ( void )
270 test_floats();
271 return 0;