clone.S 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. ;
  2. ; Port of uClibc for TMS320C6000 DSP architecture
  3. ; Copyright (C) 2004 Texas Instruments Incorporated
  4. ; Author of TMS320C6000 port: Aurelien Jacquiot
  5. ;
  6. ; This program is free software; you can redistribute it and/or modify it
  7. ; under the terms of the GNU Library General Public License as published by
  8. ; the Free Software Foundation; either version 2 of the License, or (at your
  9. ; option) any 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
  13. ; FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
  14. ; for more 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. #define __ASSEMBLY__
  20. ; int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg);
  21. #include <asm/errno.h>
  22. #include <sys/syscall.h>
  23. .global __clone
  24. .global clone
  25. .global __errno_location
  26. ;Currently supports only
  27. ;int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
  28. ;
  29. ;Requires update for supporting
  30. ; int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  31. ; int *parent_tidptr, struct user_desc *newtls, int *child_pidptr)
  32. __clone:
  33. ; index 1 points to the forth argument and is to be moved to B6
  34. LDW .D2T2 *+B15[1],B5
  35. NOP 4
  36. OR .D2X B4,A4,B2 ; sanity check arguments, no NULL function or stack pointers
  37. || MV .S2 B4,B9
  38. || MV .D1 A4,A9 ; backup fn and child_stack pointers
  39. [!B2] B .S2 __syscall_error
  40. ||[!B2] MVK .S1 EINVAL,A4
  41. NOP 4
  42. MV .D1 A6,A4 ; get flags as arg0, arg1 is the new stack
  43. || AND .D2 ~7,B4,B4
  44. ; do the system call
  45. || MVK .S2 __NR_clone,B0
  46. || MV .L2 B5,B6
  47. 0:
  48. #ifndef _TMS320C6400_PLUS
  49. MVC .S2 CSR,B2
  50. CLR .S2 B2,0,0,B1
  51. MVC .S2 B1,CSR
  52. MVC .S2 IFR,B1
  53. SET .S2 B1,6,6,B1
  54. MVC .S2 B1,ISR
  55. MVC .S2 B2,CSR
  56. NOP
  57. #else
  58. SWE
  59. #endif
  60. MV .D2 B9,B4 ; restore child stack
  61. || CMPEQ .L1 0,A4,A2
  62. || CMPLT .L2X A4,0,B2
  63. [B2] B .S2 __syscall_error ; if syscall < 0, it is an error
  64. NOP 5
  65. [A2] B .S2X A9 ; branch to function
  66. || [A2] MV .D1X B6,A4 ; set arg (B6 is preserved by syscall)
  67. [!A2] B .S2 B3 ; otherwise (syscall result > 0) returns directly
  68. [A2] ADDKPC .S2 __return_thread,B3, 4
  69. __return_thread:
  70. b .s2 HIDDEN_JUMPTARGET(_exit)
  71. nop 5
  72. __syscall_error:
  73. NEG .S1 A4,A4
  74. STW .D2T1 A4,*B15--[2]
  75. STW .D2T2 B3,*+B15[1]
  76. CALLP .S2 __errno_location,B3
  77. LDW .D2T2 *+B15[1],B3
  78. LDW .D2T1 *++B15[2],A5
  79. NOP 3
  80. BNOP .S2 B3,3
  81. STW .D1T1 A5,*A4
  82. MVK .L1 -1,A4
  83. .set clone, __clone