Optimize x86_64 atomics to take advantage of 64-bitness.
[musl] / arch / x86_64 / atomic.h
1 #ifndef _INTERNAA_ATOMIC_H
2 #define _INTERNAA_ATOMIC_H
3
4 #include <stdint.h>
5
6 static inline int a_ctz_64(uint64_t x)
7 {
8         long r;
9         __asm__( "bsf %1,%0" : "=r"(r) : "r"(x) );
10         return r;
11 }
12
13
14 static inline void a_and_64(volatile uint64_t *p, uint64_t v)
15 {
16         __asm__( "lock ; andq %1, %0"
17                          : "=m"(*(long *)p) : "r"(v) : "memory" );
18 }
19
20 static inline void a_or_64(volatile uint64_t *p, uint64_t v)
21 {
22         __asm__( "lock ; orq %1, %0"
23                          : "=m"(*(long *)p) : "r"(v) : "memory" );
24 }
25
26 static inline void a_store_l(volatile void *p, long x)
27 {
28         __asm__( "movq %1, %0" : "=m"(*(long *)p) : "r"(x) : "memory" );
29 }
30
31 static inline void a_or_l(volatile void *p, long v)
32 {
33         __asm__( "lock ; orq %1, %0"
34                 : "=m"(*(long *)p) : "r"(v) : "memory" );
35 }
36
37 static inline void *a_cas_p(volatile void *p, void *t, void *s)
38 {
39         __asm__( "lock ; cmpxchg %3, %1"
40                 : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
41         return t;
42 }
43
44 static inline long a_cas_l(volatile void *p, long t, long s)
45 {
46         __asm__( "lock ; cmpxchg %3, %1"
47                 : "=a"(t), "=m"(*(long *)p) : "a"(t), "r"(s) : "memory" );
48         return t;
49 }
50
51 static inline void *a_swap_p(void *volatile *x, void *v)
52 {
53         __asm__( "xchg %0, %1" : "=r"(v), "=m"(*(void **)x) : "0"(v) : "memory" );
54         return v;
55 }
56 static inline long a_swap_l(volatile void *x, long v)
57 {
58         __asm__( "xchg %0, %1" : "=r"(v), "=m"(*(long *)x) : "0"(v) : "memory" );
59         return v;
60 }
61
62 static inline void a_or(volatile void *p, int v)
63 {
64         __asm__( "lock ; orl %1, %0"
65                 : "=m"(*(int *)p) : "r"(v) : "memory" );
66 }
67
68 static inline void a_and(volatile void *p, int v)
69 {
70         __asm__( "lock ; andl %1, %0"
71                 : "=m"(*(int *)p) : "r"(v) : "memory" );
72 }
73
74 static inline int a_swap(volatile int *x, int v)
75 {
76         __asm__( "xchg %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
77         return v;
78 }
79
80 #define a_xchg a_swap
81
82 static inline int a_fetch_add(volatile int *x, int v)
83 {
84         __asm__( "lock ; xadd %0, %1" : "=r"(v), "=m"(*x) : "0"(v) : "memory" );
85         return v;
86 }
87
88 static inline void a_inc(volatile int *x)
89 {
90         __asm__( "lock ; incl %0" : "=m"(*x) : "m"(*x) : "memory" );
91 }
92
93 static inline void a_dec(volatile int *x)
94 {
95         __asm__( "lock ; decl %0" : "=m"(*x) : "m"(*x) : "memory" );
96 }
97
98 static inline void a_store(volatile int *p, int x)
99 {
100         __asm__( "movl %1, %0" : "=m"(*p) : "r"(x) : "memory" );
101 }
102
103 static inline void a_spin()
104 {
105         __asm__ __volatile__( "pause" : : : "memory" );
106 }
107
108
109 #endif