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,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 {