ia64/xen-unstable

changeset 18841:90ed7af65570

x86_emulate: Fix for test harness and simplify some opcodes.

- Need to use EFLG_DF rather than EF_DF
- No need to force EAX destination for many opcodes, as this will be
the default behaviour for DstReg with no ModRM.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Nov 27 16:22:14 2008 +0000 (2008-11-27)
parents 8d5474a5c66b
children 9be2fe3de567
files xen/arch/x86/x86_emulate/x86_emulate.c
line diff
     1.1 --- a/xen/arch/x86/x86_emulate/x86_emulate.c	Thu Nov 27 12:43:25 2008 +0000
     1.2 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c	Thu Nov 27 16:22:14 2008 +0000
     1.3 @@ -28,6 +28,7 @@
     1.4  #define DstImplicit (0<<1) /* Destination operand is implicit in the opcode. */
     1.5  #define DstBitBase  (1<<1) /* Memory operand, bit string. */
     1.6  #define DstReg      (2<<1) /* Register operand. */
     1.7 +#define DstEax      DstReg /* Register EAX (aka DstReg with no ModRM) */
     1.8  #define DstMem      (3<<1) /* Memory operand. */
     1.9  #define DstMask     (3<<1)
    1.10  /* Source operand type. */
    1.11 @@ -51,35 +52,35 @@ static uint8_t opcode_table[256] = {
    1.12      /* 0x00 - 0x07 */
    1.13      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.14      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    1.15 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,
    1.16 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps, ImplicitOps,
    1.17      /* 0x08 - 0x0F */
    1.18      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.19      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    1.20 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, 0,
    1.21 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps, 0,
    1.22      /* 0x10 - 0x17 */
    1.23      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.24      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    1.25 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,
    1.26 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps, ImplicitOps,
    1.27      /* 0x18 - 0x1F */
    1.28      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.29      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    1.30 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, ImplicitOps, ImplicitOps,
    1.31 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm, ImplicitOps, ImplicitOps,
    1.32      /* 0x20 - 0x27 */
    1.33      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.34      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    1.35 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
    1.36 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps,
    1.37      /* 0x28 - 0x2F */
    1.38      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.39      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    1.40 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
    1.41 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps,
    1.42      /* 0x30 - 0x37 */
    1.43      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.44      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    1.45 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
    1.46 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps,
    1.47      /* 0x38 - 0x3F */
    1.48      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    1.49      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    1.50 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps,
    1.51 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm, 0, ImplicitOps,
    1.52      /* 0x40 - 0x4F */
    1.53      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
    1.54      ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps,
    1.55 @@ -125,7 +126,7 @@ static uint8_t opcode_table[256] = {
    1.56      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
    1.57      ByteOp|ImplicitOps, ImplicitOps,
    1.58      /* 0xA8 - 0xAF */
    1.59 -    ByteOp|DstReg|SrcImm, DstReg|SrcImm,
    1.60 +    ByteOp|DstEax|SrcImm, DstEax|SrcImm,
    1.61      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
    1.62      ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
    1.63      ByteOp|ImplicitOps, ImplicitOps,
    1.64 @@ -687,12 +688,12 @@ static void __put_rep_prefix(
    1.65  })
    1.66  
    1.67  /* Clip maximum repetitions so that the index register only just wraps. */
    1.68 -#define truncate_ea_and_reps(ea, reps, bytes_per_rep) ({                \
    1.69 -    unsigned long __todo = (ctxt->regs->eflags & EF_DF) ? (ea) : ~(ea); \
    1.70 -    __todo = truncate_word(__todo, ad_bytes);                           \
    1.71 -    __todo = (__todo / (bytes_per_rep)) + 1;                            \
    1.72 -    (reps) = (__todo < (reps)) ? __todo : (reps);                       \
    1.73 -    truncate_word((ea), ad_bytes);                                      \
    1.74 +#define truncate_ea_and_reps(ea, reps, bytes_per_rep) ({                  \
    1.75 +    unsigned long __todo = (ctxt->regs->eflags & EFLG_DF) ? (ea) : ~(ea); \
    1.76 +    __todo = truncate_word(__todo, ad_bytes);                             \
    1.77 +    __todo = (__todo / (bytes_per_rep)) + 1;                              \
    1.78 +    (reps) = (__todo < (reps)) ? __todo : (reps);                         \
    1.79 +    truncate_word((ea), ad_bytes);                                        \
    1.80  })
    1.81  
    1.82  /* Compatibility function: read guest memory, zero-extend result to a ulong. */
    1.83 @@ -1574,59 +1575,35 @@ x86_emulate(
    1.84  
    1.85      switch ( b )
    1.86      {
    1.87 -    case 0x04 ... 0x05: /* add imm,%%eax */
    1.88 -        dst.reg = (unsigned long *)&_regs.eax;
    1.89 -        dst.val = _regs.eax;
    1.90 -    case 0x00 ... 0x03: add: /* add */
    1.91 +    case 0x00 ... 0x05: add: /* add */
    1.92          emulate_2op_SrcV("add", src, dst, _regs.eflags);
    1.93          break;
    1.94  
    1.95 -    case 0x0c ... 0x0d: /* or imm,%%eax */
    1.96 -        dst.reg = (unsigned long *)&_regs.eax;
    1.97 -        dst.val = _regs.eax;
    1.98 -    case 0x08 ... 0x0b: or:  /* or */
    1.99 +    case 0x08 ... 0x0d: or:  /* or */
   1.100          emulate_2op_SrcV("or", src, dst, _regs.eflags);
   1.101          break;
   1.102  
   1.103 -    case 0x14 ... 0x15: /* adc imm,%%eax */
   1.104 -        dst.reg = (unsigned long *)&_regs.eax;
   1.105 -        dst.val = _regs.eax;
   1.106 -    case 0x10 ... 0x13: adc: /* adc */
   1.107 +    case 0x10 ... 0x15: adc: /* adc */
   1.108          emulate_2op_SrcV("adc", src, dst, _regs.eflags);
   1.109          break;
   1.110  
   1.111 -    case 0x1c ... 0x1d: /* sbb imm,%%eax */
   1.112 -        dst.reg = (unsigned long *)&_regs.eax;
   1.113 -        dst.val = _regs.eax;
   1.114 -    case 0x18 ... 0x1b: sbb: /* sbb */
   1.115 +    case 0x18 ... 0x1d: sbb: /* sbb */
   1.116          emulate_2op_SrcV("sbb", src, dst, _regs.eflags);
   1.117          break;
   1.118  
   1.119 -    case 0x24 ... 0x25: /* and imm,%%eax */
   1.120 -        dst.reg = (unsigned long *)&_regs.eax;
   1.121 -        dst.val = _regs.eax;
   1.122 -    case 0x20 ... 0x23: and: /* and */
   1.123 +    case 0x20 ... 0x25: and: /* and */
   1.124          emulate_2op_SrcV("and", src, dst, _regs.eflags);
   1.125          break;
   1.126  
   1.127 -    case 0x2c ... 0x2d: /* sub imm,%%eax */
   1.128 -        dst.reg = (unsigned long *)&_regs.eax;
   1.129 -        dst.val = _regs.eax;
   1.130 -    case 0x28 ... 0x2b: sub: /* sub */
   1.131 +    case 0x28 ... 0x2d: sub: /* sub */
   1.132          emulate_2op_SrcV("sub", src, dst, _regs.eflags);
   1.133          break;
   1.134  
   1.135 -    case 0x34 ... 0x35: /* xor imm,%%eax */
   1.136 -        dst.reg = (unsigned long *)&_regs.eax;
   1.137 -        dst.val = _regs.eax;
   1.138 -    case 0x30 ... 0x33: xor: /* xor */
   1.139 +    case 0x30 ... 0x35: xor: /* xor */
   1.140          emulate_2op_SrcV("xor", src, dst, _regs.eflags);
   1.141          break;
   1.142  
   1.143 -    case 0x3c ... 0x3d: /* cmp imm,%%eax */
   1.144 -        dst.reg = (unsigned long *)&_regs.eax;
   1.145 -        dst.val = _regs.eax;
   1.146 -    case 0x38 ... 0x3b: cmp: /* cmp */
   1.147 +    case 0x38 ... 0x3d: cmp: /* cmp */
   1.148          emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
   1.149          dst.type = OP_NONE;
   1.150          break;
   1.151 @@ -1988,8 +1965,6 @@ x86_emulate(
   1.152          break;
   1.153  
   1.154      case 0xa8 ... 0xa9: /* test imm,%%eax */
   1.155 -        dst.reg = (unsigned long *)&_regs.eax;
   1.156 -        dst.val = _regs.eax;
   1.157      case 0x84 ... 0x85: test: /* test */
   1.158          emulate_2op_SrcV("test", src, dst, _regs.eflags);
   1.159          dst.type = OP_NONE;