1570af302Sopenharmony_ci#include "libc.h"
2570af302Sopenharmony_ci
3570af302Sopenharmony_ci#if __ARM_ARCH_4__ || __ARM_ARCH_4T__ || __ARM_ARCH == 4
4570af302Sopenharmony_ci#define BLX "mov lr,pc\n\tbx"
5570af302Sopenharmony_ci#else
6570af302Sopenharmony_ci#define BLX "blx"
7570af302Sopenharmony_ci#endif
8570af302Sopenharmony_ci
9570af302Sopenharmony_ciextern hidden uintptr_t __a_cas_ptr, __a_barrier_ptr;
10570af302Sopenharmony_ci
11570af302Sopenharmony_ci#if ((__ARM_ARCH_6__ || __ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
12570af302Sopenharmony_ci || __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
13570af302Sopenharmony_ci
14570af302Sopenharmony_ci#define a_ll a_ll
15570af302Sopenharmony_cistatic inline int a_ll(volatile int *p)
16570af302Sopenharmony_ci{
17570af302Sopenharmony_ci	int v;
18570af302Sopenharmony_ci	__asm__ __volatile__ ("ldrex %0, %1" : "=r"(v) : "Q"(*p));
19570af302Sopenharmony_ci	return v;
20570af302Sopenharmony_ci}
21570af302Sopenharmony_ci
22570af302Sopenharmony_ci#define a_sc a_sc
23570af302Sopenharmony_cistatic inline int a_sc(volatile int *p, int v)
24570af302Sopenharmony_ci{
25570af302Sopenharmony_ci	int r;
26570af302Sopenharmony_ci	__asm__ __volatile__ ("strex %0,%2,%1" : "=&r"(r), "=Q"(*p) : "r"(v) : "memory");
27570af302Sopenharmony_ci	return !r;
28570af302Sopenharmony_ci}
29570af302Sopenharmony_ci
30570af302Sopenharmony_ci#if __ARM_ARCH_7A__ || __ARM_ARCH_7R__ ||  __ARM_ARCH >= 7
31570af302Sopenharmony_ci
32570af302Sopenharmony_ci#define a_barrier a_barrier
33570af302Sopenharmony_cistatic inline void a_barrier()
34570af302Sopenharmony_ci{
35570af302Sopenharmony_ci	__asm__ __volatile__ ("dmb ish" : : : "memory");
36570af302Sopenharmony_ci}
37570af302Sopenharmony_ci
38570af302Sopenharmony_ci#endif
39570af302Sopenharmony_ci
40570af302Sopenharmony_ci#define a_pre_llsc a_barrier
41570af302Sopenharmony_ci#define a_post_llsc a_barrier
42570af302Sopenharmony_ci
43570af302Sopenharmony_ci#else
44570af302Sopenharmony_ci
45570af302Sopenharmony_ci#define a_cas a_cas
46570af302Sopenharmony_cistatic inline int a_cas(volatile int *p, int t, int s)
47570af302Sopenharmony_ci{
48570af302Sopenharmony_ci	for (;;) {
49570af302Sopenharmony_ci		register int r0 __asm__("r0") = t;
50570af302Sopenharmony_ci		register int r1 __asm__("r1") = s;
51570af302Sopenharmony_ci		register volatile int *r2 __asm__("r2") = p;
52570af302Sopenharmony_ci		register uintptr_t r3 __asm__("r3") = __a_cas_ptr;
53570af302Sopenharmony_ci		int old;
54570af302Sopenharmony_ci		__asm__ __volatile__ (
55570af302Sopenharmony_ci			BLX " r3"
56570af302Sopenharmony_ci			: "+r"(r0), "+r"(r3) : "r"(r1), "r"(r2)
57570af302Sopenharmony_ci			: "memory", "lr", "ip", "cc" );
58570af302Sopenharmony_ci		if (!r0) return t;
59570af302Sopenharmony_ci		if ((old=*p)!=t) return old;
60570af302Sopenharmony_ci	}
61570af302Sopenharmony_ci}
62570af302Sopenharmony_ci
63570af302Sopenharmony_ci#endif
64570af302Sopenharmony_ci
65570af302Sopenharmony_ci#ifndef a_barrier
66570af302Sopenharmony_ci#define a_barrier a_barrier
67570af302Sopenharmony_cistatic inline void a_barrier()
68570af302Sopenharmony_ci{
69570af302Sopenharmony_ci	register uintptr_t ip __asm__("ip") = __a_barrier_ptr;
70570af302Sopenharmony_ci	__asm__ __volatile__( BLX " ip" : "+r"(ip) : : "memory", "cc", "lr" );
71570af302Sopenharmony_ci}
72570af302Sopenharmony_ci#endif
73570af302Sopenharmony_ci
74570af302Sopenharmony_ci#define a_crash a_crash
75570af302Sopenharmony_cistatic inline void a_crash()
76570af302Sopenharmony_ci{
77570af302Sopenharmony_ci	__asm__ __volatile__(
78570af302Sopenharmony_ci#ifndef __thumb__
79570af302Sopenharmony_ci		".word 0xe7f000f0"
80570af302Sopenharmony_ci#else
81570af302Sopenharmony_ci		".short 0xdeff"
82570af302Sopenharmony_ci#endif
83570af302Sopenharmony_ci		: : : "memory");
84570af302Sopenharmony_ci}
85570af302Sopenharmony_ci
86570af302Sopenharmony_ci#if __ARM_ARCH >= 5 && (!__thumb__ || __thumb2__)
87570af302Sopenharmony_ci
88570af302Sopenharmony_ci#define a_clz_32 a_clz_32
89570af302Sopenharmony_cistatic inline int a_clz_32(uint32_t x)
90570af302Sopenharmony_ci{
91570af302Sopenharmony_ci	__asm__ ("clz %0, %1" : "=r"(x) : "r"(x));
92570af302Sopenharmony_ci	return x;
93570af302Sopenharmony_ci}
94570af302Sopenharmony_ci
95570af302Sopenharmony_ci#if __ARM_ARCH_6T2__ || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
96570af302Sopenharmony_ci
97570af302Sopenharmony_ci#define a_ctz_32 a_ctz_32
98570af302Sopenharmony_cistatic inline int a_ctz_32(uint32_t x)
99570af302Sopenharmony_ci{
100570af302Sopenharmony_ci	uint32_t xr;
101570af302Sopenharmony_ci	__asm__ ("rbit %0, %1" : "=r"(xr) : "r"(x));
102570af302Sopenharmony_ci	return a_clz_32(xr);
103570af302Sopenharmony_ci}
104570af302Sopenharmony_ci
105570af302Sopenharmony_ci#endif
106570af302Sopenharmony_ci
107570af302Sopenharmony_ci#endif
108