1#__clone(func, stack, flags, arg, ptid, tls, ctid) 2# a0, a1, a2, a3, a4, a5, a6 3# sys_clone(flags, stack, ptid, ctid, tls) 4# a0, a1, a2, a3, a4 5 6.global __clone 7.hidden __clone 8.type __clone,@function 9__clone: 10 bstrins.d $a1, $zero, 3, 0 #stack to 16 align 11 # Save function pointer and argument pointer on new thread stack 12 addi.d $a1, $a1, -16 13 st.d $a0, $a1, 0 # save function pointer 14 st.d $a3, $a1, 8 # save argument pointer 15 or $a0, $a2, $zero 16 or $a2, $a4, $zero 17 or $a3, $a6, $zero 18 or $a4, $a5, $zero 19 ori $a7, $zero, 220 20 syscall 0 # call clone 21 22 beqz $a0, 1f # whether child process 23 jirl $zero, $ra, 0 # parent process return 241: 25 ld.d $t8, $sp, 0 # function pointer 26 ld.d $a0, $sp, 8 # argument pointer 27 jirl $ra, $t8, 0 # call the user's function 28 ori $a7, $zero, 93 29 syscall 0 # child process exit 30