diff --git a/compiler-rt/lib/builtins/atomic.c b/compiler-rt/lib/builtins/atomic.c --- a/compiler-rt/lib/builtins/atomic.c +++ b/compiler-rt/lib/builtins/atomic.c @@ -328,6 +328,18 @@ return tmp; \ } +// No lockfree atomic_fetch_*_explicit variation. +#define ATOMIC_RMW_NEG(n, lockfree, type, opname, op) \ + type __atomic_fetch_##opname##_##n(_Atomic(type) * ptr, type val, \ + memory_order model) { \ + Lock *l = lock_for_pointer(ptr); \ + lock(l); \ + type tmp = *ptr; \ + *ptr = ~(tmp op val); \ + unlock(l); \ + return tmp; \ + } + #define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, add, +) OPTIMISED_CASES #undef OPTIMISED_CASE @@ -343,3 +355,7 @@ #define OPTIMISED_CASE(n, lockfree, type) ATOMIC_RMW(n, lockfree, type, xor, ^) OPTIMISED_CASES #undef OPTIMISED_CASE +#define OPTIMISED_CASE(n, lockfree, type) \ + ATOMIC_RMW_NEG(n, lockfree, type, nand, &) +OPTIMISED_CASES +#undef OPTIMISED_CASE