chibicc
chibicc copied to clipboard
Fix atomic fetch operations
The atomic_fetch ops are supposed to return the old value of the object. chibicc is currently returning the new values.
stdatomic.h:
#define atomic_fetch_add(obj, val) (*(obj) += (val))
#define atomic_fetch_sub(obj, val) (*(obj) -= (val))
#define atomic_fetch_or(obj, val) (*(obj) |= (val))
#define atomic_fetch_xor(obj, val) (*(obj) ^= (val))
#define atomic_fetch_and(obj, val) (*(obj) &= (val))
I was originally thinking about how to fix this in a simple way. Three of them (add/sub/xor) are fixable with macros. Something like:
#define atomic_fetch_add(obj, val) ({ \
typeof(val) _val = (val); \
((*(obj) += _val) - _val); \
})
#define atomic_fetch_sub(obj, val) ({ \
typeof(val) _val = (val); \
((*(obj) -= _val) + _val); \
})
#define atomic_fetch_xor(obj, val) ({ \
typeof(val) _val = (val); \
((*(obj) ^= _val) ^ _val); \
})
However, atomic_fetch_and
and atomic_fetch_or
are not fixable via macro as they are not reversible.
This PR adds a single new builtin (__builtin_atomic_fetch_op
) which reuses the existing atomic operation code.