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
33int 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