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