Commit 86bd2ca58a99c5dec1372809236640bcc8ede2cd

Authored by bellard
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;