Commit c39d5b78f62b0bdc10b9371c33e754ee1ba50f73

Authored by bellard
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 */
... ...