fix failure to preserve r6 in s390x asm; per ABI it is call-saved
[musl] / src / thread / s390x / clone.s
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)
14         #
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;
19
20         # preserve call-saved register used as syscall arg
21         stg  %r6, 48(%r15)
22
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)
28
29         # save fn and arg to child stack
30         stg  %r2,  8(%r3)
31         stg  %r5, 16(%r3)
32
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
40
41         # restore call-saved register
42         lg   %r6, 48(%r15)
43
44         # if error or if we're the parent, return
45         ltgr %r2, %r2
46         bnzr %r14
47
48         # we're the child. call fn(arg)
49         lg   %r1,  8(%r15)
50         lg   %r2, 16(%r15)
51         basr %r14, %r1
52
53         # call SYS_exit. exit code is already in r2 from fn return value
54         svc  1