master
  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