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