/[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.52 by bellard, Sat Jul 26 12:06:08 2003 UTC revision 1.53 by bellard, Sat Jul 26 17:59:00 2003 UTC
# Line 52  typedef struct DisasContext { Line 52  typedef struct DisasContext {
52                     static state change (stop translation) */                     static state change (stop translation) */
53      /* current block context */      /* current block context */
54      uint8_t *cs_base; /* base of CS segment */      uint8_t *cs_base; /* base of CS segment */
55        int pe;     /* protected mode */
56      int code32; /* 32 bit code segment */      int code32; /* 32 bit code segment */
57      int ss32;   /* 32 bit stack segment */      int ss32;   /* 32 bit stack segment */
58      int cc_op;  /* current CC operation */      int cc_op;  /* current CC operation */
# Line 989  static void gen_lea_modrm(DisasContext * Line 990  static void gen_lea_modrm(DisasContext *
990          if (base >= 0) {          if (base >= 0) {
991              /* for correct popl handling with esp */              /* for correct popl handling with esp */
992              if (base == 4 && s->popl_esp_hack)              if (base == 4 && s->popl_esp_hack)
993                  disp += 4;                  disp += s->popl_esp_hack;
994              gen_op_movl_A0_reg[base]();              gen_op_movl_A0_reg[base]();
995              if (disp != 0)              if (disp != 0)
996                  gen_op_addl_A0_im(disp);                  gen_op_addl_A0_im(disp);
# Line 1272  static void gen_setcc(DisasContext *s, i Line 1273  static void gen_setcc(DisasContext *s, i
1273  /* move T0 to seg_reg and compute if the CPU state may change */  /* move T0 to seg_reg and compute if the CPU state may change */
1274  static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip)  static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip)
1275  {  {
1276      if (!s->vm86)      if (s->pe && !s->vm86)
1277          gen_op_movl_seg_T0(seg_reg, cur_eip);          gen_op_movl_seg_T0(seg_reg, cur_eip);
1278      else      else
1279          gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));          gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
# Line 1855  long disas_insn(DisasContext *s, uint8_t Line 1856  long disas_insn(DisasContext *s, uint8_t
1856              gen_op_ld_T1_A0[ot]();              gen_op_ld_T1_A0[ot]();
1857              gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));              gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1858              gen_op_lduw_T0_A0();              gen_op_lduw_T0_A0();
1859              if (!s->vm86) {              if (s->pe && !s->vm86) {
1860                  /* we compute EIP to handle the exception case */                  /* we compute EIP to handle the exception case */
1861                  gen_op_jmp_im(pc_start - s->cs_base);                  gen_op_jmp_im(pc_start - s->cs_base);
1862                  gen_op_ljmp_T0_T1();                  gen_op_ljmp_T0_T1();
# Line 2036  long disas_insn(DisasContext *s, uint8_t Line 2037  long disas_insn(DisasContext *s, uint8_t
2037          ot = dflag ? OT_LONG : OT_WORD;          ot = dflag ? OT_LONG : OT_WORD;
2038          modrm = ldub(s->pc++);          modrm = ldub(s->pc++);
2039          gen_pop_T0(s);          gen_pop_T0(s);
2040          s->popl_esp_hack = 1;          s->popl_esp_hack = 2 << dflag;
2041          gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);          gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
2042          s->popl_esp_hack = 0;          s->popl_esp_hack = 0;
2043          gen_pop_update(s);          gen_pop_update(s);
# Line 2082  long disas_insn(DisasContext *s, uint8_t Line 2083  long disas_insn(DisasContext *s, uint8_t
2083          gen_pop_T0(s);          gen_pop_T0(s);
2084          gen_movl_seg_T0(s, b >> 3, pc_start - s->cs_base);          gen_movl_seg_T0(s, b >> 3, pc_start - s->cs_base);
2085          gen_pop_update(s);          gen_pop_update(s);
2086            /* XXX: if reg == SS, inhibit interrupts/trace */
2087          break;          break;
2088      case 0x1a1: /* pop fs */      case 0x1a1: /* pop fs */
2089      case 0x1a9: /* pop gs */      case 0x1a9: /* pop gs */
# Line 2134  long disas_insn(DisasContext *s, uint8_t Line 2136  long disas_insn(DisasContext *s, uint8_t
2136          gen_op_mov_reg_T0[ot][reg]();          gen_op_mov_reg_T0[ot][reg]();
2137          break;          break;
2138      case 0x8e: /* mov seg, Gv */      case 0x8e: /* mov seg, Gv */
         ot = dflag ? OT_LONG : OT_WORD;  
2139          modrm = ldub(s->pc++);          modrm = ldub(s->pc++);
2140          reg = (modrm >> 3) & 7;          reg = (modrm >> 3) & 7;
         gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0);  
