Move interrupt_request and user_mode_only to common cpu state.
[qemu] / target-i386 / cpu.h
index a6ad54b..22169a9 100644 (file)
 #define ID_MASK                 0x00200000
 
 /* hidden flags - used internally by qemu to represent additional cpu
-   states. Only the CPL, INHIBIT_IRQ and HALTED are not redundant. We avoid
-   using the IOPL_MASK, TF_MASK and VM_MASK bit position to ease oring
-   with eflags. */
+   states. Only the CPL, INHIBIT_IRQ, SMM and SVMI are not
+   redundant. We avoid using the IOPL_MASK, TF_MASK and VM_MASK bit
+   position to ease oring with eflags. */
 /* current cpl */
 #define HF_CPL_SHIFT         0
 /* true if soft mmu is being used */
 #define HF_CS64_SHIFT       15 /* only used on x86_64: 64 bit code segment  */
 #define HF_OSFXSR_SHIFT     16 /* CR4.OSFXSR */
 #define HF_VM_SHIFT         17 /* must be same as eflags */
-#define HF_HALTED_SHIFT     18 /* CPU halted */
 #define HF_SMM_SHIFT        19 /* CPU in SMM mode */
-#define HF_GIF_SHIFT        20 /* if set CPU takes interrupts */
-#define HF_HIF_SHIFT        21 /* shadow copy of IF_MASK when in SVM */
+#define HF_SVME_SHIFT       20 /* SVME enabled (copy of EFER.SVME) */
+#define HF_SVMI_SHIFT       21 /* SVM intercepts are active */
 
 #define HF_CPL_MASK          (3 << HF_CPL_SHIFT)
 #define HF_SOFTMMU_MASK      (1 << HF_SOFTMMU_SHIFT)
 #define HF_LMA_MASK          (1 << HF_LMA_SHIFT)
 #define HF_CS64_MASK         (1 << HF_CS64_SHIFT)
 #define HF_OSFXSR_MASK       (1 << HF_OSFXSR_SHIFT)
-#define HF_HALTED_MASK       (1 << HF_HALTED_SHIFT)
 #define HF_SMM_MASK          (1 << HF_SMM_SHIFT)
-#define HF_GIF_MASK          (1 << HF_GIF_SHIFT)
-#define HF_HIF_MASK          (1 << HF_HIF_SHIFT)
+#define HF_SVME_MASK         (1 << HF_SVME_SHIFT)
+#define HF_SVMI_MASK         (1 << HF_SVMI_SHIFT)
+
+/* hflags2 */
+
+#define HF2_GIF_SHIFT        0 /* if set CPU takes interrupts */
+#define HF2_HIF_SHIFT        1 /* value of IF_MASK when entering SVM */
+#define HF2_NMI_SHIFT        2 /* CPU serving NMI */
+#define HF2_VINTR_SHIFT      3 /* value of V_INTR_MASKING bit */
+
+#define HF2_GIF_MASK          (1 << HF2_GIF_SHIFT)
+#define HF2_HIF_MASK          (1 << HF2_HIF_SHIFT) 
+#define HF2_NMI_MASK          (1 << HF2_NMI_SHIFT)
+#define HF2_VINTR_MASK        (1 << HF2_VINTR_SHIFT)
 
 #define CR0_PE_MASK  (1 << 0)
 #define CR0_MP_MASK  (1 << 1)
 #define MSR_EFER_LME   (1 << 8)
 #define MSR_EFER_LMA   (1 << 10)
 #define MSR_EFER_NXE   (1 << 11)
+#define MSR_EFER_SVME  (1 << 12)
 #define MSR_EFER_FFXSR (1 << 14)
 
 #define MSR_STAR                        0xc0000081
 #define CPUID_EXT3_3DNOWPREFETCH (1 << 8)
 #define CPUID_EXT3_OSVW    (1 << 9)
 #define CPUID_EXT3_IBS     (1 << 10)
+#define CPUID_EXT3_SKINIT  (1 << 12)
 
 #define EXCP00_DIVZ    0
 #define EXCP01_SSTP    1
 #define EXCP11_ALGN    17
 #define EXCP12_MCHK    18
 
