Commit 7eee2a509a9a777aafd0c2efb14b837b83a8df9c

Authored by bellard
1 parent 42c3c0cc

CR0.MP/EM/TS support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@642 c046a42c-6fe2-441c-8c8c-71466251a162
target-i386/cpu.h
@@ -115,6 +115,9 @@ @@ -115,6 +115,9 @@
115 /* copy of CR0.PE (protected mode) */ 115 /* copy of CR0.PE (protected mode) */
116 #define HF_PE_SHIFT 7 116 #define HF_PE_SHIFT 7
117 #define HF_TF_SHIFT 8 /* must be same as eflags */ 117 #define HF_TF_SHIFT 8 /* must be same as eflags */
  118 +#define HF_MP_SHIFT 9 /* the order must be MP, EM, TS */
  119 +#define HF_EM_SHIFT 10
  120 +#define HF_TS_SHIFT 11
118 #define HF_IOPL_SHIFT 12 /* must be same as eflags */ 121 #define HF_IOPL_SHIFT 12 /* must be same as eflags */
119 #define HF_VM_SHIFT 17 /* must be same as eflags */ 122 #define HF_VM_SHIFT 17 /* must be same as eflags */
120 123
@@ -126,9 +129,15 @@ @@ -126,9 +129,15 @@
126 #define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT) 129 #define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT)
127 #define HF_PE_MASK (1 << HF_PE_SHIFT) 130 #define HF_PE_MASK (1 << HF_PE_SHIFT)
128 #define HF_TF_MASK (1 << HF_TF_SHIFT) 131 #define HF_TF_MASK (1 << HF_TF_SHIFT)
  132 +#define HF_MP_MASK (1 << HF_MP_SHIFT)
  133 +#define HF_EM_MASK (1 << HF_EM_SHIFT)
  134 +#define HF_TS_MASK (1 << HF_TS_SHIFT)
129 135
130 #define CR0_PE_MASK (1 << 0) 136 #define CR0_PE_MASK (1 << 0)
  137 +#define CR0_MP_MASK (1 << 1)
  138 +#define CR0_EM_MASK (1 << 2)
131 #define CR0_TS_MASK (1 << 3) 139 #define CR0_TS_MASK (1 << 3)
  140 +#define CR0_NE_MASK (1 << 5)
