clone.s raw

   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
  55