synccall: add separate exit_sem to fix thread release logic bug
[musl.git] / src / thread / s390x / clone.s
blob2125f20b83c759056fdc0060d12e72c1484c16e1
1 .text
2 .global __clone
3 .hidden __clone
4 .type __clone, %function
5 __clone:
6 # int clone(
7 # fn, a = r2
8 # stack, b = r3
9 # flags, c = r4
10 # arg, d = r5
11 # ptid, e = r6
12 # tls, f = *(r15+160)
13 # ctid) g = *(r15+168)
15 # pseudo C code:
16 # tid = syscall(SYS_clone,b,c,e,g,f);
17 # if (!tid) syscall(SYS_exit, a(d));
18 # return tid;
20 # preserve call-saved register used as syscall arg
21 stg %r6, 48(%r15)
23 # create initial stack frame for new thread
24 nill %r3, 0xfff8
25 aghi %r3, -160
26 lghi %r0, 0
27 stg %r0, 0(%r3)
29 # save fn and arg to child stack
30 stg %r2, 8(%r3)
31 stg %r5, 16(%r3)
33 # shuffle args into correct registers and call SYS_clone
34 lgr %r2, %r3
35 lgr %r3, %r4
36 lgr %r4, %r6
37 lg %r5, 168(%r15)
38 lg %r6, 160(%r15)
39 svc 120
41 # restore call-saved register
42 lg %r6, 48(%r15)
44 # if error or if we're the parent, return
45 ltgr %r2, %r2
46 bnzr %r14
48 # we're the child. call fn(arg)
49 lg %r1, 8(%r15)
50 lg %r2, 16(%r15)
51 basr %r14, %r1
53 # call SYS_exit. exit code is already in r2 from fn return value
54 svc 1