ia64/xen-unstable

changeset 16500:3057f813da14

x86_emulate: Fix POPA. Few other cleanups.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Nov 29 19:30:33 2007 +0000 (2007-11-29)
parents e10eacec8b91
children 32ec5dbe2978 8e3d42fdb8e7
files xen/arch/x86/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/x86_emulate.c	Wed Nov 28 22:36:33 2007 +0000
     1.2 +++ b/xen/arch/x86/x86_emulate.c	Thu Nov 29 19:30:33 2007 +0000
     1.3 @@ -1484,7 +1484,7 @@ x86_emulate(
     1.4      case 0xc4: /* les */ {
     1.5          unsigned long sel;
     1.6          dst.val = x86_seg_es;
     1.7 -    les:
     1.8 +    les: /* dst.val identifies the segment */
     1.9          generate_exception_if(src.type != OP_MEM, EXC_UD);
    1.10          if ( (rc = ops->read(src.mem.seg, src.mem.off + src.bytes,
    1.11                               &sel, 2, ctxt)) != 0 )
    1.12 @@ -1723,7 +1723,8 @@ x86_emulate(
    1.13              break;
    1.14          case 2: /* call (near) */
    1.15          case 4: /* jmp (near) */
    1.16 -            if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() )
    1.17 +            dst.type = OP_NONE;
    1.18 +            if ( (dst.bytes != 8) && mode_64bit() )
    1.19              {
    1.20                  dst.bytes = op_bytes = 8;
    1.21                  if ( dst.type == OP_REG )
    1.22 @@ -1739,7 +1740,7 @@ x86_emulate(
    1.23              break;
    1.24          case 3: /* call (far, absolute indirect) */
    1.25          case 5: /* jmp (far, absolute indirect) */ {
    1.26 -            unsigned long sel, eip = dst.val;
    1.27 +            unsigned long sel;
    1.28  
    1.29              if ( (rc = ops->read(dst.mem.seg, dst.mem.off+dst.bytes,
    1.30                                   &sel, 2, ctxt)) )
    1.31 @@ -1759,7 +1760,7 @@ x86_emulate(
    1.32  
    1.33              if ( (rc = load_seg(x86_seg_cs, sel, ctxt, ops)) != 0 )
    1.34                  goto done;
    1.35 -            _regs.eip = eip;
    1.36 +            _regs.eip = dst.val;
    1.37  
    1.38              dst.type = OP_NONE;
    1.39              break;
    1.40 @@ -1866,7 +1867,7 @@ x86_emulate(
    1.41          src.val = x86_seg_es;
    1.42      pop_seg:
    1.43          fail_if(ops->write_segment == NULL);
    1.44 -        /* 64-bit mode: PUSH defaults to a 64-bit operand. */
    1.45 +        /* 64-bit mode: POP defaults to a 64-bit operand. */
    1.46          if ( mode_64bit() && (op_bytes == 4) )
    1.47              op_bytes = 8;
    1.48          if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
    1.49 @@ -2005,9 +2006,18 @@ x86_emulate(
    1.50              (unsigned long *)&_regs.ecx, (unsigned long *)&_regs.eax };
    1.51          generate_exception_if(mode_64bit(), EXC_UD);
    1.52          for ( i = 0; i < 8; i++ )
    1.53 +        {
    1.54              if ( (rc = ops->read(x86_seg_ss, sp_post_inc(op_bytes),
    1.55 -                                 regs[i], op_bytes, ctxt)) != 0 )
    1.56 -            goto done;
    1.57 +                                 &dst.val, op_bytes, ctxt)) != 0 )
    1.58 +                goto done;
    1.59 +            switch ( op_bytes )
    1.60 +            {
    1.61 +            case 1: *(uint8_t  *)regs[i] = (uint8_t)dst.val; break;
    1.62 +            case 2: *(uint16_t *)regs[i] = (uint16_t)dst.val; break;
    1.63 +            case 4: *regs[i] = (uint32_t)dst.val; break; /* 64b: zero-ext */
    1.64 +            case 8: *regs[i] = dst.val; break;
    1.65 +            }
    1.66 +        }
    1.67          break;
    1.68      }
    1.69