debuggers.hg
changeset 16501:502f5b9469c3
x86_emulate: Decode and emulate PUSHF/POPF.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Sun Nov 25 18:05:56 2007 +0000 (2007-11-25) |
parents | f6a587e3d5c9 |
children | 7c6944d861b2 |
files | xen/arch/x86/x86_emulate.c |
line diff
1.1 --- a/xen/arch/x86/x86_emulate.c Sun Nov 25 18:05:10 2007 +0000 1.2 +++ b/xen/arch/x86/x86_emulate.c Sun Nov 25 18:05:56 2007 +0000 1.3 @@ -127,7 +127,7 @@ static uint8_t opcode_table[256] = { 1.4 ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 1.5 /* 0x98 - 0x9F */ 1.6 ImplicitOps, ImplicitOps, ImplicitOps, 0, 1.7 - 0, 0, ImplicitOps, ImplicitOps, 1.8 + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 1.9 /* 0xA0 - 0xA7 */ 1.10 ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 1.11 ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 1.12 @@ -265,17 +265,22 @@ struct operand { 1.13 }; 1.14 1.15 /* EFLAGS bit definitions. */ 1.16 -#define EFLG_VM (1<<17) 1.17 -#define EFLG_RF (1<<16) 1.18 -#define EFLG_OF (1<<11) 1.19 -#define EFLG_DF (1<<10) 1.20 -#define EFLG_IF (1<<9) 1.21 -#define EFLG_TF (1<<8) 1.22 -#define EFLG_SF (1<<7) 1.23 -#define EFLG_ZF (1<<6) 1.24 -#define EFLG_AF (1<<4) 1.25 -#define EFLG_PF (1<<2) 1.26 -#define EFLG_CF (1<<0) 1.27 +#define EFLG_VIP (1<<20) 1.28 +#define EFLG_VIF (1<<19) 1.29 +#define EFLG_AC (1<<18) 1.30 +#define EFLG_VM (1<<17) 1.31 +#define EFLG_RF (1<<16) 1.32 +#define EFLG_NT (1<<14) 1.33 +#define EFLG_IOPL (3<<12) 1.34 +#define EFLG_OF (1<<11) 1.35 +#define EFLG_DF (1<<10) 1.36 +#define EFLG_IF (1<<9) 1.37 +#define EFLG_TF (1<<8) 1.38 +#define EFLG_SF (1<<7) 1.39 +#define EFLG_ZF (1<<6) 1.40 +#define EFLG_AF (1<<4) 1.41 +#define EFLG_PF (1<<2) 1.42 +#define EFLG_CF (1<<0) 1.43 1.44 /* Exception definitions. */ 1.45 #define EXC_DE 0 1.46 @@ -2089,6 +2094,31 @@ x86_emulate( 1.47 break; 1.48 } 1.49 1.50 + case 0x9c: /* pushf */ 1.51 + src.val = _regs.eflags; 1.52 + goto push; 1.53 + 1.54 + case 0x9d: /* popf */ { 1.55 + uint32_t mask = EFLG_VIP | EFLG_VIF | EFLG_VM; 1.56 + if ( !mode_iopl() ) 1.57 + mask |= EFLG_IOPL; 1.58 + fail_if(ops->write_rflags == NULL); 1.59 + /* 64-bit mode: POP defaults to a 64-bit operand. */ 1.60 + if ( mode_64bit() && (op_bytes == 4) ) 1.61 + op_bytes = 8; 1.62 + if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes), 1.63 + &dst.val, op_bytes, ctxt)) != 0 ) 1.64 + goto done; 1.65 + if ( op_bytes == 2 ) 1.66 + dst.val = (uint16_t)dst.val | (_regs.eflags & 0xffff0000u); 1.67 + dst.val &= 0x257fd5; 1.68 + _regs.eflags &= mask; 1.69 + _regs.eflags |= (uint32_t)(dst.val & ~mask) | 0x02; 1.70 + if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 ) 1.71 + goto done; 1.72 + break; 1.73 + } 1.74 + 1.75 case 0x9e: /* sahf */ 1.76 *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02; 1.77 break;