7 * Copyright (c) 2003 Fabrice Bellard
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, see <http://www.gnu.org/licenses/>.
30 /**********************************************/
32 void test_fops(double a
, double b
)
34 printf("a=%f b=%f a+b=%f\n", a
, b
, a
+ b
);
35 printf("a=%f b=%f a-b=%f\n", a
, b
, a
- b
);
36 printf("a=%f b=%f a*b=%f\n", a
, b
, a
* b
);
37 printf("a=%f b=%f a/b=%f\n", a
, b
, a
/ b
);
38 printf("a=%f b=%f fmod(a, b)=%f\n", a
, b
, fmod(a
, b
));
39 printf("a=%f sqrt(a)=%f\n", a
, sqrt(a
));
40 printf("a=%f sin(a)=%f\n", a
, sin(a
));
41 printf("a=%f cos(a)=%f\n", a
, cos(a
));
42 printf("a=%f tan(a)=%f\n", a
, tan(a
));
43 printf("a=%f log(a)=%f\n", a
, log(a
));
44 printf("a=%f exp(a)=%f\n", a
, exp(a
));
45 printf("a=%f b=%f atan2(a, b)=%f\n", a
, b
, atan2(a
, b
));
46 /* just to test some op combining */
47 printf("a=%f asin(sin(a))=%f\n", a
, asin(sin(a
)));
48 printf("a=%f acos(cos(a))=%f\n", a
, acos(cos(a
)));
49 printf("a=%f atan(tan(a))=%f\n", a
, atan(tan(a
)));
59 void test_fcmp(double a
, double b
)
61 printf("(%f<%f)=%d\n",
63 printf("(%f<=%f)=%d\n",
65 printf("(%f==%f)=%d\n",
67 printf("(%f>%f)=%d\n",
69 printf("(%f<=%f)=%d\n",
73 /* test f(u)comi instruction */
79 printf("fcomi(%f %f)=%08x\n", a
, b
, eflags
& (CC_Z
| CC_P
| CC_C
));
83 void test_fcvt(double a
)
96 printf("(float)%f = %f\n", a
, fa
);
97 printf("(long double)%f = %Lf\n", a
, la
);
98 printf("a=%016llx\n", *(long long *)&a
);
99 printf("la=%016llx %04x\n", *(long long *)&la
,
100 *(unsigned short *)((char *)(&la
) + 8));
102 /* test all roundings */
103 asm volatile ("fstcw %0" : "=m" (fpuc
));
105 int16_t tmp
= (fpuc
& ~0x0c00) | (i
<< 10);
106 asm volatile ("fldcw %0" : : "m" (tmp
));
107 asm volatile ("fists %0" : "=m" (wa
) : "t" (a
));
108 asm volatile ("fistl %0" : "=m" (ia
) : "t" (a
));
109 asm volatile ("fistpll %0" : "=m" (lla
) : "t" (a
) : "st");
110 asm volatile ("frndint ; fstl %0" : "=m" (ra
) : "t" (a
));
111 asm volatile ("fldcw %0" : : "m" (fpuc
));
112 printf("(short)a = %d\n", wa
);
113 printf("(int)a = %d\n", ia
);
114 printf("(int64_t)a = %lld\n", lla
);
115 printf("rint(a) = %f\n", ra
);
120 asm("fld" #N : "=t" (a)); \
121 printf("fld" #N "= %f\n", a);
123 void test_fconst(void)
135 void test_fbcd(double a
)
137 unsigned short bcd
[5];
140 asm("fbstp %0" : "=m" (bcd
[0]) : "t" (a
) : "st");
141 asm("fbld %1" : "=t" (b
) : "m" (bcd
[0]));
142 printf("a=%f bcd=%04x%04x%04x%04x%04x b=%f\n",
143 a
, bcd
[4], bcd
[3], bcd
[2], bcd
[1], bcd
[0], b
);
146 #define TEST_ENV(env, save, restore)\
148 memset((env), 0xaa, sizeof(*(env)));\
150 asm volatile ("fldl %0" : : "m" (dtab[i]));\
151 asm(save " %0\n" : : "m" (*(env)));\
152 asm(restore " %0\n": : "m" (*(env)));\
154 asm volatile ("fstpl %0" : "=m" (rtab[i]));\
156 printf("res[%d]=%f\n", i, rtab[i]);\
157 printf("fpuc=%04x fpus=%04x fptag=%04x\n",\
159 (env)->fpus & 0xff00,\
165 struct __attribute__((packed
)) {
173 long double fpregs
[8];
175 struct __attribute__((packed
)) {
180 long double fpregs
[8];
189 TEST_ENV(&float_env16
, "data16/fnstenv", "data16/fldenv");
190 TEST_ENV(&float_env16
, "data16/fnsave", "data16/frstor");
191 TEST_ENV(&float_env32
, "fnstenv", "fldenv");
192 TEST_ENV(&float_env32
, "fnsave", "frstor");
196 asm volatile ("fldl %0" : : "m" (dtab
[i
]));
197 asm volatile("ffree %st(2)");
198 asm volatile ("fnstenv %0\n" : : "m" (float_env32
));
199 asm volatile ("fninit");
200 printf("fptag=%04x\n", float_env32
.fptag
);
204 #define TEST_FCMOV(a, b, eflags, CC)\
209 "fcmov" CC " %2, %0\n"\
211 : "0" (a), "u" (b), "g" (eflags));\
212 printf("fcmov%s eflags=0x%04x-> %f\n", \
216 void test_fcmov(void)
223 for(i
= 0; i
< 4; i
++) {
229 TEST_FCMOV(a
, b
, eflags
, "b");
230 TEST_FCMOV(a
, b
, eflags
, "e");
231 TEST_FCMOV(a
, b
, eflags
, "be");
232 TEST_FCMOV(a
, b
, eflags
, "nb");
233 TEST_FCMOV(a
, b
, eflags
, "ne");
234 TEST_FCMOV(a
, b
, eflags
, "nbe");
236 TEST_FCMOV(a
, b
, 0, "u");
237 TEST_FCMOV(a
, b
, CC_P
, "u");
238 TEST_FCMOV(a
, b
, 0, "nu");
239 TEST_FCMOV(a
, b
, CC_P
, "nu");
242 void test_floats(void)