summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cpu-i386.h34
-rw-r--r--exec-i386.c11
2 files changed, 26 insertions, 19 deletions
diff --git a/cpu-i386.h b/cpu-i386.h
index 700370e717..4eeb6be88c 100644
--- a/cpu-i386.h
+++ b/cpu-i386.h
@@ -48,6 +48,7 @@
#define R_FS 4
#define R_GS 5
+/* eflags masks */
#define CC_C 0x0001
#define CC_P 0x0004
#define CC_A 0x0010
@@ -55,15 +56,17 @@
#define CC_S 0x0080
#define CC_O 0x0800
-#define TRAP_FLAG 0x0100
-#define INTERRUPT_FLAG 0x0200
-#define DIRECTION_FLAG 0x0400
-#define IOPL_FLAG_MASK 0x3000
-#define NESTED_FLAG 0x4000
-#define BYTE_FL 0x8000 /* Intel reserved! */
-#define RF_FLAG 0x10000
-#define VM_FLAG 0x20000
-/* AC 0x40000 */
+#define TF_MASK 0x00000100
+#define IF_MASK 0x00000200
+#define DF_MASK 0x00000400
+#define IOPL_MASK 0x00003000
+#define NT_MASK 0x00004000
+#define RF_MASK 0x00010000
+#define VM_MASK 0x00020000
+#define AC_MASK 0x00040000
+#define VIF_MASK 0x00080000
+#define VIP_MASK 0x00100000
+#define ID_MASK 0x00200000
#define EXCP00_DIVZ 1
#define EXCP01_SSTP 2
@@ -158,7 +161,9 @@ typedef struct CPUX86State {
/* standard registers */
uint32_t regs[8];
uint32_t eip;
- uint32_t eflags;
+ uint32_t eflags; /* eflags register. During CPU emulation, CC
+ flags and DF are set to zero because they are
+ store elsewhere */
/* emulator internal eflags handling */
uint32_t cc_src;
@@ -183,13 +188,13 @@ typedef struct CPUX86State {
SegmentDescriptorTable ldt;
SegmentDescriptorTable idt;
- /* various CPU modes */
- int vm86;
-
/* exception/interrupt handling */
jmp_buf jmp_env;
int exception_index;
int interrupt_request;
+
+ /* user data */
+ void *opaque;
} CPUX86State;
/* all CPU memory access use these macros */
@@ -418,7 +423,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
#define GEN_FLAG_CODE32_SHIFT 0
#define GEN_FLAG_ADDSEG_SHIFT 1
#define GEN_FLAG_SS32_SHIFT 2
-#define GEN_FLAG_ST_SHIFT 3
+#define GEN_FLAG_VM_SHIFT 3
+#define GEN_FLAG_ST_SHIFT 4
int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
int *gen_code_size_ptr,
diff --git a/exec-i386.c b/exec-i386.c
index 5dbe7fa534..f59e1ccecf 100644
--- a/exec-i386.c
+++ b/exec-i386.c
@@ -330,9 +330,10 @@ int cpu_x86_exec(CPUX86State *env1)
#endif
/* put eflags in CPU temporary format */
- T0 = env->eflags;
- op_movl_eflags_T0();
+ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+ DF = 1 - (2 * ((env->eflags >> 10) & 1));
CC_OP = CC_OP_EFLAGS;
+ env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
env->interrupt_request = 0;
/* prepare setjmp context for exception handling */
@@ -354,6 +355,7 @@ int cpu_x86_exec(CPUX86State *env1)
(unsigned long)env->seg_cache[R_ES].base |
(unsigned long)env->seg_cache[R_SS].base) != 0) <<
GEN_FLAG_ADDSEG_SHIFT;
+ flags |= (env->eflags & VM_MASK) >> (17 - GEN_FLAG_VM_SHIFT);
cs_base = env->seg_cache[R_CS].base;
pc = cs_base + env->eip;
tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base,
@@ -390,8 +392,7 @@ int cpu_x86_exec(CPUX86State *env1)
ret = env->exception_index;
/* restore flags in standard format */
- op_movl_T0_eflags();
- env->eflags = T0;
+ env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
/* restore global registers */
#ifdef reg_EAX
@@ -489,7 +490,7 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info,
/* for glibc 2.1 */
#define REG_EIP EIP
#endif
- pc = uc->uc_mcontext.gregs[EIP];
+ pc = uc->uc_mcontext.gregs[REG_EIP];
pold_set = &uc->uc_sigmask;
return handle_cpu_signal(pc, pold_set);
#else