From: Julian Seward Date: Tue, 28 Sep 2010 14:58:03 +0000 (+0000) Subject: Add test cases for CMPXCHG reg, reg on amd64. (Vince Weaver, X-Git-Tag: svn/VALGRIND_3_6_0~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=552292d2065bd6ccd25b9aab3573445493b73196;p=thirdparty%2Fvalgrind.git Add test cases for CMPXCHG reg, reg on amd64. (Vince Weaver, vince@csl.cornell.edu). See #246311. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11386 --- diff --git a/none/tests/amd64/Makefile.am b/none/tests/amd64/Makefile.am index 0928d568a1..eca836ad9f 100644 --- a/none/tests/amd64/Makefile.am +++ b/none/tests/amd64/Makefile.am @@ -30,6 +30,7 @@ EXTRA_DIST = \ bug156404-amd64.vgtest bug156404-amd64.stdout.exp \ bug156404-amd64.stderr.exp \ clc.vgtest clc.stdout.exp clc.stderr.exp \ + cmpxchg.vgtest cmpxchg.stdout.exp cmpxchg.stderr.exp \ faultstatus.disabled faultstatus.stderr.exp \ fcmovnu.vgtest fcmovnu.stderr.exp fcmovnu.stdout.exp \ fxtract.vgtest fxtract.stderr.exp fxtract.stdout.exp \ @@ -60,6 +61,7 @@ check_PROGRAMS = \ amd64locked \ bug127521-64 bug132813-amd64 bug132918 \ clc \ + cmpxchg \ $(INSN_TESTS) \ rcl-amd64 \ redundantRexW \ diff --git a/none/tests/amd64/cmpxchg.c b/none/tests/amd64/cmpxchg.c new file mode 100644 index 0000000000..62f146280f --- /dev/null +++ b/none/tests/amd64/cmpxchg.c @@ -0,0 +1,273 @@ +#include "tests/asm.h" +#include + +/* This test only checks register/register cmpxchg */ + +typedef unsigned long long int ULong; +typedef unsigned int UInt; + +ULong m64; + +ULong rax; +ULong rbx; +ULong rcx; +ULong rdx; +ULong rax_out; +ULong rbx_out; +ULong rcx_out; + +int main ( void ) +{ + + /* 8-bit */ + + rdx = 0x11111111; rax = 0x22222222; + rcx = 0x33333333; rbx = 0x44444444; + + printf("cmpxchg %%bl,%%cl (al=%llx bl=%llx cl=%llx)\n", + rax&0xff,rbx&0xff,rcx&0xff); + + asm("\n" + "\tpush %rax\n" + "\tpush %rbx\n" + "\tpush %rcx\n" + "\tpush %rdx\n" + "\txor %rax, %rax\n" // get eflags in a known state + "\tmov " VG_SYM(rax) ",%rax\n" + "\tmov " VG_SYM(rbx) ",%rbx\n" + "\tmov " VG_SYM(rcx) ",%rcx\n" + "\tmov " VG_SYM(rdx) ",%rdx\n" + "\tcmpxchg %bl,%cl \n" + "\tmov %rax," VG_SYM(rax_out) "\n" + "\tmov %rbx," VG_SYM(rbx_out) "\n" + "\tmov %rcx," VG_SYM(rcx_out) "\n" + "\tpop %rdx\n" + "\tpop %rcx\n" + "\tpop %rbx\n" + "\tpop %rax\n" + ); + + printf(" al!=cl so al should equal cl (Result al=%llx bl=%llx cl=%llx)\n", + rax_out&0xff,rbx_out&0xff,rcx_out&0xff); + + + + rdx = 0x99999999; rax = 0x77777777; + rcx = 0x55555555; rbx = 0x55555555; + + printf("cmpxchg %%bl,%%cl (al=%llx bl=%llx cl=%llx)\n", + rax&0xff,rbx&0xff,rcx&0xff); + + asm("\n" + "\tpush %rax\n" + "\tpush %rbx\n" + "\tpush %rcx\n" + "\tpush %rdx\n" + "\txor %rax, %rax\n" // get eflags in a known state + "\tmov " VG_SYM(rax) ",%rax\n" + "\tmov " VG_SYM(rbx) ",%rbx\n" + "\tmov " VG_SYM(rcx) ",%rcx\n" + "\tmov " VG_SYM(rdx) ",%rdx\n" + "\tcmpxchg %bl,%cl \n" + "\tmov %rax," VG_SYM(rax_out) "\n" + "\tmov %rbx," VG_SYM(rbx_out) "\n" + "\tmov %rcx," VG_SYM(rcx_out) "\n" + "\tpop %rdx\n" + "\tpop %rcx\n" + "\tpop %rbx\n" + "\tpop %rax\n" + ); + + printf(" al==cl so cl should equal bl (Result al=%llx bl=%llx cl=%llx)\n", + rax_out&0xff,rbx_out&0xff,rcx_out&0xff); + + /* 16-bit */ + + rdx = 0x11111111; rax = 0x22222222; + rcx = 0x33333333; rbx = 0x44444444; + + printf("cmpxchg %%bx,%%cx (ax=%llx bx=%llx cx=%llx)\n", + rax&0xffff,rbx&0xffff,rcx&0xffff); + + asm("\n" + "\tpush %rax\n" + "\tpush %rbx\n" + "\tpush %rcx\n" + "\tpush %rdx\n" + "\txor %rax, %rax\n" // get eflags in a known state + "\tmov " VG_SYM(rax) ",%rax\n" + "\tmov " VG_SYM(rbx) ",%rbx\n" + "\tmov " VG_SYM(rcx) ",%rcx\n" + "\tmov " VG_SYM(rdx) ",%rdx\n" + "\tcmpxchg %bx,%cx \n" + "\tmov %rax," VG_SYM(rax_out) "\n" + "\tmov %rbx," VG_SYM(rbx_out) "\n" + "\tmov %rcx," VG_SYM(rcx_out) "\n" + "\tpop %rdx\n" + "\tpop %rcx\n" + "\tpop %rbx\n" + "\tpop %rax\n" + ); + + printf(" ax!=cx so ax should equal cx (Result ax=%llx bx=%llx cx=%llx)\n", + rax_out&0xffff,rbx_out&0xffff,rcx_out&0xffff); + + + + rdx = 0x99999999; rax = 0x77777777; + rcx = 0x55555555; rbx = 0x55555555; + + printf("cmpxchg %%bx,%%cx (ax=%llx bx=%llx cx=%llx)\n", + rax&0xffff,rbx&0xffff,rcx&0xffff); + + asm("\n" + "\tpush %rax\n" + "\tpush %rbx\n" + "\tpush %rcx\n" + "\tpush %rdx\n" + "\txor %rax, %rax\n" // get eflags in a known state + "\tmov " VG_SYM(rax) ",%rax\n" + "\tmov " VG_SYM(rbx) ",%rbx\n" + "\tmov " VG_SYM(rcx) ",%rcx\n" + "\tmov " VG_SYM(rdx) ",%rdx\n" + "\tcmpxchg %bx,%cx \n" + "\tmov %rax," VG_SYM(rax_out) "\n" + "\tmov %rbx," VG_SYM(rbx_out) "\n" + "\tmov %rcx," VG_SYM(rcx_out) "\n" + "\tpop %rdx\n" + "\tpop %rcx\n" + "\tpop %rbx\n" + "\tpop %rax\n" + ); + + printf(" ax==cx so cx should equal bx (Result ax=%llx bx=%llx cx=%llx)\n", + rax_out&0xffff,rbx_out&0xffff,rcx_out&0xffff); + + + /* 32-bit */ + + rdx = 0x11111111; rax = 0x22222222; + rcx = 0x33333333; rbx = 0x44444444; + + printf("cmpxchg %%ebx,%%ecx (eax=%llx ebx=%llx ecx=%llx)\n", + rax&0xffffffff,rbx&0xffffffff,rcx&0xffffffff); + + asm("\n" + "\tpush %rax\n" + "\tpush %rbx\n" + "\tpush %rcx\n" + "\tpush %rdx\n" + "\txor %rax, %rax\n" // get eflags in a known state + "\tmov " VG_SYM(rax) ",%rax\n" + "\tmov " VG_SYM(rbx) ",%rbx\n" + "\tmov " VG_SYM(rcx) ",%rcx\n" + "\tmov " VG_SYM(rdx) ",%rdx\n" + "\tcmpxchg %ebx,%ecx \n" + "\tmov %rax," VG_SYM(rax_out) "\n" + "\tmov %rbx," VG_SYM(rbx_out) "\n" + "\tmov %rcx," VG_SYM(rcx_out) "\n" + "\tpop %rdx\n" + "\tpop %rcx\n" + "\tpop %rbx\n" + "\tpop %rax\n" + ); + + printf(" eax!=ecx so eax should equal ecx (Result eax=%llx ebx=%llx ecx=%llx)\n", + rax_out&0xffffffff,rbx_out&0xffffffff,rcx_out&0xffffffff); + + + + rdx = 0x99999999; rax = 0x77777777; + rcx = 0x55555555; rbx = 0x55555555; + + printf("cmpxchg %%ebx,%%ecx (eax=%llx ebx=%llx ecx=%llx)\n", + rax&0xffffffff,rbx&0xffffffff,rcx&0xffffffff); + + asm("\n" + "\tpush %rax\n" + "\tpush %rbx\n" + "\tpush %rcx\n" + "\tpush %rdx\n" + "\txor %rax, %rax\n" // get eflags in a known state + "\tmov " VG_SYM(rax) ",%rax\n" + "\tmov " VG_SYM(rbx) ",%rbx\n" + "\tmov " VG_SYM(rcx) ",%rcx\n" + "\tmov " VG_SYM(rdx) ",%rdx\n" + "\tcmpxchg %ebx,%ecx \n" + "\tmov %rax," VG_SYM(rax_out) "\n" + "\tmov %rbx," VG_SYM(rbx_out) "\n" + "\tmov %rcx," VG_SYM(rcx_out) "\n" + "\tpop %rdx\n" + "\tpop %rcx\n" + "\tpop %rbx\n" + "\tpop %rax\n" + ); + + printf(" eax==ecx so ecx should equal ebx (Result eax=%llx ebx=%llx ecx=%llx)\n", + rax_out&0xffffffff,rbx_out&0xffffffff,rcx_out&0xffffffff); + + + /* 64-bit */ + + rdx = 0x111111111; rax = 0x222222222; + rcx = 0x333333333; rbx = 0x444444444; + + printf("cmpxchg %%rbx,%%rcx (rax=%llx rbx=%llx rcx=%llx)\n", + rax,rbx,rcx); + + asm("\n" + "\tpush %rax\n" + "\tpush %rbx\n" + "\tpush %rcx\n" + "\tpush %rdx\n" + "\txor %rax, %rax\n" // get eflags in a known state + "\tmov " VG_SYM(rax) ",%rax\n" + "\tmov " VG_SYM(rbx) ",%rbx\n" + "\tmov " VG_SYM(rcx) ",%rcx\n" + "\tmov " VG_SYM(rdx) ",%rdx\n" + "\tcmpxchg %rbx,%rcx \n" + "\tmov %rax," VG_SYM(rax_out) "\n" + "\tmov %rbx," VG_SYM(rbx_out) "\n" + "\tmov %rcx," VG_SYM(rcx_out) "\n" + "\tpop %rdx\n" + "\tpop %rcx\n" + "\tpop %rbx\n" + "\tpop %rax\n" + ); + + printf(" rax!=rcx so rax should equal rcx (Result rax=%llx rbx=%llx rcx=%llx)\n", + rax_out,rbx_out,rcx_out); + + + + rdx = 0x999999999; rax = 0x777777777; + rcx = 0x555555555; rbx = 0x555555555; + + printf("cmpxchg %%rbx,%%rcx (rax=%llx rbx=%llx rcx=%llx)\n", + rax,rbx,rcx); + + asm("\n" + "\tpush %rax\n" + "\tpush %rbx\n" + "\tpush %rcx\n" + "\tpush %rdx\n" + "\txor %rax, %rax\n" // get eflags in a known state + "\tmov " VG_SYM(rax) ",%rax\n" + "\tmov " VG_SYM(rbx) ",%rbx\n" + "\tmov " VG_SYM(rcx) ",%rcx\n" + "\tmov " VG_SYM(rdx) ",%rdx\n" + "\tcmpxchg %rbx,%rcx \n" + "\tmov %rax," VG_SYM(rax_out) "\n" + "\tmov %rbx," VG_SYM(rbx_out) "\n" + "\tmov %rcx," VG_SYM(rcx_out) "\n" + "\tpop %rdx\n" + "\tpop %rcx\n" + "\tpop %rbx\n" + "\tpop %rax\n" + ); + + printf(" rax==rcx so ecx should equal rbx (Result rax=%llx rbx=%llx rcx=%llx)\n", + rax_out,rbx_out,rcx_out); + + return 0; +} diff --git a/none/tests/amd64/cmpxchg.stderr.exp b/none/tests/amd64/cmpxchg.stderr.exp new file mode 100644 index 0000000000..139597f9cb --- /dev/null +++ b/none/tests/amd64/cmpxchg.stderr.exp @@ -0,0 +1,2 @@ + + diff --git a/none/tests/amd64/cmpxchg.stdout.exp b/none/tests/amd64/cmpxchg.stdout.exp new file mode 100644 index 0000000000..75a54b48b0 --- /dev/null +++ b/none/tests/amd64/cmpxchg.stdout.exp @@ -0,0 +1,16 @@ +cmpxchg %bl,%cl (al=22 bl=44 cl=33) + al!=cl so al should equal cl (Result al=33 bl=44 cl=33) +cmpxchg %bl,%cl (al=77 bl=55 cl=55) + al==cl so cl should equal bl (Result al=55 bl=55 cl=55) +cmpxchg %bx,%cx (ax=2222 bx=4444 cx=3333) + ax!=cx so ax should equal cx (Result ax=3333 bx=4444 cx=3333) +cmpxchg %bx,%cx (ax=7777 bx=5555 cx=5555) + ax==cx so cx should equal bx (Result ax=5555 bx=5555 cx=5555) +cmpxchg %ebx,%ecx (eax=22222222 ebx=44444444 ecx=33333333) + eax!=ecx so eax should equal ecx (Result eax=33333333 ebx=44444444 ecx=33333333) +cmpxchg %ebx,%ecx (eax=77777777 ebx=55555555 ecx=55555555) + eax==ecx so ecx should equal ebx (Result eax=55555555 ebx=55555555 ecx=55555555) +cmpxchg %rbx,%rcx (rax=222222222 rbx=444444444 rcx=333333333) + rax!=rcx so rax should equal rcx (Result rax=333333333 rbx=444444444 rcx=333333333) +cmpxchg %rbx,%rcx (rax=777777777 rbx=555555555 rcx=555555555) + rax==rcx so ecx should equal rbx (Result rax=555555555 rbx=555555555 rcx=555555555) diff --git a/none/tests/amd64/cmpxchg.vgtest b/none/tests/amd64/cmpxchg.vgtest new file mode 100644 index 0000000000..a6d32f32a0 --- /dev/null +++ b/none/tests/amd64/cmpxchg.vgtest @@ -0,0 +1 @@ +prog: cmpxchg