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,6 +48,7 @@ | ||
| 48 | #define R_FS 4 | 48 | #define R_FS 4 |
| 49 | #define R_GS 5 | 49 | #define R_GS 5 |
| 50 | 50 | ||
| 51 | +/* eflags masks */ | ||
| 51 | #define CC_C 0x0001 | 52 | #define CC_C 0x0001 |
| 52 | #define CC_P 0x0004 | 53 | #define CC_P 0x0004 |
| 53 | #define CC_A 0x0010 | 54 | #define CC_A 0x0010 |
| @@ -55,15 +56,17 @@ | @@ -55,15 +56,17 @@ | ||
| 55 | #define CC_S 0x0080 | 56 | #define CC_S 0x0080 |
| 56 | #define CC_O 0x0800 | 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 | #define EXCP00_DIVZ 1 | 71 | #define EXCP00_DIVZ 1 |
| 69 | #define EXCP01_SSTP 2 | 72 | #define EXCP01_SSTP 2 |
| @@ -158,7 +161,9 @@ typedef struct CPUX86State { | @@ -158,7 +161,9 @@ typedef struct CPUX86State { | ||
| 158 | /* standard registers */ | 161 | /* standard registers */ |
| 159 | uint32_t regs[8]; | 162 | uint32_t regs[8]; |
| 160 | uint32_t eip; | 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 | /* emulator internal eflags handling */ | 168 | /* emulator internal eflags handling */ |
| 164 | uint32_t cc_src; | 169 | uint32_t cc_src; |
| @@ -183,13 +188,13 @@ typedef struct CPUX86State { | @@ -183,13 +188,13 @@ typedef struct CPUX86State { | ||
| 183 | SegmentDescriptorTable ldt; | 188 | SegmentDescriptorTable ldt; |
| 184 | SegmentDescriptorTable idt; | 189 | SegmentDescriptorTable idt; |
| 185 | 190 | ||
| 186 | - /* various CPU modes */ | ||
| 187 | - int vm86; | ||
| 188 | - | ||
| 189 | /* exception/interrupt handling */ | 191 | /* exception/interrupt handling */ |
| 190 | jmp_buf jmp_env; | 192 | jmp_buf jmp_env; |
| 191 | int exception_index; | 193 | int exception_index; |
| 192 | int interrupt_request; | 194 | int interrupt_request; |
| 195 | + | ||
| 196 | + /* user data */ | ||
| 197 | + void *opaque; | ||
| 193 | } CPUX86State; | 198 | } CPUX86State; |
| 194 | 199 | ||
| 195 | /* all CPU memory access use these macros */ | 200 | /* all CPU memory access use these macros */ |
| @@ -418,7 +423,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, | @@ -418,7 +423,8 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, | ||
| 418 | #define GEN_FLAG_CODE32_SHIFT 0 | 423 | #define GEN_FLAG_CODE32_SHIFT 0 |
| 419 | #define GEN_FLAG_ADDSEG_SHIFT 1 | 424 | #define GEN_FLAG_ADDSEG_SHIFT 1 |
| 420 | #define GEN_FLAG_SS32_SHIFT 2 | 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 | int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, | 429 | int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, |
| 424 | int *gen_code_size_ptr, | 430 | int *gen_code_size_ptr, |
exec-i386.c
| @@ -330,9 +330,10 @@ int cpu_x86_exec(CPUX86State *env1) | @@ -330,9 +330,10 @@ int cpu_x86_exec(CPUX86State *env1) | ||
| 330 | #endif | 330 | #endif |
| 331 | 331 | ||
| 332 | /* put eflags in CPU temporary format */ | 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 | CC_OP = CC_OP_EFLAGS; | 335 | CC_OP = CC_OP_EFLAGS; |
| 336 | + env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); | ||
| 336 | env->interrupt_request = 0; | 337 | env->interrupt_request = 0; |
| 337 | 338 | ||
| 338 | /* prepare setjmp context for exception handling */ | 339 | /* prepare setjmp context for exception handling */ |
| @@ -354,6 +355,7 @@ int cpu_x86_exec(CPUX86State *env1) | @@ -354,6 +355,7 @@ int cpu_x86_exec(CPUX86State *env1) | ||
| 354 | (unsigned long)env->seg_cache[R_ES].base | | 355 | (unsigned long)env->seg_cache[R_ES].base | |
| 355 | (unsigned long)env->seg_cache[R_SS].base) != 0) << | 356 | (unsigned long)env->seg_cache[R_SS].base) != 0) << |
| 356 | GEN_FLAG_ADDSEG_SHIFT; | 357 | GEN_FLAG_ADDSEG_SHIFT; |
| 358 | + flags |= (env->eflags & VM_MASK) >> (17 - GEN_FLAG_VM_SHIFT); | ||
| 357 | cs_base = env->seg_cache[R_CS].base; | 359 | cs_base = env->seg_cache[R_CS].base; |
| 358 | pc = cs_base + env->eip; | 360 | pc = cs_base + env->eip; |
| 359 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, | 361 | tb = tb_find(&ptb, (unsigned long)pc, (unsigned long)cs_base, |
| @@ -390,8 +392,7 @@ int cpu_x86_exec(CPUX86State *env1) | @@ -390,8 +392,7 @@ int cpu_x86_exec(CPUX86State *env1) | ||
| 390 | ret = env->exception_index; | 392 | ret = env->exception_index; |
| 391 | 393 | ||
| 392 | /* restore flags in standard format */ | 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 | /* restore global registers */ | 397 | /* restore global registers */ |
| 397 | #ifdef reg_EAX | 398 | #ifdef reg_EAX |
| @@ -489,7 +490,7 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, | @@ -489,7 +490,7 @@ int cpu_x86_signal_handler(int host_signum, struct siginfo *info, | ||
| 489 | /* for glibc 2.1 */ | 490 | /* for glibc 2.1 */ |
| 490 | #define REG_EIP EIP | 491 | #define REG_EIP EIP |
| 491 | #endif | 492 | #endif |
| 492 | - pc = uc->uc_mcontext.gregs[EIP]; | 493 | + pc = uc->uc_mcontext.gregs[REG_EIP]; |
| 493 | pold_set = &uc->uc_sigmask; | 494 | pold_set = &uc->uc_sigmask; |
| 494 | return handle_cpu_signal(pc, pold_set); | 495 | return handle_cpu_signal(pc, pold_set); |
| 495 | #else | 496 | #else |