+#define EXCP_SYSCALL    0x100 /* only happens in user only emulation
+                                 for syscall instruction */
+
 enum {
     CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
-    CC_OP_EFLAGS,  /* all cc are explicitely computed, CC_SRC = flags */
+    CC_OP_EFLAGS,  /* all cc are explicitly computed, CC_SRC = flags */
 
     CC_OP_MULB, /* modify all flags, C, O = (CC_SRC != 0) */
     CC_OP_MULW,
@@ -425,8 +440,9 @@ typedef union {
 
 typedef union {
     uint8_t _b[8];
-    uint16_t _w[2];
-    uint32_t _l[1];
+    uint16_t _w[4];
+    uint32_t _l[2];
+    float32 _s[2];
     uint64_t q;
 } MMXReg;
 
@@ -441,6 +457,7 @@ typedef union {
 #define MMX_B(n) _b[7 - (n)]
 #define MMX_W(n) _w[3 - (n)]
 #define MMX_L(n) _l[1 - (n)]
+#define MMX_S(n) _s[1 - (n)]
 #else
 #define XMM_B(n) _b[n]
 #define XMM_W(n) _w[n]
@@ -452,6 +469,7 @@ typedef union {
 #define MMX_B(n) _b[n]
 #define MMX_W(n) _w[n]
 #define MMX_L(n) _l[n]
+#define MMX_S(n) _s[n]
 #endif
 #define MMX_Q(n) q
 
@@ -464,11 +482,6 @@ typedef union {
 #define NB_MMU_MODES 2
 
 typedef struct CPUX86State {
-#if TARGET_LONG_BITS > HOST_LONG_BITS
-    /* temporaries if we cannot store them in host registers */
-    target_ulong t0, t1, t2;
-#endif
-
     /* standard registers */
     target_ulong regs[CPU_NB_REGS];
     target_ulong eip;
@@ -481,7 +494,9 @@ typedef struct CPUX86State {
     target_ulong cc_dst;
     uint32_t cc_op;
     int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
-    uint32_t hflags; /* hidden flags, see HF_xxx constants */
+    uint32_t hflags; /* TB flags, see HF_xxx constants. These flags
+                        are known at translation time. */
+    uint32_t hflags2; /* various other flags, see HF2_xxx constants. */
 
     /* segments */
     SegmentCache segs[6]; /* selector values */
@@ -491,7 +506,7 @@ typedef struct CPUX86State {
     SegmentCache idt; /* only base and limit are used */
 
     target_ulong cr[5]; /* NOTE: cr1 is unused */
-    uint32_t a20_mask;
+    uint64_t a20_mask;
 
     /* FPU state */
     unsigned int fpstt; /* top of stack index */
@@ -510,18 +525,14 @@ typedef struct CPUX86State {
     /* emulator internal variables */
     float_status fp_status;
     CPU86_LDouble ft0;
-    union {
-       float f;
-        double d;
-       int i32;
-        int64_t i64;
-    } fp_convert;
 
+    float_status mmx_status; /* for 3DNow! float ops */
     float_status sse_status;
     uint32_t mxcsr;
     XMMReg xmm_regs[CPU_NB_REGS];
     XMMReg xmm_t0;
     MMXReg mmx_t0;
+    target_ulong cc_tmp; /* temporary for rcr/rcl */
 
     /* sysenter registers */
     uint32_t sysenter_cs;
@@ -530,14 +541,16 @@ typedef struct CPUX86State {
     uint64_t efer;
     uint64_t star;
 
-    target_phys_addr_t vm_hsave;
-    target_phys_addr_t vm_vmcb;
+    uint64_t vm_hsave;
+    uint64_t vm_vmcb;
+    uint64_t tsc_offset;
     uint64_t intercept;
     uint16_t intercept_cr_read;
     uint16_t intercept_cr_write;
     uint16_t intercept_dr_read;
     uint16_t intercept_dr_write;
     uint32_t intercept_exceptions;
+    uint8_t v_tpr;
 
 #ifdef TARGET_X86_64
     target_ulong lstar;
@@ -549,15 +562,11 @@ typedef struct CPUX86State {
     uint64_t pat;
 
     /* exception/interrupt handling */
-    jmp_buf jmp_env;
-    int exception_index;
     int error_code;
     int exception_is_int;
     target_ulong exception_next_eip;
     target_ulong dr[8]; /* debug registers */
     uint32_t smbase;
-    int interrupt_request;
-    int user_mode_only; /* user mode only simulation */
     int old_exception;  /* exception in flight */
 
     CPU_COMMON
@@ -670,8 +679,8 @@ CPU86_LDouble cpu_set_fp80(uint64_t mant, uint16_t upper);
 /* the following helpers are only usable in user mode simulation as
    they can trigger unexpected exceptions */
 void cpu_x86_load_seg(CPUX86State *s, int seg_reg, int selector);
-void cpu_x86_fsave(CPUX86State *s, uint8_t *ptr, int data32);
-void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32);
+void cpu_x86_fsave(CPUX86State *s, target_ulong ptr, int data32);
+void cpu_x86_frstor(CPUX86State *s, target_ulong ptr, int data32);
 
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
@@ -715,6 +724,8 @@ static inline int cpu_get_time_fast(void)
 #define cpu_signal_handler cpu_x86_signal_handler
 #define cpu_list x86_cpu_list
 
+#define CPU_SAVE_VERSION 6
+
 /* MMU modes definitions */
 #define MMU_MODE0_SUFFIX _kernel
 #define MMU_MODE1_SUFFIX _user
@@ -724,6 +735,26 @@ static inline int cpu_mmu_index (CPUState *env)
     return (env->hflags & HF_CPL_MASK) == 3 ? 1 : 0;
 }
 
+void optimize_flags_init(void);
+
+typedef struct CCTable {
+    int (*compute_all)(void); /* return all the flags */
+    int (*compute_c)(void);  /* return the C flag */
+} CCTable;
+
+extern CCTable cc_table[];
+
+#if defined(CONFIG_USER_ONLY)
+static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
+{
+    if (newsp)
+        env->regs[R_ESP] = newsp;
+    env->regs[R_EAX] = 0;
+}
+#endif
+
+#define CPU_PC_FROM_TB(env, tb) env->eip = tb->pc - tb->cs_base
+
 #include "cpu-all.h"
 
 #include "svm.h"