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 115 /* copy of CR0.PE (protected mode) */
116 116 #define HF_PE_SHIFT 7
117 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 121 #define HF_IOPL_SHIFT 12 /* must be same as eflags */
119 122 #define HF_VM_SHIFT 17 /* must be same as eflags */
120 123  
... ... @@ -126,9 +129,15 @@
126 129 #define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT)
127 130 #define HF_PE_MASK (1 << HF_PE_SHIFT)
128 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 136 #define CR0_PE_MASK (1 << 0)
  137 +#define CR0_MP_MASK (1 << 1)
  138 +#define CR0_EM_MASK (1 << 2)
131 139 #define CR0_TS_MASK (1 << 3)
  140 +#define CR0_NE_MASK (1 << 5)
132 141 #define CR0_WP_MASK (1 << 16)
133 142 #define CR0_AM_MASK (1 << 18)
134 143 #define CR0_PG_MASK (1 << 31)
... ... @@ -280,7 +289,7 @@ typedef struct CPUX86State {
280 289 unsigned int fpus;
281 290 unsigned int fpuc;
282 291 uint8_t fptags[8]; /* 0 = valid, 1 = empty */
283   - CPU86_LDouble fpregs[8];
  292 + CPU86_LDouble fpregs[8];
284 293  
285 294 /* emulator internal variables */
286 295 CPU86_LDouble ft0;
... ... @@ -304,8 +313,11 @@ typedef struct CPUX86State {
304 313 uint32_t sysenter_eip;
305 314  
306 315 /* temporary data for USE_CODE_COPY mode */
  316 +#ifdef USE_CODE_COPY
307 317 uint32_t tmp0;
308 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 322 /* exception/interrupt handling */
311 323 jmp_buf jmp_env;
... ...
target-i386/op.c
... ... @@ -998,6 +998,7 @@ void OPPROTO op_movl_env_T1(void)
998 998 void OPPROTO op_clts(void)
999 999 {
1000 1000 env->cr[0] &= ~CR0_TS_MASK;
  1001 + env->hflags &= ~HF_TS_MASK;
1001 1002 }
1002 1003  
1003 1004 /* flags handling */
... ...
target-i386/translate.c
... ... @@ -63,6 +63,7 @@ typedef struct DisasContext {
63 63 int singlestep_enabled; /* "hardware" single step enabled */
64 64 int jmp_opt; /* use direct block chaining for direct jumps */
65 65 int mem_index; /* select memory access functions */
  66 + int flags; /* all execution flags */
66 67 struct TranslationBlock *tb;
67 68 int popl_esp_hack; /* for correct popl with esp base handling */
68 69 } DisasContext;
... ... @@ -2814,6 +2815,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
2814 2815 /************************/
2815 2816 /* floats */
2816 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 2824 modrm = ldub_code(s->pc++);
2818 2825 mod = (modrm >> 6) & 3;
2819 2826 rm = modrm & 7;
... ... @@ -3225,6 +3232,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3225 3232 goto illegal_op;
3226 3233 }
3227 3234 }
  3235 +#ifdef USE_CODE_COPY
  3236 + s->tb->cflags |= CF_TB_FP_USED;
  3237 +#endif
3228 3238 break;
3229 3239 /************************/
3230 3240 /* string ops */
... ... @@ -3747,6 +3757,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
3747 3757 goto illegal_op;
3748 3758 break;
3749 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 3764 break;
3751 3765 case 0xcc: /* int3 */
3752 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 4154 gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
4141 4155 } else {
4142 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 4161 break;
4145 4162 default:
... ... @@ -4504,6 +4521,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4504 4521 else
4505 4522 dc->mem_index = 3;
4506 4523 }
  4524 + dc->flags = flags;
4507 4525 dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
4508 4526 (flags & HF_INHIBIT_IRQ_MASK)
4509 4527 #ifndef CONFIG_SOFTMMU
... ...