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 | ... | ... |