aboutsummaryrefslogtreecommitdiff
path: root/sys/linux/arm64/arch/atomic.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/linux/arm64/arch/atomic.h')
-rw-r--r--sys/linux/arm64/arch/atomic.h82
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;
+}