xref: /linux/arch/x86/include/asm/rmwcc.h (revision ab520be8cd5d56867fc95cfbc34b90880faf1f9d)
1 #ifndef _ASM_X86_RMWcc
2 #define _ASM_X86_RMWcc
3 
4 #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CC_HAVE_ASM_GOTO)
5 
6 /* Use asm goto */
7 
8 #define __GEN_RMWcc(fullop, var, cc, ...)				\
9 do {									\
10 	asm_volatile_goto (fullop "; j" #cc " %l[cc_label]"		\
11 			: : "m" (var), ## __VA_ARGS__ 			\
12 			: "memory" : cc_label);				\
13 	return 0;							\
14 cc_label:								\
15 	return 1;							\
16 } while (0)
17 
18 #define GEN_UNARY_RMWcc(op, var, arg0, cc) 				\
19 	__GEN_RMWcc(op " " arg0, var, cc)
20 
21 #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc)			\
22 	__GEN_RMWcc(op " %1, " arg0, var, cc, vcon (val))
23 
24 #else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */
25 
26 /* Use flags output or a set instruction */
27 
28 #define __GEN_RMWcc(fullop, var, cc, ...)				\
29 do {									\
30 	bool c;								\
31 	asm volatile (fullop ";" CC_SET(cc)				\
32 			: "+m" (var), CC_OUT(cc) (c)			\
33 			: __VA_ARGS__ : "memory");			\
34 	return c;							\
35 } while (0)
36 
37 #define GEN_UNARY_RMWcc(op, var, arg0, cc)				\
38 	__GEN_RMWcc(op " " arg0, var, cc)
39 
40 #define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc)			\
41 	__GEN_RMWcc(op " %2, " arg0, var, cc, vcon (val))
42 
43 #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CC_HAVE_ASM_GOTO) */
44 
45 #endif /* _ASM_X86_RMWcc */
46