/* copy of CR0.PE (protected mode) */
#define HF_PE_SHIFT 7
#define HF_TF_SHIFT 8 /* must be same as eflags */
+#define HF_MP_SHIFT 9 /* the order must be MP, EM, TS */
+#define HF_EM_SHIFT 10
+#define HF_TS_SHIFT 11
#define HF_IOPL_SHIFT 12 /* must be same as eflags */
#define HF_VM_SHIFT 17 /* must be same as eflags */
#define HF_ADDSEG_MASK (1 << HF_ADDSEG_SHIFT)
#define HF_PE_MASK (1 << HF_PE_SHIFT)
#define HF_TF_MASK (1 << HF_TF_SHIFT)
+#define HF_MP_MASK (1 << HF_MP_SHIFT)
+#define HF_EM_MASK (1 << HF_EM_SHIFT)
+#define HF_TS_MASK (1 << HF_TS_SHIFT)
#define CR0_PE_MASK (1 << 0)
+#define CR0_MP_MASK (1 << 1)
+#define CR0_EM_MASK (1 << 2)
#define CR0_TS_MASK (1 << 3)
+#define CR0_NE_MASK (1 << 5)
#define CR0_WP_MASK (1 << 16)
#define CR0_AM_MASK (1 << 18)
#define CR0_PG_MASK (1 << 31)
unsigned int fpus;
unsigned int fpuc;
uint8_t fptags[8]; /* 0 = valid, 1 = empty */
- CPU86_LDouble fpregs[8];
+ CPU86_LDouble fpregs[8];
/* emulator internal variables */
CPU86_LDouble ft0;
uint32_t sysenter_eip;
/* temporary data for USE_CODE_COPY mode */
+#ifdef USE_CODE_COPY
uint32_t tmp0;
uint32_t saved_esp;
+ int native_fp_regs; /* if true, the FPU state is in the native CPU regs */
+#endif
/* exception/interrupt handling */
jmp_buf jmp_env;
void OPPROTO op_clts(void)
{
env->cr[0] &= ~CR0_TS_MASK;
+ env->hflags &= ~HF_TS_MASK;
}
/* flags handling */
int singlestep_enabled; /* "hardware" single step enabled */
int jmp_opt; /* use direct block chaining for direct jumps */
int mem_index; /* select memory access functions */
+ int flags; /* all execution flags */
struct TranslationBlock *tb;
int popl_esp_hack; /* for correct popl with esp base handling */
} DisasContext;
/************************/
/* floats */
case 0xd8 ... 0xdf:
+ if (s->flags & (HF_EM_MASK | HF_TS_MASK)) {
+ /* if CR0.EM or CR0.TS are set, generate an FPU exception */
+ /* XXX: what to do if illegal op ? */
+ gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ break;
+ }
modrm = ldub_code(s->pc++);
mod = (modrm >> 6) & 3;
rm = modrm & 7;
goto illegal_op;
}
}
+#ifdef USE_CODE_COPY
+ s->tb->cflags |= CF_TB_FP_USED;
+#endif
break;
/************************/
/* string ops */
goto illegal_op;
break;
case 0x9b: /* fwait */
+ if ((s->flags & (HF_MP_MASK | HF_TS_MASK)) ==
+ (HF_MP_MASK | HF_TS_MASK)) {
+ gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ }
break;
case 0xcc: /* int3 */
gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base);
gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base);
} else {
gen_op_clts();
+ /* abort block because static cpu state changed */
+ gen_op_jmp_im(s->pc - s->cs_base);
+ gen_eob(s);
}
break;
default:
else
dc->mem_index = 3;
}
+ dc->flags = flags;
dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
(flags & HF_INHIBIT_IRQ_MASK)
#ifndef CONFIG_SOFTMMU