Commit c39d5b78f62b0bdc10b9371c33e754ee1ba50f73
1 parent
4d40895f
make FPU load exception safe
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@305 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
50 additions
and
18 deletions
op-i386.c
| ... | ... | @@ -1406,28 +1406,40 @@ void OPPROTO op_fildll_FT0_A0(void) |
| 1406 | 1406 | |
| 1407 | 1407 | void OPPROTO op_flds_ST0_A0(void) |
| 1408 | 1408 | { |
| 1409 | + int new_fpstt; | |
| 1410 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1409 | 1411 | #ifdef USE_FP_CONVERT |
| 1410 | 1412 | FP_CONVERT.i32 = ldl((void *)A0); |
| 1411 | - ST0 = FP_CONVERT.f; | |
| 1413 | + env->fpregs[new_fpstt] = FP_CONVERT.f; | |
| 1412 | 1414 | #else |
| 1413 | - ST0 = ldfl((void *)A0); | |
| 1415 | + env->fpregs[new_fpstt] = ldfl((void *)A0); | |
| 1414 | 1416 | #endif |
| 1417 | + env->fpstt = new_fpstt; | |
| 1418 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1415 | 1419 | } |
| 1416 | 1420 | |
| 1417 | 1421 | void OPPROTO op_fldl_ST0_A0(void) |
| 1418 | 1422 | { |
| 1423 | + int new_fpstt; | |
| 1424 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1419 | 1425 | #ifdef USE_FP_CONVERT |
| 1420 | 1426 | FP_CONVERT.i64 = ldq((void *)A0); |
| 1421 | - ST0 = FP_CONVERT.d; | |
| 1427 | + env->fpregs[new_fpstt] = FP_CONVERT.d; | |
| 1422 | 1428 | #else |
| 1423 | - ST0 = ldfq((void *)A0); | |
| 1429 | + env->fpregs[new_fpstt] = ldfq((void *)A0); | |
| 1424 | 1430 | #endif |
| 1431 | + env->fpstt = new_fpstt; | |
| 1432 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1425 | 1433 | } |
| 1426 | 1434 | |
| 1427 | 1435 | #ifdef USE_X86LDOUBLE |
| 1428 | 1436 | void OPPROTO op_fldt_ST0_A0(void) |
| 1429 | 1437 | { |
| 1430 | - ST0 = *(long double *)A0; | |
| 1438 | + int new_fpstt; | |
| 1439 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1440 | + env->fpregs[new_fpstt] = *(long double *)A0; | |
| 1441 | + env->fpstt = new_fpstt; | |
| 1442 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1431 | 1443 | } |
| 1432 | 1444 | #else |
| 1433 | 1445 | void OPPROTO op_fldt_ST0_A0(void) |
| ... | ... | @@ -1441,17 +1453,29 @@ void OPPROTO op_fldt_ST0_A0(void) |
| 1441 | 1453 | |
| 1442 | 1454 | void helper_fild_ST0_A0(void) |
| 1443 | 1455 | { |
| 1444 | - ST0 = (CPU86_LDouble)ldsw((void *)A0); | |
| 1456 | + int new_fpstt; | |
| 1457 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1458 | + env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0); | |
| 1459 | + env->fpstt = new_fpstt; | |
| 1460 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1445 | 1461 | } |
| 1446 | 1462 | |
| 1447 | 1463 | void helper_fildl_ST0_A0(void) |
| 1448 | 1464 | { |
| 1449 | - ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0)); | |
| 1465 | + int new_fpstt; | |
| 1466 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1467 | + env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0)); | |
| 1468 | + env->fpstt = new_fpstt; | |
| 1469 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1450 | 1470 | } |
| 1451 | 1471 | |
| 1452 | 1472 | void helper_fildll_ST0_A0(void) |
| 1453 | 1473 | { |
| 1454 | - ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); | |
| 1474 | + int new_fpstt; | |
| 1475 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1476 | + env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0)); | |
| 1477 | + env->fpstt = new_fpstt; | |
| 1478 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1455 | 1479 | } |
| 1456 | 1480 | |
| 1457 | 1481 | void OPPROTO op_fild_ST0_A0(void) |
| ... | ... | @@ -1473,32 +1497,44 @@ void OPPROTO op_fildll_ST0_A0(void) |
| 1473 | 1497 | |
| 1474 | 1498 | void OPPROTO op_fild_ST0_A0(void) |
| 1475 | 1499 | { |
| 1500 | + int new_fpstt; | |
| 1501 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1476 | 1502 | #ifdef USE_FP_CONVERT |
| 1477 | 1503 | FP_CONVERT.i32 = ldsw((void *)A0); |
| 1478 | - ST0 = (CPU86_LDouble)FP_CONVERT.i32; | |
| 1504 | + env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32; | |
| 1479 | 1505 | #else |
| 1480 | - ST0 = (CPU86_LDouble)ldsw((void *)A0); | |
| 1506 | + env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0); | |
| 1481 | 1507 | #endif |
| 1508 | + env->fpstt = new_fpstt; | |
| 1509 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1482 | 1510 | } |
| 1483 | 1511 | |
| 1484 | 1512 | void OPPROTO op_fildl_ST0_A0(void) |
| 1485 | 1513 | { |
| 1514 | + int new_fpstt; | |
| 1515 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1486 | 1516 | #ifdef USE_FP_CONVERT |
| 1487 | 1517 | FP_CONVERT.i32 = (int32_t) ldl((void *)A0); |
| 1488 | - ST0 = (CPU86_LDouble)FP_CONVERT.i32; | |
| 1518 | + env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32; | |
| 1489 | 1519 | #else |
| 1490 | - ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0)); | |
| 1520 | + env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0)); | |
| 1491 | 1521 | #endif |
| 1522 | + env->fpstt = new_fpstt; | |
| 1523 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1492 | 1524 | } |
| 1493 | 1525 | |
| 1494 | 1526 | void OPPROTO op_fildll_ST0_A0(void) |
| 1495 | 1527 | { |
| 1528 | + int new_fpstt; | |
| 1529 | + new_fpstt = (env->fpstt - 1) & 7; | |
| 1496 | 1530 | #ifdef USE_FP_CONVERT |
| 1497 | 1531 | FP_CONVERT.i64 = (int64_t) ldq((void *)A0); |
| 1498 | - ST0 = (CPU86_LDouble)FP_CONVERT.i64; | |
| 1532 | + env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i64; | |
| 1499 | 1533 | #else |
| 1500 | - ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); | |
| 1534 | + env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0)); | |
| 1501 | 1535 | #endif |
| 1536 | + env->fpstt = new_fpstt; | |
| 1537 | + env->fptags[new_fpstt] = 0; /* validate stack entry */ | |
| 1502 | 1538 | } |
| 1503 | 1539 | |
| 1504 | 1540 | #endif | ... | ... |
translate-i386.c
| ... | ... | @@ -2489,7 +2489,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
| 2489 | 2489 | |
| 2490 | 2490 | switch(op & 7) { |
| 2491 | 2491 | case 0: |
| 2492 | - gen_op_fpush(); | |
| 2493 | 2492 | switch(op >> 4) { |
| 2494 | 2493 | case 0: |
| 2495 | 2494 | gen_op_flds_ST0_A0(); |
| ... | ... | @@ -2540,7 +2539,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
| 2540 | 2539 | gen_op_fnstcw_A0(); |
| 2541 | 2540 | break; |
| 2542 | 2541 | case 0x1d: /* fldt mem */ |
| 2543 | - gen_op_fpush(); | |
| 2544 | 2542 | gen_op_fldt_ST0_A0(); |
| 2545 | 2543 | break; |
| 2546 | 2544 | case 0x1f: /* fstpt mem */ |
| ... | ... | @@ -2557,7 +2555,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
| 2557 | 2555 | gen_op_fnstsw_A0(); |
| 2558 | 2556 | break; |
| 2559 | 2557 | case 0x3c: /* fbld */ |
| 2560 | - gen_op_fpush(); | |
| 2561 | 2558 | gen_op_fbld_ST0_A0(); |
| 2562 | 2559 | break; |
| 2563 | 2560 | case 0x3e: /* fbstp */ |
| ... | ... | @@ -2565,7 +2562,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) |
| 2565 | 2562 | gen_op_fpop(); |
| 2566 | 2563 | break; |
| 2567 | 2564 | case 0x3d: /* fildll */ |
| 2568 | - gen_op_fpush(); | |
| 2569 | 2565 | gen_op_fildll_ST0_A0(); |
| 2570 | 2566 | break; |
| 2571 | 2567 | case 0x3f: /* fistpll */ | ... | ... |