github.com/afumu/libc@v0.0.6/musl/src/thread/powerpc/clone.s (about)

     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