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	# create initial stack frame for new thread
21	nill %r3, 0xfff8
22	aghi %r3, -160
23	lghi %r0, 0
24	stg  %r0, 0(%r3)
25
26	# save fn and arg to child stack
27	stg  %r2,  8(%r3)
28	stg  %r5, 16(%r3)
29
30	# shuffle args into correct registers and call SYS_clone
31	lgr  %r2, %r3
32	lgr  %r3, %r4
33	lgr  %r4, %r6
34	lg   %r5, 168(%r15)
35	lg   %r6, 160(%r15)
36	svc  120
37
38	# if error or if we're the parent, return
39	ltgr %r2, %r2
40	bnzr %r14
41
42	# we're the child. call fn(arg)
43	lg   %r1,  8(%r15)
44	lg   %r2, 16(%r15)
45	basr %r14, %r1
46
47	# call SYS_exit. exit code is already in r2 from fn return value
48	svc  1
49