Commit 77729c244527432e5795ae1811c2d0226b6cff9b

Authored by bellard
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 2304 case 0x58 ... 0x5f: /* pop */
2305 2305 ot = dflag ? OT_LONG : OT_WORD;
2306 2306 gen_pop_T0(s);
2307   - gen_op_mov_reg_T0[ot][b & 7]();
  2307 + /* NOTE: order is important for pop %sp */
2308 2308 gen_pop_update(s);
  2309 + gen_op_mov_reg_T0[ot][b & 7]();
2309 2310 break;
2310 2311 case 0x60: /* pusha */
2311 2312 gen_pusha(s);
... ... @@ -2326,11 +2327,20 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2326 2327 case 0x8f: /* pop Ev */
2327 2328 ot = dflag ? OT_LONG : OT_WORD;
2328 2329 modrm = ldub_code(s->pc++);
  2330 + mod = (modrm >> 6) & 3;
2329 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 2344 break;
2335 2345 case 0xc8: /* enter */
2336 2346 {
... ...