xref: /openbmc/linux/arch/x86/include/asm/rmwcc.h (revision c595db6d7c8bcf87ef42204391fa890e5950e566)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
20c44c2d0SPeter Zijlstra #ifndef _ASM_X86_RMWcc
30c44c2d0SPeter Zijlstra #define _ASM_X86_RMWcc
40c44c2d0SPeter Zijlstra 
515beb1b7SAndy Shevchenko #include <linux/args.h>
6288e4521SPeter Zijlstra 
7700b7c54SJan Beulich #define __CLOBBERS_MEM(clb...)	"memory", ## clb
8df340524SKees Cook 
9a0a12c3eSNick Desaulniers #ifndef __GCC_ASM_FLAG_OUTPUTS__
10ba741e35SH. Peter Anvin 
11ba741e35SH. Peter Anvin /* Use asm goto */
120c44c2d0SPeter Zijlstra 
13288e4521SPeter Zijlstra #define __GEN_RMWcc(fullop, _var, cc, clobbers, ...)			\
14288e4521SPeter Zijlstra ({									\
15288e4521SPeter Zijlstra 	bool c = false;							\
16*aaff74d8SLinus Torvalds 	asm goto (fullop "; j" #cc " %l[cc_label]"		\
17288e4521SPeter Zijlstra 			: : [var] "m" (_var), ## __VA_ARGS__		\
18df340524SKees Cook 			: clobbers : cc_label);				\
19288e4521SPeter Zijlstra 	if (0) {							\
20288e4521SPeter Zijlstra cc_label:	c = true;						\
21288e4521SPeter Zijlstra 	}								\
22288e4521SPeter Zijlstra 	c;								\
23288e4521SPeter Zijlstra })
240c44c2d0SPeter Zijlstra 
25a0a12c3eSNick Desaulniers #else /* defined(__GCC_ASM_FLAG_OUTPUTS__) */
26ba741e35SH. Peter Anvin 
27ba741e35SH. Peter Anvin /* Use flags output or a set instruction */
280c44c2d0SPeter Zijlstra 
29288e4521SPeter Zijlstra #define __GEN_RMWcc(fullop, _var, cc, clobbers, ...)			\
30288e4521SPeter Zijlstra ({									\
31117780eeSH. Peter Anvin 	bool c;								\
323c52b5c6SUros Bizjak 	asm volatile (fullop CC_SET(cc)					\
33288e4521SPeter Zijlstra 			: [var] "+m" (_var), CC_OUT(cc) (c)		\
34df340524SKees Cook 			: __VA_ARGS__ : clobbers);			\
35288e4521SPeter Zijlstra 	c;								\
36288e4521SPeter Zijlstra })
370c44c2d0SPeter Zijlstra 
38a0a12c3eSNick Desaulniers #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) */
390c44c2d0SPeter Zijlstra 
40288e4521SPeter Zijlstra #define GEN_UNARY_RMWcc_4(op, var, cc, arg0)				\
41700b7c54SJan Beulich 	__GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM())
42df340524SKees Cook 
43288e4521SPeter Zijlstra #define GEN_UNARY_RMWcc_3(op, var, cc)					\
44288e4521SPeter Zijlstra 	GEN_UNARY_RMWcc_4(op, var, cc, "%[var]")
45288e4521SPeter Zijlstra 
4615beb1b7SAndy Shevchenko #define GEN_UNARY_RMWcc(X...)	CONCATENATE(GEN_UNARY_RMWcc_, COUNT_ARGS(X))(X)
47288e4521SPeter Zijlstra 
48288e4521SPeter Zijlstra #define GEN_BINARY_RMWcc_6(op, var, cc, vcon, _val, arg0)		\
49288e4521SPeter Zijlstra 	__GEN_RMWcc(op " %[val], " arg0, var, cc,			\
50288e4521SPeter Zijlstra 		    __CLOBBERS_MEM(), [val] vcon (_val))
51288e4521SPeter Zijlstra 
52288e4521SPeter Zijlstra #define GEN_BINARY_RMWcc_5(op, var, cc, vcon, val)			\
53288e4521SPeter Zijlstra 	GEN_BINARY_RMWcc_6(op, var, cc, vcon, val, "%[var]")
54288e4521SPeter Zijlstra 
5515beb1b7SAndy Shevchenko #define GEN_BINARY_RMWcc(X...)	CONCATENATE(GEN_BINARY_RMWcc_, COUNT_ARGS(X))(X)
56288e4521SPeter Zijlstra 
57288e4521SPeter Zijlstra #define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, cc, clobbers...)	\
58288e4521SPeter Zijlstra 	__GEN_RMWcc(op " %[var]\n\t" suffix, var, cc,			\
59700b7c54SJan Beulich 		    __CLOBBERS_MEM(clobbers))
60df340524SKees Cook 
61288e4521SPeter Zijlstra #define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, cc, vcon, _val, clobbers...)\
62288e4521SPeter Zijlstra 	__GEN_RMWcc(op " %[val], %[var]\n\t" suffix, var, cc,		\
63288e4521SPeter Zijlstra 		    __CLOBBERS_MEM(clobbers), [val] vcon (_val))
64df340524SKees Cook 
650c44c2d0SPeter Zijlstra #endif /* _ASM_X86_RMWcc */
66