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 */ | ... | ... |