VirtualBox

source: vbox/trunk/src/recompiler/InnoTek/testmath.c@ 3752

Last change on this file since 3752 was 3752, checked in by vboxsync, 17 years ago

typo

  • Property svn:keywords set to Id
File size: 23.7 KB
Line 
1/* $Id: testmath.c 3752 2007-07-20 16:55:31Z vboxsync $ */
2/** @file
3 * Testcase for the no-crt math stuff.
4 */
5
6
7/*******************************************************************************
8* Header Files *
9*******************************************************************************/
10#ifndef MATHTEST_STANDALONE
11# include <iprt/assert.h>
12# include <math.h>
13# undef printf
14# define printf AssertMsg2
15#else
16# include <stdio.h>
17# include <math.h>
18#endif
19
20static void bitch(const char *pszWhat, const long double *plrdResult, const long double *plrdExpected)
21{
22 const unsigned char *pach1 = (const unsigned char *)plrdResult;
23 const unsigned char *pach2 = (const unsigned char *)plrdExpected;
24#ifndef MATHTEST_STANDALONE
25 printf("error: %s - %d instead of %d\n", pszWhat, (int)(*plrdResult * 100000), (int)(*plrdExpected * 100000));
26#else
27 printf("error: %s - %.25f instead of %.25f\n", pszWhat, (double)*plrdResult, (double)*plrdExpected);
28#endif
29 printf(" %02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x\n", pach1[0], pach1[1], pach1[2], pach1[3], pach1[4], pach1[5], pach1[6], pach1[7], pach1[8], pach1[9]);
30 printf(" %02x%02x%02x%02x-%02x%02x%02x%02x-%02x%02x\n", pach2[0], pach2[1], pach2[2], pach2[3], pach2[4], pach2[5], pach2[6], pach2[7], pach2[8], pach2[9]);
31}
32
33static void bitchll(const char *pszWhat, long long llResult, long long llExpected)
34{
35#if defined(__MINGW32__) && !defined(Assert)
36 printf("error: %s - %I64d instead of %I64d\n", pszWhat, llResult, llExpected);
37#else
38 printf("error: %s - %lld instead of %lld\n", pszWhat, llResult, llExpected);
39#endif
40}
41
42static void bitchl(const char *pszWhat, long lResult, long lExpected)
43{
44 printf("error: %s - %ld instead of %ld\n", pszWhat, lResult, lExpected);
45}
46
47extern int testsin(void)
48{
49 return sinl(180.0L) == -0.801152635733830477871L;
50}
51
52extern int testremainder(void)
53{
54 static double s_rd1 = 2.5;
55 static double s_rd2 = 2.0;
56 static double s_rd3 = 0.5;
57 return remainder(s_rd1, s_rd2) == s_rd3;
58}
59
60static __inline__ void set_cw(unsigned cw)
61{
62 __asm __volatile("fldcw %0" : : "m" (cw));
63}
64
65static __inline__ unsigned get_cw(void)
66{
67 unsigned cw;
68 __asm __volatile("fstcw %0" : : "m" (cw));
69 return cw & 0xffff;
70}
71
72static long double check_lrd(const long double lrd, const unsigned long long ull, const unsigned short us)
73{
74 static volatile long double lrd2;
75 lrd2 = lrd;
76 if ( *(unsigned long long *)&lrd2 != ull
77 || ((unsigned short *)&lrd2)[4] != us)
78 {
79#if defined(__MINGW32__) && !defined(Assert)
80 printf("%I64x:%04x instead of %I64x:%04x\n", *(unsigned long long *)&lrd2, ((unsigned short *)&lrd2)[4], ull, us);
81#else
82 printf("%llx:%04x instead of %llx:%04x\n", *(unsigned long long *)&lrd2, ((unsigned short *)&lrd2)[4], ull, us);
83#endif
84 __asm__("int3\n");
85 }
86 return lrd;
87}
88
89
90static long double make_lrd(const unsigned long long ull, const unsigned short us)
91{
92 union
93 {
94 long double lrd;
95 struct
96 {
97 unsigned long long ull;
98 unsigned short us;
99 } i;
100 } u;
101
102 u.i.ull = ull;
103 u.i.us = us;
104 return u.lrd;
105}
106
107static long double check_lrd_cw(const long double lrd, const unsigned long long ull, const unsigned short us, const unsigned cw)
108{
109 set_cw(cw);
110 if (cw != get_cw())
111 {
112 printf("get_cw() -> %#x expected %#x\n", get_cw(), cw);
113 __asm__("int3\n");
114 }
115 return check_lrd(lrd, ull, us);
116}
117
118static long double make_lrd_cw(unsigned long long ull, unsigned short us, unsigned cw)
119{
120 set_cw(cw);
121 return check_lrd_cw(make_lrd(ull, us), ull, us, cw);
122}
123
124extern int testmath(void)
125{
126 unsigned cErrors = 0;
127 long double lrdResult;
128 long double lrdExpect;
129 long double lrd;
130#define CHECK(operation, expect) \
131 do { \
132 lrdExpect = expect; \
133 lrdResult = operation; \
134 if (lrdResult != lrdExpect) \
135 { \
136 bitch(#operation, &lrdResult, &lrdExpect); \
137 cErrors++; \
138 } \
139 } while (0)
140
141 long long llResult;
142 long long llExpect;
143#define CHECKLL(operation, expect) \
144 do { \
145 llExpect = expect; \
146 llResult = operation; \
147 if (llResult != llExpect) \
148 { \
149 bitchll(#operation, llResult, llExpect); \
150 cErrors++; \
151 } \
152 } while (0)
153
154 long lResult;
155 long lExpect;
156#define CHECKL(operation, expect) \
157 do { \
158 lExpect = expect; \
159 lResult = operation; \
160 if (lResult != lExpect) \
161 { \
162 bitchl(#operation, lResult, lExpect); \
163 cErrors++; \
164 } \
165 } while (0)
166
167 CHECK(atan2l(1.0L, 1.0L), 0.785398163397448309603L);
168 CHECK(atan2l(2.3L, 3.3L), 0.608689307327411694890L);
169
170 CHECK(ceill(1.9L), 2.0L);
171 CHECK(ceill(4.5L), 5.0L);
172 CHECK(ceill(3.3L), 4.0L);
173 CHECK(ceill(6.1L), 7.0L);
174
175 CHECK(floorl(1.9L), 1.0L);
176 CHECK(floorl(4.5L), 4.0L);
177 CHECK(floorl(7.3L), 7.0L);
178 CHECK(floorl(1234.1L), 1234.0L);
179 CHECK(floor(1233.1), 1233.0);
180 CHECK(floor(1239.98989898), 1239.0);
181 CHECK(floorf(9999.999), 9999.0);
182
183 CHECK(ldexpl(1.0L, 1), 2.0L);
184 CHECK(ldexpl(1.0L, 10), 1024.0L);
185 CHECK(ldexpl(2.25L, 10), 2304.0L);
186
187 CHECKLL(llrintl(1.0L), 1);
188 CHECKLL(llrintl(1.3L), 1);
189 CHECKLL(llrintl(1.5L), 2);
190 CHECKLL(llrintl(1.9L), 2);
191 CHECKLL(llrintf(123.34), 123);
192 CHECKLL(llrintf(-123.50), -124);
193 CHECKLL(llrint(42.42), 42);
194 CHECKLL(llrint(-2147483648.12343), -2147483648LL);
195#if !defined(RT_ARCH_AMD64)
196 CHECKLL(lrint(-21474836499.12343), -2147483648LL);
197 CHECKLL(lrint(-2147483649932412.12343), -2147483648LL);
198#else
199 CHECKLL(lrint(-21474836499.12343), -21474836499L);
200 CHECKLL(lrint(-2147483649932412.12343), -2147483649932412L);
201#endif
202
203// __asm__("int3");
204 CHECKL(lrintl(make_lrd_cw(000000000000000000ULL,000000,0x027f)), 0L);
205 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x3ffe,0x027f)), 0L);
206 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x3ffe,0x027f)), 0L);
207 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x3ffe,0x067f)), 0L);
208 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x3ffe,0x067f)), 0L);
209 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x3ffe,0x0a7f)), 1L);
210 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x3ffe,0x0a7f)), 1L);
211 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x3ffe,0x0e7f)), 0L);
212 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x3ffe,0x0e7f)), 0L);
213 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0xbffe,0x027f)), 0L);
214 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0xbffe,0x027f)), 0L);
215 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0xbffe,0x067f)), -1L);
216 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0xbffe,0x067f)), -1L);
217 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0xbffe,0x0a7f)), 0L);
218 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0xbffe,0x0a7f)), 0L);
219 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0xbffe,0x0e7f)), 0L);
220 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0xbffe,0x0e7f)), 0L);
221 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL,0x3ffc,0x027f)), 0L);
222 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL,0x3ffc,0x027f)), 0L);
223 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL,0x3ffc,0x067f)), 0L);
224 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL,0x3ffc,0x067f)), 0L);
225 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL,0x3ffc,0x0a7f)), 1L);
226 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL,0x3ffc,0x0a7f)), 1L);
227 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL,0x3ffc,0x0e7f)), 0L);
228 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL,0x3ffc,0x0e7f)), 0L);
229 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL,0xbffb,0x027f)), 0L);
230 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL,0xbffb,0x027f)), 0L);
231 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL,0xbffb,0x067f)), -1L);
232 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL,0xbffb,0x067f)), -1L);
233 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL,0xbffb,0x0a7f)), 0L);
234 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL,0xbffb,0x0a7f)), 0L);
235 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL,0xbffb,0x0e7f)), 0L);
236 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL,0xbffb,0x0e7f)), 0L);
237 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x400e,0x027f)), 32768L);
238 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x400e,0x027f)), 32768L);
239 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x400e,0x067f)), 32768L);
240 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x400e,0x067f)), 32768L);
241 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x400e,0x0a7f)), 32768L);
242 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x400e,0x0a7f)), 32768L);
243 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x400e,0x0e7f)), 32768L);
244 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL,0x400e,0x0e7f)), 32768L);
245#if !defined(RT_ARCH_AMD64)
246 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL,0xc041,0x027f)), (long)-2147483648L);
247 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL,0xc041,0x027f)), (long)-2147483648L);
248 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL,0xc041,0x067f)), (long)-2147483648L);
249 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL,0xc041,0x067f)), (long)-2147483648L);
250 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL,0xc041,0x0a7f)), (long)-2147483648L);
251 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL,0xc041,0x0a7f)), (long)-2147483648L);
252 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL,0xc041,0x0e7f)), (long)-2147483648L);
253 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL,0xc041,0x0e7f)), (long)-2147483648L);
254#endif
255 set_cw(0x27f);
256
257 CHECK(logl(2.7182818284590452353602874713526625L), 1.0);
258
259 CHECK(remainderl(1.0L, 1.0L), 0.0);
260 CHECK(remainderl(1.0L, 1.5L), -0.5);
261 CHECK(remainderl(42.0L, 34.25L), 7.75);
262 CHECK(remainderf(43.0, 34.25), 8.75);
263 CHECK(remainder(44.25, 34.25), 10.00);
264 double rd1 = 44.25;
265 double rd2 = 34.25;
266 CHECK(remainder(rd1, rd2), 10.00);
267 CHECK(remainder(2.5, 2.0), 0.5);
268 CHECK(remainder(2.5, 2.0), 0.5);
269 CHECK(remainder(2.5, 2.0), 0.5);
270 CHECKLL(testremainder(), 1);
271
272
273 CHECK(rintl(1.0L), 1.0);
274 CHECK(rintl(1.4L), 1.0);
275 CHECK(rintl(1.3L), 1.0);
276 CHECK(rintl(0.9L), 1.0);
277 CHECK(rintl(3123.1232L), 3123.0);
278 CHECK(rint(3985.13454), 3985.0);
279 CHECK(rintf(9999.999), 10000.0);
280
281 CHECK(sinl(1.0L), 0.84147098480789650664L);
282 lrd = 180.0L;
283 CHECK(sinl(lrd), -0.801152635733830477871L);
284 CHECK(sinl(180.0L), -0.801152635733830477871L);
285 CHECKLL(testsin(), 1);
286
287 CHECK(sqrtl(1.0L), 1.0);
288 CHECK(sqrtl(4.0L), 2.0);
289 CHECK(sqrtl(1525225.0L), 1235.0);
290
291 CHECK(tanl(0.0L), 0.0);
292 CHECK(tanl(0.7853981633974483096156608458198757L), 1.0);
293
294 CHECK(powl(0.0, 0.0), 1.0);
295 CHECK(powl(2.0, 2.0), 4.0);
296 CHECK(powl(3.0, 3.0), 27.0);
297
298 return cErrors;
299}
300
301
302/////////////////////////////////////////////////////////////////////////////////////////
303/////////////////////////////////////////////////////////////////////////////////////////
304/////////////////////////////////////////////////////////////////////////////////////////
305#if 0
306
307#define floatx_to_int32 floatx80_to_int32
308#define floatx_to_int64 floatx80_to_int64
309#define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero
310#define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero
311#define floatx_abs floatx80_abs
312#define floatx_chs floatx80_chs
313#define floatx_round_to_int(foo, bar) floatx80_round_to_int(foo, NULL)
314#define floatx_compare floatx80_compare
315#define floatx_compare_quiet floatx80_compare_quiet
316#undef sin
317#undef cos
318#undef sqrt
319#undef pow
320#undef log
321#undef tan
322#undef atan2
323#undef floor
324#undef ceil
325#undef ldexp
326#define sin sinl
327#define cos cosl
328#define sqrt sqrtl
329#define pow powl
330#define log logl
331#define tan tanl
332#define atan2 atan2l
333#define floor floorl
334#define ceil ceill
335#define ldexp ldexpl
336
337
338typedef long double CPU86_LDouble;
339
340typedef union {
341 long double d;
342 struct {
343 unsigned long long lower;
344 unsigned short upper;
345 } l;
346} CPU86_LDoubleU;
347
348/* the following deal with x86 long double-precision numbers */
349#define MAXEXPD 0x7fff
350#define EXPBIAS 16383
351#define EXPD(fp) (fp.l.upper & 0x7fff)
352#define SIGND(fp) ((fp.l.upper) & 0x8000)
353#define MANTD(fp) (fp.l.lower)
354#define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
355
356typedef long double floatx80;
357#define STATUS_PARAM , void *pv
358
359static floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM)
360{
361 return rintl(a);
362}
363
364
365
366struct myenv
367{
368 unsigned int fpstt; /* top of stack index */
369 unsigned int fpus;
370 unsigned int fpuc;
371 unsigned char fptags[8]; /* 0 = valid, 1 = empty */
372 union {
373#ifdef USE_X86LDOUBLE
374 CPU86_LDouble d __attribute__((aligned(16)));
375#else
376 CPU86_LDouble d;
377#endif
378 } fpregs[8];
379
380} my_env, env_org, env_res, *env = &my_env;
381
382
383#define ST0 (env->fpregs[env->fpstt].d)
384#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
385#define ST1 ST(1)
386#define MAXTAN 9223372036854775808.0
387
388
389static inline void fpush(void)
390{
391 env->fpstt = (env->fpstt - 1) & 7;
392 env->fptags[env->fpstt] = 0; /* validate stack entry */
393}
394
395static inline void fpop(void)
396{
397 env->fptags[env->fpstt] = 1; /* invvalidate stack entry */
398 env->fpstt = (env->fpstt + 1) & 7;
399}
400
401static void helper_f2xm1(void)
402{
403 ST0 = pow(2.0,ST0) - 1.0;
404}
405
406static void helper_fyl2x(void)
407{
408 CPU86_LDouble fptemp;
409
410 fptemp = ST0;
411 if (fptemp>0.0){
412 fptemp = log(fptemp)/log(2.0); /* log2(ST) */
413 ST1 *= fptemp;
414 fpop();
415 } else {
416 env->fpus &= (~0x4700);
417 env->fpus |= 0x400;
418 }
419}
420
421static void helper_fptan(void)
422{
423 CPU86_LDouble fptemp;
424
425 fptemp = ST0;
426 if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
427 env->fpus |= 0x400;
428 } else {
429 ST0 = tan(fptemp);
430 fpush();
431 ST0 = 1.0;
432 env->fpus &= (~0x400); /* C2 <-- 0 */
433 /* the above code is for |arg| < 2**52 only */
434 }
435}
436
437static void helper_fpatan(void)
438{
439 CPU86_LDouble fptemp, fpsrcop;
440
441 fpsrcop = ST1;
442 fptemp = ST0;
443 ST1 = atan2(fpsrcop,fptemp);
444 fpop();
445}
446
447static void helper_fxtract(void)
448{
449 CPU86_LDoubleU temp;
450 unsigned int expdif;
451
452 temp.d = ST0;
453 expdif = EXPD(temp) - EXPBIAS;
454 /*DP exponent bias*/
455 ST0 = expdif;
456 fpush();
457 BIASEXPONENT(temp);
458 ST0 = temp.d;
459}
460
461static void helper_fprem1(void)
462{
463 CPU86_LDouble dblq, fpsrcop, fptemp;
464 CPU86_LDoubleU fpsrcop1, fptemp1;
465 int expdif;
466 int q;
467
468 fpsrcop = ST0;
469 fptemp = ST1;
470 fpsrcop1.d = fpsrcop;
471 fptemp1.d = fptemp;
472 expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
473 if (expdif < 53) {
474 dblq = fpsrcop / fptemp;
475 dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
476 ST0 = fpsrcop - fptemp*dblq;
477 q = (int)dblq; /* cutting off top bits is assumed here */
478 env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
479 /* (C0,C1,C3) <-- (q2,q1,q0) */
480 env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
481 env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
482 env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
483 } else {
484 env->fpus |= 0x400; /* C2 <-- 1 */
485 fptemp = pow(2.0, expdif-50);
486 fpsrcop = (ST0 / ST1) / fptemp;
487 /* fpsrcop = integer obtained by rounding to the nearest */
488 fpsrcop = (fpsrcop-floor(fpsrcop) < ceil(fpsrcop)-fpsrcop)?
489 floor(fpsrcop): ceil(fpsrcop);
490 ST0 -= (ST1 * fpsrcop * fptemp);
491 }
492}
493
494static void helper_fprem(void)
495{
496#if 0
497LogFlow(("helper_fprem: ST0=%.*Vhxs ST1=%.*Vhxs fpus=%#x\n", sizeof(ST0), &ST0, sizeof(ST1), &ST1, env->fpus));
498
499 __asm__ __volatile__("fldt (%2)\n"
500 "fldt (%1)\n"
501 "fprem \n"
502 "fnstsw (%0)\n"
503 "fstpt (%1)\n"
504 "fstpt (%2)\n"
505 : : "r" (&env->fpus), "r" (&ST0), "r" (&ST1) : "memory");
506
507LogFlow(("helper_fprem: -> ST0=%.*Vhxs fpus=%#x c\n", sizeof(ST0), &ST0, env->fpus));
508#else
509 CPU86_LDouble dblq, fpsrcop, fptemp;
510 CPU86_LDoubleU fpsrcop1, fptemp1;
511 int expdif;
512 int q;
513
514 fpsrcop = ST0;
515 fptemp = ST1;
516 fpsrcop1.d = fpsrcop;
517 fptemp1.d = fptemp;
518
519 expdif = EXPD(fpsrcop1) - EXPD(fptemp1);
520 if ( expdif < 53 ) {
521 dblq = fpsrcop / fptemp;
522 dblq = (dblq < 0.0)? ceil(dblq): floor(dblq);
523 ST0 = fpsrcop - fptemp*dblq;
524 q = (int)dblq; /* cutting off top bits is assumed here */
525 env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
526 /* (C0,C1,C3) <-- (q2,q1,q0) */
527 env->fpus |= (q&0x4) << 6; /* (C0) <-- q2 */
528 env->fpus |= (q&0x2) << 8; /* (C1) <-- q1 */
529 env->fpus |= (q&0x1) << 14; /* (C3) <-- q0 */
530 } else {
531 env->fpus |= 0x400; /* C2 <-- 1 */
532 fptemp = pow(2.0, expdif-50);
533 fpsrcop = (ST0 / ST1) / fptemp;
534 /* fpsrcop = integer obtained by chopping */
535 fpsrcop = (fpsrcop < 0.0)?
536 -(floor(fabs(fpsrcop))): floor(fpsrcop);
537 ST0 -= (ST1 * fpsrcop * fptemp);
538 }
539#endif
540}
541
542static void helper_fyl2xp1(void)
543{
544 CPU86_LDouble fptemp;
545
546 fptemp = ST0;
547 if ((fptemp+1.0)>0.0) {
548 fptemp = log(fptemp+1.0) / log(2.0); /* log2(ST+1.0) */
549 ST1 *= fptemp;
550 fpop();
551 } else {
552 env->fpus &= (~0x4700);
553 env->fpus |= 0x400;
554 }
555}
556
557static void helper_fsqrt(void)
558{
559 CPU86_LDouble fptemp;
560
561 fptemp = ST0;
562 if (fptemp<0.0) {
563 env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
564 env->fpus |= 0x400;
565 }
566 ST0 = sqrt(fptemp);
567}
568
569static void helper_fsincos(void)
570{
571 CPU86_LDouble fptemp;
572
573 fptemp = ST0;
574 if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
575 env->fpus |= 0x400;
576 } else {
577 ST0 = sin(fptemp);
578 fpush();
579 ST0 = cos(fptemp);
580 env->fpus &= (~0x400); /* C2 <-- 0 */
581 /* the above code is for |arg| < 2**63 only */
582 }
583}
584
585static void helper_frndint(void)
586{
587 ST0 = floatx_round_to_int(ST0, &env->fp_status);
588}
589
590static void helper_fscale(void)
591{
592 ST0 = ldexp (ST0, (int)(ST1));
593}
594
595static void helper_fsin(void)
596{
597 CPU86_LDouble fptemp;
598
599 fptemp = ST0;
600 if ((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
601 env->fpus |= 0x400;
602 } else {
603 ST0 = sin(fptemp);
604 env->fpus &= (~0x400); /* C2 <-- 0 */
605 /* the above code is for |arg| < 2**53 only */
606 }
607}
608
609static void helper_fcos(void)
610{
611 CPU86_LDouble fptemp;
612
613 fptemp = ST0;
614 if((fptemp > MAXTAN)||(fptemp < -MAXTAN)) {
615 env->fpus |= 0x400;
616 } else {
617 ST0 = cos(fptemp);
618 env->fpus &= (~0x400); /* C2 <-- 0 */
619 /* the above code is for |arg5 < 2**63 only */
620 }
621}
622
623static void helper_fxam_ST0(void)
624{
625 CPU86_LDoubleU temp;
626 int expdif;
627
628 temp.d = ST0;
629
630 env->fpus &= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
631 if (SIGND(temp))
632 env->fpus |= 0x200; /* C1 <-- 1 */
633
634 /* XXX: test fptags too */
635 expdif = EXPD(temp);
636 if (expdif == MAXEXPD) {
637#ifdef USE_X86LDOUBLE
638 if (MANTD(temp) == 0x8000000000000000ULL)
639#else
640 if (MANTD(temp) == 0)
641#endif
642 env->fpus |= 0x500 /*Infinity*/;
643 else
644 env->fpus |= 0x100 /*NaN*/;
645 } else if (expdif == 0) {
646 if (MANTD(temp) == 0)
647 env->fpus |= 0x4000 /*Zero*/;
648 else
649 env->fpus |= 0x4400 /*Denormal*/;
650 } else {
651 env->fpus |= 0x400;
652 }
653}
654
655
656void check_env(void)
657{
658 int i;
659 for (i = 0; i < 8; i++)
660 {
661 CPU86_LDoubleU my, res;
662 my.d = env->fpregs[i].d;
663 res.d = env_res.fpregs[i].d;
664
665 if ( my.l.lower != res.l.lower
666 || my.l.upper != res.l.upper)
667 printf("register %i: %#018llx:%#06x\n"
668 " expected %#018llx:%#06x\n",
669 i,
670 my.l.lower, my.l.upper,
671 res.l.lower, res.l.upper);
672 }
673 for (i = 0; i < 8; i++)
674 if (env->fptags[i] != env_res.fptags[i])
675 printf("tag %i: %d != %d\n", i, env->fptags[i], env_res.fptags[i]);
676 if (env->fpstt != env_res.fpstt)
677 printf("fpstt: %#06x != %#06x\n", env->fpstt, env_res.fpstt);
678 if (env->fpuc != env_res.fpuc)
679 printf("fpuc: %#06x != %#06x\n", env->fpuc, env_res.fpuc);
680 if (env->fpus != env_res.fpus)
681 printf("fpus: %#06x != %#06x\n", env->fpus, env_res.fpus);
682}
683#endif /* not used. */
684
685#if 0 /* insert this into helper.c */
686/* FPU helpers */
687CPU86_LDoubleU my_st[8];
688unsigned int my_fpstt;
689unsigned int my_fpus;
690unsigned int my_fpuc;
691unsigned char my_fptags[8];
692
693void hlp_fpu_enter(void)
694{
695 int i;
696 for (i = 0; i < 8; i++)
697 my_st[i].d = env->fpregs[i].d;
698 my_fpstt = env->fpstt;
699 my_fpus = env->fpus;
700 my_fpuc = env->fpuc;
701 memcpy(&my_fptags, &env->fptags, sizeof(my_fptags));
702}
703
704void hlp_fpu_leave(const char *psz)
705{
706 int i;
707 Log(("/*code*/ \n"));
708 for (i = 0; i < 8; i++)
709 Log(("/*code*/ *(unsigned long long *)&env_org.fpregs[%d] = %#018llxULL; ((unsigned short *)&env_org.fpregs[%d])[4] = %#06x; env_org.fptags[%d]=%d;\n",
710 i, my_st[i].l.lower, i, my_st[i].l.upper, i, my_fptags[i]));
711 Log(("/*code*/ env_org.fpstt=%#x;\n", my_fpstt));
712 Log(("/*code*/ env_org.fpus=%#x;\n", my_fpus));
713 Log(("/*code*/ env_org.fpuc=%#x;\n", my_fpuc));
714 for (i = 0; i < 8; i++)
715 {
716 CPU86_LDoubleU u;
717 u.d = env->fpregs[i].d;
718 Log(("/*code*/ *(unsigned long long *)&env_res.fpregs[%d] = %#018llxULL; ((unsigned short *)&env_res.fpregs[%d])[4] = %#06x; env_res.fptags[%d]=%d;\n",
719 i, u.l.lower, i, u.l.upper, i, env->fptags[i]));
720 }
721 Log(("/*code*/ env_res.fpstt=%#x;\n", env->fpstt));
722 Log(("/*code*/ env_res.fpus=%#x;\n", env->fpus));
723 Log(("/*code*/ env_res.fpuc=%#x;\n", env->fpuc));
724
725 Log(("/*code*/ my_env = env_org;\n"));
726 Log(("/*code*/ %s();\n", psz));
727 Log(("/*code*/ check_env();\n"));
728}
729#endif /* helper.c */
730
731extern void testmath2(void )
732{
733#if 0
734#include "/tmp/code.h"
735#endif
736}
737
738
739/////////////////////////////////////////////////////////////////////////////////////////
740/////////////////////////////////////////////////////////////////////////////////////////
741/////////////////////////////////////////////////////////////////////////////////////////
742
743#ifdef MATHTEST_STANDALONE
744
745void test_fops(double a, double b)
746{
747 printf("a=%f b=%f a+b=%f\n", a, b, a + b);
748 printf("a=%f b=%f a-b=%f\n", a, b, a - b);
749 printf("a=%f b=%f a*b=%f\n", a, b, a * b);
750 printf("a=%f b=%f a/b=%f\n", a, b, a / b);
751 printf("a=%f b=%f fmod(a, b)=%f\n", a, b, (double)fmod(a, b));
752 printf("a=%f sqrt(a)=%f\n", a, (double)sqrtl(a));
753 printf("a=%f sin(a)=%f\n", a, (double)sinl(a));
754 printf("a=%f cos(a)=%f\n", a, (double)cos(a));
755 printf("a=%f tan(a)=%f\n", a, (double)tanl(a));
756 printf("a=%f log(a)=%f\n", a, (double)log(a));
757 printf("a=%f exp(a)=%f\n", a, (double)exp(a));
758 printf("a=%f b=%f atan2(a, b)=%f\n", a, b, atan2(a, b));
759 /* just to test some op combining */
760 printf("a=%f asin(sinl(a))=%f\n", a, (double)asin(sinl(a)));
761 printf("a=%f acos(cos(a))=%f\n", a, (double)acos(cos(a)));
762 printf("a=%f atan(tanl(a))=%f\n", a, (double)atan(tanl(a)));
763}
764
765int main()
766{
767 unsigned cErrors = testmath();
768
769 testmath2();
770 test_fops(2, 3);
771 test_fops(1.4, -5);
772
773 printf("cErrors=%d\n", cErrors);
774 return cErrors;
775}
776#endif
777
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette