summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/thread/arm
diff options
context:
space:
mode:
Diffstat (limited to 'libc-top-half/musl/src/thread/arm')
-rw-r--r--libc-top-half/musl/src/thread/arm/__aeabi_read_tp.s10
-rw-r--r--libc-top-half/musl/src/thread/arm/__set_thread_area.c52
-rw-r--r--libc-top-half/musl/src/thread/arm/__unmapself.s9
-rw-r--r--libc-top-half/musl/src/thread/arm/atomics.s106
-rw-r--r--libc-top-half/musl/src/thread/arm/clone.s28
-rw-r--r--libc-top-half/musl/src/thread/arm/syscall_cp.s29
6 files changed, 234 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/thread/arm/__aeabi_read_tp.s b/libc-top-half/musl/src/thread/arm/__aeabi_read_tp.s
new file mode 100644
index 0000000..2585620
--- /dev/null
+++ b/libc-top-half/musl/src/thread/arm/__aeabi_read_tp.s
@@ -0,0 +1,10 @@
+.syntax unified
+.global __aeabi_read_tp
+.type __aeabi_read_tp,%function
+__aeabi_read_tp:
+ ldr r0,1f
+ add r0,r0,pc
+ ldr r0,[r0]
+2: bx r0
+ .align 2
+1: .word __a_gettp_ptr - 2b
diff --git a/libc-top-half/musl/src/thread/arm/__set_thread_area.c b/libc-top-half/musl/src/thread/arm/__set_thread_area.c
new file mode 100644
index 0000000..09de65a
--- /dev/null
+++ b/libc-top-half/musl/src/thread/arm/__set_thread_area.c
@@ -0,0 +1,52 @@
+#include <stdint.h>
+#include <elf.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+#define HWCAP_TLS (1 << 15)
+
+extern hidden const unsigned char
+ __a_barrier_oldkuser[], __a_barrier_v6[], __a_barrier_v7[],
+ __a_cas_v6[], __a_cas_v7[],
+ __a_gettp_cp15[];
+
+#define __a_barrier_kuser 0xffff0fa0
+#define __a_barrier_oldkuser (uintptr_t)__a_barrier_oldkuser
+#define __a_barrier_v6 (uintptr_t)__a_barrier_v6
+#define __a_barrier_v7 (uintptr_t)__a_barrier_v7
+
+#define __a_cas_kuser 0xffff0fc0
+#define __a_cas_v6 (uintptr_t)__a_cas_v6
+#define __a_cas_v7 (uintptr_t)__a_cas_v7
+
+#define __a_gettp_kuser 0xffff0fe0
+#define __a_gettp_cp15 (uintptr_t)__a_gettp_cp15
+
+extern hidden uintptr_t __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
+
+int __set_thread_area(void *p)
+{
+#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
+ if (__hwcap & HWCAP_TLS) {
+ size_t *aux;
+ __a_cas_ptr = __a_cas_v7;
+ __a_barrier_ptr = __a_barrier_v7;
+ for (aux=libc.auxv; *aux; aux+=2) {
+ if (*aux != AT_PLATFORM) continue;
+ const char *s = (void *)aux[1];
+ if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
+ __a_cas_ptr = __a_cas_v6;
+ __a_barrier_ptr = __a_barrier_v6;
+ break;
+ }
+ } else {
+ int ver = *(int *)0xffff0ffc;
+ __a_gettp_ptr = __a_gettp_kuser;
+ __a_cas_ptr = __a_cas_kuser;
+ __a_barrier_ptr = __a_barrier_kuser;
+ if (ver < 2) a_crash();
+ if (ver < 3) __a_barrier_ptr = __a_barrier_oldkuser;
+ }
+#endif
+ return __syscall(0xf0005, p);
+}
diff --git a/libc-top-half/musl/src/thread/arm/__unmapself.s b/libc-top-half/musl/src/thread/arm/__unmapself.s
new file mode 100644
index 0000000..29c2d07
--- /dev/null
+++ b/libc-top-half/musl/src/thread/arm/__unmapself.s
@@ -0,0 +1,9 @@
+.syntax unified
+.text
+.global __unmapself
+.type __unmapself,%function
+__unmapself:
+ mov r7,#91
+ svc 0
+ mov r7,#1
+ svc 0
diff --git a/libc-top-half/musl/src/thread/arm/atomics.s b/libc-top-half/musl/src/thread/arm/atomics.s
new file mode 100644
index 0000000..da50508
--- /dev/null
+++ b/libc-top-half/musl/src/thread/arm/atomics.s
@@ -0,0 +1,106 @@
+.syntax unified
+.text
+
+.global __a_barrier_dummy
+.hidden __a_barrier_dummy
+.type __a_barrier_dummy,%function
+__a_barrier_dummy:
+ bx lr
+
+.global __a_barrier_oldkuser
+.hidden __a_barrier_oldkuser
+.type __a_barrier_oldkuser,%function
+__a_barrier_oldkuser:
+ push {r0,r1,r2,r3,ip,lr}
+ mov r1,r0
+ mov r2,sp
+ ldr ip,=0xffff0fc0
+ bl 1f
+ pop {r0,r1,r2,r3,ip,lr}
+ bx lr
+1: bx ip
+
+.global __a_barrier_v6
+.hidden __a_barrier_v6
+.type __a_barrier_v6,%function
+__a_barrier_v6:
+ .arch armv6t2
+ mcr p15,0,r0,c7,c10,5
+ bx lr
+
+.global __a_barrier_v7
+.hidden __a_barrier_v7
+.type __a_barrier_v7,%function
+__a_barrier_v7:
+ .arch armv7-a
+ dmb ish
+ bx lr
+
+.global __a_cas_dummy
+.hidden __a_cas_dummy
+.type __a_cas_dummy,%function
+__a_cas_dummy:
+ mov r3,r0
+ ldr r0,[r2]
+ subs r0,r3,r0
+ streq r1,[r2]
+ bx lr
+
+.global __a_cas_v6
+.hidden __a_cas_v6
+.type __a_cas_v6,%function
+__a_cas_v6:
+ .arch armv6t2
+ mov r3,r0
+ mcr p15,0,r0,c7,c10,5
+1: ldrex r0,[r2]
+ subs r0,r3,r0
+ strexeq r0,r1,[r2]
+ teqeq r0,#1
+ beq 1b
+ mcr p15,0,r0,c7,c10,5
+ bx lr
+
+.global __a_cas_v7
+.hidden __a_cas_v7
+.type __a_cas_v7,%function
+__a_cas_v7:
+ .arch armv7-a
+ mov r3,r0
+ dmb ish
+1: ldrex r0,[r2]
+ subs r0,r3,r0
+ strexeq r0,r1,[r2]
+ teqeq r0,#1
+ beq 1b
+ dmb ish
+ bx lr
+
+.global __a_gettp_cp15
+.hidden __a_gettp_cp15
+.type __a_gettp_cp15,%function
+__a_gettp_cp15:
+ mrc p15,0,r0,c13,c0,3
+ bx lr
+
+/* Tag this file with minimum ISA level so as not to affect linking. */
+.object_arch armv4t
+.eabi_attribute 6,2
+
+.data
+.align 2
+
+.global __a_barrier_ptr
+.hidden __a_barrier_ptr
+__a_barrier_ptr:
+ .word __a_barrier_dummy
+
+.global __a_cas_ptr
+.hidden __a_cas_ptr
+__a_cas_ptr:
+ .word __a_cas_dummy
+
+.global __a_gettp_ptr
+.hidden __a_gettp_ptr
+__a_gettp_ptr:
+ .word __a_gettp_cp15
diff --git a/libc-top-half/musl/src/thread/arm/clone.s b/libc-top-half/musl/src/thread/arm/clone.s
new file mode 100644
index 0000000..bb0965d
--- /dev/null
+++ b/libc-top-half/musl/src/thread/arm/clone.s
@@ -0,0 +1,28 @@
+.syntax unified
+.text
+.global __clone
+.hidden __clone
+.type __clone,%function
+__clone:
+ stmfd sp!,{r4,r5,r6,r7}
+ mov r7,#120
+ mov r6,r3
+ mov r5,r0
+ mov r0,r2
+ and r1,r1,#-16
+ ldr r2,[sp,#16]
+ ldr r3,[sp,#20]
+ ldr r4,[sp,#24]
+ svc 0
+ tst r0,r0
+ beq 1f
+ ldmfd sp!,{r4,r5,r6,r7}
+ bx lr
+
+1: mov r0,r6
+ bl 3f
+2: mov r7,#1
+ svc 0
+ b 2b
+
+3: bx r5
diff --git a/libc-top-half/musl/src/thread/arm/syscall_cp.s b/libc-top-half/musl/src/thread/arm/syscall_cp.s
new file mode 100644
index 0000000..e607dd4
--- /dev/null
+++ b/libc-top-half/musl/src/thread/arm/syscall_cp.s
@@ -0,0 +1,29 @@
+.syntax unified
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+.type __syscall_cp_asm,%function
+__syscall_cp_asm:
+ mov ip,sp
+ stmfd sp!,{r4,r5,r6,r7}
+__cp_begin:
+ ldr r0,[r0]
+ cmp r0,#0
+ bne __cp_cancel
+ mov r7,r1
+ mov r0,r2
+ mov r1,r3
+ ldmfd ip,{r2,r3,r4,r5,r6}
+ svc 0
+__cp_end:
+ ldmfd sp!,{r4,r5,r6,r7}
+ bx lr
+__cp_cancel:
+ ldmfd sp!,{r4,r5,r6,r7}
+ b __cancel