1570af302Sopenharmony_ci.text
2570af302Sopenharmony_ci.global __clone
3570af302Sopenharmony_ci.hidden __clone
4570af302Sopenharmony_ci.type __clone, %function
5570af302Sopenharmony_ci__clone:
6570af302Sopenharmony_ci	# int clone(
7570af302Sopenharmony_ci	#    fn,      a = r2
8570af302Sopenharmony_ci	#    stack,   b = r3
9570af302Sopenharmony_ci	#    flags,   c = r4
10570af302Sopenharmony_ci	#    arg,     d = r5
11570af302Sopenharmony_ci	#    ptid,    e = r6
12570af302Sopenharmony_ci	#    tls,     f = *(r15+160)
13570af302Sopenharmony_ci	#    ctid)    g = *(r15+168)
14570af302Sopenharmony_ci	#
15570af302Sopenharmony_ci	# pseudo C code:
16570af302Sopenharmony_ci	# tid = syscall(SYS_clone,b,c,e,g,f);
17570af302Sopenharmony_ci	# if (!tid) syscall(SYS_exit, a(d));
18570af302Sopenharmony_ci	# return tid;
19570af302Sopenharmony_ci
20570af302Sopenharmony_ci	# preserve call-saved register used as syscall arg
21570af302Sopenharmony_ci	stg  %r6, 48(%r15)
22570af302Sopenharmony_ci
23570af302Sopenharmony_ci	# create initial stack frame for new thread
24570af302Sopenharmony_ci	nill %r3, 0xfff8
25570af302Sopenharmony_ci	aghi %r3, -160
26570af302Sopenharmony_ci	lghi %r0, 0
27570af302Sopenharmony_ci	stg  %r0, 0(%r3)
28570af302Sopenharmony_ci
29570af302Sopenharmony_ci	# save fn and arg to child stack
30570af302Sopenharmony_ci	stg  %r2,  8(%r3)
31570af302Sopenharmony_ci	stg  %r5, 16(%r3)
32570af302Sopenharmony_ci
33570af302Sopenharmony_ci	# shuffle args into correct registers and call SYS_clone
34570af302Sopenharmony_ci	lgr  %r2, %r3
35570af302Sopenharmony_ci	lgr  %r3, %r4
36570af302Sopenharmony_ci	lgr  %r4, %r6
37570af302Sopenharmony_ci	lg   %r5, 168(%r15)
38570af302Sopenharmony_ci	lg   %r6, 160(%r15)
39570af302Sopenharmony_ci	svc  120
40570af302Sopenharmony_ci
41570af302Sopenharmony_ci	# restore call-saved register
42570af302Sopenharmony_ci	lg   %r6, 48(%r15)
43570af302Sopenharmony_ci
44570af302Sopenharmony_ci	# if error or if we're the parent, return
45570af302Sopenharmony_ci	ltgr %r2, %r2
46570af302Sopenharmony_ci	bnzr %r14
47570af302Sopenharmony_ci
48570af302Sopenharmony_ci	# we're the child. call fn(arg)
49570af302Sopenharmony_ci	lg   %r1,  8(%r15)
50570af302Sopenharmony_ci	lg   %r2, 16(%r15)
51570af302Sopenharmony_ci	basr %r14, %r1
52570af302Sopenharmony_ci
53570af302Sopenharmony_ci	# call SYS_exit. exit code is already in r2 from fn return value
54570af302Sopenharmony_ci	svc  1
55