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