clone.S 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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, write to the Free Software Foundation,
  18. ; Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  19. ;
  20. #define __ASSEMBLY__
  21. ; int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg);
  22. #include <asm/errno.h>
  23. #include <sys/syscall.h>
  24. .global __clone
  25. .global clone
  26. .global __errno_location
  27. ;Currently supports only
  28. ;int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg)
  29. ;
  30. ;Requires update for supporting
  31. ; int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg,
  32. ; int *parent_tidptr, struct user_desc *newtls, int *child_pidptr)
  33. __clone:
  34. ; index 1 points to the forth argument and is to be moved to B6
  35. LDW .D2T2 *+B15[1],B5
  36. NOP 4
  37. OR .D2X B4,A4,B2 ; sanity check arguments, no NULL function or stack pointers
  38. || MV .S2 B4,B9
  39. || MV .D1 A4,A9 ; backup fn and child_stack pointers
  40. [!B2] B .S2 __syscall_error
  41. ||[!B2] MVK .S1 EINVAL,A4
  42. NOP 4
  43. MV .D1 A6,A4 ; get flags as arg0, arg1 is the new stack
  44. || AND .D2 ~7,B4,B4
  45. ; do the system call
  46. || MVK .S2 __NR_clone,B0
  47. || MV .L2 B5,B6
  48. 0:
  49. #ifndef _TMS320C6400_PLUS
  50. MVC .S2 CSR,B2
  51. CLR .S2 B2,0,0,B1
  52. MVC .S2 B1,CSR
  53. MVC .S2 IFR,B1
  54. SET .S2 B1,6,6,B1
  55. MVC .S2 B1,ISR
  56. MVC .S2 B2,CSR
  57. NOP
  58. #else
  59. SWE
  60. #endif
  61. MV .D2 B9,B4 ; restore child stack
  62. || CMPEQ .L1 0,A4,A2
  63. || CMPLT .L2X A4,0,B2
  64. [B2] B .S2 __syscall_error ; if syscall < 0, it is an error
  65. NOP 5
  66. [A2] B .S2X A9 ; branch to function
  67. || [A2] MV .D1X B6,A4 ; set arg (B6 is preserved by syscall)
  68. [!A2] B .S2 B3 ; otherwise (syscall result > 0) returns directly
  69. [A2] ADDKPC .S2 __return_thread,B3, 4
  70. __return_thread:
  71. b .s2 HIDDEN_JUMPTARGET(_exit)
  72. nop 5
  73. __syscall_error:
  74. NEG .S1 A4,A4
  75. STW .D2T1 A4,*B15--[2]
  76. STW .D2T2 B3,*+B15[1]
  77. CALLP .S2 __errno_location,B3
  78. LDW .D2T2 *+B15[1],B3
  79. LDW .D2T1 *++B15[2],A5
  80. NOP 3
  81. BNOP .S2 B3,3
  82. STW .D1T1 A5,*A4
  83. MVK .L1 -1,A4
  84. .set clone, __clone