clone.s 940 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. .text
  2. .global __clone
  3. .type __clone, %function
  4. __clone:
  5. # int clone(fn, stack, flags, arg, ptid, tls, ctid)
  6. # a b c d e f g
  7. # 3 4 5 6 7 8 9
  8. # pseudo C code:
  9. # tid = syscall(SYS_clone,c,b,e,f,g);
  10. # if (!tid) syscall(SYS_exit, a(d));
  11. # return tid;
  12. # create initial stack frame for new thread
  13. clrrdi 4, 4, 4
  14. li 0, 0
  15. stdu 0,-32(4)
  16. # save fn and arg to child stack
  17. std 3, 8(4)
  18. std 6, 16(4)
  19. # shuffle args into correct registers and call SYS_clone
  20. mr 3, 5
  21. #mr 4, 4
  22. mr 5, 7
  23. mr 6, 8
  24. mr 7, 9
  25. li 0, 120 # SYS_clone = 120
  26. sc
  27. # if error, negate return (errno)
  28. bns+ 1f
  29. neg 3, 3
  30. 1: # if we're the parent, return
  31. cmpwi cr7, 3, 0
  32. bnelr cr7
  33. # we're the child. call fn(arg)
  34. ld 3, 16(1)
  35. ld 12, 8(1)
  36. mtctr 12
  37. bctrl
  38. # call SYS_exit. exit code is already in r3 from fn return value
  39. li 0, 1 # SYS_exit = 1
  40. sc