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 40 #define TEST_CMOV 1
41 41 #define TEST_FCOMI 1
42 42 #else
  43 +//#define TEST_SSE
43 44 #define TEST_CMOV 0
44 45 #define TEST_FCOMI 0
45 46 #endif
... ... @@ -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 709 void test_fops(double a, double b)
701 710 {
702 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 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 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 770 if (TEST_FCOMI) {
734   - long eflags;
735 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 775 "pushf\n"
738 776 "pop %0\n"
739   - : "=r" (eflags)
  777 + : "=r" (eflags), "=a" (fpus)
740 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 794 void test_fcvt(double a)
... ... @@ -907,6 +956,8 @@ void test_floats(void)
907 956 test_fcmp(2, -1);
908 957 test_fcmp(2, 2);
909 958 test_fcmp(2, 3);
  959 + test_fcmp(2, q_nan.d);
  960 + test_fcmp(q_nan.d, -1);
910 961 test_fcvt(0.5);
911 962 test_fcvt(-0.5);
912 963 test_fcvt(1.0/7.0);
... ... @@ -2191,6 +2242,7 @@ void test_fxsave(void)
2191 2242 void test_sse(void)
2192 2243 {
2193 2244 XMMReg r, a, b;
  2245 + int i;
2194 2246  
2195 2247 MMX_OP2(punpcklbw);
2196 2248 MMX_OP2(punpcklwd);
... ... @@ -2354,51 +2406,65 @@ void test_sse(void)
2354 2406 test_sse_comi(2, -1);
2355 2407 test_sse_comi(2, 2);
2356 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 2468 /* float to float/int */
2403 2469 a.s[0] = 2.7;
2404 2470 a.s[1] = 3.4;
... ...