| 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 |
| 24 | 1: |
| 25 | 	move $fp, $zero |
| 26 | 	ld.d $t8, $sp, 0 # function pointer |
| 27 | 	ld.d $a0, $sp, 8 # argument pointer |
| 28 | 	jirl $ra, $t8, 0 # call the user's function |
| 29 | 	ori $a7, $zero, 93 |
| 30 | 	syscall 0 # child process exit |