clone.S 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. #
  2. # clone.S, part of the i960 support for the uClibc library.
  3. #
  4. # Copyright (C) 2002 by Okiok Data Ltd. http://www.okiok.com/
  5. #
  6. # This program is free software; you can redistribute it and/or modify it under
  7. # the terms of the GNU Library General Public License as published by the Free
  8. # Software Foundation; either version 2 of the License, or (at your option) any
  9. # later version.
  10. #
  11. # This program is distributed in the hope that it will be useful, but WITHOUT
  12. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  13. # FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more
  14. # details.
  15. #
  16. # You should have received a copy of the GNU Library General Public License
  17. # along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. #
  19. # Derived from an old port of uC-libc to the i960 by Keith Adams (kma@cse.ogi.edu).
  20. #
  21. #include <sys/syscall.h>
  22. #include <bits/errno.h>
  23. /* clone is even more special than fork as it mucks with stacks
  24. and invokes a function in the right context after its all over. */
  25. /* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
  26. .globl clone
  27. clone:
  28. /* set up new stack image in regs r4-r7; argument will be in r3 in child. */
  29. ldconst 0, r4 /* pfp == 0 */
  30. addo 16, g1, r5 /* sp == newfp + 16 */
  31. mov g0, r6 /* rip == fnc */
  32. mov g2, r7
  33. stq r4, (g1)
  34. addo sp, 4, sp
  35. st g10, -4(sp)
  36. mov sp, g10
  37. ldconst __NR_clone, g13
  38. calls 0
  39. /* Do the system call */
  40. cmpibg 0, g0, __syscall_error /* if < 0, error */
  41. be thread_start /* if == 0, we're the child */
  42. ret /* we're the parent */
  43. __syscall_error:
  44. not g0, r3
  45. callx ___errno_location
  46. st r3, (g0)
  47. ret
  48. thread_start:
  49. # our new pfp is in g1; here we go
  50. flushreg
  51. mov g1, pfp
  52. flushreg
  53. ret