0001
0002 #ifndef _ASM_X86_RMWcc
0003 #define _ASM_X86_RMWcc
0004
0005
0006 #define __RMWcc_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n
0007 #define RMWcc_ARGS(X...) __RMWcc_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
0008
0009 #define __RMWcc_CONCAT(a, b) a ## b
0010 #define RMWcc_CONCAT(a, b) __RMWcc_CONCAT(a, b)
0011
0012 #define __CLOBBERS_MEM(clb...) "memory", ## clb
0013
0014 #ifndef __GCC_ASM_FLAG_OUTPUTS__
0015
0016
0017
0018 #define __GEN_RMWcc(fullop, _var, cc, clobbers, ...) \
0019 ({ \
0020 bool c = false; \
0021 asm_volatile_goto (fullop "; j" #cc " %l[cc_label]" \
0022 : : [var] "m" (_var), ## __VA_ARGS__ \
0023 : clobbers : cc_label); \
0024 if (0) { \
0025 cc_label: c = true; \
0026 } \
0027 c; \
0028 })
0029
0030 #else
0031
0032
0033
0034 #define __GEN_RMWcc(fullop, _var, cc, clobbers, ...) \
0035 ({ \
0036 bool c; \
0037 asm volatile (fullop CC_SET(cc) \
0038 : [var] "+m" (_var), CC_OUT(cc) (c) \
0039 : __VA_ARGS__ : clobbers); \
0040 c; \
0041 })
0042
0043 #endif
0044
0045 #define GEN_UNARY_RMWcc_4(op, var, cc, arg0) \
0046 __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM())
0047
0048 #define GEN_UNARY_RMWcc_3(op, var, cc) \
0049 GEN_UNARY_RMWcc_4(op, var, cc, "%[var]")
0050
0051 #define GEN_UNARY_RMWcc(X...) RMWcc_CONCAT(GEN_UNARY_RMWcc_, RMWcc_ARGS(X))(X)
0052
0053 #define GEN_BINARY_RMWcc_6(op, var, cc, vcon, _val, arg0) \
0054 __GEN_RMWcc(op " %[val], " arg0, var, cc, \
0055 __CLOBBERS_MEM(), [val] vcon (_val))
0056
0057 #define GEN_BINARY_RMWcc_5(op, var, cc, vcon, val) \
0058 GEN_BINARY_RMWcc_6(op, var, cc, vcon, val, "%[var]")
0059
0060 #define GEN_BINARY_RMWcc(X...) RMWcc_CONCAT(GEN_BINARY_RMWcc_, RMWcc_ARGS(X))(X)
0061
0062 #define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, cc, clobbers...) \
0063 __GEN_RMWcc(op " %[var]\n\t" suffix, var, cc, \
0064 __CLOBBERS_MEM(clobbers))
0065
0066 #define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, cc, vcon, _val, clobbers...)\
0067 __GEN_RMWcc(op " %[val], %[var]\n\t" suffix, var, cc, \
0068 __CLOBBERS_MEM(clobbers), [val] vcon (_val))
0069
0070 #endif