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