summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/thread/sh
diff options
context:
space:
mode:
Diffstat (limited to 'libc-top-half/musl/src/thread/sh')
-rw-r--r--libc-top-half/musl/src/thread/sh/__set_thread_area.c37
-rw-r--r--libc-top-half/musl/src/thread/sh/__unmapself.c24
-rw-r--r--libc-top-half/musl/src/thread/sh/__unmapself_mmu.s23
-rw-r--r--libc-top-half/musl/src/thread/sh/atomics.s65
-rw-r--r--libc-top-half/musl/src/thread/sh/clone.s54
-rw-r--r--libc-top-half/musl/src/thread/sh/syscall_cp.s45
6 files changed, 248 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/thread/sh/__set_thread_area.c b/libc-top-half/musl/src/thread/sh/__set_thread_area.c
new file mode 100644
index 0000000..34264bd
--- /dev/null
+++ b/libc-top-half/musl/src/thread/sh/__set_thread_area.c
@@ -0,0 +1,37 @@
+#include "pthread_impl.h"
+#include "libc.h"
+#include <elf.h>
+
+/* Also perform sh-specific init */
+
+#define CPU_HAS_LLSC 0x0040
+#define CPU_HAS_CAS_L 0x0400
+
+extern hidden const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];
+
+hidden const void *__sh_cas_ptr;
+
+hidden unsigned __sh_nommu;
+
+int __set_thread_area(void *p)
+{
+ size_t *aux;
+ __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
+#ifndef __SH4A__
+ __sh_cas_ptr = __sh_cas_gusa;
+#if !defined(__SH3__) && !defined(__SH4__)
+ for (aux=libc.auxv; *aux; aux+=2) {
+ if (*aux != AT_PLATFORM) continue;
+ const char *s = (void *)aux[1];
+ if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
+ __sh_cas_ptr = __sh_cas_imask;
+ __sh_nommu = 1;
+ }
+#endif
+ if (__hwcap & CPU_HAS_CAS_L)
+ __sh_cas_ptr = __sh_cas_cas_l;
+ else if (__hwcap & CPU_HAS_LLSC)
+ __sh_cas_ptr = __sh_cas_llsc;
+#endif
+ return 0;
+}
diff --git a/libc-top-half/musl/src/thread/sh/__unmapself.c b/libc-top-half/musl/src/thread/sh/__unmapself.c
new file mode 100644
index 0000000..35fb3c9
--- /dev/null
+++ b/libc-top-half/musl/src/thread/sh/__unmapself.c
@@ -0,0 +1,24 @@
+#include "pthread_impl.h"
+
+hidden void __unmapself_sh_mmu(void *, size_t);
+hidden void __unmapself_sh_nommu(void *, size_t);
+
+#if !defined(__SH3__) && !defined(__SH4__)
+#define __unmapself __unmapself_sh_nommu
+#include "dynlink.h"
+#undef CRTJMP
+#define CRTJMP(pc,sp) __asm__ __volatile__( \
+ "mov.l @%0+,r0 ; mov.l @%0,r12 ; jmp @r0 ; mov %1,r15" \
+ : : "r"(pc), "r"(sp) : "r0", "memory" )
+#include "../__unmapself.c"
+#undef __unmapself
+extern hidden unsigned __sh_nommu;
+#else
+#define __sh_nommu 0
+#endif
+
+void __unmapself(void *base, size_t size)
+{
+ if (__sh_nommu) __unmapself_sh_nommu(base, size);
+ else __unmapself_sh_mmu(base, size);
+}
diff --git a/libc-top-half/musl/src/thread/sh/__unmapself_mmu.s b/libc-top-half/musl/src/thread/sh/__unmapself_mmu.s
new file mode 100644
index 0000000..688087b
--- /dev/null
+++ b/libc-top-half/musl/src/thread/sh/__unmapself_mmu.s
@@ -0,0 +1,23 @@
+.text
+.global __unmapself_sh_mmu
+.hidden __unmapself_sh_mmu
+.type __unmapself_sh_mmu, @function
+__unmapself_sh_mmu:
+ mov #91, r3 ! SYS_munmap
+ trapa #31
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+ mov #1, r3 ! SYS_exit
+ mov #0, r4
+ trapa #31
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
diff --git a/libc-top-half/musl/src/thread/sh/atomics.s b/libc-top-half/musl/src/thread/sh/atomics.s
new file mode 100644
index 0000000..9d9fcb6
--- /dev/null
+++ b/libc-top-half/musl/src/thread/sh/atomics.s
@@ -0,0 +1,65 @@
+/* Contract for all versions is same as cas.l r2,r3,@r0
+ * pr and r1 are also clobbered (by jsr & r1 as temp).
+ * r0,r2,r4-r15 must be preserved.
+ * r3 contains result (==r2 iff cas succeeded). */
+
+ .align 2
+.global __sh_cas_gusa
+.hidden __sh_cas_gusa
+__sh_cas_gusa:
+ mov.l r5,@-r15
+ mov.l r4,@-r15
+ mov r0,r4
+ mova 1f,r0
+ mov r15,r1
+ mov #(0f-1f),r15
+0: mov.l @r4,r5
+ cmp/eq r5,r2
+ bf 1f
+ mov.l r3,@r4
+1: mov r1,r15
+ mov r5,r3
+ mov r4,r0
+ mov.l @r15+,r4
+ rts
+ mov.l @r15+,r5
+
+.global __sh_cas_llsc
+.hidden __sh_cas_llsc
+__sh_cas_llsc:
+ mov r0,r1
+ .word 0x00ab /* synco */
+0: .word 0x0163 /* movli.l @r1,r0 */
+ cmp/eq r0,r2
+ bf 1f
+ mov r3,r0
+ .word 0x0173 /* movco.l r0,@r1 */
+ bf 0b
+ mov r2,r0
+1: .word 0x00ab /* synco */
+ mov r0,r3
+ rts
+ mov r1,r0
+
+.global __sh_cas_imask
+.hidden __sh_cas_imask
+__sh_cas_imask:
+ mov r0,r1
+ stc sr,r0
+ mov.l r0,@-r15
+ or #0xf0,r0
+ ldc r0,sr
+ mov.l @r1,r0
+ cmp/eq r0,r2
+ bf 1f
+ mov.l r3,@r1
+1: ldc.l @r15+,sr
+ mov r0,r3
+ rts
+ mov r1,r0
+
+.global __sh_cas_cas_l
+.hidden __sh_cas_cas_l
+__sh_cas_cas_l:
+ rts
+ .word 0x2323 /* cas.l r2,r3,@r0 */
diff --git a/libc-top-half/musl/src/thread/sh/clone.s b/libc-top-half/musl/src/thread/sh/clone.s
new file mode 100644
index 0000000..9cfd862
--- /dev/null
+++ b/libc-top-half/musl/src/thread/sh/clone.s
@@ -0,0 +1,54 @@
+.text
+.global __clone
+.hidden __clone
+.type __clone, @function
+__clone:
+! incoming: fn stack flags arg ptid tls ctid
+! r4 r5 r6 r7 @r15 @(4,r15) @(8,r15)
+
+ mov #-16, r0
+ and r0, r5
+
+ mov r4, r1 ! r1 = fn
+ mov r7, r2 ! r2 = arg
+
+ mov #120, r3 ! r3 = __NR_clone
+ mov r6, r4 ! r4 = flags
+ !mov r5, r5 ! r5 = stack
+ mov.l @r15, r6 ! r6 = ptid
+ mov.l @(8,r15), r7 ! r7 = ctid
+ mov.l @(4,r15), r0 ! r0 = tls
+ trapa #31
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+ cmp/eq #0, r0
+ bt 1f
+
+ ! we are the parent, return
+ rts
+ nop
+
+1: ! we are the child, call fn(arg)
+ mov.l 1f, r0
+ mov r1, r5
+ bsrf r0
+ mov r2, r4
+
+2: mov #1, r3 ! __NR_exit
+ mov r0, r4
+ trapa #31
+
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+.align 2
+.hidden __shcall
+1: .long __shcall@PCREL+(.-2b)
diff --git a/libc-top-half/musl/src/thread/sh/syscall_cp.s b/libc-top-half/musl/src/thread/sh/syscall_cp.s
new file mode 100644
index 0000000..bb848ef
--- /dev/null
+++ b/libc-top-half/musl/src/thread/sh/syscall_cp.s
@@ -0,0 +1,45 @@
+.text
+.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:
+
+__cp_begin:
+ mov.l @r4, r4
+ tst r4, r4
+ bf __cp_cancel
+ mov r5, r3
+ mov r6, r4
+ mov r7, r5
+ mov.l @r15, r6
+ mov.l @(4,r15), r7
+ mov.l @(8,r15), r0
+ mov.l @(12,r15), r1
+ trapa #31
+
+__cp_end:
+ ! work around hardware bug
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+ or r0, r0
+
+ rts
+ nop
+
+__cp_cancel:
+ mov.l 2f, r0
+ braf r0
+ nop
+1:
+
+.align 2
+2: .long __cancel@PCREL-(1b-.)