| .. | .. | 
|---|
| 2 | 2 |  #ifndef _ASM_X86_RMWcc | 
|---|
| 3 | 3 |  #define _ASM_X86_RMWcc | 
|---|
| 4 | 4 |   | 
|---|
 | 5 | +/* This counts to 12. Any more, it will return 13th argument. */  | 
|---|
 | 6 | +#define __RMWcc_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n  | 
|---|
 | 7 | +#define RMWcc_ARGS(X...) __RMWcc_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)  | 
|---|
 | 8 | +  | 
|---|
 | 9 | +#define __RMWcc_CONCAT(a, b) a ## b  | 
|---|
 | 10 | +#define RMWcc_CONCAT(a, b) __RMWcc_CONCAT(a, b)  | 
|---|
 | 11 | +  | 
|---|
| 5 | 12 |  #define __CLOBBERS_MEM(clb...)	"memory", ## clb | 
|---|
| 6 | 13 |   | 
|---|
| 7 | 14 |  #if !defined(__GCC_ASM_FLAG_OUTPUTS__) && defined(CONFIG_CC_HAS_ASM_GOTO) | 
|---|
| 8 | 15 |   | 
|---|
| 9 | 16 |  /* Use asm goto */ | 
|---|
| 10 | 17 |   | 
|---|
| 11 |  | -#define __GEN_RMWcc(fullop, var, cc, clobbers, ...)			\  | 
|---|
| 12 |  | -do {									\  | 
|---|
 | 18 | +#define __GEN_RMWcc(fullop, _var, cc, clobbers, ...)			\  | 
|---|
 | 19 | +({									\  | 
|---|
 | 20 | +	bool c = false;							\  | 
|---|
| 13 | 21 |  	asm_volatile_goto (fullop "; j" #cc " %l[cc_label]"		\ | 
|---|
| 14 |  | -			: : [counter] "m" (var), ## __VA_ARGS__		\  | 
|---|
 | 22 | +			: : [var] "m" (_var), ## __VA_ARGS__		\  | 
|---|
| 15 | 23 |  			: clobbers : cc_label);				\ | 
|---|
| 16 |  | -	return 0;							\  | 
|---|
| 17 |  | -cc_label:								\  | 
|---|
| 18 |  | -	return 1;							\  | 
|---|
| 19 |  | -} while (0)  | 
|---|
| 20 |  | -  | 
|---|
| 21 |  | -#define __BINARY_RMWcc_ARG	" %1, "  | 
|---|
| 22 |  | -  | 
|---|
 | 24 | +	if (0) {							\  | 
|---|
 | 25 | +cc_label:	c = true;						\  | 
|---|
 | 26 | +	}								\  | 
|---|
 | 27 | +	c;								\  | 
|---|
 | 28 | +})  | 
|---|
| 23 | 29 |   | 
|---|
| 24 | 30 |  #else /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CONFIG_CC_HAS_ASM_GOTO) */ | 
|---|
| 25 | 31 |   | 
|---|
| 26 | 32 |  /* Use flags output or a set instruction */ | 
|---|
| 27 | 33 |   | 
|---|
| 28 |  | -#define __GEN_RMWcc(fullop, var, cc, clobbers, ...)			\  | 
|---|
| 29 |  | -do {									\  | 
|---|
 | 34 | +#define __GEN_RMWcc(fullop, _var, cc, clobbers, ...)			\  | 
|---|
 | 35 | +({									\  | 
|---|
| 30 | 36 |  	bool c;								\ | 
|---|
| 31 | 37 |  	asm volatile (fullop CC_SET(cc)					\ | 
|---|
| 32 |  | -			: [counter] "+m" (var), CC_OUT(cc) (c)		\  | 
|---|
 | 38 | +			: [var] "+m" (_var), CC_OUT(cc) (c)		\  | 
|---|
| 33 | 39 |  			: __VA_ARGS__ : clobbers);			\ | 
|---|
| 34 |  | -	return c;							\  | 
|---|
| 35 |  | -} while (0)  | 
|---|
| 36 |  | -  | 
|---|
| 37 |  | -#define __BINARY_RMWcc_ARG	" %2, "  | 
|---|
 | 40 | +	c;								\  | 
|---|
 | 41 | +})  | 
