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  # SYS_clone = 120
  15  # SYS_exit = 1
  16  
  17  # store non-volatile regs r30, r31 on stack in order to put our
  18  # start func and its arg there
  19  stwu 30, -16(1)
  20  stw 31, 4(1)
  21  
  22  # save r3 (func) into r30, and r6(arg) into r31
  23  mr 30, 3
  24  mr 31, 6
  25  
  26  # create initial stack frame for new thread
  27  clrrwi 4, 4, 4
  28  li 0, 0
  29  stwu 0, -16(4)
  30  
  31  #move c into first arg
  32  mr 3, 5
  33  #mr 4, 4
  34  mr 5, 7
  35  mr 6, 8
  36  mr 7, 9
  37  
  38  # move syscall number into r0    
  39  li 0, 120
  40  
  41  sc
  42  
  43  # check for syscall error
  44  bns+ 1f # jump to label 1 if no summary overflow.
  45  #else
  46  neg 3, 3 #negate the result (errno)
  47  1:
  48  # compare sc result with 0
  49  cmpwi cr7, 3, 0
  50  
  51  # if not 0, jump to end
  52  bne cr7, 2f
  53  
  54  #else: we're the child
  55  #call funcptr: move arg (d) into r3
  56  mr 3, 31
  57  #move r30 (funcptr) into CTR reg
  58  mtctr 30
  59  # call CTR reg
  60  bctrl
  61  # mov SYS_exit into r0 (the exit param is already in r3)
  62  li 0, 1
  63  sc
  64  
  65  2:
  66  
  67  # restore stack
  68  lwz 30, 0(1)
  69  lwz 31, 4(1)
  70  addi 1, 1, 16
  71  
  72  blr
  73  
  74