1 
2 #include "config.h"
3 #include <stdio.h>
4 #include <assert.h>
5 
6 /* Simple test program, no race.
7    Tests the 'xadd' exchange-and-add instruction with {r,r} operands, which is rarely generated by compilers. */
8 
9 #undef PLAT_x86_linux
10 #undef PLAT_amd64_linux
11 #undef PLAT_ppc32_linux
12 #undef PLAT_ppc64be_linux
13 
14 #if defined(__i386__)
15 #  define PLAT_x86_linux 1
16 #elif defined(__x86_64__)
17 #  define PLAT_amd64_linux 1
18 #endif
19 
20 
21 #if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux)
22 #  define XADD_R_R(_addr,_lval) \
23 	__asm__ __volatile__( \
24 	"xadd %1, %0" \
25 	: /*out*/ "=r"(_lval),"=r"(_addr) \
26 	: /*in*/  "0"(_lval),"1"(_addr) \
27 	: "flags" \
28 	)
29 #else
30 #  error "Unsupported architecture"
31 #endif
32 
main(void)33 int main ( void )
34 {
35    long d = 20, s = 2;
36    long xadd_r_r_res;
37 #define XADD_R_R_RES 42
38 
39    XADD_R_R(s, d);
40    xadd_r_r_res = s + d;
41    assert(xadd_r_r_res == XADD_R_R_RES);
42 
43    if (xadd_r_r_res == XADD_R_R_RES)
44       printf("success\n");
45    else
46       printf("failure\n");
47 
48    return xadd_r_r_res;
49 }
50