Commit fc2b4c4879955829430f33bf262e7eab93c6173a
1 parent
9c605cb1
eflags update
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@56 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
26 additions
and
19 deletions
cpu-i386.h
... | ... | @@ -48,6 +48,7 @@ |
48 | 48 | #define R_FS 4 |
49 | 49 | #define R_GS 5 |
50 | 50 | |
51 | +/* eflags masks */ | |
51 | 52 | #define CC_C 0x0001 |
52 | 53 | #define CC_P 0x0004 |
53 | 54 | #define CC_A 0x0010 |
... | ... | @@ -55,15 +56,17 @@ |
55 | 56 | #define CC_S 0x0080 |
56 | 57 | #define CC_O 0x0800 |
57 | 58 | |
58 | -#define TRAP_FLAG 0x0100 | |
59 | -#define INTERRUPT_FLAG 0x0200 | |
60 | -#define DIRECTION_FLAG 0x0400 | |
61 | -#define IOPL_FLAG_MASK 0x3000 | |
62 | -#define NESTED_FLAG 0x4000 | |
63 | -#define BYTE_FL 0x8000 /* Intel reserved! */ | |
64 | -#define RF_FLAG 0x10000 | |
65 | -#define VM_FLAG 0x20000 | |
66 | -/* AC 0x40000 */ | |
59 | +#define TF_MASK 0x00000100 | |
60 | +#define IF_MASK 0x00000200 | |
61 | +#define DF_MASK 0x00000400 | |
62 | +#define IOPL_MASK 0x00003000 | |
63 | +#define NT_MASK 0x00004000 | |
64 | +#define RF_MASK 0x00010000 | |
65 | +#define VM_MASK 0x00020000 | |
66 | +#define AC_MASK 0x00040000 | |
67 | +#define VIF_MASK 0x00080000 | |
68 | +#define VIP_MASK 0x00100000 | |
69 | +#define ID_MASK 0x00200000 | |
67 | 70 | |
68 | 71 | #define EXCP00_DIVZ 1 |
69 | 72 | #define EXCP01_SSTP 2 |
... | ... | @@ -158,7 +161,9 @@ typedef struct CPUX86State { |
158 | 161 | /* standard registers */ |
159 | 162 | uint32_t regs[8]; |
160 | 163 | uint32_t eip; |
161 | - uint32_t eflags; | |
164 | + uint32_t eflags; /* eflags register. During CPU emulation, CC | |
165 | + flags and DF are set to zero because they are | |
166 | + store elsewhere */ | |
162 | 167 | |
163 | 168 | /* emulator internal eflags handling */ |
164 | 169 | uint32_t cc_src; |
... | ... | @@ -183,13 +188,13 @@ typedef struct CPUX86State { |
183 | 188 | SegmentDescriptorTable ldt; |
184 | 189 | SegmentDescriptorTable idt; |
185 | 190 | |
186 | - /* various CPU modes */ | |
187 | - int vm86; | |
188 | - | |
189 | 191 | /* exception/interrupt handling */ |
190 | 192 | jmp_buf jmp_env; |
191 | 193 | int exception_index; |
192 | 194 | int interrupt_request; |
195 | + | |
196 | + /* user data */ | |
197 | + void *opaque; | |
193 | 198 | } CPUX86State; |
194 | 199 | |
195 | 200 | /* all CPU memory access use these macros */ |
... | ... | @@ -418,7 +423,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
418 | 423 | #define GEN_FLAG_CODE32_SHIFT 0 |
419 | 424 | #define GEN_FLAG_ADDSEG_SHIFT 1 |
420 | 425 | #define GEN_FLAG_SS32_SHIFT 2 |
421 | -#define GEN_FLAG_ST_SHIFT 3 | |
426 | +#define GEN_FLAG_VM_SHIFT 3 | |
427 | +#define GEN_FLAG_ST_SHIFT 4 | |
422 | 428 | |
423 | 429 | int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, |
424 | 430 | int *gen_code_size_ptr, | ... | ... |
exec-i386.c
... | ... | @@ -330,9 +330,10 @@ int cpu_x86_exec(CPUX86State *env1) |
330 | 330 | #endif |
331 | 331 | |
332 | 332 | /* put eflags in CPU temporary format */ |
333 | - T0 = env->eflags; | |
334 | - op_movl_eflags_T0(); | |
333 | + CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); | |
334 | + DF = 1 - (2 * ((env->eflags >> 10) & 1)); | |
335 | 335 | CC_OP = CC_OP_EFLAGS; |
336 | + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); | |
336 | 337 | env->interrupt_request = 0; |
337 | 338 | |
338 | 339 | /* prepare setjmp context for exception handling */ |
... | ... | @@ -354,6 +355,7 @@ int cpu_x86_exec(CPUX86State *env1) |
354 | 355 | (unsigned long)env->seg_cache[R_ES].base | |
355 | 356 | (unsigned long)env->seg_cache[R_SS].base) != 0) << |
356 | 357 | GEN_FLAG_ADDSEG_SHIFT; |
358 | + flags |= (env->eflags & VM_MASK) >> (17 - GEN_FLAG_VM_SHIFT); | |
357 | 359 | cs_base = env->seg_cache[R_CS].base; |
358 | 360 | pc = cs_base + env->eip; |
359 | 361 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
... | ... | @@ -390,8 +392,7 @@ int cpu_x86_exec(CPUX86State *env1) |
390 | 392 | ret = env->exception_index; |
391 | 393 | |
392 | 394 | /* restore flags in standard format */ |
393 | - op_movl_T0_eflags(); | |
394 | - env->eflags = T0; | |
395 | + env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK); | |
395 | 396 | |
396 | 397 | /* restore global registers */ |
397 | 398 | #ifdef reg_EAX |
... | ... | @@ -489,7 +490,7 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
489 | 490 | /* for glibc 2.1 */ |
490 | 491 | #define REG_EIP EIP |
491 | 492 | #endif |
492 | - pc = uc->uc_mcontext.gregs[EIP]; | |
493 | + pc = uc->uc_mcontext.gregs[REG_EIP]; | |
493 | 494 | pold_set = &uc->uc_sigmask; |
494 | 495 | return handle_cpu_signal(pc, pold_set); |
495 | 496 | #else | ... | ... |