/[qemu]/qemu/translate-i386.c
ViewVC logotype

Diff of /qemu/translate-i386.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.38 by bellard, Tue May 27 23:24:27 2003 UTC revision 1.39 by bellard, Thu May 29 20:04:28 2003 UTC
# Line 1273  static void gen_pop_T0(DisasContext *s) Line 1273  static void gen_pop_T0(DisasContext *s)
1273      }      }
1274  }  }
1275    
1276  static void gen_pop_update(DisasContext *s)  static inline void gen_stack_update(DisasContext *s, int addend)
1277  {  {
1278      if (s->ss32) {      if (s->ss32) {
1279          if (s->dflag)          if (addend == 2)
             gen_op_addl_ESP_4();  
         else  
1280              gen_op_addl_ESP_2();              gen_op_addl_ESP_2();
1281            else if (addend == 4)
1282                gen_op_addl_ESP_4();
1283            else
1284                gen_op_addl_ESP_im(addend);
1285      } else {      } else {
1286          if (s->dflag)          if (addend == 2)
1287                gen_op_addw_ESP_2();
1288            else if (addend == 4)
1289              gen_op_addw_ESP_4();              gen_op_addw_ESP_4();
1290          else          else
1291              gen_op_addw_ESP_2();              gen_op_addw_ESP_im(addend);
1292      }      }
1293  }  }
1294    
1295    static void gen_pop_update(DisasContext *s)
1296    {
1297        gen_stack_update(s, 2 << s->dflag);
1298    }
1299    
1300    static void gen_stack_A0(DisasContext *s)
1301    {
1302        gen_op_movl_A0_ESP();
1303        if (!s->ss32)
1304            gen_op_andl_A0_ffff();
1305        gen_op_movl_T1_A0();
1306        if (s->addseg)
1307            gen_op_addl_A0_seg(offsetof(CPUX86State,seg_cache[R_SS].base));
1308    }
1309    
1310  /* NOTE: wrap around in 16 bit not fully handled */  /* NOTE: wrap around in 16 bit not fully handled */
1311  static void gen_pusha(DisasContext *s)  static void gen_pusha(DisasContext *s)
1312  {  {
# Line 1957  long disas_insn(DisasContext *s, uint8_t Line 1976  long disas_insn(DisasContext *s, uint8_t
1976          }          }
1977          break;          break;
1978      case 0xc9: /* leave */      case 0xc9: /* leave */
1979          /* XXX: exception not precise (ESP is update before potential exception) */          /* XXX: exception not precise (ESP is updated before potential exception) */
1980          if (s->ss32) {          if (s->ss32) {
1981              gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();              gen_op_mov_TN_reg[OT_LONG][0][R_EBP]();
1982              gen_op_mov_reg_T0[OT_LONG][R_ESP]();              gen_op_mov_reg_T0[OT_LONG][R_ESP]();
# Line 2453  long disas_insn(DisasContext *s, uint8_t Line 2472  long disas_insn(DisasContext *s, uint8_t
2472                      break;                      break;
2473                  }                  }
2474                  break;                  break;
2475                case 0x0c: /* fldenv mem */
2476                    gen_op_fldenv_A0(s->dflag);
2477                    break;
2478              case 0x0d: /* fldcw mem */              case 0x0d: /* fldcw mem */
2479                  gen_op_fldcw_A0();                  gen_op_fldcw_A0();
2480                  break;                  break;
2481                case 0x0e: /* fnstenv mem */
2482                    gen_op_fnstenv_A0(s->dflag);
2483                    break;
2484              case 0x0f: /* fnstcw mem */              case 0x0f: /* fnstcw mem */
2485                  gen_op_fnstcw_A0();                  gen_op_fnstcw_A0();
2486                  break;                  break;
# Line 2467  long disas_insn(DisasContext *s, uint8_t Line 2492  long disas_insn(DisasContext *s, uint8_t
2492                  gen_op_fstt_ST0_A0();                  gen_op_fstt_ST0_A0();
2493                  gen_op_fpop();                  gen_op_fpop();
2494                  break;                  break;
2495                case 0x2c: /* frstor mem */
2496                    gen_op_frstor_A0(s->dflag);
2497                    break;
2498                case 0x2e: /* fnsave mem */
2499                    gen_op_fnsave_A0(s->dflag);
2500                    break;
2501              case 0x2f: /* fnstsw mem */              case 0x2f: /* fnstsw mem */
2502                  gen_op_fnstsw_A0();                  gen_op_fnstsw_A0();
2503                  break;                  break;
# Line 2672  long disas_insn(DisasContext *s, uint8_t Line 2703  long disas_insn(DisasContext *s, uint8_t
2703                      goto illegal_op;                      goto illegal_op;
2704                  }                  }
2705                  break;                  break;
2706                case 0x1d: /* fucomi */
2707                    if (s->cc_op != CC_OP_DYNAMIC)
2708                        gen_op_set_cc_op(s->cc_op);
2709                    gen_op_fmov_FT0_STN(opreg);
2710                    gen_op_fucomi_ST0_FT0();
2711                    s->cc_op = CC_OP_EFLAGS;
2712                    break;
2713                case 0x1e: /* fcomi */
2714                    if (s->cc_op != CC_OP_DYNAMIC)
2715                        gen_op_set_cc_op(s->cc_op);
2716                    gen_op_fmov_FT0_STN(opreg);
2717                    gen_op_fcomi_ST0_FT0();
2718                    s->cc_op = CC_OP_EFLAGS;
2719                    break;
2720              case 0x2a: /* fst sti */              case 0x2a: /* fst sti */
2721                  gen_op_fmov_STN_ST0(opreg);                  gen_op_fmov_STN_ST0(opreg);
2722                  break;                  break;
# Line 2709  long disas_insn(DisasContext *s, uint8_t Line 2754  long disas_insn(DisasContext *s, uint8_t
2754                      goto illegal_op;                      goto illegal_op;
2755                  }                  }
2756                  break;                  break;
2757                case 0x3d: /* fucomip */
2758                    if (s->cc_op != CC_OP_DYNAMIC)
2759                        gen_op_set_cc_op(s->cc_op);
2760                    gen_op_fmov_FT0_STN(opreg);
2761                    gen_op_fucomi_ST0_FT0();
2762                    gen_op_fpop();
2763                    s->cc_op = CC_OP_EFLAGS;
2764                    break;
2765                case 0x3e: /* fcomip */
2766                    if (s->cc_op != CC_OP_DYNAMIC)
2767                        gen_op_set_cc_op(s->cc_op);
2768                    gen_op_fmov_FT0_STN(opreg);
2769                    gen_op_fcomi_ST0_FT0();
2770                    gen_op_fpop();
2771                    s->cc_op = CC_OP_EFLAGS;
2772                    break;
2773              default:              default:
2774                  goto illegal_op;                  goto illegal_op;
2775              }              }
# Line 2901  long disas_insn(DisasContext *s, uint8_t Line 2962  long disas_insn(DisasContext *s, uint8_t
2962          val = ldsw(s->pc);          val = ldsw(s->pc);
2963          s->pc += 2;          s->pc += 2;
2964          gen_pop_T0(s);          gen_pop_T0(s);
2965          if (s->ss32)          gen_stack_update(s, val + (2 << s->dflag));
             gen_op_addl_ESP_im(val + (2 << s->dflag));  
         else  
             gen_op_addw_ESP_im(val + (2 << s->dflag));  
