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, jump to end 52bne cr7, 2f 53 54#else: we're the child 55#call funcptr: move arg (d) into r3 56mr 3, 31 57#move r30 (funcptr) into CTR reg 58mtctr 30 59# call CTR reg 60bctrl 61# mov SYS_exit into r0 (the exit param is already in r3) 62li 0, 1 63sc 64 652: 66 67# restore stack 68lwz 30, 0(1) 69lwz 31, 4(1) 70addi 1, 1, 16 71 72blr 73 74