clone.s raw

   1  .text
   2  .global __clone
   3  .hidden __clone
   4  .type __clone, %function
   5  __clone:
   6  	# int clone(fn, stack, flags, arg, ptid, tls, ctid)
   7  	#            a  b       c     d     e    f    g
   8  	#            3  4       5     6     7    8    9
   9  	# pseudo C code:
  10  	# tid = syscall(SYS_clone,c,b,e,f,g);
  11  	# if (!tid) syscall(SYS_exit, a(d));
  12  	# return tid;
  13  
  14  	# create initial stack frame for new thread
  15  	clrrdi 4, 4, 4
  16  	li     0, 0
  17  	stdu   0,-32(4)
  18  
  19  	# save fn and arg to child stack
  20  	std    3,  8(4)
  21  	std    6, 16(4)
  22  
  23  	# shuffle args into correct registers and call SYS_clone
  24  	mr    3, 5
  25  	#mr   4, 4
  26  	mr    5, 7
  27  	mr    6, 8
  28  	mr    7, 9
  29  	li    0, 120  # SYS_clone = 120
  30  	sc
  31  
  32  	# if error, negate return (errno)
  33  	bns+  1f
  34  	neg   3, 3
  35  
  36  1:	# if we're the parent, return
  37  	cmpwi cr7, 3, 0
  38  	bnelr cr7
  39  
  40  	# we're the child. call fn(arg)
  41  	ld     3, 16(1)
  42  	ld    12,  8(1)
  43  	mtctr 12
  44  	bctrl
  45  
  46  	# call SYS_exit. exit code is already in r3 from fn return value
  47  	li    0, 1    # SYS_exit = 1
  48  	sc
  49