diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-07-01 15:07:14 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-07-01 15:07:14 +0000 |
commit | c39d5b78f62b0bdc10b9371c33e754ee1ba50f73 (patch) | |
tree | b05c0c4467b85182e6b928eb69d6da691dfc8f43 | |
parent | 4d40895f2c30354c48ad9181e366e8d738f9b4d7 (diff) | |
download | qemu-c39d5b78f62b0bdc10b9371c33e754ee1ba50f73.zip qemu-c39d5b78f62b0bdc10b9371c33e754ee1ba50f73.tar.gz qemu-c39d5b78f62b0bdc10b9371c33e754ee1ba50f73.tar.bz2 |
make FPU load exception safe
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@305 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | op-i386.c | 64 | ||||
-rw-r--r-- | translate-i386.c | 4 |
2 files changed, 50 insertions, 18 deletions
@@ -1406,28 +1406,40 @@ void OPPROTO op_fildll_FT0_A0(void) void OPPROTO op_flds_ST0_A0(void) { + int new_fpstt; + new_fpstt = (env->fpstt - 1) & 7; #ifdef USE_FP_CONVERT FP_CONVERT.i32 = ldl((void *)A0); - ST0 = FP_CONVERT.f; + env->fpregs[new_fpstt] = FP_CONVERT.f; #else - ST0 = ldfl((void *)A0); + env->fpregs[new_fpstt] = ldfl((void *)A0); #endif + env->fpstt = new_fpstt; + env->fptags[new_fpstt] = 0; /* validate stack entry */ } void OPPROTO op_fldl_ST0_A0(void) { + int new_fpstt; + new_fpstt = (env->fpstt - 1) & 7; #ifdef USE_FP_CONVERT FP_CONVERT.i64 = ldq((void *)A0); - ST0 = FP_CONVERT.d; + env->fpregs[new_fpstt] = FP_CONVERT.d; #else - ST0 = ldfq((void *)A0); + env->fpregs[new_fpstt] = ldfq((void *)A0); #endif + env->fpstt = new_fpstt; + env->fptags[new_fpstt] = 0; /* validate stack entry */ } #ifdef USE_X86LDOUBLE 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 void OPPROTO op_fldt_ST0_A0(void) @@ -1441,17 +1453,29 @@ void OPPROTO op_fldt_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) { - 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) { - 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) @@ -1473,32 +1497,44 @@ void OPPROTO op_fildll_ST0_A0(void) void OPPROTO op_fild_ST0_A0(void) { + int new_fpstt; + new_fpstt = (env->fpstt - 1) & 7; #ifdef USE_FP_CONVERT FP_CONVERT.i32 = ldsw((void *)A0); - ST0 = (CPU86_LDouble)FP_CONVERT.i32; + env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32; #else - ST0 = (CPU86_LDouble)ldsw((void *)A0); + env->fpregs[new_fpstt] = (CPU86_LDouble)ldsw((void *)A0); #endif + env->fpstt = new_fpstt; + env->fptags[new_fpstt] = 0; /* validate stack entry */ } void OPPROTO op_fildl_ST0_A0(void) { + int new_fpstt; + new_fpstt = (env->fpstt - 1) & 7; #ifdef USE_FP_CONVERT FP_CONVERT.i32 = (int32_t) ldl((void *)A0); - ST0 = (CPU86_LDouble)FP_CONVERT.i32; + env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i32; #else - ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0)); + env->fpregs[new_fpstt] = (CPU86_LDouble)((int32_t)ldl((void *)A0)); #endif + env->fpstt = new_fpstt; + env->fptags[new_fpstt] = 0; /* validate stack entry */ } void OPPROTO op_fildll_ST0_A0(void) { + int new_fpstt; + new_fpstt = (env->fpstt - 1) & 7; #ifdef USE_FP_CONVERT FP_CONVERT.i64 = (int64_t) ldq((void *)A0); - ST0 = (CPU86_LDouble)FP_CONVERT.i64; + env->fpregs[new_fpstt] = (CPU86_LDouble)FP_CONVERT.i64; #else - ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); + env->fpregs[new_fpstt] = (CPU86_LDouble)((int64_t)ldq((void *)A0)); #endif + env->fpstt = new_fpstt; + env->fptags[new_fpstt] = 0; /* validate stack entry */ } #endif diff --git a/translate-i386.c b/translate-i386.c index bfc9884..c8bd12f 100644 --- a/translate-i386.c +++ b/translate-i386.c @@ -2489,7 +2489,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) switch(op & 7) { case 0: - gen_op_fpush(); switch(op >> 4) { case 0: gen_op_flds_ST0_A0(); @@ -2540,7 +2539,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) gen_op_fnstcw_A0(); break; case 0x1d: /* fldt mem */ - gen_op_fpush(); gen_op_fldt_ST0_A0(); break; case 0x1f: /* fstpt mem */ @@ -2557,7 +2555,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) gen_op_fnstsw_A0(); break; case 0x3c: /* fbld */ - gen_op_fpush(); gen_op_fbld_ST0_A0(); break; case 0x3e: /* fbstp */ @@ -2565,7 +2562,6 @@ long disas_insn(DisasContext *s, uint8_t *pc_start) gen_op_fpop(); break; case 0x3d: /* fildll */ - gen_op_fpush(); gen_op_fildll_ST0_A0(); break; case 0x3f: /* fistpll */ |