ia64/xen-unstable

changeset 4047:be135facb9ee

bitkeeper revision 1.1236.18.1 (422f27c9EveZXnXhkLBg8iYwaAffoQ)

Begin integrating new instruction decoder and emulator.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Mar 09 16:43:53 2005 +0000 (2005-03-09)
parents fec6466347ca
children cf2f74cc53af
files .rootkeys BitKeeper/etc/ignore tools/tests/Makefile tools/tests/test_x86_emulator.c xen/arch/x86/traps.c xen/arch/x86/x86_32/seg_fixup.c xen/arch/x86/x86_64/traps.c xen/arch/x86/x86_emulate.c xen/include/asm-x86/x86_emulate.h
line diff
     1.1 --- a/.rootkeys	Wed Mar 09 16:01:32 2005 +0000
     1.2 +++ b/.rootkeys	Wed Mar 09 16:43:53 2005 +0000
     1.3 @@ -788,6 +788,8 @@ 4104ffca-jPHLVOrW0n0VghEXXtKxg tools/sv/
     1.4  40fcefb3yMSrZvApO9ToIi-iQwnchA tools/sv/images/xen.png
     1.5  41013a83z27rKvWIxAfUBMVZ1eDCDg tools/sv/inc/script.js
     1.6  40fcefb3zGC9XNBkSwTEobCoq8YClA tools/sv/inc/style.css
     1.7 +422f27c8MDeRoOWZNdcRC5VDTcj3TQ tools/tests/Makefile
     1.8 +422f27c81CCtXt4Lthf7JF3Ajr0fUA tools/tests/test_x86_emulator.c
     1.9  420b963dK3yGNtqxRM8npGZtrCQd1g tools/vnet/00INSTALL
    1.10  41a21888_WlknVWjSxb32Fo13_ujsw tools/vnet/00README
    1.11  420a9b706I-bN_uPdiy0m3rmDifNNg tools/vnet/INSTALL
    1.12 @@ -1017,6 +1019,7 @@ 41bf1717XhPz_dNT5OKSjgmbFuWBuA xen/arch/
    1.13  42000d3cMb8o1WuFBXC07c8i3lPZBw xen/arch/x86/x86_64/traps.c
    1.14  40e96d3ahBTZqbTViInnq0lM03vs7A xen/arch/x86/x86_64/usercopy.c
    1.15  40e96d3akN3Hu_J5Bk-WXD8OGscrYQ xen/arch/x86/x86_64/xen.lds
    1.16 +422f27c8J9DQfCpegccMid59XhSmGA xen/arch/x86/x86_emulate.c
    1.17  3ddb79bdff-gj-jFGKjOejeHLqL8Lg xen/common/Makefile
    1.18  3e397e66AyyD5fYraAySWuwi9uqSXg xen/common/ac_timer.c
    1.19  3ddb79bdLX_P6iB7ILiblRLWvebapg xen/common/dom0_ops.c
    1.20 @@ -1180,6 +1183,7 @@ 4208e2a3Fktw4ZttKdDxbhvTQ6brfQ xen/inclu
    1.21  404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/include/asm-x86/x86_64/regs.h
    1.22  40e1966azOJZfNI6Ilthe6Q-T3Hewg xen/include/asm-x86/x86_64/string.h
    1.23  404f1bc4tWkB9Qr8RkKtZGW5eMQzhw xen/include/asm-x86/x86_64/uaccess.h
    1.24 +422f27c8RHFkePhD34VIEpMMqofZcA xen/include/asm-x86/x86_emulate.h
    1.25  400304fcmRQmDdFYEzDh0wcBba9alg xen/include/public/COPYING
    1.26  421098b7OKb9YH_EUA_UpCxBjaqtgA xen/include/public/arch-ia64.h
    1.27  404f1bc68SXxmv0zQpXBWGrCzSyp8w xen/include/public/arch-x86_32.h
     2.1 --- a/BitKeeper/etc/ignore	Wed Mar 09 16:01:32 2005 +0000
     2.2 +++ b/BitKeeper/etc/ignore	Wed Mar 09 16:43:53 2005 +0000
     2.3 @@ -121,32 +121,6 @@ tools/blktap/vdi_snap
     2.4  tools/blktap/vdi_snap_list
     2.5  tools/blktap/vdi_tree
     2.6  tools/blktap/vdi_validate
     2.7 -tools/blktap/xen/arch-ia64.h
     2.8 -tools/blktap/xen/arch-x86_32.h
     2.9 -tools/blktap/xen/arch-x86_64.h
    2.10 -tools/blktap/xen/dom0_ops.h
    2.11 -tools/blktap/xen/event_channel.h
    2.12 -tools/blktap/xen/grant_table.h
    2.13 -tools/blktap/xen/io/blkif.h
    2.14 -tools/blktap/xen/io/domain_controller.h
    2.15 -tools/blktap/xen/io/ioreq.h
    2.16 -tools/blktap/xen/io/netif.h
    2.17 -tools/blktap/xen/io/ring.h
    2.18 -tools/blktap/xen/io/usbif.h
    2.19 -tools/blktap/xen/linux/privcmd.h
    2.20 -tools/blktap/xen/linux/suspend.h
    2.21 -tools/blktap/xen/physdev.h
    2.22 -tools/blktap/xen/sched_ctl.h
    2.23 -tools/blktap/xen/trace.h
    2.24 -tools/blktap/xen/xen.h
    2.25 -tools/cmdline/Makefile
    2.26 -tools/cmdline/ringbuster
    2.27 -tools/cmdline/ringbuster.c
    2.28 -tools/cmdline/xdestroy
    2.29 -tools/cmdline/xdestroy.c
    2.30 -tools/cmdline/xevtchn
    2.31 -tools/cmdline/xevtchn.c
    2.32 -tools/cmdline/xls
    2.33 -tools/cmdline/xls.c
    2.34 -tools/cmdline/xphysinfo
    2.35 -tools/cmdline/xphysinfo.c
    2.36 +tools/blktap/xen/*
    2.37 +tools/cmdline/*
    2.38 +tools/tests/test_x86_emulator
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/tools/tests/Makefile	Wed Mar 09 16:43:53 2005 +0000
     3.3 @@ -0,0 +1,22 @@
     3.4 +
     3.5 +XEN_ROOT=../..
     3.6 +include $(XEN_ROOT)/tools/Rules.mk
     3.7 +
     3.8 +TARGET := test_x86_emulator
     3.9 +
    3.10 +CC     := gcc
    3.11 +CFLAGS := -O2 -Wall -Werror -D__TEST_HARNESS__
    3.12 +
    3.13 +$(TARGET): x86_emulate.o test_x86_emulator.o
    3.14 +	$(CC) -o $@ $^
    3.15 +
    3.16 +clean:
    3.17 +	rm -rf $(TARGET) *.o *~ core
    3.18 +
    3.19 +install:
    3.20 +
    3.21 +x86_emulate.o: $(XEN_ROOT)/xen/arch/x86/x86_emulate.c
    3.22 +	$(CC) $(CFLAGS) -I$(XEN_ROOT)/xen/include -c -o $@ $<
    3.23 +
    3.24 +%.o: %.c
    3.25 +	$(CC) $(CFLAGS) -I$(XEN_ROOT)/xen/include -c -o $@ $<
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/tests/test_x86_emulator.c	Wed Mar 09 16:43:53 2005 +0000
     4.3 @@ -0,0 +1,168 @@
     4.4 +
     4.5 +#include <stdio.h>
     4.6 +#include <stdlib.h>
     4.7 +#include <string.h>
     4.8 +#include <stdint.h>
     4.9 +typedef uint8_t            u8;
    4.10 +typedef uint16_t           u16;
    4.11 +typedef uint32_t           u32;
    4.12 +typedef uint64_t           u64;
    4.13 +typedef int8_t             s8;
    4.14 +typedef int16_t            s16;
    4.15 +typedef int32_t            s32;
    4.16 +typedef int64_t            s64;
    4.17 +#include <public/xen.h>
    4.18 +#include <asm-x86/x86_emulate.h>
    4.19 +
    4.20 +static int read_any(
    4.21 +    unsigned long addr,
    4.22 +    unsigned long *val,
    4.23 +    unsigned int bytes)
    4.24 +{
    4.25 +    switch ( bytes )
    4.26 +    {
    4.27 +    case 1: *val = *(u8 *)addr; break;
    4.28 +    case 2: *val = *(u16 *)addr; break;
    4.29 +    case 4: *val = *(u32 *)addr; break;
    4.30 +    case 8: *val = *(unsigned long *)addr; break;
    4.31 +    }
    4.32 +    return 0;
    4.33 +}
    4.34 +
    4.35 +static int write_any(
    4.36 +    unsigned long addr,
    4.37 +    unsigned long val,
    4.38 +    unsigned int bytes)
    4.39 +{
    4.40 +    switch ( bytes )
    4.41 +    {
    4.42 +    case 1: *(u8 *)addr = (u8)val; break;
    4.43 +    case 2: *(u16 *)addr = (u16)val; break;
    4.44 +    case 4: *(u32 *)addr = (u32)val; break;
    4.45 +    case 8: *(unsigned long *)addr = val; break;
    4.46 +    }
    4.47 +    return 0;
    4.48 +}
    4.49 +
    4.50 +static int cmpxchg_any(
    4.51 +    unsigned long addr,
    4.52 +    unsigned long old,
    4.53 +    unsigned long new,
    4.54 +    unsigned long *seen,
    4.55 +    unsigned int bytes)
    4.56 +{
    4.57 +    *seen = old;
    4.58 +    switch ( bytes )
    4.59 +    {
    4.60 +    case 1: *(u8 *)addr = (u8)new; break;
    4.61 +    case 2: *(u16 *)addr = (u16)new; break;
    4.62 +    case 4: *(u32 *)addr = (u32)new; break;
    4.63 +    case 8: *(unsigned long *)addr = new; break;
    4.64 +    }
    4.65 +    return 0;
    4.66 +}
    4.67 +
    4.68 +static struct x86_mem_emulator emulops = {
    4.69 +    read_any, write_any, read_any, write_any, cmpxchg_any
    4.70 +};
    4.71 +
    4.72 +int main(int argc, char **argv)
    4.73 +{
    4.74 +    struct xen_regs regs;
    4.75 +    char instr[] = { 0x01, 0x08 }; /* add %ecx,(%eax) */
    4.76 +    unsigned int res = 0x7FFFFFFF;
    4.77 +    unsigned long cr2;
    4.78 +    int rc;
    4.79 +
    4.80 +    printf("%-40s", "Testing addl %%ecx,(%%eax)...");
    4.81 +    instr[0] = 0x01; instr[1] = 0x08;
    4.82 +    regs.eflags = 0x200;
    4.83 +    regs.eip    = (unsigned long)&instr[0];
    4.84 +    regs.ecx    = 0x12345678;
    4.85 +    cr2         = (unsigned long)&res;
    4.86 +    res         = 0x7FFFFFFF;
    4.87 +    rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
    4.88 +    if ( (rc != 0) || 
    4.89 +         (res != 0x92345677) || 
    4.90 +         (regs.eflags != 0xa94) ||
    4.91 +         (regs.eip != (unsigned long)&instr[2]) )
    4.92 +        goto fail;
    4.93 +    printf("okay\n");
    4.94 +
    4.95 +    printf("%-40s", "Testing xorl (%%eax),%%ecx...");
    4.96 +    instr[0] = 0x33; instr[1] = 0x08;
    4.97 +    regs.eflags = 0x200;
    4.98 +    regs.eip    = (unsigned long)&instr[0];
    4.99 +#ifdef __x86_64__
   4.100 +    regs.ecx    = 0xFFFFFFFF12345678UL;
   4.101 +#else
   4.102 +    regs.ecx    = 0x12345678UL;
   4.103 +#endif
   4.104 +    cr2         = (unsigned long)&res;
   4.105 +    rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
   4.106 +    if ( (rc != 0) || 
   4.107 +         (res != 0x92345677) || 
   4.108 +         (regs.ecx != 0x8000000FUL) ||
   4.109 +         (regs.eip != (unsigned long)&instr[2]) )
   4.110 +        goto fail;
   4.111 +    printf("okay\n");
   4.112 +
   4.113 +    printf("%-40s", "Testing lock cmpxchgb %%cl,(%%eax)...");
   4.114 +    instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x08;
   4.115 +    regs.eflags = 0x200;
   4.116 +    regs.eip    = (unsigned long)&instr[0];
   4.117 +    regs.eax    = 0x92345677UL;
   4.118 +    regs.ecx    = 0xAA;
   4.119 +    cr2         = (unsigned long)&res;
   4.120 +    rc = x86_emulate_memop(&regs, cr2, &emulops, 4);    
   4.121 +    if ( (rc != 0) || 
   4.122 +         (res != 0x923456AA) || 
   4.123 +         (regs.eflags != 0x244) ||
   4.124 +         (regs.eax != 0x92345677UL) ||
   4.125 +         (regs.eip != (unsigned long)&instr[4]) )
   4.126 +        goto fail;
   4.127 +    printf("okay\n");
   4.128 +
   4.129 +    printf("%-40s", "Testing lock cmpxchgl %%ecx,(%%eax)...");
   4.130 +    instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb1; instr[3] = 0x08;
   4.131 +    regs.eflags = 0x200;
   4.132 +    regs.eip    = (unsigned long)&instr[0];
   4.133 +    regs.eax    = 0x923456AAUL;
   4.134 +    regs.ecx    = 0xDDEEFF00L;
   4.135 +    cr2         = (unsigned long)&res;
   4.136 +    rc = x86_emulate_memop(&regs, cr2, &emulops, 4);    
   4.137 +    if ( (rc != 0) || 
   4.138 +         (res != 0xDDEEFF00) || 
   4.139 +         (regs.eflags != 0x244) ||
   4.140 +         (regs.eax != 0x923456AAUL) ||
   4.141 +         (regs.eip != (unsigned long)&instr[4]) )
   4.142 +        goto fail;
   4.143 +    printf("okay\n");
   4.144 +
   4.145 +    printf("%-40s", "Testing rep movsw...");
   4.146 +    instr[0] = 0xf3; instr[1] = 0x66; instr[2] = 0xa5;
   4.147 +    res         = 0x22334455;
   4.148 +    regs.eflags = 0x200;
   4.149 +    regs.ecx    = 23;
   4.150 +    regs.eip    = (unsigned long)&instr[0];
   4.151 +    regs.esi    = (unsigned long)&res + 0;
   4.152 +    regs.edi    = (unsigned long)&res + 2;
   4.153 +    regs.error_code = 0; /* read fault */
   4.154 +    cr2         = regs.esi;
   4.155 +    rc = x86_emulate_memop(&regs, cr2, &emulops, 4);    
   4.156 +    if ( (rc != 0) || 
   4.157 +         (res != 0x44554455) ||
   4.158 +         (regs.eflags != 0x200) ||
   4.159 +         (regs.ecx != 22) || 
   4.160 +         (regs.esi != ((unsigned long)&res + 2)) ||
   4.161 +         (regs.edi != ((unsigned long)&res + 4)) ||
   4.162 +         (regs.eip != (unsigned long)&instr[0]) )
   4.163 +        goto fail;
   4.164 +    printf("okay\n");
   4.165 +
   4.166 +    return 0;
   4.167 +
   4.168 + fail:
   4.169 +    printf("failed!\n");
   4.170 +    return 1;
   4.171 +}
     5.1 --- a/xen/arch/x86/traps.c	Wed Mar 09 16:01:32 2005 +0000
     5.2 +++ b/xen/arch/x86/traps.c	Wed Mar 09 16:43:53 2005 +0000
     5.3 @@ -52,6 +52,7 @@
     5.4  #include <asm/i387.h>
     5.5  #include <asm/debugger.h>
     5.6  #include <asm/msr.h>
     5.7 +#include <asm/x86_emulate.h>
     5.8  
     5.9  /*
    5.10   * opt_nmi: one of 'ignore', 'dom0', or 'fatal'.
    5.11 @@ -369,8 +370,6 @@ long do_fpu_taskswitch(int set)
    5.12  
    5.13  static int emulate_privileged_op(struct xen_regs *regs)
    5.14  {
    5.15 -    extern void *decode_reg(struct xen_regs *regs, u8 b);
    5.16 -
    5.17      struct exec_domain *ed = current;
    5.18      unsigned long *reg, eip = regs->eip;
    5.19      u8 opcode;
    5.20 @@ -405,7 +404,7 @@ static int emulate_privileged_op(struct 
    5.21          eip += 1;
    5.22          if ( (opcode & 0xc0) != 0xc0 )
    5.23              goto fail;
    5.24 -        reg = decode_reg(regs, opcode & 7);
    5.25 +        reg = decode_register(opcode & 7, regs, 0);
    5.26          switch ( (opcode >> 3) & 7 )
    5.27          {
    5.28          case 0: /* Read CR0 */
    5.29 @@ -433,7 +432,7 @@ static int emulate_privileged_op(struct 
    5.30          eip += 1;
    5.31          if ( (opcode & 0xc0) != 0xc0 )
    5.32              goto fail;
    5.33 -        reg = decode_reg(regs, opcode & 7);
    5.34 +        reg = decode_register(opcode & 7, regs, 0);
    5.35          switch ( (opcode >> 3) & 7 )
    5.36          {
    5.37          case 0: /* Write CR0 */
     6.1 --- a/xen/arch/x86/x86_32/seg_fixup.c	Wed Mar 09 16:01:32 2005 +0000
     6.2 +++ b/xen/arch/x86/x86_32/seg_fixup.c	Wed Mar 09 16:43:53 2005 +0000
     6.3 @@ -28,6 +28,7 @@
     6.4  #include <xen/mm.h>
     6.5  #include <xen/perfc.h>
     6.6  #include <asm/processor.h>
     6.7 +#include <asm/x86_emulate.h>
     6.8  
     6.9  /* Make the scary benign errors go away. */
    6.10  #undef  DPRINTK
    6.11 @@ -258,24 +259,6 @@ int fixup_seg(u16 seg, unsigned long off
    6.12      return 1;
    6.13  }
    6.14  
    6.15 -/* Decode Reg field of a ModRM byte: return a pointer into a register block. */
    6.16 -void *decode_reg(struct xen_regs *regs, u8 b)
    6.17 -{
    6.18 -    switch ( b & 7 )
    6.19 -    {
    6.20 -    case 0: return &regs->eax;
    6.21 -    case 1: return &regs->ecx;
    6.22 -    case 2: return &regs->edx;
    6.23 -    case 3: return &regs->ebx;
    6.24 -    case 4: return &regs->esp;
    6.25 -    case 5: return &regs->ebp;
    6.26 -    case 6: return &regs->esi;
    6.27 -    case 7: return &regs->edi;
    6.28 -    }
    6.29 -
    6.30 -    return NULL;
    6.31 -}
    6.32 -
    6.33  /*
    6.34   * Called from the general-protection fault handler to attempt to decode
    6.35   * and emulate an instruction that depends on 4GB segments.
    6.36 @@ -402,8 +385,8 @@ int gpf_emulate_4gb(struct xen_regs *reg
    6.37      }
    6.38  
    6.39      /* Decode Reg and R/M fields. */
    6.40 -    regreg = decode_reg(regs, reg);
    6.41 -    memreg = decode_reg(regs, rm);
    6.42 +    regreg = decode_register(reg, regs, 0);
    6.43 +    memreg = decode_register(rm,  regs, 0);
    6.44  
    6.45      /* Decode Mod field. */
    6.46      switch ( modrm >> 6 )
     7.1 --- a/xen/arch/x86/x86_64/traps.c	Wed Mar 09 16:01:32 2005 +0000
     7.2 +++ b/xen/arch/x86/x86_64/traps.c	Wed Mar 09 16:43:53 2005 +0000
     7.3 @@ -248,31 +248,6 @@ void __init percpu_traps_init(void)
     7.4      wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U);
     7.5  }
     7.6  
     7.7 -void *decode_reg(struct xen_regs *regs, u8 b)
     7.8 -{
     7.9 -    switch ( b )
    7.10 -    {
    7.11 -    case  0: return &regs->rax;
    7.12 -    case  1: return &regs->rcx;
    7.13 -    case  2: return &regs->rdx;
    7.14 -    case  3: return &regs->rbx;
    7.15 -    case  4: return &regs->rsp;
    7.16 -    case  5: return &regs->rbp;
    7.17 -    case  6: return &regs->rsi;
    7.18 -    case  7: return &regs->rdi;
    7.19 -    case  8: return &regs->r8;
    7.20 -    case  9: return &regs->r9;
    7.21 -    case 10: return &regs->r10;
    7.22 -    case 11: return &regs->r11;
    7.23 -    case 12: return &regs->r12;
    7.24 -    case 13: return &regs->r13;
    7.25 -    case 14: return &regs->r14;
    7.26 -    case 15: return &regs->r15;
    7.27 -    }
    7.28 -
    7.29 -    return NULL;
    7.30 -}
    7.31 -
    7.32  long do_set_callbacks(unsigned long event_address,
    7.33                        unsigned long failsafe_address,
    7.34                        unsigned long syscall_address)
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/arch/x86/x86_emulate.c	Wed Mar 09 16:43:53 2005 +0000
     8.3 @@ -0,0 +1,968 @@
     8.4 +/******************************************************************************
     8.5 + * x86_emulate.c
     8.6 + * 
     8.7 + * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
     8.8 + * 
     8.9 + * Copyright (c) 2005 Keir Fraser
    8.10 + */
    8.11 +
    8.12 +#ifdef __TEST_HARNESS__
    8.13 +#include <stdio.h>
    8.14 +#include <stdint.h>
    8.15 +typedef uint8_t            u8;
    8.16 +typedef uint16_t           u16;
    8.17 +typedef uint32_t           u32;
    8.18 +typedef uint64_t           u64;
    8.19 +typedef int8_t             s8;
    8.20 +typedef int16_t            s16;
    8.21 +typedef int32_t            s32;
    8.22 +typedef int64_t            s64;
    8.23 +#include <public/xen.h>
    8.24 +#else
    8.25 +#include <xen/config.h>
    8.26 +#include <xen/types.h>
    8.27 +#include <xen/lib.h>
    8.28 +#include <asm/regs.h>
    8.29 +#endif
    8.30 +#include <asm-x86/x86_emulate.h>
    8.31 +
    8.32 +/*
    8.33 + * Opcode effective-address decode tables.
    8.34 + * Note that we only emulate instructions that have at least one memory
    8.35 + * operand (excluding implicit stack references). We assume that stack
    8.36 + * references and instruction fetches will never occur in special memory
    8.37 + * areas that require emulation. So, for example, 'mov <imm>,<reg>' need
    8.38 + * not be handled.
    8.39 + */
    8.40 +
    8.41 +/* Operand sizes: 8-bit operands or specified/overridden size. */
    8.42 +#define ByteOp      (1<<0) /* 8-bit operands. */
    8.43 +/* Destination operand type. */
    8.44 +#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
    8.45 +#define DstReg      (2<<1) /* Register operand. */
    8.46 +#define DstMem      (3<<1) /* Memory operand. */
    8.47 +#define DstMask     (3<<1)
    8.48 +/* Source operand type. */
    8.49 +#define SrcNone     (0<<3) /* No source operand. */
    8.50 +#define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
    8.51 +#define SrcReg      (1<<3) /* Register operand. */
    8.52 +#define SrcMem      (2<<3) /* Memory operand. */
    8.53 +#define SrcImm      (3<<3) /* Immediate operand. */
    8.54 +#define SrcImmByte  (4<<3) /* 8-bit sign-extended immediate operand. */
    8.55 +#define SrcMask     (7<<3)
    8.56 +/* Generic ModRM decode. */
    8.57 +#define ModRM       (1<<6)
    8.58 +/* Destination is only written; never read. */
    8.59 +#define Mov         (1<<7)
    8.60 +
    8.61 +static u8 opcode_table[256] = {
    8.62 +    /* 0x00 - 0x07 */
    8.63 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    8.64 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    8.65 +    0, 0, 0, 0,
    8.66 +    /* 0x08 - 0x0F */
    8.67 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    8.68 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    8.69 +    0, 0, 0, 0,
    8.70 +    /* 0x10 - 0x17 */
    8.71 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    8.72 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    8.73 +    0, 0, 0, 0,
    8.74 +    /* 0x18 - 0x1F */
    8.75 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    8.76 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    8.77 +    0, 0, 0, 0,
    8.78 +    /* 0x20 - 0x27 */
    8.79 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    8.80 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    8.81 +    0, 0, 0, 0,
    8.82 +    /* 0x28 - 0x2F */
    8.83 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    8.84 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    8.85 +    0, 0, 0, 0,
    8.86 +    /* 0x30 - 0x37 */
    8.87 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    8.88 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    8.89 +    0, 0, 0, 0,
    8.90 +    /* 0x38 - 0x3F */
    8.91 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
    8.92 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
    8.93 +    0, 0, 0, 0,
    8.94 +    /* 0x40 - 0x4F */
    8.95 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    8.96 +    /* 0x50 - 0x5F */
    8.97 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    8.98 +    /* 0x60 - 0x6F */
    8.99 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.100 +    /* 0x70 - 0x7F */
   8.101 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.102 +    /* 0x80 - 0x87 */
   8.103 +    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
   8.104 +    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM,
   8.105 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   8.106 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   8.107 +    /* 0x88 - 0x8F */
   8.108 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   8.109 +    ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
   8.110 +    0, 0, 0, DstMem|SrcNone|ModRM|Mov,
   8.111 +    /* 0x90 - 0x9F */
   8.112 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.113 +    /* 0xA0 - 0xA7 */
   8.114 +    ByteOp|DstReg|SrcMem|Mov, DstReg|SrcMem|Mov,
   8.115 +    ByteOp|DstMem|SrcReg|Mov, DstMem|SrcReg|Mov,
   8.116 +    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   8.117 +    ByteOp|ImplicitOps, ImplicitOps,
   8.118 +    /* 0xA8 - 0xAF */
   8.119 +    0, 0, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   8.120 +    ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
   8.121 +    ByteOp|ImplicitOps, ImplicitOps,
   8.122 +    /* 0xB0 - 0xBF */
   8.123 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.124 +    /* 0xC0 - 0xC7 */
   8.125 +    ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0,
   8.126 +    0, 0, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM,
   8.127 +    /* 0xC8 - 0xCF */
   8.128 +    0, 0, 0, 0, 0, 0, 0, 0,
   8.129 +    /* 0xD0 - 0xD7 */
   8.130 +    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 
   8.131 +    ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, 
   8.132 +    0, 0, 0, 0,
   8.133 +    /* 0xD8 - 0xDF */
   8.134 +    0, 0, 0, 0, 0, 0, 0, 0,
   8.135 +    /* 0xE0 - 0xEF */
   8.136 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.137 +    /* 0xF0 - 0xF7 */
   8.138 +    0, 0, 0, 0,
   8.139 +    0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM,
   8.140 +    /* 0xF8 - 0xFF */
   8.141 +    0, 0, 0, 0,
   8.142 +    0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM
   8.143 +};
   8.144 +
   8.145 +static u8 twobyte_table[256] = {
   8.146 +    /* 0x00 - 0x0F */
   8.147 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0,
   8.148 +    /* 0x10 - 0x1F */
   8.149 +    0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0,
   8.150 +    /* 0x20 - 0x2F */
   8.151 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.152 +    /* 0x30 - 0x3F */
   8.153 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.154 +    /* 0x40 - 0x47 */
   8.155 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   8.156 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   8.157 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   8.158 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   8.159 +    /* 0x48 - 0x4F */
   8.160 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   8.161 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   8.162 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   8.163 +    DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov,
   8.164 +    /* 0x50 - 0x5F */
   8.165 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.166 +    /* 0x60 - 0x6F */
   8.167 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.168 +    /* 0x70 - 0x7F */
   8.169 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.170 +    /* 0x80 - 0x8F */
   8.171 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.172 +    /* 0x90 - 0x9F */
   8.173 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.174 +    /* 0xA0 - 0xA7 */
   8.175 +    0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0, 
   8.176 +    /* 0xA8 - 0xAF */
   8.177 +    0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
   8.178 +    /* 0xB0 - 0xB7 */
   8.179 +    ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstMem|SrcReg|ModRM,
   8.180 +    0, 0, 0, 0,
   8.181 +    /* 0xB8 - 0xBF */
   8.182 +    0, 0, DstMem|SrcImmByte|ModRM, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
   8.183 +    /* 0xC0 - 0xCF */
   8.184 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.185 +    /* 0xD0 - 0xDF */
   8.186 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.187 +    /* 0xE0 - 0xEF */
   8.188 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   8.189 +    /* 0xF0 - 0xFF */
   8.190 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   8.191 +};
   8.192 +
   8.193 +/* Type, address-of, and value of an instruction's operand. */
   8.194 +struct operand {
   8.195 +    enum { OP_REG, OP_MEM, OP_IMM } type;
   8.196 +    unsigned int  bytes;
   8.197 +    unsigned long val, orig_val, *ptr;
   8.198 +};
   8.199 +
   8.200 +/* EFLAGS bit definitions. */
   8.201 +#define EFLG_OF (1<<11)
   8.202 +#define EFLG_DF (1<<10)
   8.203 +#define EFLG_SF (1<<7)
   8.204 +#define EFLG_ZF (1<<6)
   8.205 +#define EFLG_AF (1<<4)
   8.206 +#define EFLG_PF (1<<2)
   8.207 +#define EFLG_CF (1<<0)
   8.208 +
   8.209 +/*
   8.210 + * Instruction emulation:
   8.211 + * Most instructions are emulated directly via a fragment of inline assembly
   8.212 + * code. This allows us to save/restore EFLAGS and thus very easily pick up
   8.213 + * any modified flags.
   8.214 + */
   8.215 +
   8.216 +#if defined(__x86_64__)
   8.217 +#define _LO32 "k"          /* force 32-bit operand */
   8.218 +#define _STK  "%%rsp"      /* stack pointer */
   8.219 +#elif defined(__i386__)
   8.220 +#define _LO32 ""           /* force 32-bit operand */
   8.221 +#define _STK  "%%esp"      /* stack pointer */
   8.222 +#endif
   8.223 +
   8.224 +/*
   8.225 + * These EFLAGS bits are restored from saved value during emulation, and
   8.226 + * any changes are written back to the saved value after emulation.
   8.227 + */
   8.228 +#define EFLAGS_MASK (EFLG_OF|EFLG_SF|EFLG_ZF|EFLG_AF|EFLG_PF|EFLG_CF)
   8.229 +
   8.230 +/* Before executing instruction: restore necessary bits in EFLAGS. */
   8.231 +/* EFLAGS = (_sav & _msk) | (EFLAGS & ~_msk); _sav &= ~msk; */
   8.232 +#define _PRE_EFLAGS(_sav, _msk, _tmp)           \
   8.233 +"push %"_sav"; "                                \
   8.234 +"movl %"_msk",%"_LO32 _tmp"; "                  \
   8.235 +"andl %"_LO32 _tmp",("_STK"); "                 \
   8.236 +"notl %"_LO32 _tmp"; "                          \
   8.237 +"andl %"_LO32 _tmp",%"_sav"; "                  \
   8.238 +"pushf; "                                       \
   8.239 +"andl %"_LO32 _tmp",("_STK"); "                 \
   8.240 +"pop  %"_tmp"; "                                \
   8.241 +"orl  %"_LO32 _tmp",("_STK"); "                 \
   8.242 +"popf; "
   8.243 +
   8.244 +/* After executing instruction: write-back necessary bits in EFLAGS. */
   8.245 +/* _sav |= EFLAGS & _msk; */
   8.246 +#define _POST_EFLAGS(_sav, _msk, _tmp)          \
   8.247 +"pushf; "                                       \
   8.248 +"pop  %"_tmp"; "                                \
   8.249 +"andl %"_msk",%"_LO32 _tmp"; "                  \
   8.250 +"orl  %"_LO32 _tmp",%"_sav"; "
   8.251 +
   8.252 +/* Raw emulation: instruction has two explicit operands. */
   8.253 +#define __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy)\
   8.254 +do{ unsigned long _tmp;                                                    \
   8.255 +    switch ( (_dst).bytes )                                                \
   8.256 +    {                                                                      \
   8.257 +    case 2:                                                                \
   8.258 +        __asm__ __volatile__ (                                             \
   8.259 +            _PRE_EFLAGS("0","4","2")                                       \
   8.260 +            _op"w %"_wx"3,%1; "                                            \
   8.261 +            _POST_EFLAGS("0","4","2")                                      \
   8.262 +            : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
   8.263 +            : _wy ((_src).val), "i" (EFLAGS_MASK) );                       \
   8.264 +        break;                                                             \
   8.265 +    case 4:                                                                \
   8.266 +        __asm__ __volatile__ (                                             \
   8.267 +            _PRE_EFLAGS("0","4","2")                                       \
   8.268 +            _op"l %"_lx"3,%1; "                                            \
   8.269 +            _POST_EFLAGS("0","4","2")                                      \
   8.270 +            : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
   8.271 +            : _ly ((_src).val), "i" (EFLAGS_MASK) );                       \
   8.272 +        break;                                                             \
   8.273 +    case 8:                                                                \
   8.274 +        __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy);           \
   8.275 +        break;                                                             \
   8.276 +    }                                                                      \
   8.277 +} while (0)
   8.278 +#define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy)\
   8.279 +do{ unsigned long _tmp;                                                    \
   8.280 +    switch ( (_dst).bytes )                                                \
   8.281 +    {                                                                      \
   8.282 +    case 1:                                                                \
   8.283 +        __asm__ __volatile__ (                                             \
   8.284 +            _PRE_EFLAGS("0","4","2")                                       \
   8.285 +            _op"b %"_bx"3,%1; "                                            \
   8.286 +            _POST_EFLAGS("0","4","2")                                      \
   8.287 +            : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
   8.288 +            : _by ((_src).val), "i" (EFLAGS_MASK) );                       \
   8.289 +        break;                                                             \
   8.290 +    default:                                                               \
   8.291 +        __emulate_2op_nobyte(_op,_src,_dst,_eflags,_wx,_wy,_lx,_ly,_qx,_qy);\
   8.292 +        break;                                                             \
   8.293 +    }                                                                      \
   8.294 +} while (0)
   8.295 +/* Source operand is byte-sized and may be restricted to just %cl. */
   8.296 +#define emulate_2op_SrcB(_op, _src, _dst, _eflags)                         \
   8.297 +    __emulate_2op(_op, _src, _dst, _eflags,                                \
   8.298 +                  "b", "c", "b", "c", "b", "c", "b", "c")
   8.299 +/* Source operand is byte, word, long or quad sized. */
   8.300 +#define emulate_2op_SrcV(_op, _src, _dst, _eflags)                         \
   8.301 +    __emulate_2op(_op, _src, _dst, _eflags,                                \
   8.302 +                  "b", "q", "w", "r", _LO32, "r", "", "r")
   8.303 +/* Source operand is word, long or quad sized. */
   8.304 +#define emulate_2op_SrcV_nobyte(_op, _src, _dst, _eflags)                  \
   8.305 +    __emulate_2op_nobyte(_op, _src, _dst, _eflags,                         \
   8.306 +                  "w", "r", _LO32, "r", "", "r")
   8.307 +
   8.308 +/* Instruction has only one explicit operand (no source operand). */
   8.309 +#define emulate_1op(_op,_dst,_eflags)                                      \
   8.310 +do{ unsigned long _tmp;                                                    \
   8.311 +    switch ( (_dst).bytes )                                                \
   8.312 +    {                                                                      \
   8.313 +    case 1:                                                                \
   8.314 +        __asm__ __volatile__ (                                             \
   8.315 +            _PRE_EFLAGS("0","3","2")                                       \
   8.316 +            _op"b %1; "                                                    \
   8.317 +            _POST_EFLAGS("0","3","2")                                      \
   8.318 +            : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
   8.319 +            : "i" (EFLAGS_MASK) );                                         \
   8.320 +        break;                                                             \
   8.321 +    case 2:                                                                \
   8.322 +        __asm__ __volatile__ (                                             \
   8.323 +            _PRE_EFLAGS("0","3","2")                                       \
   8.324 +            _op"w %1; "                                                    \
   8.325 +            _POST_EFLAGS("0","3","2")                                      \
   8.326 +            : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
   8.327 +            : "i" (EFLAGS_MASK) );                                         \
   8.328 +        break;                                                             \
   8.329 +    case 4:                                                                \
   8.330 +        __asm__ __volatile__ (                                             \
   8.331 +            _PRE_EFLAGS("0","3","2")                                       \
   8.332 +            _op"l %1; "                                                    \
   8.333 +            _POST_EFLAGS("0","3","2")                                      \
   8.334 +            : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)              \
   8.335 +            : "i" (EFLAGS_MASK) );                                         \
   8.336 +        break;                                                             \
   8.337 +    case 8:                                                                \
   8.338 +        __emulate_1op_8byte(_op, _dst, _eflags);                           \
   8.339 +        break;                                                             \
   8.340 +    }                                                                      \
   8.341 +} while (0)
   8.342 +
   8.343 +/* Emulate an instruction with quadword operands (x86/64 only). */
   8.344 +#if defined(__x86_64__)
   8.345 +#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)         \
   8.346 +do{ __asm__ __volatile__ (                                              \
   8.347 +        _PRE_EFLAGS("0","4","2")                                        \
   8.348 +        _op"q %"_qx"3,%1; "                                             \
   8.349 +        _POST_EFLAGS("0","4","2")                                       \
   8.350 +        : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)               \
   8.351 +        : _qy ((_src).val), "i" (EFLAGS_MASK) );                        \
   8.352 +} while (0)
   8.353 +#define __emulate_1op_8byte(_op, _dst, _eflags)                         \
   8.354 +do{ __asm__ __volatile__ (                                              \
   8.355 +        _PRE_EFLAGS("0","3","2")                                        \
   8.356 +        _op"q %1; "                                                     \
   8.357 +        _POST_EFLAGS("0","3","2")                                       \
   8.358 +        : "=m" (_eflags), "=m" ((_dst).val), "=&r" (_tmp)               \
   8.359 +        : "i" (EFLAGS_MASK) );                                          \
   8.360 +} while (0)
   8.361 +#elif defined(__i386__)
   8.362 +#define __emulate_2op_8byte(_op, _src, _dst, _eflags, _qx, _qy)
   8.363 +#define __emulate_1op_8byte(_op, _dst, _eflags)
   8.364 +#endif /* __i386__ */
   8.365 +
   8.366 +/* Fetch next part of the instruction being emulated. */
   8.367 +#define insn_fetch(_type, _size, _eip) \
   8.368 +({ unsigned long _x; \
   8.369 +   if ( ops->read_std((unsigned long)(_eip), &_x, (_size)) ) \
   8.370 +       goto done; \
   8.371 +   (_eip) += (_size); \
   8.372 +   (_type)_x; \
   8.373 +})
   8.374 +
   8.375 +#define DPRINTF(_f, _a...) printf( _f , ## _a )
   8.376 +
   8.377 +void *
   8.378 +decode_register(
   8.379 +    u8 modrm_reg, struct xen_regs *regs, int highbyte_regs)
   8.380 +{
   8.381 +    void *p;
   8.382 +
   8.383 +    switch ( modrm_reg )
   8.384 +    {
   8.385 +    case  0: p = &regs->eax; break;
   8.386 +    case  1: p = &regs->ecx; break;
   8.387 +    case  2: p = &regs->edx; break;
   8.388 +    case  3: p = &regs->ebx; break;
   8.389 +    case  4: p = (highbyte_regs ?
   8.390 +                  ((unsigned char *)&regs->eax + 1) : 
   8.391 +                  (unsigned char *)&regs->esp); break;
   8.392 +    case  5: p = (highbyte_regs ?
   8.393 +                  ((unsigned char *)&regs->ecx + 1) : 
   8.394 +                  (unsigned char *)&regs->ebp); break;
   8.395 +    case  6: p = (highbyte_regs ?
   8.396 +                  ((unsigned char *)&regs->edx + 1) : 
   8.397 +                  (unsigned char *)&regs->esi); break;
   8.398 +    case  7: p = (highbyte_regs ?
   8.399 +                  ((unsigned char *)&regs->ebx + 1) : 
   8.400 +                  (unsigned char *)&regs->edi); break;
   8.401 +#if defined(__x86_64__)
   8.402 +    case  8: p = &regs->r8;  break;
   8.403 +    case  9: p = &regs->r9;  break;
   8.404 +    case 10: p = &regs->r10; break;
   8.405 +    case 11: p = &regs->r11; break;
   8.406 +    case 12: p = &regs->r12; break;
   8.407 +    case 13: p = &regs->r13; break;
   8.408 +    case 14: p = &regs->r14; break;
   8.409 +    case 15: p = &regs->r15; break;
   8.410 +#endif
   8.411 +    default: p = NULL; break;
   8.412 +    }
   8.413 +
   8.414 +    return p;
   8.415 +}
   8.416 +
   8.417 +int 
   8.418 +x86_emulate_memop(
   8.419 +    struct xen_regs *regs,
   8.420 +    unsigned long cr2,
   8.421 +    struct x86_mem_emulator *ops,
   8.422 +    int mode)
   8.423 +{
   8.424 +    u8 b, d, sib, twobyte = 0, rex_prefix = 0;
   8.425 +    u8 modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
   8.426 +    unsigned int op_bytes = (mode == 8) ? 4 : mode, ad_bytes = mode;
   8.427 +    unsigned int lock_prefix = 0, rep_prefix = 0;
   8.428 +    struct operand src, dst;
   8.429 +
   8.430 +    /* Shadow copy of register state. Committed on successful emulation. */
   8.431 +    struct xen_regs _regs = *regs;
   8.432 +
   8.433 +    /* Legacy prefixes. */
   8.434 + next_prefix:
   8.435 +    switch ( b = insn_fetch(u8, 1, _regs.eip) )
   8.436 +    {
   8.437 +    case 0x66: /* operand-size override */
   8.438 +        op_bytes ^= 6;                    /* switch between 2/4 bytes */
   8.439 +        goto next_prefix;
   8.440 +    case 0x67: /* address-size override */
   8.441 +        ad_bytes ^= (mode == 8) ? 12 : 6; /* switch between 2/4 or 4/8 bytes */
   8.442 +        goto next_prefix;
   8.443 +    case 0x2e: /* CS override */
   8.444 +    case 0x3e: /* DS override */
   8.445 +    case 0x26: /* ES override */
   8.446 +    case 0x64: /* FS override */
   8.447 +    case 0x65: /* GS override */
   8.448 +    case 0x36: /* SS override */
   8.449 +        DPRINTF("Warning: ignoring a segment override. Probably okay. :-)\n");
   8.450 +        goto next_prefix;
   8.451 +    case 0xf0: /* LOCK */
   8.452 +        lock_prefix = 1;
   8.453 +        goto next_prefix;
   8.454 +    case 0xf3: /* REP/REPE/REPZ */
   8.455 +        rep_prefix = 1;
   8.456 +        goto next_prefix;
   8.457 +    case 0xf2: /* REPNE/REPNZ */
   8.458 +        goto next_prefix;
   8.459 +    }
   8.460 +
   8.461 +    if ( ad_bytes == 2 )
   8.462 +    {
   8.463 +        DPRINTF("Cannot parse 16-bit effective addresses.\n");
   8.464 +        goto cannot_emulate;
   8.465 +    }
   8.466 +
   8.467 +    /* REX prefix. */
   8.468 +    if ( (mode == 8) && ((b & 0xf0) == 0x40) )
   8.469 +    {
   8.470 +        rex_prefix = b;
   8.471 +        if ( b & 8 )
   8.472 +            op_bytes = 8;          /* REX.W */
   8.473 +        modrm_reg = (b & 4) << 1;  /* REX.R */
   8.474 +        /* REX.B and REX.X do not need to be decoded. */
   8.475 +        b = insn_fetch(u8, 1, _regs.eip);
   8.476 +    }
   8.477 +
   8.478 +    /* Opcode byte(s). */
   8.479 +    d = opcode_table[b];
   8.480 +    if ( d == 0 )
   8.481 +    {
   8.482 +        /* Two-byte opcode? */
   8.483 +        if ( b == 0x0f )
   8.484 +        {
   8.485 +            twobyte = 1;
   8.486 +            b = insn_fetch(u8, 1, _regs.eip);
   8.487 +            d = twobyte_table[b];
   8.488 +        }
   8.489 +
   8.490 +        /* Unrecognised? */
   8.491 +        if ( d == 0 )
   8.492 +            goto cannot_emulate;
   8.493 +    }
   8.494 +
   8.495 +    /* ModRM and SIB bytes. */
   8.496 +    if ( d & ModRM )
   8.497 +    {
   8.498 +        modrm = insn_fetch(u8, 1, _regs.eip);
   8.499 +        modrm_mod |= (modrm & 0xc0) >> 6;
   8.500 +        modrm_reg |= (modrm & 0x38) >> 3;
   8.501 +        modrm_rm  |= (modrm & 0x07);
   8.502 +        switch ( modrm_mod )
   8.503 +        {
   8.504 +        case 0:
   8.505 +            if ( (modrm_rm == 4) && 
   8.506 +                 (((sib = insn_fetch(u8, 1, _regs.eip)) & 7) == 5) )
   8.507 +                _regs.eip += 4; /* skip disp32 specified by SIB.base */
   8.508 +            else if ( modrm_rm == 5 )
   8.509 +                _regs.eip += 4; /* skip disp32 */
   8.510 +            break;
   8.511 +        case 1:
   8.512 +            if ( modrm_rm == 4 )
   8.513 +                sib = insn_fetch(u8, 1, _regs.eip);
   8.514 +            _regs.eip += 1; /* skip disp8 */
   8.515 +            break;
   8.516 +        case 2:
   8.517 +            if ( modrm_rm == 4 )
   8.518 +                sib = insn_fetch(u8, 1, _regs.eip);
   8.519 +            _regs.eip += 4; /* skip disp32 */
   8.520 +            break;
   8.521 +        case 3:
   8.522 +            DPRINTF("Cannot parse ModRM.mod == 3.\n");
   8.523 +            goto cannot_emulate;
   8.524 +        }
   8.525 +    }
   8.526 +
   8.527 +    /* Decode and fetch the destination operand: register or memory. */
   8.528 +    switch ( d & DstMask )
   8.529 +    {
   8.530 +    case ImplicitOps:
   8.531 +        /* Special instructions do their own operand decoding. */
   8.532 +        goto special_insn;
   8.533 +    case DstReg:
   8.534 +        dst.type = OP_REG;
   8.535 +        if ( d & ByteOp )
   8.536 +        {
   8.537 +            dst.ptr = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
   8.538 +            dst.val = *(u8 *)dst.ptr;
   8.539 +            dst.bytes = 1;
   8.540 +        }
   8.541 +        else
   8.542 +        {
   8.543 +            dst.ptr = decode_register(modrm_reg, &_regs, 0);
   8.544 +            switch ( (dst.bytes = op_bytes) )
   8.545 +            {
   8.546 +            case 2: dst.val = *(u16 *)dst.ptr; break;
   8.547 +            case 4: dst.val = *(u32 *)dst.ptr; break;
   8.548 +            case 8: dst.val = *(u64 *)dst.ptr; break;
   8.549 +            }
   8.550 +        }
   8.551 +        break;
   8.552 +    case DstMem:
   8.553 +        dst.type  = OP_MEM;
   8.554 +        dst.ptr   = (unsigned long *)cr2;
   8.555 +        dst.bytes = (d & ByteOp) ? 1 : op_bytes;
   8.556 +        if ( !(d & Mov) && /* optimisation - avoid slow emulated read */
   8.557 +             ops->read_emulated((unsigned long)dst.ptr, &dst.val, dst.bytes) )
   8.558 +             goto done;
   8.559 +        break;
   8.560 +    }
   8.561 +    dst.orig_val = dst.val;
   8.562 +
   8.563 +    /* Decode and fetch the source operand: register, memory or immediate. */
   8.564 +    switch ( d & SrcMask )
   8.565 +    {
   8.566 +    case SrcNone:
   8.567 +        break;
   8.568 +    case SrcReg:
   8.569 +        src.type = OP_REG;
   8.570 +        if ( d & ByteOp )
   8.571 +        {
   8.572 +            src.ptr = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
   8.573 +            src.val = src.orig_val = *(u8 *)src.ptr;
   8.574 +            src.bytes = 1;
   8.575 +        }
   8.576 +        else
   8.577 +        {
   8.578 +            src.ptr = decode_register(modrm_reg, &_regs, 0);
   8.579 +            switch ( (src.bytes = op_bytes) )
   8.580 +            {
   8.581 +            case 2: src.val = src.orig_val = *(u16 *)src.ptr; break;
   8.582 +            case 4: src.val = src.orig_val = *(u32 *)src.ptr; break;
   8.583 +            case 8: src.val = src.orig_val = *(u64 *)src.ptr; break;
   8.584 +            }
   8.585 +        }
   8.586 +        break;
   8.587 +    case SrcMem:
   8.588 +        src.type  = OP_MEM;
   8.589 +        src.ptr   = (unsigned long *)cr2;
   8.590 +        src.bytes = (d & ByteOp) ? 1 : op_bytes;
   8.591 +        if ( ops->read_emulated((unsigned long)src.ptr, &src.val, src.bytes) )
   8.592 +            goto done;
   8.593 +        src.orig_val = src.val;
   8.594 +        break;
   8.595 +    case SrcImm:
   8.596 +        src.type  = OP_IMM;
   8.597 +        src.ptr   = (unsigned long *)_regs.eip;
   8.598 +        src.bytes = (d & ByteOp) ? 1 : op_bytes;
   8.599 +        if ( src.bytes == 8 ) src.bytes = 4;
   8.600 +        /* NB. Immediates are sign-extended as necessary. */
   8.601 +        switch ( src.bytes )
   8.602 +        {
   8.603 +        case 1: src.val = insn_fetch(s8,  1, _regs.eip); break;
   8.604 +        case 2: src.val = insn_fetch(s16, 2, _regs.eip); break;
   8.605 +        case 4: src.val = insn_fetch(s32, 4, _regs.eip); break;
   8.606 +        }
   8.607 +        break;
   8.608 +    case SrcImmByte:
   8.609 +        src.type  = OP_IMM;
   8.610 +        src.ptr   = (unsigned long *)_regs.eip;
   8.611 +        src.bytes = 1;
   8.612 +        src.val   = insn_fetch(s8,  1, _regs.eip);
   8.613 +        break;
   8.614 +    }
   8.615 +
   8.616 +    if ( twobyte )
   8.617 +        goto twobyte_insn;
   8.618 +
   8.619 +    switch ( b )
   8.620 +    {
   8.621 +    case 0x00 ... 0x05: add: /* add */
   8.622 +        emulate_2op_SrcV("add", src, dst, _regs.eflags);
   8.623 +        break;
   8.624 +    case 0x08 ... 0x0d: or:  /* or */
   8.625 +        emulate_2op_SrcV("or", src, dst, _regs.eflags);
   8.626 +        break;
   8.627 +    case 0x10 ... 0x15: adc: /* adc */
   8.628 +        emulate_2op_SrcV("adc", src, dst, _regs.eflags);
   8.629 +        break;
   8.630 +    case 0x18 ... 0x1d: sbb: /* sbb */
   8.631 +        emulate_2op_SrcV("sbb", src, dst, _regs.eflags);
   8.632 +        break;
   8.633 +    case 0x20 ... 0x25: and: /* and */
   8.634 +        emulate_2op_SrcV("and", src, dst, _regs.eflags);
   8.635 +        break;
   8.636 +    case 0x28 ... 0x2d: sub: /* sub */
   8.637 +        emulate_2op_SrcV("sub", src, dst, _regs.eflags);
   8.638 +        break;
   8.639 +    case 0x30 ... 0x35: xor: /* xor */
   8.640 +        emulate_2op_SrcV("xor", src, dst, _regs.eflags);
   8.641 +        break;
   8.642 +    case 0x38 ... 0x3d: cmp: /* cmp */
   8.643 +        emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
   8.644 +        break;
   8.645 +    case 0x80 ... 0x83: /* Grp1 */
   8.646 +        switch ( modrm_reg )
   8.647 +        {
   8.648 +        case 0: goto add;
   8.649 +        case 1: goto or;
   8.650 +        case 2: goto adc;
   8.651 +        case 3: goto sbb;
   8.652 +        case 4: goto and;
   8.653 +        case 5: goto sub;
   8.654 +        case 6: goto xor;
   8.655 +        case 7: goto cmp;
   8.656 +        }
   8.657 +        break;
   8.658 +    case 0x84 ... 0x85: test: /* test */
   8.659 +        emulate_2op_SrcV("test", src, dst, _regs.eflags);
   8.660 +        break;
   8.661 +    case 0x86 ... 0x87: /* xchg */
   8.662 +        src.val ^= dst.val;
   8.663 +        dst.val ^= src.val;
   8.664 +        src.val ^= dst.val;
   8.665 +        break;
   8.666 +    case 0xa0 ... 0xa1: /* mov */
   8.667 +        dst.ptr = (unsigned long *)&_regs.eax;
   8.668 +        dst.val = src.val;
   8.669 +        _regs.eip += ad_bytes; /* skip src displacement */
   8.670 +        break;
   8.671 +    case 0xa2 ... 0xa3: /* mov */
   8.672 +        dst.val = (unsigned long)_regs.eax;
   8.673 +        _regs.eip += ad_bytes; /* skip dst displacement */
   8.674 +        break;
   8.675 +    case 0x88 ... 0x8b: /* mov */
   8.676 +    case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */
   8.677 +        dst.val = src.val;
   8.678 +        break;
   8.679 +    case 0x8f: /* pop (sole member of Grp1a) */
   8.680 +        /* 64-bit mode: POP defaults to 64-bit operands. */
   8.681 +        if ( (mode == 8) && (dst.bytes == 4) )
   8.682 +            dst.bytes = 8;
   8.683 +        if ( ops->read_std(_regs.esp, &dst.val, dst.bytes) )
   8.684 +            goto done;
   8.685 +        _regs.esp += dst.bytes;
   8.686 +        break;
   8.687 +    case 0xc0 ... 0xc1: grp2: /* Grp2 */
   8.688 +        switch ( modrm_reg )
   8.689 +        {
   8.690 +        case 0: /* rol */
   8.691 +            emulate_2op_SrcB("rol", src, dst, _regs.eflags);
   8.692 +            break;
   8.693 +        case 1: /* ror */
   8.694 +            emulate_2op_SrcB("ror", src, dst, _regs.eflags);
   8.695 +            break;
   8.696 +        case 2: /* rcl */
   8.697 +            emulate_2op_SrcB("rcl", src, dst, _regs.eflags);
   8.698 +            break;
   8.699 +        case 3: /* rcr */
   8.700 +            emulate_2op_SrcB("rcr", src, dst, _regs.eflags);
   8.701 +            break;
   8.702 +        case 4: /* sal/shl */
   8.703 +        case 6: /* sal/shl */
   8.704 +            emulate_2op_SrcB("sal", src, dst, _regs.eflags);
   8.705 +            break;
   8.706 +        case 5: /* shr */
   8.707 +            emulate_2op_SrcB("shr", src, dst, _regs.eflags);
   8.708 +            break;
   8.709 +        case 7: /* sar */
   8.710 +            emulate_2op_SrcB("sar", src, dst, _regs.eflags);
   8.711 +            break;
   8.712 +        }
   8.713 +        break;
   8.714 +    case 0xd0 ... 0xd1: /* Grp2 */
   8.715 +        src.val = 1;
   8.716 +        goto grp2;
   8.717 +    case 0xd2 ... 0xd3: /* Grp2 */
   8.718 +        src.val = _regs.ecx;
   8.719 +        goto grp2;
   8.720 +    case 0xf6 ... 0xf7: /* Grp3 */
   8.721 +        switch ( modrm_reg )
   8.722 +        {
   8.723 +        case 0 ... 1: /* test */
   8.724 +            /* Special case in Grp3: test has an immediate source operand. */
   8.725 +            src.type = OP_IMM;
   8.726 +            src.ptr  = (unsigned long *)_regs.eip;
   8.727 +            src.bytes = (d & ByteOp) ? 1 : op_bytes;
   8.728 +            if ( src.bytes == 8 ) src.bytes = 4;
   8.729 +            switch ( src.bytes )
   8.730 +            {
   8.731 +            case 1: src.val = insn_fetch(s8,  1, _regs.eip); break;
   8.732 +            case 2: src.val = insn_fetch(s16, 2, _regs.eip); break;
   8.733 +            case 4: src.val = insn_fetch(s32, 4, _regs.eip); break;
   8.734 +            }
   8.735 +            goto test;
   8.736 +        case 2: /* not */
   8.737 +            dst.val = ~dst.val;
   8.738 +            break;
   8.739 +        case 3: /* neg */
   8.740 +            emulate_1op("neg", dst, _regs.eflags);
   8.741 +            break;
   8.742 +        default:
   8.743 +            goto cannot_emulate;
   8.744 +        }
   8.745 +        break;
   8.746 +    case 0xfe ... 0xff: /* Grp4/Grp5 */
   8.747 +        switch ( modrm_reg )
   8.748 +        {
   8.749 +        case 0: /* inc */
   8.750 +            emulate_1op("inc", dst, _regs.eflags);
   8.751 +            break;
   8.752 +        case 1: /* dec */
   8.753 +            emulate_1op("dec", dst, _regs.eflags);
   8.754 +            break;
   8.755 +        case 6: /* push */
   8.756 +            /* 64-bit mode: PUSH defaults to 64-bit operands. */
   8.757 +            if ( (mode == 8) && (dst.bytes == 4) )
   8.758 +            {
   8.759 +                dst.bytes = 8;
   8.760 +                if ( ops->read_std((unsigned long)dst.ptr, &dst.val, 8) )
   8.761 +                    goto done;
   8.762 +            }
   8.763 +            _regs.esp -= dst.bytes;
   8.764 +            if ( ops->write_std(_regs.esp, dst.val, dst.bytes) )
   8.765 +                goto done;
   8.766 +            dst.val = dst.orig_val; /* skanky: disable writeback */
   8.767 +            break;
   8.768 +        default:
   8.769 +            goto cannot_emulate;
   8.770 +        }
   8.771 +        break;
   8.772 +    }
   8.773 +
   8.774 + writeback:
   8.775 +    if ( (d & Mov) || (dst.orig_val != dst.val) )
   8.776 +    {
   8.777 +        switch ( dst.type )
   8.778 +        {
   8.779 +        case OP_REG:
   8.780 +            /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
   8.781 +            switch ( dst.bytes )
   8.782 +            {
   8.783 +            case 1: *(u8  *)dst.ptr = (u8)dst.val; break;
   8.784 +            case 2: *(u16 *)dst.ptr = (u16)dst.val; break;
   8.785 +            case 4: *dst.ptr = (u32)dst.val; break; /* 64b mode: zero-extend */
   8.786 +            case 8: *dst.ptr = dst.val; break;
   8.787 +            }
   8.788 +            break;
   8.789 +        case OP_MEM:
   8.790 +            if ( lock_prefix )
   8.791 +            {
   8.792 +                unsigned long seen;
   8.793 +                if ( ops->cmpxchg_emulated((unsigned long)dst.ptr,
   8.794 +                                           dst.orig_val, dst.val,
   8.795 +                                           &seen, dst.bytes) )
   8.796 +                    goto done;
   8.797 +                if ( seen != dst.orig_val )
   8.798 +                    goto done; /* Try again... */
   8.799 +            }
   8.800 +            else
   8.801 +            {
   8.802 +                if ( ops->write_emulated((unsigned long)dst.ptr,
   8.803 +                                         dst.val, dst.bytes) )
   8.804 +                    goto done;
   8.805 +            }
   8.806 +            break;
   8.807 +        default:
   8.808 +            break;
   8.809 +        }
   8.810 +    }
   8.811 +
   8.812 +    /* Commit shadow register state. */
   8.813 +    *regs = _regs;
   8.814 +
   8.815 + done:
   8.816 +    return 0;
   8.817 +
   8.818 + special_insn:
   8.819 +    if ( twobyte )
   8.820 +        goto twobyte_special_insn;
   8.821 +    if ( rep_prefix )
   8.822 +    {
   8.823 +        if ( _regs.ecx == 0 )
   8.824 +        {
   8.825 +            regs->eip = _regs.eip;
   8.826 +            goto done;
   8.827 +        }
   8.828 +        _regs.ecx--;
   8.829 +        _regs.eip = regs->eip;
   8.830 +    }
   8.831 +    switch ( b )
   8.832 +    {
   8.833 +    case 0xa4 ... 0xa5: /* movs */
   8.834 +        dst.type  = OP_MEM;
   8.835 +        dst.bytes = (d & ByteOp) ? 1 : op_bytes;
   8.836 +        if ( _regs.error_code & 2 )
   8.837 +        {
   8.838 +            /* Write fault: destination is special memory. */
   8.839 +            dst.ptr = (unsigned long *)cr2;
   8.840 +            if ( ops->read_std(_regs.esi - _regs.edi + cr2, 
   8.841 +                               &dst.val, dst.bytes) )
   8.842 +                goto done;
   8.843 +        }
   8.844 +        else
   8.845 +        {
   8.846 +            /* Read fault: source is special memory. */
   8.847 +            dst.ptr = (unsigned long *)(_regs.edi - _regs.esi + cr2);
   8.848 +            if ( ops->read_emulated(cr2, &dst.val, dst.bytes) )
   8.849 +                goto done;
   8.850 +        }
   8.851 +        _regs.esi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
   8.852 +        _regs.edi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
   8.853 +        break;
   8.854 +    case 0xa6 ... 0xa7: /* cmps */
   8.855 +        DPRINTF("Urk! I don't handle CMPS.\n");
   8.856 +        goto cannot_emulate;
   8.857 +    case 0xaa ... 0xab: /* stos */
   8.858 +        dst.type  = OP_MEM;
   8.859 +        dst.bytes = (d & ByteOp) ? 1 : op_bytes;
   8.860 +        dst.ptr   = (unsigned long *)cr2;
   8.861 +        dst.val   = _regs.eax;
   8.862 +        _regs.edi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
   8.863 +        break;
   8.864 +    case 0xac ... 0xad: /* lods */
   8.865 +        dst.type  = OP_REG;
   8.866 +        dst.bytes = (d & ByteOp) ? 1 : op_bytes;
   8.867 +        dst.ptr   = (unsigned long *)&_regs.eax;
   8.868 +        if ( ops->read_emulated(cr2, &dst.val, dst.bytes) )
   8.869 +            goto done;
   8.870 +        _regs.esi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes;
   8.871 +        break;
   8.872 +    case 0xae ... 0xaf: /* scas */
   8.873 +        DPRINTF("Urk! I don't handle SCAS.\n");
   8.874 +        goto cannot_emulate;
   8.875 +    }
   8.876 +    goto writeback;
   8.877 +
   8.878 + twobyte_insn:
   8.879 +    switch ( b )
   8.880 +    {
   8.881 +    case 0x40 ... 0x4f: /* cmov */
   8.882 +        dst.val = dst.orig_val = src.val;
   8.883 +        d &= ~Mov; /* default to no move */
   8.884 +        /* First, assume we're decoding an even cmov opcode (lsb == 0). */
   8.885 +        switch ( (b & 15) >> 1 )
   8.886 +        {
   8.887 +        case 0: /* cmovo */
   8.888 +            d |= (_regs.eflags & EFLG_OF) ? Mov : 0;
   8.889 +            break;
   8.890 +        case 1: /* cmovb/cmovc/cmovnae */
   8.891 +            d |= (_regs.eflags & EFLG_CF) ? Mov : 0;
   8.892 +            break;
   8.893 +        case 2: /* cmovz/cmove */
   8.894 +            d |= (_regs.eflags & EFLG_ZF) ? Mov : 0;
   8.895 +            break;
   8.896 +        case 3: /* cmovbe/cmovna */
   8.897 +            d |= (_regs.eflags & (EFLG_CF|EFLG_ZF)) ? Mov : 0;
   8.898 +            break;
   8.899 +        case 4: /* cmovs */
   8.900 +            d |= (_regs.eflags & EFLG_SF) ? Mov : 0;
   8.901 +            break;
   8.902 +        case 5: /* cmovp/cmovpe */
   8.903 +            d |= (_regs.eflags & EFLG_PF) ? Mov : 0;
   8.904 +            break;
   8.905 +        case 7: /* cmovle/cmovng */
   8.906 +            d |= (_regs.eflags & EFLG_ZF) ? Mov : 0;
   8.907 +            /* fall through */
   8.908 +        case 6: /* cmovl/cmovnge */
   8.909 +            d |= (!(_regs.eflags & EFLG_SF) != !(_regs.eflags & EFLG_OF)) ?
   8.910 +                Mov : 0;
   8.911 +            break;
   8.912 +        }
   8.913 +        /* Odd cmov opcodes (lsb == 1) have inverted sense. */
   8.914 +        d ^= (b & 1) ? Mov : 0;
   8.915 +        break;
   8.916 +    case 0xb0 ... 0xb1: /* cmpxchg */
   8.917 +        /* Save real source value, then compare EAX against destination. */
   8.918 +        src.orig_val = src.val;
   8.919 +        src.val = _regs.eax;
   8.920 +        emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
   8.921 +        /* Always write back. The question is: where to? */
   8.922 +        d |= Mov;
   8.923 +        if ( _regs.eflags & EFLG_ZF )
   8.924 +        {
   8.925 +            /* Success: write back to memory. */
   8.926 +            dst.val = src.orig_val;
   8.927 +        }
   8.928 +        else
   8.929 +        {
   8.930 +            /* Failure: write the value we saw to EAX. */
   8.931 +            dst.type = OP_REG;
   8.932 +            dst.ptr  = (unsigned long *)&_regs.eax;
   8.933 +        }
   8.934 +        break;
   8.935 +    case 0xa3: bt: /* bt */
   8.936 +        src.val &= (1UL << (1 << dst.bytes)) - 1; /* only subword offset */
   8.937 +        emulate_2op_SrcV_nobyte("bt", src, dst, _regs.eflags);
   8.938 +        break;
   8.939 +    case 0xb3: btr: /* btr */
   8.940 +        src.val &= (1UL << (1 << dst.bytes)) - 1; /* only subword offset */
   8.941 +        emulate_2op_SrcV_nobyte("btr", src, dst, _regs.eflags);
   8.942 +        break;
   8.943 +    case 0xab: bts: /* bts */
   8.944 +        src.val &= (1UL << (1 << dst.bytes)) - 1; /* only subword offset */
   8.945 +        emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
   8.946 +        break;
   8.947 +    case 0xbb: btc: /* btc */
   8.948 +        src.val &= (1UL << (1 << dst.bytes)) - 1; /* only subword offset */
   8.949 +        emulate_2op_SrcV_nobyte("btc", src, dst, _regs.eflags);
   8.950 +        break;
   8.951 +    case 0xba: /* Grp8 */
   8.952 +        switch ( modrm_reg >> 1 )
   8.953 +        {
   8.954 +        case 0: goto bt;
   8.955 +        case 1: goto bts;
   8.956 +        case 2: goto btr;
   8.957 +        case 3: goto btc;
   8.958 +        }
   8.959 +        break;
   8.960 +    }
   8.961 +    goto writeback;
   8.962 +
   8.963 + twobyte_special_insn:
   8.964 +    /* Only prefetch instructions get here, so nothing to do. */
   8.965 +    dst.orig_val = dst.val; /* disable writeback */
   8.966 +    goto writeback;
   8.967 +
   8.968 + cannot_emulate:
   8.969 +    DPRINTF("Cannot emulate %02x\n", b);
   8.970 +    return -1;
   8.971 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/xen/include/asm-x86/x86_emulate.h	Wed Mar 09 16:43:53 2005 +0000
     9.3 @@ -0,0 +1,131 @@
     9.4 +/******************************************************************************
     9.5 + * x86_emulate.h
     9.6 + * 
     9.7 + * Generic x86 (32-bit and 64-bit) instruction decoder and emulator.
     9.8 + * 
     9.9 + * Copyright (c) 2005 Keir Fraser
    9.10 + */
    9.11 +
    9.12 +#ifndef __X86_EMULATE_H__
    9.13 +#define __X86_EMULATE_H__
    9.14 +
    9.15 +/*
    9.16 + * x86_mem_emulator:
    9.17 + * 
    9.18 + * These operations represent the instruction emulator's interface to memory.
    9.19 + * There are two categories of operation: those that act on ordinary memory
    9.20 + * regions (*_std), and those that act on memory regions known to require
    9.21 + * special treatment or emulation (*_emulated).
    9.22 + * 
    9.23 + * The emulator assumes that an instruction accesses only one 'emulated memory'
    9.24 + * location, and that this is one of its data operands. Instruction fetches and
    9.25 + * stack operations are assumed never to access emulated memory. The emulator
    9.26 + * automatically deduces which operand of a string-move operation is accessing
    9.27 + * emulated memory, and requires that the other operand accesses normal memory.
    9.28 + * 
    9.29 + * NOTES:
    9.30 + *  1. The emulator isn't very smart about emulated vs. standard memory.
    9.31 + *     'Emulated memory' access addresses should be checked for sanity.
    9.32 + *     'Normal memory' accesses may fault, and the caller must arrange to
    9.33 + *     detect and handle reentrancy into the emulator via recursive faults.
    9.34 + *     Accesses may be unaligned and may cross page boundaries.
    9.35 + *  2. If the access fails (cannot emulate, or a standard access faults) then
    9.36 + *     it is up to the memop to propagate the fault to the guest VM via
    9.37 + *     some out-of-band mechanism, unknown to the emulator. The memop signals
    9.38 + *     failure by returning a non-zero value to the emulator, which will then
    9.39 + *     immediately bail.
    9.40 + */
    9.41 +struct x86_mem_emulator
    9.42 +{
    9.43 +    /*
    9.44 +     * read_std: Read bytes of standard (non-emulated/special) memory.
    9.45 +     *           Used for instruction fetch, stack operations, and others.
    9.46 +     *  @addr:  [IN ] Linear address from which to read.
    9.47 +     *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
    9.48 +     *  @bytes: [IN ] Number of bytes to read from memory.
    9.49 +     */
    9.50 +    int (*read_std)(
    9.51 +        unsigned long addr,
    9.52 +        unsigned long *val,
    9.53 +        unsigned int bytes);
    9.54 +
    9.55 +    /*
    9.56 +     * write_std: Write bytes of standard (non-emulated/special) memory.
    9.57 +     *            Used for stack operations, and others.
    9.58 +     *  @addr:  [IN ] Linear address to which to write.
    9.59 +     *  @val:   [IN ] Value to write to memory (low-order bytes used as req'd).
    9.60 +     *  @bytes: [IN ] Number of bytes to write to memory.
    9.61 +     */
    9.62 +    int (*write_std)(
    9.63 +        unsigned long addr,
    9.64 +        unsigned long val,
    9.65 +        unsigned int bytes);
    9.66 +
    9.67 +    /*
    9.68 +     * read_emulated: Read bytes from emulated/special memory area.
    9.69 +     *  @addr:  [IN ] Linear address from which to read.
    9.70 +     *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
    9.71 +     *  @bytes: [IN ] Number of bytes to read from memory.
    9.72 +     */
    9.73 +    int (*read_emulated)(
    9.74 +        unsigned long addr,
    9.75 +        unsigned long *val,
    9.76 +        unsigned int bytes);
    9.77 +
    9.78 +    /*
    9.79 +     * write_emulated: Read bytes from emulated/special memory area.
    9.80 +     *  @addr:  [IN ] Linear address to which to write.
    9.81 +     *  @val:   [IN ] Value to write to memory (low-order bytes used as req'd).
    9.82 +     *  @bytes: [IN ] Number of bytes to write to memory.
    9.83 +     */
    9.84 +    int (*write_emulated)(
    9.85 +        unsigned long addr,
    9.86 +        unsigned long val,
    9.87 +        unsigned int bytes);
    9.88 +
    9.89 +    /*
    9.90 +     * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
    9.91 +     *                   emulated/special memory area.
    9.92 +     *  @addr:  [IN ] Linear address to access.
    9.93 +     *  @old:   [IN ] Value expected to be current at @addr.
    9.94 +     *  @new:   [IN ] Value to write to @addr.
    9.95 +     *  @seen:  [OUT] Value actually seen at @addr, zero-extended to 'u_long'.
    9.96 +     *  @bytes: [IN ] Number of bytes to access using CMPXCHG.
    9.97 +     */
    9.98 +    int (*cmpxchg_emulated)(
    9.99 +        unsigned long addr,
   9.100 +        unsigned long old, 
   9.101 +        unsigned long new,
   9.102 +        unsigned long *seen,
   9.103 +        unsigned int bytes);
   9.104 +};
   9.105 +
   9.106 +
   9.107 +struct xen_regs;
   9.108 +
   9.109 +/*
   9.110 + * x86_emulate_memop: Emulate an instruction that faulted attempting to
   9.111 + *                    read/write a 'special' memory area.
   9.112 + *  @regs: Register state at time of fault.
   9.113 + *  @cr2:  Linear faulting address.
   9.114 + *  @ops:  Interface to access special memory.
   9.115 + *  @mode: Current execution mode, represented by the default size of memory
   9.116 + *         addresses, in bytes. Valid values are 2, 4 and 8 (x86/64 only).
   9.117 + */
   9.118 +extern int
   9.119 +x86_emulate_memop(
   9.120 +    struct xen_regs *regs,
   9.121 +    unsigned long cr2,
   9.122 +    struct x86_mem_emulator *ops,
   9.123 +    int mode);
   9.124 +
   9.125 +/*
   9.126 + * Given the 'reg' portion of a ModRM byte, and a register block, return a
   9.127 + * pointer into the block that addresses the relevant register.
   9.128 + * @highbyte_regs specifies whether to decode AH,CH,DH,BH.
   9.129 + */
   9.130 +extern void *
   9.131 +decode_register(
   9.132 +    u8 modrm_reg, struct xen_regs *regs, int highbyte_regs);
   9.133 +
   9.134 +#endif /* __X86_EMULATE_H__ */