xref: /third_party/musl/src/thread/powerpc64/clone.s (revision 570af302)
1570af302Sopenharmony_ci.text
2570af302Sopenharmony_ci.global __clone
3570af302Sopenharmony_ci.hidden __clone
4570af302Sopenharmony_ci.type __clone, %function
5570af302Sopenharmony_ci__clone:
6570af302Sopenharmony_ci	# int clone(fn, stack, flags, arg, ptid, tls, ctid)
7570af302Sopenharmony_ci	#            a  b       c     d     e    f    g
8570af302Sopenharmony_ci	#            3  4       5     6     7    8    9
9570af302Sopenharmony_ci	# pseudo C code:
10570af302Sopenharmony_ci	# tid = syscall(SYS_clone,c,b,e,f,g);
11570af302Sopenharmony_ci	# if (!tid) syscall(SYS_exit, a(d));
12570af302Sopenharmony_ci	# return tid;
13570af302Sopenharmony_ci
14570af302Sopenharmony_ci	# create initial stack frame for new thread
15570af302Sopenharmony_ci	clrrdi 4, 4, 4
16570af302Sopenharmony_ci	li     0, 0
17570af302Sopenharmony_ci	stdu   0,-32(4)
18570af302Sopenharmony_ci
19570af302Sopenharmony_ci	# save fn and arg to child stack
20570af302Sopenharmony_ci	std    3,  8(4)
21570af302Sopenharmony_ci	std    6, 16(4)
22570af302Sopenharmony_ci
23570af302Sopenharmony_ci	# shuffle args into correct registers and call SYS_clone
24570af302Sopenharmony_ci	mr    3, 5
25570af302Sopenharmony_ci	#mr   4, 4
26570af302Sopenharmony_ci	mr    5, 7
27570af302Sopenharmony_ci	mr    6, 8
28570af302Sopenharmony_ci	mr    7, 9
29570af302Sopenharmony_ci	li    0, 120  # SYS_clone = 120
30570af302Sopenharmony_ci	sc
31570af302Sopenharmony_ci
32570af302Sopenharmony_ci	# if error, negate return (errno)
33570af302Sopenharmony_ci	bns+  1f
34570af302Sopenharmony_ci	neg   3, 3
35570af302Sopenharmony_ci
36570af302Sopenharmony_ci1:	# if we're the parent, return
37570af302Sopenharmony_ci	cmpwi cr7, 3, 0
38570af302Sopenharmony_ci	bnelr cr7
39570af302Sopenharmony_ci
40570af302Sopenharmony_ci	# we're the child. call fn(arg)
41570af302Sopenharmony_ci	ld     3, 16(1)
42570af302Sopenharmony_ci	ld    12,  8(1)
43570af302Sopenharmony_ci	mtctr 12
44570af302Sopenharmony_ci	bctrl
45570af302Sopenharmony_ci
46570af302Sopenharmony_ci	# call SYS_exit. exit code is already in r3 from fn return value
47570af302Sopenharmony_ci	li    0, 1    # SYS_exit = 1
48570af302Sopenharmony_ci	sc
49