1*c9945492SAndroid Build Coastguard Worker #include "libc.h"
2*c9945492SAndroid Build Coastguard Worker
3*c9945492SAndroid Build Coastguard Worker #if __ARM_ARCH_4__ || __ARM_ARCH_4T__ || __ARM_ARCH == 4
4*c9945492SAndroid Build Coastguard Worker #define BLX "mov lr,pc\n\tbx"
5*c9945492SAndroid Build Coastguard Worker #else
6*c9945492SAndroid Build Coastguard Worker #define BLX "blx"
7*c9945492SAndroid Build Coastguard Worker #endif
8*c9945492SAndroid Build Coastguard Worker
9*c9945492SAndroid Build Coastguard Worker extern hidden uintptr_t __a_cas_ptr, __a_barrier_ptr;
10*c9945492SAndroid Build Coastguard Worker
11*c9945492SAndroid Build Coastguard Worker #if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
12*c9945492SAndroid Build Coastguard Worker || __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
13*c9945492SAndroid Build Coastguard Worker
14*c9945492SAndroid Build Coastguard Worker #define a_ll a_ll
a_ll(volatile int * p)15*c9945492SAndroid Build Coastguard Worker static inline int a_ll(volatile int *p)
16*c9945492SAndroid Build Coastguard Worker {
17*c9945492SAndroid Build Coastguard Worker int v;
18*c9945492SAndroid Build Coastguard Worker __asm__ __volatile__ ("ldrex %0, %1" : "=r"(v) : "Q"(*p));
19*c9945492SAndroid Build Coastguard Worker return v;
20*c9945492SAndroid Build Coastguard Worker }
21*c9945492SAndroid Build Coastguard Worker
22*c9945492SAndroid Build Coastguard Worker #define a_sc a_sc
a_sc(volatile int * p,int v)23*c9945492SAndroid Build Coastguard Worker static inline int a_sc(volatile int *p, int v)
24*c9945492SAndroid Build Coastguard Worker {
25*c9945492SAndroid Build Coastguard Worker int r;
26*c9945492SAndroid Build Coastguard Worker __asm__ __volatile__ ("strex %0,%2,%1" : "=&r"(r), "=Q"(*p) : "r"(v) : "memory");
27*c9945492SAndroid Build Coastguard Worker return !r;
28*c9945492SAndroid Build Coastguard Worker }
29*c9945492SAndroid Build Coastguard Worker
30*c9945492SAndroid Build Coastguard Worker #if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
31*c9945492SAndroid Build Coastguard Worker
32*c9945492SAndroid Build Coastguard Worker #define a_barrier a_barrier
a_barrier()33*c9945492SAndroid Build Coastguard Worker static inline void a_barrier()
34*c9945492SAndroid Build Coastguard Worker {
35*c9945492SAndroid Build Coastguard Worker __asm__ __volatile__ ("dmb ish" : : : "memory");
36*c9945492SAndroid Build Coastguard Worker }
37*c9945492SAndroid Build Coastguard Worker
38*c9945492SAndroid Build Coastguard Worker #endif
39*c9945492SAndroid Build Coastguard Worker
40*c9945492SAndroid Build Coastguard Worker #define a_pre_llsc a_barrier
41*c9945492SAndroid Build Coastguard Worker #define a_post_llsc a_barrier
42*c9945492SAndroid Build Coastguard Worker
43*c9945492SAndroid Build Coastguard Worker #else
44*c9945492SAndroid Build Coastguard Worker
45*c9945492SAndroid Build Coastguard Worker #define a_cas a_cas
a_cas(volatile int * p,int t,int s)46*c9945492SAndroid Build Coastguard Worker static inline int a_cas(volatile int *p, int t, int s)
47*c9945492SAndroid Build Coastguard Worker {
48*c9945492SAndroid Build Coastguard Worker for (;;) {
49*c9945492SAndroid Build Coastguard Worker register int r0 __asm__("r0") = t;
50*c9945492SAndroid Build Coastguard Worker register int r1 __asm__("r1") = s;
51*c9945492SAndroid Build Coastguard Worker register volatile int *r2 __asm__("r2") = p;
52*c9945492SAndroid Build Coastguard Worker register uintptr_t r3 __asm__("r3") = __a_cas_ptr;
53*c9945492SAndroid Build Coastguard Worker int old;
54*c9945492SAndroid Build Coastguard Worker __asm__ __volatile__ (
55*c9945492SAndroid Build Coastguard Worker BLX " r3"
56*c9945492SAndroid Build Coastguard Worker : "+r"(r0), "+r"(r3) : "r"(r1), "r"(r2)
57*c9945492SAndroid Build Coastguard Worker : "memory", "lr", "ip", "cc" );
58*c9945492SAndroid Build Coastguard Worker if (!r0) return t;
59*c9945492SAndroid Build Coastguard Worker if ((old=*p)!=t) return old;
60*c9945492SAndroid Build Coastguard Worker }
61*c9945492SAndroid Build Coastguard Worker }
62*c9945492SAndroid Build Coastguard Worker
63*c9945492SAndroid Build Coastguard Worker #endif
64*c9945492SAndroid Build Coastguard Worker
65*c9945492SAndroid Build Coastguard Worker #ifndef a_barrier
66*c9945492SAndroid Build Coastguard Worker #define a_barrier a_barrier
a_barrier()67*c9945492SAndroid Build Coastguard Worker static inline void a_barrier()
68*c9945492SAndroid Build Coastguard Worker {
69*c9945492SAndroid Build Coastguard Worker register uintptr_t ip __asm__("ip") = __a_barrier_ptr;
70*c9945492SAndroid Build Coastguard Worker __asm__ __volatile__( BLX " ip" : "+r"(ip) : : "memory", "cc", "lr" );
71*c9945492SAndroid Build Coastguard Worker }
72*c9945492SAndroid Build Coastguard Worker #endif
73*c9945492SAndroid Build Coastguard Worker
74*c9945492SAndroid Build Coastguard Worker #define a_crash a_crash
a_crash()75*c9945492SAndroid Build Coastguard Worker static inline void a_crash()
76*c9945492SAndroid Build Coastguard Worker {
77*c9945492SAndroid Build Coastguard Worker __asm__ __volatile__(
78*c9945492SAndroid Build Coastguard Worker #ifndef __thumb__
79*c9945492SAndroid Build Coastguard Worker ".word 0xe7f000f0"
80*c9945492SAndroid Build Coastguard Worker #else
81*c9945492SAndroid Build Coastguard Worker ".short 0xdeff"
82*c9945492SAndroid Build Coastguard Worker #endif
83*c9945492SAndroid Build Coastguard Worker : : : "memory");
84*c9945492SAndroid Build Coastguard Worker }
85*c9945492SAndroid Build Coastguard Worker
86*c9945492SAndroid Build Coastguard Worker #if __ARM_ARCH >= 5 && (!__thumb__ || __thumb2__)
87*c9945492SAndroid Build Coastguard Worker
88*c9945492SAndroid Build Coastguard Worker #define a_clz_32 a_clz_32
a_clz_32(uint32_t x)89*c9945492SAndroid Build Coastguard Worker static inline int a_clz_32(uint32_t x)
90*c9945492SAndroid Build Coastguard Worker {
91*c9945492SAndroid Build Coastguard Worker __asm__ ("clz %0, %1" : "=r"(x) : "r"(x));
92*c9945492SAndroid Build Coastguard Worker return x;
93*c9945492SAndroid Build Coastguard Worker }
94*c9945492SAndroid Build Coastguard Worker
95*c9945492SAndroid Build Coastguard Worker #if __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
96*c9945492SAndroid Build Coastguard Worker
97*c9945492SAndroid Build Coastguard Worker #define a_ctz_32 a_ctz_32
a_ctz_32(uint32_t x)98*c9945492SAndroid Build Coastguard Worker static inline int a_ctz_32(uint32_t x)
99*c9945492SAndroid Build Coastguard Worker {
100*c9945492SAndroid Build Coastguard Worker uint32_t xr;
101*c9945492SAndroid Build Coastguard Worker __asm__ ("rbit %0, %1" : "=r"(xr) : "r"(x));
102*c9945492SAndroid Build Coastguard Worker return a_clz_32(xr);
103*c9945492SAndroid Build Coastguard Worker }
104*c9945492SAndroid Build Coastguard Worker
105*c9945492SAndroid Build Coastguard Worker #endif
106*c9945492SAndroid Build Coastguard Worker
107*c9945492SAndroid Build Coastguard Worker #endif
108