]> xenbits.xensource.com Git - qemu-xen-4.4-testing.git/commitdiff
CR0.MP/EM/TS support
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 25 Feb 2004 23:17:58 +0000 (23:17 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Wed, 25 Feb 2004 23:17:58 +0000 (23:17 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@642 c046a42c-6fe2-441c-8c8c-71466251a162

target-i386/cpu.h
target-i386/op.c
target-i386/translate.c

index 99c6bb98c168cfe72d04fdc8117866b30dc2bf28..84b202659a5f4126d54d9161c241cafccc663735 100644 (file)
 /* 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)
@@ -280,7 +289,7 @@ typedef struct CPUX86State {
     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;
@@ -304,8 +313,11 @@ typedef struct CPUX86State {
     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;
index 1503134d1f7742d69f1f48a889cc741755bda593..f592b67a6af25ba316f027a0f0afac4cd1651082 100644 (file)
@@ -998,6 +998,7 @@ void OPPROTO op_movl_env_T1(void)
 void OPPROTO op_clts(void)
 {
     env->cr[0] &= ~CR0_TS_MASK;
+    env->hflags &= ~HF_TS_MASK;
 }
 
 /* flags handling */
index 6e8d8116c7df20f7f63d09947e14c6a4897d97fe..f9823a49d19f15a36898a278e8e3f0f876846c35 100644 (file)
@@ -63,6 +63,7 @@ typedef struct DisasContext {
     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;
@@ -2814,6 +2815,12 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
         /************************/
         /* 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;
@@ -3225,6 +3232,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
                 goto illegal_op;
             }
         }
+#ifdef USE_CODE_COPY
+        s->tb->cflags |= CF_TB_FP_USED;
+#endif
         break;
         /************************/
         /* string ops */
@@ -3747,6 +3757,10 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
             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);
@@ -4140,6 +4154,9 @@ static uint8_t *disas_insn(DisasContext *s, uint8_t *pc_start)
             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:
@@ -4504,6 +4521,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
         else
             dc->mem_index = 3;
     }
+    dc->flags = flags;
     dc->jmp_opt = !(dc->tf || env->singlestep_enabled ||
                     (flags & HF_INHIBIT_IRQ_MASK)
 #ifndef CONFIG_SOFTMMU