162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_X86_RMWcc 362306a36Sopenharmony_ci#define _ASM_X86_RMWcc 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <linux/args.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_ci#define __CLOBBERS_MEM(clb...) "memory", ## clb 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef __GCC_ASM_FLAG_OUTPUTS__ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* Use asm goto */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#define __GEN_RMWcc(fullop, _var, cc, clobbers, ...) \ 1462306a36Sopenharmony_ci({ \ 1562306a36Sopenharmony_ci bool c = false; \ 1662306a36Sopenharmony_ci asm goto (fullop "; j" #cc " %l[cc_label]" \ 1762306a36Sopenharmony_ci : : [var] "m" (_var), ## __VA_ARGS__ \ 1862306a36Sopenharmony_ci : clobbers : cc_label); \ 1962306a36Sopenharmony_ci if (0) { \ 2062306a36Sopenharmony_cicc_label: c = true; \ 2162306a36Sopenharmony_ci } \ 2262306a36Sopenharmony_ci c; \ 2362306a36Sopenharmony_ci}) 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#else /* defined(__GCC_ASM_FLAG_OUTPUTS__) */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/* Use flags output or a set instruction */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#define __GEN_RMWcc(fullop, _var, cc, clobbers, ...) \ 3062306a36Sopenharmony_ci({ \ 3162306a36Sopenharmony_ci bool c; \ 3262306a36Sopenharmony_ci asm volatile (fullop CC_SET(cc) \ 3362306a36Sopenharmony_ci : [var] "+m" (_var), CC_OUT(cc) (c) \ 3462306a36Sopenharmony_ci : __VA_ARGS__ : clobbers); \ 3562306a36Sopenharmony_ci c; \ 3662306a36Sopenharmony_ci}) 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#endif /* defined(__GCC_ASM_FLAG_OUTPUTS__) */ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define GEN_UNARY_RMWcc_4(op, var, cc, arg0) \ 4162306a36Sopenharmony_ci __GEN_RMWcc(op " " arg0, var, cc, __CLOBBERS_MEM()) 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define GEN_UNARY_RMWcc_3(op, var, cc) \ 4462306a36Sopenharmony_ci GEN_UNARY_RMWcc_4(op, var, cc, "%[var]") 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define GEN_UNARY_RMWcc(X...) CONCATENATE(GEN_UNARY_RMWcc_, COUNT_ARGS(X))(X) 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#define GEN_BINARY_RMWcc_6(op, var, cc, vcon, _val, arg0) \ 4962306a36Sopenharmony_ci __GEN_RMWcc(op " %[val], " arg0, var, cc, \ 5062306a36Sopenharmony_ci __CLOBBERS_MEM(), [val] vcon (_val)) 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define GEN_BINARY_RMWcc_5(op, var, cc, vcon, val) \ 5362306a36Sopenharmony_ci GEN_BINARY_RMWcc_6(op, var, cc, vcon, val, "%[var]") 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#define GEN_BINARY_RMWcc(X...) CONCATENATE(GEN_BINARY_RMWcc_, COUNT_ARGS(X))(X) 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#define GEN_UNARY_SUFFIXED_RMWcc(op, suffix, var, cc, clobbers...) \ 5862306a36Sopenharmony_ci __GEN_RMWcc(op " %[var]\n\t" suffix, var, cc, \ 5962306a36Sopenharmony_ci __CLOBBERS_MEM(clobbers)) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define GEN_BINARY_SUFFIXED_RMWcc(op, suffix, var, cc, vcon, _val, clobbers...)\ 6262306a36Sopenharmony_ci __GEN_RMWcc(op " %[val], %[var]\n\t" suffix, var, cc, \ 6362306a36Sopenharmony_ci __CLOBBERS_MEM(clobbers), [val] vcon (_val)) 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#endif /* _ASM_X86_RMWcc */ 66