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,28 +1406,40 @@ void OPPROTO op_fildll_FT0_A0(void)
1406 1406
1407 void OPPROTO op_flds_ST0_A0(void) 1407 void OPPROTO op_flds_ST0_A0(void)
1408 { 1408 {
  1409 + int new_fpstt;
  1410 + new_fpstt = (env->fpstt - 1) & 7;
1409 #ifdef USE_FP_CONVERT 1411 #ifdef USE_FP_CONVERT
1410 FP_CONVERT.i32 = ldl((void *)A0); 1412 FP_CONVERT.i32 = ldl((void *)A0);
1411 - ST0 = FP_CONVERT.f; 1413 + env->fpregs[new_fpstt] = FP_CONVERT.f;
1412 #else 1414 #else
1413 - ST0 = ldfl((void *)A0); 1415 + env->fpregs[new_fpstt] = ldfl((void *)A0);
1414 #endif 1416 #endif
  1417 + env->fpstt = new_fpstt;
  1418 + env->fptags[new_fpstt] = 0; /* validate stack entry */
1415 } 1419 }
1416 1420
1417 void OPPROTO op_fldl_ST0_A0(void) 1421 void OPPROTO op_fldl_ST0_A0(void)
1418 { 1422 {
  1423 + int new_fpstt;
  1424 + new_fpstt = (env->fpstt - 1) & 7;
1419 #ifdef USE_FP_CONVERT 1425 #ifdef USE_FP_CONVERT
1420 FP_CONVERT.i64 = ldq((void *)A0); 1426 FP_CONVERT.i64 = ldq((void *)A0);
1421 - ST0 = FP_CONVERT.d; 1427 + env->fpregs[new_fpstt] = FP_CONVERT.d;
1422 #else 1428 #else
1423 - ST0 = ldfq((void *)A0); 1429 + env->fpregs[new_fpstt] = ldfq((void *)A0);
1424 #endif 1430 #endif
  1431 + env->fpstt = new_fpstt;
  1432 + env->fptags[new_fpstt] = 0; /* validate stack entry */
1425 } 1433 }
1426 1434
1427 #ifdef USE_X86LDOUBLE 1435 #ifdef USE_X86LDOUBLE
1428 void OPPROTO op_fldt_ST0_A0(void) 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 #else 1444 #else
1433 void OPPROTO op_fldt_ST0_A0(void) 1445 void OPPROTO op_fldt_ST0_A0(void)
@@ -1441,17 +1453,29 @@ void OPPROTO op_fldt_ST0_A0(void) @@ -1441,17 +1453,29 @@ void OPPROTO op_fldt_ST0_A0(void)
1441 1453
1442 void helper_fild_ST0_A0(void) 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 void helper_fildl_ST0_A0(void) 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 void helper_fildll_ST0_A0(void) 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 void OPPROTO op_fild_ST0_A0(void) 1481 void OPPROTO op_fild_ST0_A0(void)
@@ -1473,32 +1497,44 @@ void OPPROTO op_fildll_ST0_A0(void) @@ -1473,32 +1497,44 @@ void OPPROTO op_fildll_ST0_A0(void)
1473 1497
1474 void OPPROTO op_fild_ST0_A0(void) 1498 void OPPROTO op_fild_ST0_A0(void)
1475 { 1499 {
  1500 + int new_fpstt;
  1501 + new_fpstt = (env->fpstt - 1) & 7;
1476 #ifdef USE_FP_CONVERT 1502 #ifdef USE_FP_CONVERT
1477 FP_CONVERT.i32 = ldsw((void *)A0); 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 #else 1505 #else
1480 - ST0 = (CPU86_LDouble)ldsw((void *)A0); 1506 + env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
1481 #endif 1507 #endif
  1508 + env->fpstt = new_fpstt;
  1509 + env->fptags[new_fpstt] = 0; /* validate stack entry */
1482 } 1510 }
1483 1511
1484 void OPPROTO op_fildl_ST0_A0(void) 1512 void OPPROTO op_fildl_ST0_A0(void)
1485 { 1513 {
  1514 + int new_fpstt;
  1515 + new_fpstt = (env->fpstt - 1) & 7;
1486 #ifdef USE_FP_CONVERT 1516 #ifdef USE_FP_CONVERT
1487 FP_CONVERT.i32 = (int32_t) ldl((void *)A0); 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 #else 1519 #else
1490 - ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0)); 1520 + env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
1491 #endif 1521 #endif
  1522 + env->fpstt = new_fpstt;
  1523 + env->fptags[new_fpstt] = 0; /* validate stack entry */
1492 } 1524 }
1493 1525
1494 void OPPROTO op_fildll_ST0_A0(void) 1526 void OPPROTO op_fildll_ST0_A0(void)
1495 { 1527 {
  1528 + int new_fpstt;
  1529 + new_fpstt = (env->fpstt - 1) & 7;
1496 #ifdef USE_FP_CONVERT 1530 #ifdef USE_FP_CONVERT
1497 FP_CONVERT.i64 = (int64_t) ldq((void *)A0); 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 #else 1533 #else
1500 - ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); 1534 + env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1501 #endif 1535 #endif
  1536 + env->fpstt = new_fpstt;
  1537 + env->fptags[new_fpstt] = 0; /* validate stack entry */
1502 } 1538 }
1503 1539
1504 #endif 1540 #endif
translate-i386.c
@@ -2489,7 +2489,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2489,7 +2489,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2489 2489
2490 switch(op & 7) { 2490 switch(op & 7) {
2491 case 0: 2491 case 0:
2492 - gen_op_fpush();  
2493 switch(op >> 4) { 2492 switch(op >> 4) {
2494 case 0: 2493 case 0:
2495 gen_op_flds_ST0_A0(); 2494 gen_op_flds_ST0_A0();
@@ -2540,7 +2539,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2540,7 +2539,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2540 gen_op_fnstcw_A0(); 2539 gen_op_fnstcw_A0();
2541 break; 2540 break;
2542 case 0x1d: /* fldt mem */ 2541 case 0x1d: /* fldt mem */
2543 - gen_op_fpush();  
2544 gen_op_fldt_ST0_A0(); 2542 gen_op_fldt_ST0_A0();
2545 break; 2543 break;
2546 case 0x1f: /* fstpt mem */ 2544 case 0x1f: /* fstpt mem */
@@ -2557,7 +2555,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2557,7 +2555,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2557 gen_op_fnstsw_A0(); 2555 gen_op_fnstsw_A0();
2558 break; 2556 break;
2559 case 0x3c: /* fbld */ 2557 case 0x3c: /* fbld */
2560 - gen_op_fpush();  
2561 gen_op_fbld_ST0_A0(); 2558 gen_op_fbld_ST0_A0();
2562 break; 2559 break;
2563 case 0x3e: /* fbstp */ 2560 case 0x3e: /* fbstp */
@@ -2565,7 +2562,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2565,7 +2562,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2565 gen_op_fpop(); 2562 gen_op_fpop();
2566 break; 2563 break;
2567 case 0x3d: /* fildll */ 2564 case 0x3d: /* fildll */
2568 - gen_op_fpush();  
2569 gen_op_fildll_ST0_A0(); 2565 gen_op_fildll_ST0_A0();
2570 break; 2566 break;
2571 case 0x3f: /* fistpll */ 2567 case 0x3f: /* fistpll */