2141          if (reg >= 6 || reg == R_CS)          if (reg >= 6 || reg == R_CS)
2142              goto illegal_op;              goto illegal_op;
2143            gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0);
2144          gen_movl_seg_T0(s, reg, pc_start - s->cs_base);          gen_movl_seg_T0(s, reg, pc_start - s->cs_base);
2145            /* XXX: if reg == SS, inhibit interrupts/trace */
2146          break;          break;
2147      case 0x8c: /* mov Gv, seg */      case 0x8c: /* mov Gv, seg */
         ot = dflag ? OT_LONG : OT_WORD;  
2148          modrm = ldub(s->pc++);          modrm = ldub(s->pc++);
2149          reg = (modrm >> 3) & 7;          reg = (modrm >> 3) & 7;
2150            mod = (modrm >> 6) & 3;
2151          if (reg >= 6)          if (reg >= 6)
2152              goto illegal_op;              goto illegal_op;
2153          gen_op_movl_T0_seg(reg);          gen_op_movl_T0_seg(reg);
2154            ot = OT_WORD;
2155            if (mod == 3 && dflag)
2156                ot = OT_LONG;
2157          gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);          gen_ldst_modrm(s, modrm, ot, OR_TMP0, 1);
2158          break;          break;
2159    
# Line 2938  long disas_insn(DisasContext *s, uint8_t Line 2943  long disas_insn(DisasContext *s, uint8_t
2943          break;          break;
2944      case 0x6c: /* insS */      case 0x6c: /* insS */
2945      case 0x6d:      case 0x6d:
2946          if (s->cpl > s->iopl || s->vm86) {          if (s->pe && (s->cpl > s->iopl || s->vm86)) {
2947              /* NOTE: even for (E)CX = 0 the exception is raised */              /* NOTE: even for (E)CX = 0 the exception is raised */
2948              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2949          } else {          } else {
# Line 2955  long disas_insn(DisasContext *s, uint8_t Line 2960  long disas_insn(DisasContext *s, uint8_t
2960          break;          break;
2961      case 0x6e: /* outsS */      case 0x6e: /* outsS */
2962      case 0x6f:      case 0x6f:
2963          if (s->cpl > s->iopl || s->vm86) {          if (s->pe && (s->cpl > s->iopl || s->vm86)) {
2964              /* NOTE: even for (E)CX = 0 the exception is raised */              /* NOTE: even for (E)CX = 0 the exception is raised */
2965              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2966          } else {          } else {
# Line 2975  long disas_insn(DisasContext *s, uint8_t Line 2980  long disas_insn(DisasContext *s, uint8_t
2980          /* port I/O */          /* port I/O */
2981      case 0xe4:      case 0xe4:
2982      case 0xe5:      case 0xe5:
2983          if (s->cpl > s->iopl || s->vm86) {          if (s->pe && (s->cpl > s->iopl || s->vm86)) {
2984              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
2985          } else {          } else {
2986              if ((b & 1) == 0)              if ((b & 1) == 0)
# Line 2990  long disas_insn(DisasContext *s, uint8_t Line 2995  long disas_insn(DisasContext *s, uint8_t
2995          break;          break;
2996      case 0xe6:      case 0xe6:
2997      case 0xe7:      case 0xe7:
2998          if (s->cpl > s->iopl || s->vm86) {          if (s->pe && (s->cpl > s->iopl || s->vm86)) {
2999              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3000          } else {          } else {
3001              if ((b & 1) == 0)              if ((b & 1) == 0)
# Line 3005  long disas_insn(DisasContext *s, uint8_t Line 3010  long disas_insn(DisasContext *s, uint8_t
3010          break;          break;
3011      case 0xec:      case 0xec:
3012      case 0xed:      case 0xed:
3013          if (s->cpl > s->iopl || s->vm86) {          if (s->pe && (s->cpl > s->iopl || s->vm86)) {
3014              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3015          } else {          } else {
3016              if ((b & 1) == 0)              if ((b & 1) == 0)
# Line 3019  long disas_insn(DisasContext *s, uint8_t Line 3024  long disas_insn(DisasContext *s, uint8_t
3024          break;          break;
3025      case 0xee:      case 0xee:
3026      case 0xef:      case 0xef:
3027          if (s->cpl > s->iopl || s->vm86) {          if (s->pe && (s->cpl > s->iopl || s->vm86)) {
3028              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3029          } else {          } else {
3030              if ((b & 1) == 0)              if ((b & 1) == 0)
# Line 3076  long disas_insn(DisasContext *s, uint8_t Line 3081  long disas_insn(DisasContext *s, uint8_t
3081          val = 0;          val = 0;
3082          goto do_lret;          goto do_lret;
3083      case 0xcf: /* iret */      case 0xcf: /* iret */
3084          if (s->vm86 && s->iopl != 3) {          if (!s->pe) {
3085                /* real mode */
3086                gen_op_iret_real(s->dflag);
3087                s->cc_op = CC_OP_EFLAGS;
3088            } else if (s->vm86 && s->iopl != 3) {
3089              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);              gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3090          } else {          } else {
3091              if (s->cc_op != CC_OP_DYNAMIC)              if (s->cc_op != CC_OP_DYNAMIC)
# Line 3142  long disas_insn(DisasContext *s, uint8_t Line 3151  long disas_insn(DisasContext *s, uint8_t
3151                            
3152              /* change cs and pc */              /* change cs and pc */
3153              gen_op_movl_T0_im(selector);              gen_op_movl_T0_im(selector);
3154              if (!s->vm86) {              if (s->pe && !s->vm86) {
3155                  /* we compute EIP to handle the exception case */                  /* we compute EIP to handle the exception case */
3156                  gen_op_jmp_im(pc_start - s->cs_base);                  gen_op_jmp_im(pc_start - s->cs_base);
3157                  gen_op_movl_T1_im(offset);                  gen_op_movl_T1_im(offset);
# Line 3442  long disas_insn(DisasContext *s, uint8_t Line 3451  long disas_insn(DisasContext *s, uint8_t
3451                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);                  gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
3452              }              }
3453          }          }
3454            /* XXX: interruptions are enabled only the first insn after sti */
3455          break;          break;
3456      case 0x62: /* bound */      case 0x62: /* bound */
3457          ot = dflag ? OT_LONG : OT_WORD;          ot = dflag ? OT_LONG : OT_WORD;
# Line 3628  long disas_insn(DisasContext *s, uint8_t Line 3638  long disas_insn(DisasContext *s, uint8_t
3638          break;          break;
3639      case 0x102: /* lar */      case 0x102: /* lar */
3640      case 0x103: /* lsl */      case 0x103: /* lsl */
3641          if (s->vm86)          if (!s->pe || s->vm86)
3642              goto illegal_op;              goto illegal_op;
3643          ot = dflag ? OT_LONG : OT_WORD;          ot = dflag ? OT_LONG : OT_WORD;
3644          modrm = ldub(s->pc++);          modrm = ldub(s->pc++);
# Line 4106  static inline int gen_intermediate_code_ Line 4116  static inline int gen_intermediate_code_
4116      cs_base = (uint8_t *)tb->cs_base;      cs_base = (uint8_t *)tb->cs_base;
4117      flags = tb->flags;      flags = tb->flags;
4118                
4119        dc->pe = env->cr[0] & CR0_PE_MASK;
4120      dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1;      dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1;
4121      dc->ss32 = (flags >> GEN_FLAG_SS32_SHIFT) & 1;      dc->ss32 = (flags >> GEN_FLAG_SS32_SHIFT) & 1;
4122      dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;      dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;
4123      dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;      dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;
4124      dc->vm86 = (flags >> GEN_FLAG_VM_SHIFT) & 1;      dc->vm86 = (flags >> GEN_FLAG_VM_SHIFT) & 1;
4125      dc->cpl = (flags >> GEN_FLAG_CPL_SHIFT) & 3;      /* CPL is implicit if real mode or vm86 mode */
4126        if (!dc->pe)
4127            dc->cpl = 0;
4128        else if (dc->vm86)
4129            dc->cpl = 3;
4130        else
4131            dc->cpl = (flags >> GEN_FLAG_CPL_SHIFT) & 3;
4132      dc->iopl = (flags >> GEN_FLAG_IOPL_SHIFT) & 3;      dc->iopl = (flags >> GEN_FLAG_IOPL_SHIFT) & 3;
4133      dc->tf = (flags >> GEN_FLAG_TF_SHIFT) & 1;      dc->tf = (flags >> GEN_FLAG_TF_SHIFT) & 1;
4134      dc->cc_op = CC_OP_DYNAMIC;      dc->cc_op = CC_OP_DYNAMIC;
4135      dc->cs_base = cs_base;      dc->cs_base = cs_base;
4136      dc->tb = tb;      dc->tb = tb;
4137      dc->popl_esp_hack = 0;      dc->popl_esp_hack = 0;
4138        
4139      gen_opc_ptr = gen_opc_buf;      gen_opc_ptr = gen_opc_buf;
4140      gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;      gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4141      gen_opparam_ptr = gen_opparam_buf;      gen_opparam_ptr = gen_opparam_buf;
# Line 4270  void cpu_x86_close(CPUX86State *env) Line 4287  void cpu_x86_close(CPUX86State *env)
4287    
4288  /* called when cr3 or PG bit are modified */  /* called when cr3 or PG bit are modified */
4289  static int last_pg_state = -1;  static int last_pg_state = -1;
4290    static int last_pe_state = 0;
4291  int phys_ram_size;  int phys_ram_size;
4292  int phys_ram_fd;  int phys_ram_fd;
4293  uint8_t *phys_ram_base;  uint8_t *phys_ram_base;
4294    
4295  void cpu_x86_update_cr0(CPUX86State *env)  void cpu_x86_update_cr0(CPUX86State *env)
4296  {  {
4297      int pg_state;      int pg_state, pe_state;
4298      void *map_addr;      void *map_addr;
4299    
4300  #ifdef DEBUG_MMU  #ifdef DEBUG_MMU
# Line 4304  void cpu_x86_update_cr0(CPUX86State *env Line 4322  void cpu_x86_update_cr0(CPUX86State *env
4322          }          }
4323          last_pg_state = pg_state;          last_pg_state = pg_state;
4324      }      }
4325        pe_state = env->cr[0] & CR0_PE_MASK;
4326        if (last_pe_state != pe_state) {
4327            tb_flush();
4328            last_pe_state = pe_state;
4329        }
4330  }  }
4331    
4332  void cpu_x86_update_cr3(CPUX86State *env)  void cpu_x86_update_cr3(CPUX86State *env)

Legend:
Removed from v.1.52  
changed lines
  Added in v.1.53

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