From 15094943050eb9a564f409323070e50b40f78816 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Fri, 11 Nov 2016 21:52:05 -0600 Subject: add s390x port --- src/thread/s390x/__set_thread_area.s | 9 +++++++ src/thread/s390x/__tls_get_offset.s | 17 +++++++++++++ src/thread/s390x/__unmapself.s | 6 +++++ src/thread/s390x/clone.s | 47 ++++++++++++++++++++++++++++++++++++ src/thread/s390x/syscall_cp.s | 32 ++++++++++++++++++++++++ 5 files changed, 111 insertions(+) create mode 100644 src/thread/s390x/__set_thread_area.s create mode 100644 src/thread/s390x/__tls_get_offset.s create mode 100644 src/thread/s390x/__unmapself.s create mode 100644 src/thread/s390x/clone.s create mode 100644 src/thread/s390x/syscall_cp.s (limited to 'src/thread') diff --git a/src/thread/s390x/__set_thread_area.s b/src/thread/s390x/__set_thread_area.s new file mode 100644 index 00000000..fd412913 --- /dev/null +++ b/src/thread/s390x/__set_thread_area.s @@ -0,0 +1,9 @@ +.text +.global __set_thread_area +.type __set_thread_area, %function +__set_thread_area: + sar %a1, %r2 + srlg %r2, %r2, 32 + sar %a0, %r2 + lghi %r2, 0 + br %r14 diff --git a/src/thread/s390x/__tls_get_offset.s b/src/thread/s390x/__tls_get_offset.s new file mode 100644 index 00000000..8ee92de8 --- /dev/null +++ b/src/thread/s390x/__tls_get_offset.s @@ -0,0 +1,17 @@ + .global __tls_get_offset + .type __tls_get_offset,%function +__tls_get_offset: + stmg %r14, %r15, 112(%r15) + aghi %r15, -160 + + la %r2, 0(%r2, %r12) + brasl %r14, __tls_get_addr + + ear %r1, %a0 + sllg %r1, %r1, 32 + ear %r1, %a1 + + sgr %r2, %r1 + + lmg %r14, %r15, 272(%r15) + br %r14 diff --git a/src/thread/s390x/__unmapself.s b/src/thread/s390x/__unmapself.s new file mode 100644 index 00000000..48b312cd --- /dev/null +++ b/src/thread/s390x/__unmapself.s @@ -0,0 +1,6 @@ +.text +.global __unmapself +.type __unmapself, @function +__unmapself: + svc 91 # SYS_munmap + svc 1 # SYS_exit diff --git a/src/thread/s390x/clone.s b/src/thread/s390x/clone.s new file mode 100644 index 00000000..3e08c213 --- /dev/null +++ b/src/thread/s390x/clone.s @@ -0,0 +1,47 @@ +.text +.global __clone +.type __clone, %function +__clone: + # int clone( + # fn, a = r2 + # stack, b = r3 + # flags, c = r4 + # arg, d = r5 + # ptid, e = r6 + # tls, f = *(r15+160) + # ctid) g = *(r15+168) + # + # pseudo C code: + # tid = syscall(SYS_clone,b,c,e,g,f); + # if (!tid) syscall(SYS_exit, a(d)); + # return tid; + + # create initial stack frame for new thread + nill %r3, 0xfff8 + aghi %r3, -160 + lghi %r0, 0 + stg %r0, 0(%r3) + + # save fn and arg to child stack + stg %r2, 8(%r3) + stg %r5, 16(%r3) + + # shuffle args into correct registers and call SYS_clone + lgr %r2, %r3 + lgr %r3, %r4 + lgr %r4, %r6 + lg %r5, 168(%r15) + lg %r6, 160(%r15) + svc 120 + + # if error or if we're the parent, return + ltgr %r2, %r2 + bnzr %r14 + + # we're the child. call fn(arg) + lg %r1, 8(%r15) + lg %r2, 16(%r15) + basr %r14, %r1 + + # call SYS_exit. exit code is already in r2 from fn return value + svc 1 diff --git a/src/thread/s390x/syscall_cp.s b/src/thread/s390x/syscall_cp.s new file mode 100644 index 00000000..c1da40de --- /dev/null +++ b/src/thread/s390x/syscall_cp.s @@ -0,0 +1,32 @@ + .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 + .text + .type __syscall_cp_asm,%function +__syscall_cp_asm: +__cp_begin: + icm %r2, 15, 0(%r2) + jne __cp_cancel + + stg %r7, 56(%r15) + lgr %r1, %r3 + lgr %r2, %r4 + lgr %r3, %r5 + lgr %r4, %r6 + lg %r5, 160(%r15) + lg %r6, 168(%r15) + lg %r7, 176(%r15) + svc 0 + +__cp_end: + lg %r7, 56(%r15) + br %r14 + +__cp_cancel: + jg __cancel -- cgit v1.2.1