132 #define CR0_WP_MASK (1 << 16) 141 #define CR0_WP_MASK (1 << 16)
133 #define CR0_AM_MASK (1 << 18) 142 #define CR0_AM_MASK (1 << 18)
134 #define CR0_PG_MASK (1 << 31) 143 #define CR0_PG_MASK (1 << 31)
@@ -280,7 +289,7 @@ typedef struct CPUX86State { @@ -280,7 +289,7 @@ typedef struct CPUX86State {
280 unsigned int fpus; 289 unsigned int fpus;
281 unsigned int fpuc; 290 unsigned int fpuc;
282 uint8_t fptags[8]; /* 0 = valid, 1 = empty */ 291 uint8_t fptags[8]; /* 0 = valid, 1 = empty */
283 - CPU86_LDouble fpregs[8]; 292 + CPU86_LDouble fpregs[8];
284 293
285 /* emulator internal variables */ 294 /* emulator internal variables */
286 CPU86_LDouble ft0; 295 CPU86_LDouble ft0;
@@ -304,8 +313,11 @@ typedef struct CPUX86State { @@ -304,8 +313,11 @@ typedef struct CPUX86State {
304 uint32_t sysenter_eip; 313 uint32_t sysenter_eip;
305 314
306 /* temporary data for USE_CODE_COPY mode */ 315 /* temporary data for USE_CODE_COPY mode */
  316 +#ifdef USE_CODE_COPY
307 uint32_t tmp0; 317 uint32_t tmp0;
308 uint32_t saved_esp; 318 uint32_t saved_esp;
  319 + int native_fp_regs; /* if true, the FPU state is in the native CPU regs */
  320 +#endif
309 321
310 /* exception/interrupt handling */ 322 /* exception/interrupt handling */
311 jmp_buf jmp_env; 323 jmp_buf jmp_env;
target-i386/op.c
@@ -998,6 +998,7 @@ void OPPROTO op_movl_env_T1(void) @@ -998,6 +998,7 @@ void OPPROTO op_movl_env_T1(void)
998 void OPPROTO op_clts(void) 998 void OPPROTO op_clts(void)
999 { 999 {
1000 env->cr[0] &= ~CR0_TS_MASK; 1000 env->cr[0] &= ~CR0_TS_MASK;
  1001 + env->hflags &= ~HF_TS_MASK;
1001 } 1002 }
1002 1003
1003 /* flags handling */ 1004 /* flags handling */
target-i386/translate.c
@@ -63,6 +63,7 @@ typedef struct DisasContext { @@ -63,6 +63,7 @@ typedef struct DisasContext {
63 int singlestep_enabled; /* "hardware" single step enabled */ 63 int singlestep_enabled; /* "hardware" single step enabled */
64 int jmp_opt; /* use direct block chaining for direct jumps */ 64 int jmp_opt; /* use direct block chaining for direct jumps */
65 int mem_index; /* select memory access functions */ 65 int mem_index; /* select memory access functions */
  66 + int flags; /* all execution flags */
66 struct TranslationBlock *tb; 67 struct TranslationBlock *tb;
67 int popl_esp_hack; /* for correct popl with esp base handling */ 68 int popl_esp_hack; /* for correct popl with esp base handling */
68 } DisasContext; 69 } DisasContext;
@@ -2814,6 +2815,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -2814,6 +2815,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2814 /************************/ 2815 /************************/
2815 /* floats */ 2816 /* floats */
2816 case 0xd8 ... 0xdf: 2817 case 0xd8 ... 0xdf:
  2818 + if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
  2819 + /* if CR0.EM or CR0.TS are set, generate an FPU exception */
  2820 + /* XXX: what to do if illegal op ? */
  2821 + gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
  2822 + break;
  2823 + }
2817 modrm = ldub_code(s->pc++); 2824 modrm = ldub_code(s->pc++);
2818 mod = (modrm >> 6) & 3; 2825 mod = (modrm >> 6) & 3;
2819 rm = modrm & 7; 2826 rm = modrm & 7;
@@ -3225,6 +3232,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3225,6 +3232,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3225 goto illegal_op; 3232 goto illegal_op;
3226 } 3233 }
3227 } 3234 }
  3235 +#ifdef USE_CODE_COPY
  3236 + s->tb->cflags |= CF_TB_FP_USED;
  3237 +#endif
3228 break; 3238 break;
3229 /************************/ 3239 /************************/
3230 /* string ops */ 3240 /* string ops */
@@ -3747,6 +3757,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -3747,6 +3757,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3747 goto illegal_op; 3757 goto illegal_op;
3748 break; 3758 break;
3749 case 0x9b: /* fwait */ 3759 case 0x9b: /* fwait */
  3760 + if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
  3761 + (HF_MP_MASK | HF_TS_MASK)) {
  3762 + gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
  3763 + }
3750 break; 3764 break;
3751 case 0xcc: /* int3 */ 3765 case 0xcc: /* int3 */
3752 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base); 3766 gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
@@ -4140,6 +4154,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start) @@ -4140,6 +4154,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
4140 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); 4154 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4141 } else { 4155 } else {
4142 gen_op_clts(); 4156 gen_op_clts();
  4157 + /* abort block because static cpu state changed */
  4158 + gen_op_jmp_im(s->pc - s->cs_base);
  4159 + gen_eob(s);
4143 } 4160 }
4144 break; 4161 break;
4145 default: 4162 default:
@@ -4504,6 +4521,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -4504,6 +4521,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4504 else 4521 else
4505 dc->mem_index = 3; 4522 dc->mem_index = 3;
4506 } 4523 }
  4524 + dc->flags = flags;
4507 dc->jmp_opt = !(dc->tf || env->singlestep_enabled || 4525 dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
4508 (flags & HF_INHIBIT_IRQ_MASK) 4526 (flags & HF_INHIBIT_IRQ_MASK)
4509 #ifndef CONFIG_SOFTMMU 4527 #ifndef CONFIG_SOFTMMU