diff options
Diffstat (limited to 'sys/linux/arm64/arch')
-rw-r--r-- | sys/linux/arm64/arch/atomic.h | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/sys/linux/arm64/arch/atomic.h b/sys/linux/arm64/arch/atomic.h new file mode 100644 index 0000000..2fa4b04 --- /dev/null +++ b/sys/linux/arm64/arch/atomic.h @@ -0,0 +1,82 @@ +static inline int +atomic·ll(volatile int *p) +{ + int v; + __asm__ __volatile__ ("ldaxr %w0,%1" : "=r"(v) : "Q"(*p)); + return v; +} + +static inline int +atomic·sc(volatile int *p, int v) +{ + int r; + __asm__ __volatile__ ("stlxr %w0,%w2,%1" : "=&r"(r), "=Q"(*p) : "r"(v) : "memory"); + return !r; +} + +static inline void +atomic·barrier() +{ + __asm__ __volatile__ ("dmb ish" : : : "memory"); +} + +static inline int +atomic·cas(volatile int *p, int t, int s) +{ + int old; + do{ + old = atomic·ll(p); + if(old != t){ + atomic·barrier(); + break; + } + }while(!atomic·sc(p, s)); + return old; +} + +static inline void +*atomic·llp(volatile void *p) +{ + void *v; + __asm__ __volatile__ ("ldaxr %0, %1" : "=r"(v) : "Q"(*(void *volatile *)p)); + return v; +} + +static inline int +atomic·scp(volatile int *p, void *v) +{ + int r; + __asm__ __volatile__ ("stlxr %w0,%2,%1" : "=&r"(r), "=Q"(*(void *volatile *)p) : "r"(v) : "memory"); + return !r; +} + +static inline void +*atomic·casp(volatile void *p, void *t, void *s) +{ + void *old; + do{ + old = atomic·llp(p); + if(old != t){ + atomic·barrier(); + break; + } + }while(!atomic·scp(p, s)); + return old; +} + +static inline int +atomic·ctz64(uint64 x) +{ + __asm__( + " rbit %0, %1\n" + " clz %0, %0\n" + : "=r"(x) : "r"(x)); + return x; +} + +static inline int +atomic·clz64(uint64 x) +{ + __asm__("clz %0, %1" : "=r"(x) : "r"(x)); + return x; +} |