1.text 2.global __clone 3.hidden __clone 4.type __clone, %function 5__clone: 6 # int clone( 7 # fn, a = r2 8 # stack, b = r3 9 # flags, c = r4 10 # arg, d = r5 11 # ptid, e = r6 12 # tls, f = *(r15+160) 13 # ctid) g = *(r15+168) 14 # 15 # pseudo C code: 16 # tid = syscall(SYS_clone,b,c,e,g,f); 17 # if (!tid) syscall(SYS_exit, a(d)); 18 # return tid; 19 20 # preserve call-saved register used as syscall arg 21 stg %r6, 48(%r15) 22 23 # create initial stack frame for new thread 24 nill %r3, 0xfff8 25 aghi %r3, -160 26 lghi %r0, 0 27 stg %r0, 0(%r3) 28 29 # save fn and arg to child stack 30 stg %r2, 8(%r3) 31 stg %r5, 16(%r3) 32 33 # shuffle args into correct registers and call SYS_clone 34 lgr %r2, %r3 35 lgr %r3, %r4 36 lgr %r4, %r6 37 lg %r5, 168(%r15) 38 lg %r6, 160(%r15) 39 svc 120 40 41 # restore call-saved register 42 lg %r6, 48(%r15) 43 44 # if error or if we're the parent, return 45 ltgr %r2, %r2 46 bnzr %r14 47 48 # we're the child. call fn(arg) 49 lg %r1, 8(%r15) 50 lg %r2, 16(%r15) 51 basr %r14, %r1 52 53 # call SYS_exit. exit code is already in r2 from fn return value 54 svc 1 55