direct-io.hg

changeset 13340:ecf6a0a05350

[XEN] Add LOOP{,Z,NZ} and CBW/CWD/... emulation.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Thu Jan 11 19:01:28 2007 +0000 (2007-01-11)
parents 568ba07641c6
children 162d9d9eaf4a
files xen/arch/x86/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/x86_emulate.c	Thu Jan 11 19:00:35 2007 +0000
     1.2 +++ b/xen/arch/x86/x86_emulate.c	Thu Jan 11 19:01:28 2007 +0000
     1.3 @@ -109,7 +109,7 @@ static uint8_t opcode_table[256] = {
     1.4      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
     1.5      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
     1.6      /* 0x98 - 0x9F */
     1.7 -    0, 0, 0, 0, 0, 0, ImplicitOps, ImplicitOps,
     1.8 +    ImplicitOps, ImplicitOps, 0, 0, 0, 0, ImplicitOps, ImplicitOps,
     1.9      /* 0xA0 - 0xA7 */
    1.10      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
    1.11      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
    1.12 @@ -139,7 +139,7 @@ static uint8_t opcode_table[256] = {
    1.13      /* 0xD8 - 0xDF */
    1.14      0, 0, 0, 0, 0, 0, 0, 0,
    1.15      /* 0xE0 - 0xE7 */
    1.16 -    0, 0, 0, ImplicitOps, 0, 0, 0, 0,
    1.17 +    ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 0, 0, 0, 0,
    1.18      /* 0xE8 - 0xEF */
    1.19      ImplicitOps, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0,
    1.20      /* 0xF0 - 0xF7 */
    1.21 @@ -1339,6 +1339,30 @@ x86_emulate(
    1.22          dst.val  = *dst.reg;
    1.23          goto xchg;
    1.24  
    1.25 +    case 0x98: /* cbw/cwde/cdqe */
    1.26 +        switch ( op_bytes )
    1.27 +        {
    1.28 +        case 2: *(int16_t *)&_regs.eax = (int8_t)_regs.eax; break; /* cbw */
    1.29 +        case 4: _regs.eax = (uint32_t)(int16_t)_regs.eax; break; /* cwde */
    1.30 +        case 8: _regs.eax = (int32_t)_regs.eax; break; /* cdqe */
    1.31 +        }
    1.32 +        break;
    1.33 +
    1.34 +    case 0x99: /* cwd/cdq/cqo */
    1.35 +        switch ( op_bytes )
    1.36 +        {
    1.37 +        case 2:
    1.38 +            *(int16_t *)&_regs.edx = ((int16_t)_regs.eax < 0) ? -1 : 0;
    1.39 +            break;
    1.40 +        case 4:
    1.41 +            _regs.edx = (uint32_t)(((int32_t)_regs.eax < 0) ? -1 : 0);
    1.42 +            break;
    1.43 +        case 8:
    1.44 +            _regs.edx = (_regs.eax < 0) ? -1 : 0;
    1.45 +            break;
    1.46 +        }
    1.47 +        break;
    1.48 +
    1.49      case 0x9e: /* sahf */
    1.50          *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02;
    1.51          break;
    1.52 @@ -1452,6 +1476,31 @@ x86_emulate(
    1.53          break;
    1.54      }
    1.55  
    1.56 +    case 0xe0 ... 0xe2: /* loop{,z,nz} */ {
    1.57 +        int rel = insn_fetch_type(int8_t);
    1.58 +        int do_jmp = !(_regs.eflags & EFLG_ZF); /* loopnz */
    1.59 +        if ( b == 0xe1 )
    1.60 +            do_jmp = !do_jmp; /* loopz */
    1.61 +        else if ( b == 0xe2 )
    1.62 +            do_jmp = 1; /* loop */
    1.63 +        switch ( ad_bytes )
    1.64 +        {
    1.65 +        case 2:
    1.66 +            do_jmp &= --(*(uint16_t *)&_regs.ecx) != 0;
    1.67 +            break;
    1.68 +        case 4:
    1.69 +            do_jmp &= --(*(uint32_t *)&_regs.ecx) != 0;
    1.70 +            _regs.ecx = (uint32_t)_regs.ecx; /* zero extend in x86/64 mode */
    1.71 +            break;
    1.72 +        default: /* case 8: */
    1.73 +            do_jmp &= --_regs.ecx != 0;
    1.74 +            break;
    1.75 +        }
    1.76 +        if ( do_jmp )
    1.77 +            jmp_rel(rel);
    1.78 +        break;
    1.79 +    }
    1.80 +
    1.81      case 0xe3: /* jcxz/jecxz (short) */ {
    1.82          int rel = insn_fetch_type(int8_t);
    1.83          if ( (ad_bytes == 2) ? !(uint16_t)_regs.ecx :