diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-03-21 18:04:36 +0000 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-03-21 18:04:36 +0000 |
commit | 1abc0a00cec5396d12d83c8725b6e33f148684c6 (patch) | |
tree | b1dd3a4ca0085838a36f30b149ce09e2d8040a8f /tools/tests | |
parent | 03d7fde4dbfc960fe6b720fa43e2b475c0c8389b (diff) | |
download | xen-1abc0a00cec5396d12d83c8725b6e33f148684c6.tar.gz xen-1abc0a00cec5396d12d83c8725b6e33f148684c6.tar.bz2 xen-1abc0a00cec5396d12d83c8725b6e33f148684c6.zip |
bitkeeper revision 1.1236.1.101 (423f0cb4e4UtnlbkQsaMhXYz4hi__w)
Add CMPXCHG8B support to the instruction emulator.
Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'tools/tests')
-rw-r--r-- | tools/tests/test_x86_emulator.c | 52 |
1 files changed, 50 insertions, 2 deletions
diff --git a/tools/tests/test_x86_emulator.c b/tools/tests/test_x86_emulator.c index 25a4a4bcbe..4347727488 100644 --- a/tools/tests/test_x86_emulator.c +++ b/tools/tests/test_x86_emulator.c @@ -60,15 +60,28 @@ static int cmpxchg_any( return X86EMUL_CONTINUE; } +static int cmpxchg8b_any( + unsigned long addr, + unsigned long old_lo, + unsigned long old_hi, + unsigned long new_lo, + unsigned long new_hi) +{ + ((unsigned long *)addr)[0] = new_lo; + ((unsigned long *)addr)[1] = new_hi; + return X86EMUL_CONTINUE; +} + static struct x86_mem_emulator emulops = { - read_any, write_any, read_any, write_any, cmpxchg_any + read_any, write_any, read_any, write_any, cmpxchg_any, cmpxchg8b_any }; int main(int argc, char **argv) { struct xen_regs regs; - char instr[] = { 0x01, 0x08 }; /* add %ecx,(%eax) */ + char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */ unsigned int res = 0x7FFFFFFF; + u32 cmpxchg8b_res[2] = { 0x12345678, 0x87654321 }; unsigned long cr2; int rc; @@ -173,6 +186,41 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); + printf("%-40s", "Testing cmpxchg (%edi) [succeeding]..."); + instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f; + regs.eflags = 0x200; + regs.eax = cmpxchg8b_res[0]; + regs.edx = cmpxchg8b_res[1]; + regs.ebx = 0x9999AAAA; + regs.ecx = 0xCCCCFFFF; + regs.eip = (unsigned long)&instr[0]; + regs.edi = (unsigned long)cmpxchg8b_res; + cr2 = regs.edi; + rc = x86_emulate_memop(®s, cr2, &emulops, 4); + if ( (rc != 0) || + (cmpxchg8b_res[0] != 0x9999AAAA) || + (cmpxchg8b_res[1] != 0xCCCCFFFF) || + ((regs.eflags&0x240) != 0x240) || + (regs.eip != (unsigned long)&instr[3]) ) + goto fail; + printf("okay\n"); + + printf("%-40s", "Testing cmpxchg (%edi) [failing]..."); + instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f; + regs.eip = (unsigned long)&instr[0]; + regs.edi = (unsigned long)cmpxchg8b_res; + cr2 = regs.edi; + rc = x86_emulate_memop(®s, cr2, &emulops, 4); + if ( (rc != 0) || + (cmpxchg8b_res[0] != 0x9999AAAA) || + (cmpxchg8b_res[1] != 0xCCCCFFFF) || + (regs.eax != 0x9999AAAA) || + (regs.edx != 0xCCCCFFFF) || + ((regs.eflags&0x240) != 0x200) || + (regs.eip != (unsigned long)&instr[3]) ) + goto fail; + printf("okay\n"); + return 0; fail: |