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