make FPU load exception safe

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@305 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-07-01 15:07:14 +00:00
parent 4d40895f2c
commit c39d5b78f6
2 changed files with 50 additions and 18 deletions

View File

@ -1406,28 +1406,40 @@ void OPPROTO op_fildll_FT0_A0(void)
void OPPROTO op_flds_ST0_A0(void) void OPPROTO op_flds_ST0_A0(void)
{ {
int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
#ifdef USE_FP_CONVERT #ifdef USE_FP_CONVERT
FP_CONVERT.i32 = ldl((void *)A0); FP_CONVERT.i32 = ldl((void *)A0);
ST0 = FP_CONVERT.f; env->fpregs[new_fpstt] = FP_CONVERT.f;
#else #else
ST0 = ldfl((void *)A0); env->fpregs[new_fpstt] = ldfl((void *)A0);
#endif #endif
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
void OPPROTO op_fldl_ST0_A0(void) void OPPROTO op_fldl_ST0_A0(void)
{ {
int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
#ifdef USE_FP_CONVERT #ifdef USE_FP_CONVERT
FP_CONVERT.i64 = ldq((void *)A0); FP_CONVERT.i64 = ldq((void *)A0);
ST0 = FP_CONVERT.d; env->fpregs[new_fpstt] = FP_CONVERT.d;
#else #else
ST0 = ldfq((void *)A0); env->fpregs[new_fpstt] = ldfq((void *)A0);
#endif #endif
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
#ifdef USE_X86LDOUBLE #ifdef USE_X86LDOUBLE
void OPPROTO op_fldt_ST0_A0(void) void OPPROTO op_fldt_ST0_A0(void)
{ {
ST0 = *(long double *)A0; int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
env->fpregs[new_fpstt] = *(long double *)A0;
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
#else #else
void OPPROTO op_fldt_ST0_A0(void) void OPPROTO op_fldt_ST0_A0(void)
@ -1441,17 +1453,29 @@ void OPPROTO op_fldt_ST0_A0(void)
void helper_fild_ST0_A0(void) void helper_fild_ST0_A0(void)
{ {
ST0 = (CPU86_LDouble)ldsw((void *)A0); int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
void helper_fildl_ST0_A0(void) void helper_fildl_ST0_A0(void)
{ {
ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0)); int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
void helper_fildll_ST0_A0(void) void helper_fildll_ST0_A0(void)
{ {
ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
void OPPROTO op_fild_ST0_A0(void) void OPPROTO op_fild_ST0_A0(void)
@ -1473,32 +1497,44 @@ void OPPROTO op_fildll_ST0_A0(void)
void OPPROTO op_fild_ST0_A0(void) void OPPROTO op_fild_ST0_A0(void)
{ {
int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
#ifdef USE_FP_CONVERT #ifdef USE_FP_CONVERT
FP_CONVERT.i32 = ldsw((void *)A0); FP_CONVERT.i32 = ldsw((void *)A0);
ST0 = (CPU86_LDouble)FP_CONVERT.i32; env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32;
#else #else
ST0 = (CPU86_LDouble)ldsw((void *)A0); env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0);
#endif #endif
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
void OPPROTO op_fildl_ST0_A0(void) void OPPROTO op_fildl_ST0_A0(void)
{ {
int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
#ifdef USE_FP_CONVERT #ifdef USE_FP_CONVERT
FP_CONVERT.i32 = (int32_t) ldl((void *)A0); FP_CONVERT.i32 = (int32_t) ldl((void *)A0);
ST0 = (CPU86_LDouble)FP_CONVERT.i32; env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32;
#else #else
ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0)); env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0));
#endif #endif
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
void OPPROTO op_fildll_ST0_A0(void) void OPPROTO op_fildll_ST0_A0(void)
{ {
int new_fpstt;
new_fpstt = (env->fpstt - 1) & 7;
#ifdef USE_FP_CONVERT #ifdef USE_FP_CONVERT
FP_CONVERT.i64 = (int64_t) ldq((void *)A0); FP_CONVERT.i64 = (int64_t) ldq((void *)A0);
ST0 = (CPU86_LDouble)FP_CONVERT.i64; env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i64;
#else #else
ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0));
#endif #endif
env->fpstt = new_fpstt;
env->fptags[new_fpstt] = 0; /* validate stack entry */
} }
#endif #endif

View File

@ -2489,7 +2489,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
switch(op & 7) { switch(op & 7) {
case 0: case 0:
gen_op_fpush();
switch(op >> 4) { switch(op >> 4) {
case 0: case 0:
gen_op_flds_ST0_A0(); gen_op_flds_ST0_A0();
@ -2540,7 +2539,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_fnstcw_A0(); gen_op_fnstcw_A0();
break; break;
case 0x1d: /* fldt mem */ case 0x1d: /* fldt mem */
gen_op_fpush();
gen_op_fldt_ST0_A0(); gen_op_fldt_ST0_A0();
break; break;
case 0x1f: /* fstpt mem */ case 0x1f: /* fstpt mem */
@ -2557,7 +2555,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_fnstsw_A0(); gen_op_fnstsw_A0();
break; break;
case 0x3c: /* fbld */ case 0x3c: /* fbld */
gen_op_fpush();
gen_op_fbld_ST0_A0(); gen_op_fbld_ST0_A0();
break; break;
case 0x3e: /* fbstp */ case 0x3e: /* fbstp */
@ -2565,7 +2562,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
gen_op_fpop(); gen_op_fpop();
break; break;
case 0x3d: /* fildll */ case 0x3d: /* fildll */
gen_op_fpush();
gen_op_fildll_ST0_A0(); gen_op_fildll_ST0_A0();
break; break;
case 0x3f: /* fistpll */ case 0x3f: /* fistpll */