OLD | NEW |
| (Empty) |
1 .text | |
2 .global __clone | |
3 .type __clone, %function | |
4 __clone: | |
5 # int clone(fn, stack, flags, arg, ptid, tls, ctid) | |
6 # a b c d e f g | |
7 # 3 4 5 6 7 8 9 | |
8 # pseudo C code: | |
9 # tid = syscall(SYS_clone,c,b,e,f,g); | |
10 # if (!tid) syscall(SYS_exit, a(d)); | |
11 # return tid; | |
12 | |
13 # SYS_clone = 120 | |
14 # SYS_exit = 1 | |
15 | |
16 # store non-volatile regs r30, r31 on stack in order to put our | |
17 # start func and its arg there | |
18 stwu 30, -16(1) | |
19 stw 31, 4(1) | |
20 | |
21 # save r3 (func) into r30, and r6(arg) into r31 | |
22 mr 30, 3 | |
23 mr 31, 6 | |
24 | |
25 #move c into first arg | |
26 mr 3, 5 | |
27 #mr 4, 4 | |
28 mr 5, 7 | |
29 mr 6, 8 | |
30 mr 7, 9 | |
31 | |
32 # move syscall number into r0 | |
33 li 0, 120 | |
34 | |
35 sc | |
36 | |
37 # check for syscall error | |
38 bns+ 1f # jump to label 1 if no summary overflow. | |
39 #else | |
40 neg 3, 3 #negate the result (errno) | |
41 1: | |
42 # compare sc result with 0 | |
43 cmpwi cr7, 3, 0 | |
44 | |
45 # if not 0, jump to end | |
46 bne cr7, 2f | |
47 | |
48 #else: we're the child | |
49 #call funcptr: move arg (d) into r3 | |
50 mr 3, 31 | |
51 #move r30 (funcptr) into CTR reg | |
52 mtctr 30 | |
53 # call CTR reg | |
54 bctrl | |
55 # mov SYS_exit into r0 (the exit param is already in r3) | |
56 li 0, 1 | |
57 sc | |
58 | |
59 2: | |
60 | |
61 # restore stack | |
62 lwz 30, 0(1) | |
63 lwz 31, 4(1) | |
64 addi 1, 1, 16 | |
65 | |
66 blr | |
67 | |
OLD | NEW |