|---|
| 38 | 42 |   | 
|---|
| 39 | 43 |  #endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) || !defined(CONFIG_CC_HAS_ASM_GOTO) */ | 
|---|
| 40 | 44 |   | 
|---|
| 41 |  | -#define GEN_UNARY_RMWcc(op, var, arg0, cc)				\  | 
|---|
 | 45 | +#define GEN_UNARY_RMWcc_4(op, var, cc, arg0)				\  | 
|---|
| 42 | 46 |  	__GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM()) | 
|---|
| 43 | 47 |   | 
|---|
| 44 |  | -#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, arg0, cc, clobbers...)\  | 
|---|
| 45 |  | -	__GEN_RMWcc(op " " arg0 "\n\t" suffix, var, cc,			\  | 
|---|
 | 48 | +#define GEN_UNARY_RMWcc_3(op, var, cc)					\  | 
|---|
 | 49 | +	GEN_UNARY_RMWcc_4(op, var, cc, "%[var]")  | 
|---|
 | 50 | +  | 
|---|
 | 51 | +#define GEN_UNARY_RMWcc(X...) RMWcc_CONCAT(GEN_UNARY_RMWcc_, RMWcc_ARGS(X))(X)  | 
|---|
 | 52 | +  | 
|---|
 | 53 | +#define GEN_BINARY_RMWcc_6(op, var, cc, vcon, _val, arg0)		\  | 
|---|
 | 54 | +	__GEN_RMWcc(op " %[val], " arg0, var, cc,			\  | 
|---|
 | 55 | +		    __CLOBBERS_MEM(), [val] vcon (_val))  | 
|---|
 | 56 | +  | 
|---|
 | 57 | +#define GEN_BINARY_RMWcc_5(op, var, cc, vcon, val)			\  | 
|---|
 | 58 | +	GEN_BINARY_RMWcc_6(op, var, cc, vcon, val, "%[var]")  | 
|---|
 | 59 | +  | 
|---|
 | 60 | +#define GEN_BINARY_RMWcc(X...) RMWcc_CONCAT(GEN_BINARY_RMWcc_, RMWcc_ARGS(X))(X)  | 
|---|
 | 61 | +  | 
|---|
 | 62 | +#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, cc, clobbers...)	\  | 
|---|
 | 63 | +	__GEN_RMWcc(op " %[var]\n\t" suffix, var, cc,			\  | 
|---|
| 46 | 64 |  		    __CLOBBERS_MEM(clobbers)) | 
|---|
| 47 | 65 |   | 
|---|
| 48 |  | -#define GEN_BINARY_RMWcc(op, var, vcon, val, arg0, cc)			\  | 
|---|
| 49 |  | -	__GEN_RMWcc(op __BINARY_RMWcc_ARG arg0, var, cc,		\  | 
|---|
| 50 |  | -		    __CLOBBERS_MEM(), vcon (val))  | 
|---|
| 51 |  | -  | 
|---|
| 52 |  | -#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, vcon, val, arg0, cc,	\  | 
|---|
| 53 |  | -				  clobbers...)				\  | 
|---|
| 54 |  | -	__GEN_RMWcc(op __BINARY_RMWcc_ARG arg0 "\n\t" suffix, var, cc,	\  | 
|---|
| 55 |  | -		    __CLOBBERS_MEM(clobbers), vcon (val))  | 
|---|
 | 66 | +#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, cc, vcon, _val, clobbers...)\  | 
|---|
 | 67 | +	__GEN_RMWcc(op " %[val], %[var]\n\t" suffix, var, cc,		\  | 
|---|
 | 68 | +		    __CLOBBERS_MEM(clobbers), [val] vcon (_val))  | 
|---|
| 56 | 69 |   | 
|---|
| 57 | 70 |  #endif /* _ASM_X86_RMWcc */ | 
|---|