3 * Testcase for the no-crt math stuff.
7 /*******************************************************************************
9 *******************************************************************************/
10 #ifndef MATHTEST_STANDALONE
11 # include <iprt/assert.h>
14 # define printf RTAssertMsg2Weak
20 /* gcc starting with version 4.3 uses the MPFR library which results in more accurate results. gcc-4.3.1 seems to emit the less accurate result. So just allow both results. */
21 #define SIN180a -0.8011526357338304777463731115L
22 #define SIN180b -0.801152635733830477871L
24 static void bitch(const char *pszWhat
, const long double *plrdResult
, const long double *plrdExpected
)
26 const unsigned char *pach1
= (const unsigned char *)plrdResult
;
27 const unsigned char *pach2
= (const unsigned char *)plrdExpected
;
28 #ifndef MATHTEST_STANDALONE
29 printf("error: %s - %d instead of %d\n", pszWhat
, (int)(*plrdResult
* 100000), (int)(*plrdExpected
* 100000));
31 printf("error: %s - %.25f instead of %.25f\n", pszWhat
, (double)*plrdResult
, (double)*plrdExpected
);
33 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]);
34 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]);
37 static void bitchll(const char *pszWhat
, long long llResult
, long long llExpected
)
39 #if defined(__MINGW32__) && !defined(Assert)
40 printf("error: %s - %I64d instead of %I64d\n", pszWhat
, llResult
, llExpected
);
42 printf("error: %s - %lld instead of %lld\n", pszWhat
, llResult
, llExpected
);
46 static void bitchl(const char *pszWhat
, long lResult
, long lExpected
)
48 printf("error: %s - %ld instead of %ld\n", pszWhat
, lResult
, lExpected
);
51 extern int testsin(void)
53 return sinl(180.0L) == SIN180a
|| sinl(180.0L) == SIN180b
;
56 extern int testremainder(void)
58 static double s_rd1
= 2.5;
59 static double s_rd2
= 2.0;
60 static double s_rd3
= 0.5;
61 return remainder(s_rd1
, s_rd2
) == s_rd3
;
64 static __inline__
void set_cw(unsigned cw
)
66 __asm
__volatile("fldcw %0" : : "m" (cw
));
69 static __inline__
unsigned get_cw(void)
72 __asm
__volatile("fstcw %0" : : "m" (cw
));
76 static long double check_lrd(const long double lrd
, const unsigned long long ull
, const unsigned short us
)
78 static volatile long double lrd2
;
80 if ( *(unsigned long long *)&lrd2
!= ull
81 || ((unsigned short *)&lrd2
)[4] != us
)
83 #if defined(__MINGW32__) && !defined(Assert)
84 printf("%I64x:%04x instead of %I64x:%04x\n", *(unsigned long long *)&lrd2
, ((unsigned short *)&lrd2
)[4], ull
, us
);
86 printf("%llx:%04x instead of %llx:%04x\n", *(unsigned long long *)&lrd2
, ((unsigned short *)&lrd2
)[4], ull
, us
);
94 static long double make_lrd(const unsigned long long ull
, const unsigned short us
)
101 unsigned long long ull
;
111 static long double check_lrd_cw(const long double lrd
, const unsigned long long ull
, const unsigned short us
, const unsigned cw
)
116 printf("get_cw() -> %#x expected %#x\n", get_cw(), cw
);
119 return check_lrd(lrd
, ull
, us
);
122 static long double make_lrd_cw(unsigned long long ull
, unsigned short us
, unsigned cw
)
125 return check_lrd_cw(make_lrd(ull
, us
), ull
, us
, cw
);
128 extern int testmath(void)
130 unsigned cErrors
= 0;
131 long double lrdResult
;
132 long double lrdExpect
;
134 #define CHECK(operation, expect) \
136 lrdExpect = expect; \
137 lrdResult = operation; \
138 if (lrdResult != lrdExpect) \
140 bitch(#operation, &lrdResult, &lrdExpect); \
147 #define CHECKLL(operation, expect) \
150 llResult = operation; \
151 if (llResult != llExpect) \
153 bitchll(#operation, llResult, llExpect); \
160 #define CHECKL(operation, expect) \
163 lResult = operation; \
164 if (lResult != lExpect) \
166 bitchl(#operation, lResult, lExpect); \
171 CHECK(atan2l(1.0L, 1.0L), 0.785398163397448309603L);
172 CHECK(atan2l(2.3L, 3.3L), 0.608689307327411694890L);
174 CHECK(ceill(1.9L), 2.0L);
175 CHECK(ceill(4.5L), 5.0L);
176 CHECK(ceill(3.3L), 4.0L);
177 CHECK(ceill(6.1L), 7.0L);
179 CHECK(floorl(1.9L), 1.0L);
180 CHECK(floorl(4.5L), 4.0L);
181 CHECK(floorl(7.3L), 7.0L);
182 CHECK(floorl(1234.1L), 1234.0L);
183 CHECK(floor(1233.1), 1233.0);
184 CHECK(floor(1239.98989898), 1239.0);
185 CHECK(floorf(9999.999), 9999.0);
187 CHECK(ldexpl(1.0L, 1), 2.0L);
188 CHECK(ldexpl(1.0L, 10), 1024.0L);
189 CHECK(ldexpl(2.25L, 10), 2304.0L);
191 CHECKLL(llrintl(1.0L), 1);
192 CHECKLL(llrintl(1.3L), 1);
193 CHECKLL(llrintl(1.5L), 2);
194 CHECKLL(llrintl(1.9L), 2);
195 CHECKLL(llrintf(123.34), 123);
196 CHECKLL(llrintf(-123.50), -124);
197 CHECKLL(llrint(42.42), 42);
198 CHECKLL(llrint(-2147483648.12343), -2147483648LL);
199 #if !defined(RT_ARCH_AMD64)
200 CHECKLL(lrint(-21474836499.12343), -2147483648LL);
201 CHECKLL(lrint(-2147483649932412.12343), -2147483648LL);
203 CHECKLL(lrint(-21474836499.12343), -21474836499L);
204 CHECKLL(lrint(-2147483649932412.12343), -2147483649932412L);
207 // __asm__("int $3");
208 CHECKL(lrintl(make_lrd_cw(000000000000000000ULL,000000,0x027f)), 0L);
209 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x3ffe,0x027f)), 0L);
210 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x3ffe,0x027f)), 0L);
211 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x3ffe,0x067f)), 0L);
212 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x3ffe,0x067f)), 0L);
213 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x3ffe,0x0a7f)), 1L);
214 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x3ffe,0x0a7f)), 1L);
215 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x3ffe,0x0e7f)), 0L);
216 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x3ffe,0x0e7f)), 0L);
217 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0xbffe,0x027f)), 0L);
218 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0xbffe,0x027f)), 0L);
219 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0xbffe,0x067f)), -1L);
220 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0xbffe,0x067f)), -1L);
221 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0xbffe,0x0a7f)), 0L);
222 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0xbffe,0x0a7f)), 0L);
223 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0xbffe,0x0e7f)), 0L);
224 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0xbffe,0x0e7f)), 0L);
225 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL
,0x3ffc,0x027f)), 0L);
226 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL
,0x3ffc,0x027f)), 0L);
227 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL
,0x3ffc,0x067f)), 0L);
228 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL
,0x3ffc,0x067f)), 0L);
229 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL
,0x3ffc,0x0a7f)), 1L);
230 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL
,0x3ffc,0x0a7f)), 1L);
231 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL
,0x3ffc,0x0e7f)), 0L);
232 CHECKL(lrintl(make_lrd_cw(0x9249249249249000ULL
,0x3ffc,0x0e7f)), 0L);
233 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL
,0xbffb,0x027f)), 0L);
234 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL
,0xbffb,0x027f)), 0L);
235 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL
,0xbffb,0x067f)), -1L);
236 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL
,0xbffb,0x067f)), -1L);
237 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL
,0xbffb,0x0a7f)), 0L);
238 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL
,0xbffb,0x0a7f)), 0L);
239 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL
,0xbffb,0x0e7f)), 0L);
240 CHECKL(lrintl(make_lrd_cw(0xe38e38e38e38e000ULL
,0xbffb,0x0e7f)), 0L);
241 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x400e,0x027f)), 32768L);
242 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x400e,0x027f)), 32768L);
243 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x400e,0x067f)), 32768L);
244 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x400e,0x067f)), 32768L);
245 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x400e,0x0a7f)), 32768L);
246 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x400e,0x0a7f)), 32768L);
247 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x400e,0x0e7f)), 32768L);
248 CHECKL(lrintl(make_lrd_cw(0x8000000000000000ULL
,0x400e,0x0e7f)), 32768L);
249 #if !defined(RT_ARCH_AMD64)
250 /* c90 says that the constant is 2147483648 (which is not representable as a signed 32-bit
251 * value). To that constant you've then applied the negation operation. c90 doesn't have
252 * negative constants, only positive ones that have been negated. */
253 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL
,0xc041,0x027f)), (long)(-2147483647L - 1));
254 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL
,0xc041,0x027f)), (long)(-2147483647L - 1));
255 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL
,0xc041,0x067f)), (long)(-2147483647L - 1));
256 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL
,0xc041,0x067f)), (long)(-2147483647L - 1));
257 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL
,0xc041,0x0a7f)), (long)(-2147483647L - 1));
258 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL
,0xc041,0x0a7f)), (long)(-2147483647L - 1));
259 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL
,0xc041,0x0e7f)), (long)(-2147483647L - 1));
260 CHECKL(lrintl(make_lrd_cw(0xad78ebc5ac620000ULL
,0xc041,0x0e7f)), (long)(-2147483647L - 1));
264 CHECK(logl(2.7182818284590452353602874713526625L), 1.0);
266 CHECK(remainderl(1.0L, 1.0L), 0.0);
267 CHECK(remainderl(1.0L, 1.5L), -0.5);
268 CHECK(remainderl(42.0L, 34.25L), 7.75);
269 CHECK(remainderf(43.0, 34.25), 8.75);
270 CHECK(remainder(44.25, 34.25), 10.00);
273 CHECK(remainder(rd1
, rd2
), 10.00);
274 CHECK(remainder(2.5, 2.0), 0.5);
275 CHECK(remainder(2.5, 2.0), 0.5);
276 CHECK(remainder(2.5, 2.0), 0.5);
277 CHECKLL(testremainder(), 1);
280 /* Only works in extended precision, while double precision is default on BSD (including Darwin) */
282 CHECK(rintl(1.0L), 1.0);
283 CHECK(rintl(1.4L), 1.0);
284 CHECK(rintl(1.3L), 1.0);
285 CHECK(rintl(0.9L), 1.0);
286 CHECK(rintl(3123.1232L), 3123.0);
287 CHECK(rint(3985.13454), 3985.0);
288 CHECK(rintf(9999.999), 10000.0);
291 CHECK(sinl(1.0L), 0.84147098480789650664L);
294 CHECK(sinl(lrd
), -0.801152635733830477871L);
298 lrdResult
= sinl(lrd
);
299 if (lrdResult
!= lrdExpect
)
302 if (lrdResult
!= lrdExpect
)
304 bitch("sinl(lrd)", &lrdResult
, &lrdExpect
);
310 CHECK(sinl(180.0L), SIN180
);
313 lrdResult
= sinl(180.0L);
314 if (lrdResult
!= lrdExpect
)
317 if (lrdResult
!= lrdExpect
)
319 bitch("sinl(180.0L)", &lrdResult
, &lrdExpect
);
324 CHECKLL(testsin(), 1);
326 CHECK(sqrtl(1.0L), 1.0);
327 CHECK(sqrtl(4.0L), 2.0);
328 CHECK(sqrtl(1525225.0L), 1235.0);
330 CHECK(tanl(0.0L), 0.0);
331 CHECK(tanl(0.7853981633974483096156608458198757L), 1.0);
333 CHECK(powl(0.0, 0.0), 1.0);
334 CHECK(powl(2.0, 2.0), 4.0);
335 CHECK(powl(3.0, 3.0), 27.0);
341 /////////////////////////////////////////////////////////////////////////////////////////
342 /////////////////////////////////////////////////////////////////////////////////////////
343 /////////////////////////////////////////////////////////////////////////////////////////
346 #define floatx_to_int32 floatx80_to_int32
347 #define floatx_to_int64 floatx80_to_int64
348 #define floatx_to_int32_round_to_zero floatx80_to_int32_round_to_zero
349 #define floatx_to_int64_round_to_zero floatx80_to_int64_round_to_zero
350 #define floatx_abs floatx80_abs
351 #define floatx_chs floatx80_chs
352 #define floatx_round_to_int(foo, bar) floatx80_round_to_int(foo, NULL)
353 #define floatx_compare floatx80_compare
354 #define floatx_compare_quiet floatx80_compare_quiet
377 typedef long double CPU86_LDouble
;
382 unsigned long long lower
;
383 unsigned short upper
;
387 /* the following deal with x86 long double-precision numbers */
388 #define MAXEXPD 0x7fff
389 #define EXPBIAS 16383
390 #define EXPD(fp) (fp.l.upper & 0x7fff)
391 #define SIGND(fp) ((fp.l.upper) & 0x8000)
392 #define MANTD(fp) (fp.l.lower)
393 #define BIASEXPONENT(fp) fp.l.upper = (fp.l.upper & ~(0x7fff)) | EXPBIAS
395 typedef long double floatx80
;
396 #define STATUS_PARAM , void *pv
398 static floatx80
floatx80_round_to_int( floatx80 a STATUS_PARAM
)
407 unsigned int fpstt
; /* top of stack index */
410 unsigned char fptags
[8]; /* 0 = valid, 1 = empty */
412 #ifdef USE_X86LDOUBLE
413 CPU86_LDouble d
__attribute__((aligned(16)));
419 } my_env
, env_org
, env_res
, *env
= &my_env
;
422 #define ST0 (env->fpregs[env->fpstt].d)
423 #define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
425 #define MAXTAN 9223372036854775808.0
428 static inline void fpush(void)
430 env
->fpstt
= (env
->fpstt
- 1) & 7;
431 env
->fptags
[env
->fpstt
] = 0; /* validate stack entry */
434 static inline void fpop(void)
436 env
->fptags
[env
->fpstt
] = 1; /* invalidate stack entry */
437 env
->fpstt
= (env
->fpstt
+ 1) & 7;
440 static void helper_f2xm1(void)
442 ST0
= pow(2.0,ST0
) - 1.0;
445 static void helper_fyl2x(void)
447 CPU86_LDouble fptemp
;
451 fptemp
= log(fptemp
)/log(2.0); /* log2(ST) */
455 env
->fpus
&= (~0x4700);
460 static void helper_fptan(void)
462 CPU86_LDouble fptemp
;
465 if((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
471 env
->fpus
&= (~0x400); /* C2 <-- 0 */
472 /* the above code is for |arg| < 2**52 only */
476 static void helper_fpatan(void)
478 CPU86_LDouble fptemp
, fpsrcop
;
482 ST1
= atan2(fpsrcop
,fptemp
);
486 static void helper_fxtract(void)
492 expdif
= EXPD(temp
) - EXPBIAS
;
500 static void helper_fprem1(void)
502 CPU86_LDouble dblq
, fpsrcop
, fptemp
;
503 CPU86_LDoubleU fpsrcop1
, fptemp1
;
509 fpsrcop1
.d
= fpsrcop
;
511 expdif
= EXPD(fpsrcop1
) - EXPD(fptemp1
);
513 dblq
= fpsrcop
/ fptemp
;
514 dblq
= (dblq
< 0.0)? ceil(dblq
): floor(dblq
);
515 ST0
= fpsrcop
- fptemp
*dblq
;
516 q
= (int)dblq
; /* cutting off top bits is assumed here */
517 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
518 /* (C0,C1,C3) <-- (q2,q1,q0) */
519 env
->fpus
|= (q
&0x4) << 6; /* (C0) <-- q2 */
520 env
->fpus
|= (q
&0x2) << 8; /* (C1) <-- q1 */
521 env
->fpus
|= (q
&0x1) << 14; /* (C3) <-- q0 */
523 env
->fpus
|= 0x400; /* C2 <-- 1 */
524 fptemp
= pow(2.0, expdif
-50);
525 fpsrcop
= (ST0
/ ST1
) / fptemp
;
526 /* fpsrcop = integer obtained by rounding to the nearest */
527 fpsrcop
= (fpsrcop
-floor(fpsrcop
) < ceil(fpsrcop
)-fpsrcop
)?
528 floor(fpsrcop
): ceil(fpsrcop
);
529 ST0
-= (ST1
* fpsrcop
* fptemp
);
533 static void helper_fprem(void)
536 LogFlow(("helper_fprem: ST0=%.*Rhxs ST1=%.*Rhxs fpus=%#x\n", sizeof(ST0
), &ST0
, sizeof(ST1
), &ST1
, env
->fpus
));
538 __asm__
__volatile__("fldt (%2)\n"
544 : : "r" (&env
->fpus
), "r" (&ST0
), "r" (&ST1
) : "memory");
546 LogFlow(("helper_fprem: -> ST0=%.*Rhxs fpus=%#x c\n", sizeof(ST0
), &ST0
, env
->fpus
));
548 CPU86_LDouble dblq
, fpsrcop
, fptemp
;
549 CPU86_LDoubleU fpsrcop1
, fptemp1
;
555 fpsrcop1
.d
= fpsrcop
;
558 expdif
= EXPD(fpsrcop1
) - EXPD(fptemp1
);
560 dblq
= fpsrcop
/ fptemp
;
561 dblq
= (dblq
< 0.0)? ceil(dblq
): floor(dblq
);
562 ST0
= fpsrcop
- fptemp
*dblq
;
563 q
= (int)dblq
; /* cutting off top bits is assumed here */
564 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
565 /* (C0,C1,C3) <-- (q2,q1,q0) */
566 env
->fpus
|= (q
&0x4) << 6; /* (C0) <-- q2 */
567 env
->fpus
|= (q
&0x2) << 8; /* (C1) <-- q1 */
568 env
->fpus
|= (q
&0x1) << 14; /* (C3) <-- q0 */
570 env
->fpus
|= 0x400; /* C2 <-- 1 */
571 fptemp
= pow(2.0, expdif
-50);
572 fpsrcop
= (ST0
/ ST1
) / fptemp
;
573 /* fpsrcop = integer obtained by chopping */
574 fpsrcop
= (fpsrcop
< 0.0)?
575 -(floor(fabs(fpsrcop
))): floor(fpsrcop
);
576 ST0
-= (ST1
* fpsrcop
* fptemp
);
581 static void helper_fyl2xp1(void)
583 CPU86_LDouble fptemp
;
586 if ((fptemp
+1.0)>0.0) {
587 fptemp
= log(fptemp
+1.0) / log(2.0); /* log2(ST+1.0) */
591 env
->fpus
&= (~0x4700);
596 static void helper_fsqrt(void)
598 CPU86_LDouble fptemp
;
602 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
608 static void helper_fsincos(void)
610 CPU86_LDouble fptemp
;
613 if ((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
619 env
->fpus
&= (~0x400); /* C2 <-- 0 */
620 /* the above code is for |arg| < 2**63 only */
624 static void helper_frndint(void)
626 ST0
= floatx_round_to_int(ST0
, &env
->fp_status
);
629 static void helper_fscale(void)
631 ST0
= ldexp (ST0
, (int)(ST1
));
634 static void helper_fsin(void)
636 CPU86_LDouble fptemp
;
639 if ((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
643 env
->fpus
&= (~0x400); /* C2 <-- 0 */
644 /* the above code is for |arg| < 2**53 only */
648 static void helper_fcos(void)
650 CPU86_LDouble fptemp
;
653 if((fptemp
> MAXTAN
)||(fptemp
< -MAXTAN
)) {
657 env
->fpus
&= (~0x400); /* C2 <-- 0 */
658 /* the above code is for |arg5 < 2**63 only */
662 static void helper_fxam_ST0(void)
669 env
->fpus
&= (~0x4700); /* (C3,C2,C1,C0) <-- 0000 */
671 env
->fpus
|= 0x200; /* C1 <-- 1 */
673 /* XXX: test fptags too */
675 if (expdif
== MAXEXPD
) {
676 #ifdef USE_X86LDOUBLE
677 if (MANTD(temp
) == 0x8000000000000000ULL
)
679 if (MANTD(temp
) == 0)
681 env
->fpus
|= 0x500 /*Infinity*/;
683 env
->fpus
|= 0x100 /*NaN*/;
684 } else if (expdif
== 0) {
685 if (MANTD(temp
) == 0)
686 env
->fpus
|= 0x4000 /*Zero*/;
688 env
->fpus
|= 0x4400 /*Denormal*/;
698 for (i
= 0; i
< 8; i
++)
700 CPU86_LDoubleU my
, res
;
701 my
.d
= env
->fpregs
[i
].d
;
702 res
.d
= env_res
.fpregs
[i
].d
;
704 if ( my
.l
.lower
!= res
.l
.lower
705 || my
.l
.upper
!= res
.l
.upper
)
706 printf("register %i: %#018llx:%#06x\n"
707 " expected %#018llx:%#06x\n",
709 my
.l
.lower
, my
.l
.upper
,
710 res
.l
.lower
, res
.l
.upper
);
712 for (i
= 0; i
< 8; i
++)
713 if (env
->fptags
[i
] != env_res
.fptags
[i
])
714 printf("tag %i: %d != %d\n", i
, env
->fptags
[i
], env_res
.fptags
[i
]);
715 if (env
->fpstt
!= env_res
.fpstt
)
716 printf("fpstt: %#06x != %#06x\n", env
->fpstt
, env_res
.fpstt
);
717 if (env
->fpuc
!= env_res
.fpuc
)
718 printf("fpuc: %#06x != %#06x\n", env
->fpuc
, env_res
.fpuc
);
719 if (env
->fpus
!= env_res
.fpus
)
720 printf("fpus: %#06x != %#06x\n", env
->fpus
, env_res
.fpus
);
722 #endif /* not used. */
724 #if 0 /* insert this into helper.c */
726 CPU86_LDoubleU my_st
[8];
727 unsigned int my_fpstt
;
728 unsigned int my_fpus
;
729 unsigned int my_fpuc
;
730 unsigned char my_fptags
[8];
732 void hlp_fpu_enter(void)
735 for (i
= 0; i
< 8; i
++)
736 my_st
[i
].d
= env
->fpregs
[i
].d
;
737 my_fpstt
= env
->fpstt
;
740 memcpy(&my_fptags
, &env
->fptags
, sizeof(my_fptags
));
743 void hlp_fpu_leave(const char *psz
)
746 Log(("/*code*/ \n"));
747 for (i
= 0; i
< 8; i
++)
748 Log(("/*code*/ *(unsigned long long *)&env_org.fpregs[%d] = %#018llxULL; ((unsigned short *)&env_org.fpregs[%d])[4] = %#06x; env_org.fptags[%d]=%d;\n",
749 i
, my_st
[i
].l
.lower
, i
, my_st
[i
].l
.upper
, i
, my_fptags
[i
]));
750 Log(("/*code*/ env_org.fpstt=%#x;\n", my_fpstt
));
751 Log(("/*code*/ env_org.fpus=%#x;\n", my_fpus
));
752 Log(("/*code*/ env_org.fpuc=%#x;\n", my_fpuc
));
753 for (i
= 0; i
< 8; i
++)
756 u
.d
= env
->fpregs
[i
].d
;
757 Log(("/*code*/ *(unsigned long long *)&env_res.fpregs[%d] = %#018llxULL; ((unsigned short *)&env_res.fpregs[%d])[4] = %#06x; env_res.fptags[%d]=%d;\n",
758 i
, u
.l
.lower
, i
, u
.l
.upper
, i
, env
->fptags
[i
]));
760 Log(("/*code*/ env_res.fpstt=%#x;\n", env
->fpstt
));
761 Log(("/*code*/ env_res.fpus=%#x;\n", env
->fpus
));
762 Log(("/*code*/ env_res.fpuc=%#x;\n", env
->fpuc
));
764 Log(("/*code*/ my_env = env_org;\n"));
765 Log(("/*code*/ %s();\n", psz
));
766 Log(("/*code*/ check_env();\n"));
768 #endif /* helper.c */
770 extern void testmath2(void )
773 #include "/tmp/code.h"
778 /////////////////////////////////////////////////////////////////////////////////////////
779 /////////////////////////////////////////////////////////////////////////////////////////
780 /////////////////////////////////////////////////////////////////////////////////////////
782 #ifdef MATHTEST_STANDALONE
784 void test_fops(double a
, double b
)
786 printf("a=%f b=%f a+b=%f\n", a
, b
, a
+ b
);
787 printf("a=%f b=%f a-b=%f\n", a
, b
, a
- b
);
788 printf("a=%f b=%f a*b=%f\n", a
, b
, a
* b
);
789 printf("a=%f b=%f a/b=%f\n", a
, b
, a
/ b
);
790 printf("a=%f b=%f fmod(a, b)=%f\n", a
, b
, (double)fmod(a
, b
));
791 printf("a=%f sqrt(a)=%f\n", a
, (double)sqrtl(a
));
792 printf("a=%f sin(a)=%f\n", a
, (double)sinl(a
));
793 printf("a=%f cos(a)=%f\n", a
, (double)cos(a
));
794 printf("a=%f tan(a)=%f\n", a
, (double)tanl(a
));
795 printf("a=%f log(a)=%f\n", a
, (double)log(a
));
796 printf("a=%f exp(a)=%f\n", a
, (double)exp(a
));
797 printf("a=%f b=%f atan2(a, b)=%f\n", a
, b
, atan2(a
, b
));
798 /* just to test some op combining */
799 printf("a=%f asin(sinl(a))=%f\n", a
, (double)asin(sinl(a
)));
800 printf("a=%f acos(cos(a))=%f\n", a
, (double)acos(cos(a
)));
801 printf("a=%f atan(tanl(a))=%f\n", a
, (double)atan(tanl(a
)));
806 unsigned cErrors
= testmath();
812 printf("cErrors=%d\n", cErrors
);