Commit 77729c244527432e5795ae1811c2d0226b6cff9b
1 parent
d71b9a8b
fixed pop %sp bug
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@458 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
15 additions
and
5 deletions
target-i386/translate.c
@@ -2304,8 +2304,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2304,8 +2304,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2304 | case 0x58 ... 0x5f: /* pop */ | 2304 | case 0x58 ... 0x5f: /* pop */ |
2305 | ot = dflag ? OT_LONG : OT_WORD; | 2305 | ot = dflag ? OT_LONG : OT_WORD; |
2306 | gen_pop_T0(s); | 2306 | gen_pop_T0(s); |
2307 | - gen_op_mov_reg_T0[ot][b & 7](); | 2307 | + /* NOTE: order is important for pop %sp */ |
2308 | gen_pop_update(s); | 2308 | gen_pop_update(s); |
2309 | + gen_op_mov_reg_T0[ot][b & 7](); | ||
2309 | break; | 2310 | break; |
2310 | case 0x60: /* pusha */ | 2311 | case 0x60: /* pusha */ |
2311 | gen_pusha(s); | 2312 | gen_pusha(s); |
@@ -2326,11 +2327,20 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | @@ -2326,11 +2327,20 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) | ||
2326 | case 0x8f: /* pop Ev */ | 2327 | case 0x8f: /* pop Ev */ |
2327 | ot = dflag ? OT_LONG : OT_WORD; | 2328 | ot = dflag ? OT_LONG : OT_WORD; |
2328 | modrm = ldub_code(s->pc++); | 2329 | modrm = ldub_code(s->pc++); |
2330 | + mod = (modrm >> 6) & 3; | ||
2329 | gen_pop_T0(s); | 2331 | gen_pop_T0(s); |
2330 | - s->popl_esp_hack = 2 << dflag; | ||
2331 | - gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); | ||
2332 | - s->popl_esp_hack = 0; | ||
2333 | - gen_pop_update(s); | 2332 | + if (mod == 3) { |
2333 | + /* NOTE: order is important for pop %sp */ | ||
2334 | + gen_pop_update(s); | ||
2335 | + rm = modrm & 7; | ||
2336 | + gen_op_mov_reg_T0[ot][rm](); | ||
2337 | + } else { | ||
2338 | + /* NOTE: order is important too for MMU exceptions */ | ||
2339 | + s->popl_esp_hack = 2 << dflag; | ||
2340 | + gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1); | ||
2341 | + s->popl_esp_hack = 0; | ||
2342 | + gen_pop_update(s); | ||
2343 | + } | ||
2334 | break; | 2344 | break; |
2335 | case 0xc8: /* enter */ | 2345 | case 0xc8: /* enter */ |
2336 | { | 2346 | { |