Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_X86_RMWcc
0003 #define _ASM_X86_RMWcc
0004 
0005 /* This counts to 12. Any more, it will return 13th argument. */
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 /* Use asm goto */
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 /* defined(__GCC_ASM_FLAG_OUTPUTS__) */
0031 
0032 /* Use flags output or a set instruction */
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 /* defined(__GCC_ASM_FLAG_OUTPUTS__) */
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 /* _ASM_X86_RMWcc */