1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef unsigned int UInt; 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef unsigned long long int ULong; 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid do_cmpxchg8b ( /*OUT*/ 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* rdxOut, ULong* raxOut, 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* memHiOut, ULong* memLoOut, 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* zOut, 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*IN*/ 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rdxIn, ULong raxIn, 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong memHiIn, ULong memLoIn, 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rcxIn, ULong rbxIn ) 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt mem[2]; 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong block[6]; 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mem[0] = (UInt)memLoIn; 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mem[1] = (UInt)memHiIn; 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[0] = rdxIn; 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[1] = raxIn; 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[2] = rcxIn; 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[3] = rbxIn; 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[4] = (ULong)&mem[0]; 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[5] = ~(0ULL); 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__( 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movq %0,%%r11\n" 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 0(%%r11),%%rdx\n" 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 8(%%r11),%%rax\n" 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 16(%%r11),%%rcx\n" 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 24(%%r11),%%rbx\n" 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 32(%%r11),%%r10\n" 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tlock cmpxchg8b (%%r10)\n" 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovabsq $0,%%r10\n" 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tsetz %%r10b\n" 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq %%r10,40(%%r11)\n" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq %%rdx,0(%%r11)\n" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq %%rax,8(%%r11)\n" 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r"(&block[0]) 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*trash*/ "%r11", "%r10", "%rax", "%rbx", "%rcx", "%rdx", 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "cc", "memory" ); 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *rdxOut = block[0]; 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *raxOut = block[1]; 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *memLoOut = (ULong)mem[0]; 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *memHiOut = (ULong)mem[1]; 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *zOut = block[5]; 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid try8b ( ULong d, ULong a, ULong mHi, ULong mLo, ULong c, ULong b ) 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong dd, aa, mmHi, mmLo, zz; 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_cmpxchg8b( &dd, &aa, &mmHi, &mmLo, &zz, 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d,a,mHi,mLo,c,b); 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf(" Q d:a=%llx:%llx mem=%llx:%llx c:b=%llx:%llx " 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "-> z=%lld d:a=%llx:%llx mem=%llx:%llx\n", 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d,a, mHi,mLo, c,b, zz, dd,aa, mmHi,mmLo ); 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid do_cmpxchg16b ( /*OUT*/ 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* rdxOut, ULong* raxOut, 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* memHiOut, ULong* memLoOut, 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong* zOut, 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*IN*/ 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rdxIn, ULong raxIn, 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong memHiIn, ULong memLoIn, 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong rcxIn, ULong rbxIn ) 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov ULong mem[2] __attribute__((aligned(16))); 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong block[6]; 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mem[0] = memLoIn; 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown mem[1] = memHiIn; 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[0] = rdxIn; 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[1] = raxIn; 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[2] = rcxIn; 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[3] = rbxIn; 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[4] = (ULong)&mem[0]; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block[5] = ~(0ULL); 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ __volatile__( 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movq %0,%%r11\n" 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 0(%%r11),%%rdx\n" 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 8(%%r11),%%rax\n" 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 16(%%r11),%%rcx\n" 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 24(%%r11),%%rbx\n" 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq 32(%%r11),%%r10\n" 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\t.byte 0xf0, 0x49, 0x0f, 0xc7, 0x0a\n" /* lock cmpxchg16b (%%r10) */ 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovabsq $0,%%r10\n" 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tsetz %%r10b\n" 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq %%r10,40(%%r11)\n" 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq %%rdx,0(%%r11)\n" 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "\tmovq %%rax,8(%%r11)\n" 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*out*/ 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*in*/ "r"(&block[0]) 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : /*trash*/ "%r11", "%r10", "%rax", "%rbx", "%rcx", "%rdx", 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "cc", "memory" ); 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *rdxOut = block[0]; 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *raxOut = block[1]; 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *memLoOut = mem[0]; 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *memHiOut = mem[1]; 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *zOut = block[5]; 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid try16b ( ULong d, ULong a, ULong mHi, ULong mLo, ULong c, ULong b ) 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong dd, aa, mmHi, mmLo, zz; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do_cmpxchg16b( &dd, &aa, &mmHi, &mmLo, &zz, 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d,a,mHi,mLo,c,b); 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("QQ d:a=%llx:%llx mem=%llx:%llx c:b=%llx:%llx " 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "-> z=%lld d:a=%llx:%llx mem=%llx:%llx\n", 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown d,a, mHi,mLo, c,b, zz, dd,aa, mmHi,mmLo ); 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(void) 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ULong z = 0xDEADBEEF00000000ULL; 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0,1, 5,4, 3,2 ); 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0,1, 0,1, 3,2 ); 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0,1, 0,4, 3,2 ); 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0,1, 0,0, 3,2 ); 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0,1, 5,0, 3,2 ); 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0,1, 1,1, 3,2 ); 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0+z,1+z, 5+z,4+z, 3+z,2+z ); 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0+z,1+z, 0+z,1+z, 3+z,2+z ); 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0+z,1+z, 0+z,4+z, 3+z,2+z ); 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0+z,1+z, 0+z,0+z, 3+z,2+z ); 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0+z,1+z, 5+z,0+z, 3+z,2+z ); 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try8b( 0+z,1+z, 1+z,1+z, 3+z,2+z ); 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0,1, 5,4, 3,2 ); 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0,1, 0,1, 3,2 ); 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0,1, 0,4, 3,2 ); 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0,1, 0,0, 3,2 ); 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0,1, 5,0, 3,2 ); 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0,1, 1,1, 3,2 ); 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0+z,1+z, 5+z,4+z, 3+z,2+z ); 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0+z,1+z, 0+z,1+z, 3+z,2+z ); 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0+z,1+z, 0+z,4+z, 3+z,2+z ); 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0+z,1+z, 0+z,0+z, 3+z,2+z ); 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0+z,1+z, 5+z,0+z, 3+z,2+z ); 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown try16b( 0+z,1+z, 1+z,1+z, 3+z,2+z ); 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 156