2966          if (s->dflag == 0)          if (s->dflag == 0)
2967              gen_op_andl_T0_ffff();              gen_op_andl_T0_ffff();
2968          gen_op_jmp_T0();          gen_op_jmp_T0();
# Line 2919  long disas_insn(DisasContext *s, uint8_t Line 2977  long disas_insn(DisasContext *s, uint8_t
2977          s->is_jmp = 1;          s->is_jmp = 1;
2978          break;          break;
2979      case 0xca: /* lret im */      case 0xca: /* lret im */
         /* XXX: not restartable */  
2980          val = ldsw(s->pc);          val = ldsw(s->pc);
2981          s->pc += 2;          s->pc += 2;
2982        do_lret:
2983            gen_stack_A0(s);
2984          /* pop offset */          /* pop offset */
2985          gen_pop_T0(s);          gen_op_ld_T0_A0[1 + s->dflag]();
2986          if (s->dflag == 0)          if (s->dflag == 0)
2987              gen_op_andl_T0_ffff();              gen_op_andl_T0_ffff();
2988            /* NOTE: keeping EIP updated is not a problem in case of
2989               exception */
2990          gen_op_jmp_T0();          gen_op_jmp_T0();
         gen_pop_update(s);  
2991          /* pop selector */          /* pop selector */
2992          gen_pop_T0(s);          gen_op_addl_A0_im(2 << s->dflag);
2993            gen_op_ld_T0_A0[1 + s->dflag]();
2994          gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);          gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);
         gen_pop_update(s);  
