Commit 03bfca946a9fdf7a437f28183be36b4bf89b51e9
1 parent
ed2dcdf6
more FPU tests
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@202 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
64 additions
and
1 deletions
tests/test-i386.c
| @@ -9,7 +9,8 @@ | @@ -9,7 +9,8 @@ | ||
| 9 | #include <sys/mman.h> | 9 | #include <sys/mman.h> |
| 10 | #include <asm/vm86.h> | 10 | #include <asm/vm86.h> |
| 11 | 11 | ||
| 12 | -#define TEST_CMOV 0 | 12 | +#define TEST_CMOV 0 |
| 13 | +#define TEST_FCOMI 0 | ||
| 13 | 14 | ||
| 14 | #define xglue(x, y) x ## y | 15 | #define xglue(x, y) x ## y |
| 15 | #define glue(x, y) xglue(x, y) | 16 | #define glue(x, y) xglue(x, y) |
| @@ -510,6 +511,16 @@ void test_fcmp(double a, double b) | @@ -510,6 +511,16 @@ void test_fcmp(double a, double b) | ||
| 510 | a, b, a > b); | 511 | a, b, a > b); |
| 511 | printf("(%f<=%f)=%d\n", | 512 | printf("(%f<=%f)=%d\n", |
| 512 | a, b, a >= b); | 513 | a, b, a >= b); |
| 514 | + if (TEST_FCOMI) { | ||
| 515 | + unsigned int eflags; | ||
| 516 | + /* test f(u)comi instruction */ | ||
| 517 | + asm("fcomi %2, %1\n" | ||
| 518 | + "pushf\n" | ||
| 519 | + "pop %0\n" | ||
| 520 | + : "=r" (eflags) | ||
| 521 | + : "t" (a), "u" (b)); | ||
| 522 | + printf("fcomi(%f %f)=%08x\n", a, b, eflags & (CC_Z | CC_P | CC_C)); | ||
| 523 | + } | ||
| 513 | } | 524 | } |
| 514 | 525 | ||
| 515 | void test_fcvt(double a) | 526 | void test_fcvt(double a) |
| @@ -556,6 +567,57 @@ void test_fbcd(double a) | @@ -556,6 +567,57 @@ void test_fbcd(double a) | ||
| 556 | a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b); | 567 | a, bcd[4], bcd[3], bcd[2], bcd[1], bcd[0], b); |
| 557 | } | 568 | } |
| 558 | 569 | ||
| 570 | +#define TEST_ENV(env, prefix)\ | ||
| 571 | +{\ | ||
| 572 | + memset((env), 0xaa, sizeof(*(env)));\ | ||
| 573 | + asm("fld1\n"\ | ||
| 574 | + prefix "fnstenv %1\n"\ | ||
| 575 | + prefix "fldenv %1\n"\ | ||
| 576 | + : "=t" (res) : "m" (*(env)) : "st");\ | ||
| 577 | + printf("res=%f\n", res);\ | ||
| 578 | + printf("fpuc=%04x fpus=%04x fptag=%04x\n",\ | ||
| 579 | + (env)->fpuc,\ | ||
| 580 | + (env)->fpus & 0xff00,\ | ||
| 581 | + (env)->fptag);\ | ||
| 582 | + memset((env), 0xaa, sizeof(*(env)));\ | ||
| 583 | + asm("fld1\n"\ | ||
| 584 | + prefix "fnsave %1\n"\ | ||
| 585 | + prefix "frstor %1\n"\ | ||
| 586 | + : "=t" (res) : "m" (*(env)) : "st");\ | ||
| 587 | + printf("res=%f\n", res);\ | ||
| 588 | + printf("fpuc=%04x fpus=%04x fptag=%04x\n",\ | ||
| 589 | + (env)->fpuc,\ | ||
| 590 | + (env)->fpus & 0xff00,\ | ||
| 591 | + (env)->fptag);\ | ||
| 592 | + printf("ST(0) = %Lf\n",\ | ||
| 593 | + (env)->fpregs[0]);\ | ||
| 594 | +} | ||
| 595 | + | ||
| 596 | +void test_fenv(void) | ||
| 597 | +{ | ||
| 598 | + struct __attribute__((packed)) { | ||
| 599 | + uint16_t fpuc; | ||
| 600 | + uint16_t dummy1; | ||
| 601 | + uint16_t fpus; | ||
| 602 | + uint16_t dummy2; | ||
| 603 | + uint16_t fptag; | ||
| 604 | + uint16_t dummy3; | ||
| 605 | + uint32_t ignored[4]; | ||
| 606 | + long double fpregs[8]; | ||
| 607 | + } float_env32; | ||
| 608 | + struct __attribute__((packed)) { | ||
| 609 | + uint16_t fpuc; | ||
| 610 | + uint16_t fpus; | ||
| 611 | + uint16_t fptag; | ||
| 612 | + uint16_t ignored[4]; | ||
| 613 | + long double fpregs[8]; | ||
| 614 | + } float_env16; | ||
| 615 | + double res; | ||
| 616 | + | ||
| 617 | + TEST_ENV(&float_env16, "data16 "); | ||
| 618 | + TEST_ENV(&float_env32, ""); | ||
| 619 | +} | ||
| 620 | + | ||
| 559 | void test_floats(void) | 621 | void test_floats(void) |
| 560 | { | 622 | { |
| 561 | test_fops(2, 3); | 623 | test_fops(2, 3); |
| @@ -569,6 +631,7 @@ void test_floats(void) | @@ -569,6 +631,7 @@ void test_floats(void) | ||
| 569 | test_fconst(); | 631 | test_fconst(); |
| 570 | test_fbcd(1234567890123456); | 632 | test_fbcd(1234567890123456); |
| 571 | test_fbcd(-123451234567890); | 633 | test_fbcd(-123451234567890); |
| 634 | + test_fenv(); | ||
| 572 | } | 635 | } |
| 573 | 636 | ||
| 574 | /**********************************************/ | 637 | /**********************************************/ |