Commit 86bd2ca58a99c5dec1372809236640bcc8ede2cd
1 parent
8422b113
NaN tests
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1342 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
124 additions
and
58 deletions
tests/test-i386.c
@@ -40,6 +40,7 @@ | @@ -40,6 +40,7 @@ | ||
40 | #define TEST_CMOV 1 | 40 | #define TEST_CMOV 1 |
41 | #define TEST_FCOMI 1 | 41 | #define TEST_FCOMI 1 |
42 | #else | 42 | #else |
43 | +//#define TEST_SSE | ||
43 | #define TEST_CMOV 0 | 44 | #define TEST_CMOV 0 |
44 | #define TEST_FCOMI 0 | 45 | #define TEST_FCOMI 0 |
45 | #endif | 46 | #endif |
@@ -697,6 +698,14 @@ void test_bsx(void) | @@ -697,6 +698,14 @@ void test_bsx(void) | ||
697 | 698 | ||
698 | /**********************************************/ | 699 | /**********************************************/ |
699 | 700 | ||
701 | +union float64u { | ||
702 | + double d; | ||
703 | + uint64_t l; | ||
704 | +}; | ||
705 | + | ||
706 | +union float64u q_nan = { .l = 0xFFF8000000000000 }; | ||
707 | +union float64u s_nan = { .l = 0xFFF0000000000000 }; | ||
708 | + | ||
700 | void test_fops(double a, double b) | 709 | void test_fops(double a, double b) |
701 | { | 710 | { |
702 | printf("a=%f b=%f a+b=%f\n", a, b, a + b); | 711 | printf("a=%f b=%f a+b=%f\n", a, b, a + b); |
@@ -718,28 +727,68 @@ void test_fops(double a, double b) | @@ -718,28 +727,68 @@ void test_fops(double a, double b) | ||
718 | 727 | ||
719 | } | 728 | } |
720 | 729 | ||
730 | +void fpu_clear_exceptions(void) | ||
731 | +{ | ||
732 | + struct __attribute__((packed)) { | ||
733 | + uint16_t fpuc; | ||
734 | + uint16_t dummy1; | ||
735 | + uint16_t fpus; | ||
736 | + uint16_t dummy2; | ||
737 | + uint16_t fptag; | ||
738 | + uint16_t dummy3; | ||
739 | + uint32_t ignored[4]; | ||
740 | + long double fpregs[8]; | ||
741 | + } float_env32; | ||
742 | + | ||
743 | + asm volatile ("fnstenv %0\n" : : "m" (float_env32)); | ||
744 | + float_env32.fpus &= ~0x7f; | ||
745 | + asm volatile ("fldenv %0\n" : : "m" (float_env32)); | ||
746 | +} | ||
747 | + | ||
748 | +/* XXX: display exception bits when supported */ | ||
749 | +#define FPUS_EMASK 0x0000 | ||
750 | +//#define FPUS_EMASK 0x007f | ||
751 | + | ||
721 | void test_fcmp(double a, double b) | 752 | void test_fcmp(double a, double b) |
722 | { | 753 | { |
723 | - printf("(%f<%f)=%d\n", | ||
724 | - a, b, a < b); | ||
725 | - printf("(%f<=%f)=%d\n", | ||
726 | - a, b, a <= b); | ||
727 | - printf("(%f==%f)=%d\n", | ||
728 | - a, b, a == b); | ||
729 | - printf("(%f>%f)=%d\n", | ||
730 | - a, b, a > b); | ||
731 | - printf("(%f<=%f)=%d\n", | ||
732 | - a, b, a >= b); | 754 | + long eflags, fpus; |
755 | + | ||
756 | + fpu_clear_exceptions(); | ||
757 | + asm("fcom %2\n" | ||
758 | + "fstsw %%ax\n" | ||
759 | + : "=a" (fpus) | ||
760 | + : "t" (a), "u" (b)); | ||
761 | + printf("fcom(%f %f)=%04lx \n", | ||
762 | + a, b, fpus & (0x4500 | FPUS_EMASK)); | ||
763 | + fpu_clear_exceptions(); | ||
764 | + asm("fucom %2\n" | ||
765 | + "fstsw %%ax\n" | ||
766 | + : "=a" (fpus) | ||
767 | + : "t" (a), "u" (b)); | ||
768 | + printf("fucom(%f %f)=%04lx\n", | ||
769 | + a, b, fpus & (0x4500 | FPUS_EMASK)); | ||
733 | if (TEST_FCOMI) { | 770 | if (TEST_FCOMI) { |
734 | - long eflags; | ||
735 | /* test f(u)comi instruction */ | 771 | /* test f(u)comi instruction */ |
736 | - asm("fcomi %2, %1\n" | 772 | + fpu_clear_exceptions(); |
773 | + asm("fcomi %3, %2\n" | ||
774 | + "fstsw %%ax\n" | ||
737 | "pushf\n" | 775 | "pushf\n" |
738 | "pop %0\n" | 776 | "pop %0\n" |
739 | - : "=r" (eflags) | 777 | + : "=r" (eflags), "=a" (fpus) |
740 | : "t" (a), "u" (b)); | 778 | : "t" (a), "u" (b)); |
741 | - printf("fcomi(%f %f)=%08lx\n", a, b, eflags & (CC_Z | CC_P | CC_C)); | 779 | + printf("fcomi(%f %f)=%04lx %02lx\n", |
780 | + a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C)); | ||
781 | + fpu_clear_exceptions(); | ||
782 | + asm("fucomi %3, %2\n" | ||
783 | + "fstsw %%ax\n" | ||
784 | + "pushf\n" | ||
785 | + "pop %0\n" | ||
786 | + : "=r" (eflags), "=a" (fpus) | ||
787 | + : "t" (a), "u" (b)); | ||
788 | + printf("fucomi(%f %f)=%04lx %02lx\n", | ||
789 | + a, b, fpus & FPUS_EMASK, eflags & (CC_Z | CC_P | CC_C)); | ||
742 | } | 790 | } |
791 | + fpu_clear_exceptions(); | ||
743 | } | 792 | } |
744 | 793 | ||
745 | void test_fcvt(double a) | 794 | void test_fcvt(double a) |
@@ -907,6 +956,8 @@ void test_floats(void) | @@ -907,6 +956,8 @@ void test_floats(void) | ||
907 | test_fcmp(2, -1); | 956 | test_fcmp(2, -1); |
908 | test_fcmp(2, 2); | 957 | test_fcmp(2, 2); |
909 | test_fcmp(2, 3); | 958 | test_fcmp(2, 3); |
959 | + test_fcmp(2, q_nan.d); | ||
960 | + test_fcmp(q_nan.d, -1); | ||
910 | test_fcvt(0.5); | 961 | test_fcvt(0.5); |
911 | test_fcvt(-0.5); | 962 | test_fcvt(-0.5); |
912 | test_fcvt(1.0/7.0); | 963 | test_fcvt(1.0/7.0); |
@@ -2191,6 +2242,7 @@ void test_fxsave(void) | @@ -2191,6 +2242,7 @@ void test_fxsave(void) | ||
2191 | void test_sse(void) | 2242 | void test_sse(void) |
2192 | { | 2243 | { |
2193 | XMMReg r, a, b; | 2244 | XMMReg r, a, b; |
2245 | + int i; | ||
2194 | 2246 | ||
2195 | MMX_OP2(punpcklbw); | 2247 | MMX_OP2(punpcklbw); |
2196 | MMX_OP2(punpcklwd); | 2248 | MMX_OP2(punpcklwd); |
@@ -2354,51 +2406,65 @@ void test_sse(void) | @@ -2354,51 +2406,65 @@ void test_sse(void) | ||
2354 | test_sse_comi(2, -1); | 2406 | test_sse_comi(2, -1); |
2355 | test_sse_comi(2, 2); | 2407 | test_sse_comi(2, 2); |
2356 | test_sse_comi(2, 3); | 2408 | test_sse_comi(2, 3); |
2409 | + test_sse_comi(2, q_nan.d); | ||
2410 | + test_sse_comi(q_nan.d, -1); | ||
2411 | + | ||
2412 | + for(i = 0; i < 2; i++) { | ||
2413 | + a.s[0] = 2.7; | ||
2414 | + a.s[1] = 3.4; | ||
2415 | + a.s[2] = 4; | ||
2416 | + a.s[3] = -6.3; | ||
2417 | + b.s[0] = 45.7; | ||
2418 | + b.s[1] = 353.4; | ||
2419 | + b.s[2] = 4; | ||
2420 | + b.s[3] = 56.3; | ||
2421 | + if (i == 1) { | ||
2422 | + a.s[0] = q_nan.d; | ||
2423 | + b.s[3] = q_nan.d; | ||
2424 | + } | ||
2425 | + | ||
2426 | + SSE_OPS(add); | ||
2427 | + SSE_OPS(mul); | ||
2428 | + SSE_OPS(sub); | ||
2429 | + SSE_OPS(min); | ||
2430 | + SSE_OPS(div); | ||
2431 | + SSE_OPS(max); | ||
2432 | + SSE_OPS(sqrt); | ||
2433 | + SSE_OPS(cmpeq); | ||
2434 | + SSE_OPS(cmplt); | ||
2435 | + SSE_OPS(cmple); | ||
2436 | + SSE_OPS(cmpunord); | ||
2437 | + SSE_OPS(cmpneq); | ||
2438 | + SSE_OPS(cmpnlt); | ||
2439 | + SSE_OPS(cmpnle); | ||
2440 | + SSE_OPS(cmpord); | ||
2441 | + | ||
2442 | + | ||
2443 | + a.d[0] = 2.7; | ||
2444 | + a.d[1] = -3.4; | ||
2445 | + b.d[0] = 45.7; | ||
2446 | + b.d[1] = -53.4; | ||
2447 | + if (i == 1) { | ||
2448 | + a.d[0] = q_nan.d; | ||
2449 | + b.d[1] = q_nan.d; | ||
2450 | + } | ||
2451 | + SSE_OPD(add); | ||
2452 | + SSE_OPD(mul); | ||
2453 | + SSE_OPD(sub); | ||
2454 | + SSE_OPD(min); | ||
2455 | + SSE_OPD(div); | ||
2456 | + SSE_OPD(max); | ||
2457 | + SSE_OPD(sqrt); | ||
2458 | + SSE_OPD(cmpeq); | ||
2459 | + SSE_OPD(cmplt); | ||
2460 | + SSE_OPD(cmple); | ||
2461 | + SSE_OPD(cmpunord); | ||
2462 | + SSE_OPD(cmpneq); | ||
2463 | + SSE_OPD(cmpnlt); | ||
2464 | + SSE_OPD(cmpnle); | ||
2465 | + SSE_OPD(cmpord); | ||
2466 | + } | ||
2357 | 2467 | ||
2358 | - a.s[0] = 2.7; | ||
2359 | - a.s[1] = 3.4; | ||
2360 | - a.s[2] = 4; | ||
2361 | - a.s[3] = -6.3; | ||
2362 | - b.s[0] = 45.7; | ||
2363 | - b.s[1] = 353.4; | ||
2364 | - b.s[2] = 4; | ||
2365 | - b.s[3] = 56.3; | ||
2366 | - SSE_OPS(add); | ||
2367 | - SSE_OPS(mul); | ||
2368 | - SSE_OPS(sub); | ||
2369 | - SSE_OPS(min); | ||
2370 | - SSE_OPS(div); | ||
2371 | - SSE_OPS(max); | ||
2372 | - SSE_OPS(sqrt); | ||
2373 | - SSE_OPS(cmpeq); | ||
2374 | - SSE_OPS(cmplt); | ||
2375 | - SSE_OPS(cmple); | ||
2376 | - SSE_OPS(cmpunord); | ||
2377 | - SSE_OPS(cmpneq); | ||
2378 | - SSE_OPS(cmpnlt); | ||
2379 | - SSE_OPS(cmpnle); | ||
2380 | - SSE_OPS(cmpord); | ||
2381 | - | ||
2382 | - a.d[0] = 2.7; | ||
2383 | - a.d[1] = -3.4; | ||
2384 | - b.d[0] = 45.7; | ||
2385 | - b.d[1] = -53.4; | ||
2386 | - SSE_OPD(add); | ||
2387 | - SSE_OPD(mul); | ||
2388 | - SSE_OPD(sub); | ||
2389 | - SSE_OPD(min); | ||
2390 | - SSE_OPD(div); | ||
2391 | - SSE_OPD(max); | ||
2392 | - SSE_OPD(sqrt); | ||
2393 | - SSE_OPD(cmpeq); | ||
2394 | - SSE_OPD(cmplt); | ||
2395 | - SSE_OPD(cmple); | ||
2396 | - SSE_OPD(cmpunord); | ||
2397 | - SSE_OPD(cmpneq); | ||
2398 | - SSE_OPD(cmpnlt); | ||
2399 | - SSE_OPD(cmpnle); | ||
2400 | - SSE_OPD(cmpord); | ||
2401 | - | ||
2402 | /* float to float/int */ | 2468 | /* float to float/int */ |
2403 | a.s[0] = 2.7; | 2469 | a.s[0] = 2.7; |
2404 | a.s[1] = 3.4; | 2470 | a.s[1] = 3.4; |