2995          /* add stack offset */          /* add stack offset */
2996          if (s->ss32)          gen_stack_update(s, val + (4 << s->dflag));
             gen_op_addl_ESP_im(val);  
         else  
             gen_op_addw_ESP_im(val);  
2997          s->is_jmp = 1;          s->is_jmp = 1;
2998          break;          break;
2999      case 0xcb: /* lret */      case 0xcb: /* lret */
3000          /* XXX: not restartable */          val = 0;
3001          /* pop offset */          goto do_lret;
         gen_pop_T0(s);  
         if (s->dflag == 0)  
             gen_op_andl_T0_ffff();  
         gen_op_jmp_T0();  
         gen_pop_update(s);  
         /* pop selector */  
         gen_pop_T0(s);  
         gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);  
         gen_pop_update(s);  
         s->is_jmp = 1;  
         break;  
3002      case 0xcf: /* iret */      case 0xcf: /* iret */
3003          if (s->vm86 && s->iopl != 3) {          if (s->vm86 && s->iopl != 3) {
3004              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3005          } else {          } else {
3006              /* XXX: not restartable */              /* XXX: not restartable */
3007                gen_stack_A0(s);
3008              /* pop offset */              /* pop offset */
3009              gen_pop_T0(s);              gen_op_ld_T0_A0[1 + s->dflag]();
3010              if (s->dflag == 0)              if (s->dflag == 0)
3011                  gen_op_andl_T0_ffff();                  gen_op_andl_T0_ffff();
3012              gen_op_jmp_T0();              /* NOTE: keeping EIP updated is not a problem in case of
3013              gen_pop_update(s);                 exception */
3014                gen_op_jmp_T0();
3015              /* pop selector */              /* pop selector */
3016              gen_pop_T0(s);              gen_op_addl_A0_im(2 << s->dflag);
3017              gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);              gen_op_ld_T0_A0[1 + s->dflag]();
             gen_pop_update(s);  
3018              /* pop eflags */              /* pop eflags */
3019              gen_pop_T0(s);              gen_op_addl_A0_im(2 << s->dflag);
3020                gen_op_ld_T1_A0[1 + s->dflag]();
3021                gen_movl_seg_T0(s, R_CS, pc_start - s->cs_base);
3022                gen_op_movl_T0_T1();
3023              if (s->dflag) {              if (s->dflag) {
3024                  gen_op_movl_eflags_T0();                  gen_op_movl_eflags_T0();
3025              } else {              } else {
3026                  gen_op_movw_eflags_T0();                  gen_op_movw_eflags_T0();
3027              }              }
3028              gen_pop_update(s);              gen_stack_update(s, (6 << s->dflag));
3029              s->cc_op = CC_OP_EFLAGS;              s->cc_op = CC_OP_EFLAGS;
3030          }          }
3031          s->is_jmp = 1;          s->is_jmp = 1;
# Line 2997  long disas_insn(DisasContext *s, uint8_t Line 3047  long disas_insn(DisasContext *s, uint8_t
3047      case 0x9a: /* lcall im */      case 0x9a: /* lcall im */
3048          {          {
3049              unsigned int selector, offset;              unsigned int selector, offset;
3050                /* XXX: not restartable */
3051    
3052              ot = dflag ? OT_LONG : OT_WORD;              ot = dflag ? OT_LONG : OT_WORD;
3053              offset = insn_get(s, ot);              offset = insn_get(s, ot);
# Line 3613  static uint16_t opc_write_flags[NB_OPS] Line 3664  static uint16_t opc_write_flags[NB_OPS]
3664      [INDEX_op_cmpxchg8b] = CC_Z,      [INDEX_op_cmpxchg8b] = CC_Z,
3665      [INDEX_op_lar] = CC_Z,      [INDEX_op_lar] = CC_Z,
3666      [INDEX_op_lsl] = CC_Z,      [INDEX_op_lsl] = CC_Z,
3667        [INDEX_op_fcomi_ST0_FT0] = CC_Z | CC_P | CC_C,
3668        [INDEX_op_fucomi_ST0_FT0] = CC_Z | CC_P | CC_C,
3669  };  };
3670    
3671  /* simpler form of an operation if no flags need to be generated */  /* simpler form of an operation if no flags need to be generated */

Legend:
Removed from v.1.38  
changed lines
  Added in v.1.39

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26