diff --git a/sys/riscv/include/atomic.h b/sys/riscv/include/atomic.h --- a/sys/riscv/include/atomic.h +++ b/sys/riscv/include/atomic.h @@ -266,6 +266,34 @@ return (ret); } +static __inline int +atomic_testandset_32(volatile uint32_t *p, u_int val) +{ + uint32_t mask, old; + + mask = 1u << (val & 31); + __asm __volatile("amoor.w %0, %2, %1" + : "=&r" (old), "+A" (*p) + : "r" (mask) + : "memory"); + + return ((old & mask) != 0); +} + +static __inline int +atomic_testandclear_32(volatile uint32_t *p, u_int val) +{ + uint32_t mask, old; + + mask = 1u << (val & 31); + __asm __volatile("amoand.w %0, %2, %1" + : "=&r" (old), "+A" (*p) + : "r" (~mask) + : "memory"); + + return ((old & mask) != 0); +} + #define atomic_add_int atomic_add_32 #define atomic_clear_int atomic_clear_32 #define atomic_cmpset_int atomic_cmpset_32 @@ -437,6 +465,48 @@ return (ret); } +static __inline int +atomic_testandclear_64(volatile uint64_t *p, u_int val) +{ + uint64_t mask, old; + + mask = 1ul << (val & 63); + __asm __volatile("amoand.d %0, %2, %1" + : "=&r" (old), "+A" (*p) + : "r" (~mask) + : "memory"); + + return ((old & mask) != 0); +} + +static __inline int +atomic_testandset_64(volatile uint64_t *p, u_int val) +{ + uint64_t mask, old; + + mask = 1ul << (val & 63); + __asm __volatile("amoor.d %0, %2, %1" + : "=&r" (old), "+A" (*p) + : "r" (mask) + : "memory"); + + return ((old & mask) != 0); +} + +static __inline int +atomic_testandset_acq_64(volatile uint64_t *p, u_int val) +{ + uint64_t mask, old; + + mask = 1ul << (val & 63); + __asm __volatile("amoor.d.aq %0, %2, %1" + : "=&r" (old), "+A" (*p) + : "r" (mask) + : "memory"); + + return ((old & mask) != 0); +} + static __inline uint32_t atomic_swap_32(volatile uint32_t *p, uint32_t val) { @@ -474,6 +544,9 @@ #define atomic_set_long atomic_set_64 #define atomic_subtract_long atomic_subtract_64 #define atomic_swap_long atomic_swap_64 +#define atomic_testandclear_long atomic_testandclear_64 +#define atomic_testandset_long atomic_testandset_64 +#define atomic_testandset_acq_long atomic_testandset_acq_64 #define atomic_add_ptr atomic_add_64 #define atomic_clear_ptr atomic_clear_64