sysdep-cancel.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. /* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. The GNU C Library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Lesser General Public
  5. License as published by the Free Software Foundation; either
  6. version 2.1 of the License, or (at your option) any later version.
  7. The GNU C Library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Lesser General Public License for more details.
  11. You should have received a copy of the GNU Lesser General Public
  12. License along with the GNU C Library; if not, see
  13. <http://www.gnu.org/licenses/>. */
  14. #include <sysdep.h>
  15. #include <tls.h>
  16. #include <pt-machine.h>
  17. #ifndef __ASSEMBLER__
  18. # include <linuxthreads/internals.h>
  19. #endif
  20. #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
  21. # define _IMM12 #-12
  22. # define _IMM16 #-16
  23. # define _IMP16 #16
  24. # undef PSEUDO
  25. # define PSEUDO(name, syscall_name, args) \
  26. .text; \
  27. ENTRY (name); \
  28. SINGLE_THREAD_P; \
  29. bf .Lpseudo_cancel; \
  30. DO_CALL (syscall_name, args); \
  31. mov r0,r1; \
  32. mov _IMM12,r2; \
  33. shad r2,r1; \
  34. not r1,r1; \
  35. tst r1,r1; \
  36. bt .Lsyscall_error; \
  37. bra .Lpseudo_end; \
  38. nop; \
  39. .Lpseudo_cancel: \
  40. sts.l pr,@-r15; \
  41. add _IMM16,r15; \
  42. SAVE_ARGS_##args; \
  43. CENABLE; \
  44. LOAD_ARGS_##args; \
  45. add _IMP16,r15; \
  46. lds.l @r15+,pr; \
  47. DO_CALL(syscall_name, args); \
  48. SYSCALL_INST_PAD; \
  49. sts.l pr,@-r15; \
  50. mov.l r0,@-r15; \
  51. CDISABLE; \
  52. mov.l @r15+,r0; \
  53. lds.l @r15+,pr; \
  54. mov r0,r1; \
  55. mov _IMM12,r2; \
  56. shad r2,r1; \
  57. not r1,r1; \
  58. tst r1,r1; \
  59. bf .Lpseudo_end; \
  60. .Lsyscall_error: \
  61. SYSCALL_ERROR_HANDLER; \
  62. .Lpseudo_end:
  63. # undef PSEUDO_END
  64. # define PSEUDO_END(sym) \
  65. END (sym)
  66. # define SAVE_ARGS_0 /* Nothing. */
  67. # define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15)
  68. # define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15)
  69. # define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15)
  70. # define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15)
  71. # define SAVE_ARGS_5 SAVE_ARGS_4
  72. # define SAVE_ARGS_6 SAVE_ARGS_5
  73. # define LOAD_ARGS_0 /* Nothing. */
  74. # define LOAD_ARGS_1 LOAD_ARGS_0; mov.l @(0,r15),r4
  75. # define LOAD_ARGS_2 LOAD_ARGS_1; mov.l @(4,r15),r5
  76. # define LOAD_ARGS_3 LOAD_ARGS_2; mov.l @(8,r15),r6
  77. # define LOAD_ARGS_4 LOAD_ARGS_3; mov.l @(12,r15),r7
  78. # define LOAD_ARGS_5 LOAD_ARGS_4
  79. # define LOAD_ARGS_6 LOAD_ARGS_5
  80. # ifdef IS_IN_libpthread
  81. # define __local_enable_asynccancel __pthread_enable_asynccancel
  82. # define __local_disable_asynccancel __pthread_disable_asynccancel
  83. # define __local_multiple_threads __pthread_multiple_threads
  84. # elif !defined NOT_IN_libc
  85. # define __local_enable_asynccancel __libc_enable_asynccancel
  86. # define __local_disable_asynccancel __libc_disable_asynccancel
  87. # define __local_multiple_threads __libc_multiple_threads
  88. # else
  89. # define __local_enable_asynccancel __librt_enable_asynccancel
  90. # define __local_disable_asynccancel __librt_disable_asynccancel
  91. # define __local_multiple_threads __librt_multiple_threads
  92. # endif
  93. # if defined IS_IN_librt && defined __PIC__
  94. # define CENABLE \
  95. mov.l r12,@-r15; \
  96. mov.l 1f,r12; \
  97. mova 1f,r0; \
  98. add r0,r12; \
  99. mov.l 2f,r0; \
  100. bsrf r0; \
  101. nop; \
  102. 0: bra 3f; \
  103. mov r0,r2; \
  104. .align 2; \
  105. 1: .long _GLOBAL_OFFSET_TABLE_; \
  106. 2: .long __local_enable_asynccancel@PLT - (0b-.); \
  107. 3: mov.l @r15+,r12
  108. # define CDISABLE \
  109. mov.l r12,@-r15; \
  110. mov.l 1f,r12; \
  111. mova 1f,r0; \
  112. add r0,r12; \
  113. mov.l 2f,r0; \
  114. bsrf r0; \
  115. mov r2,r4; \
  116. 0: bra 3f; \
  117. nop; \
  118. .align 2; \
  119. 1: .long _GLOBAL_OFFSET_TABLE_; \
  120. 2: .long __local_disable_asynccancel@PLT - (0b-.); \
  121. 3: mov.l @r15+,r12
  122. # else
  123. # define CENABLE \
  124. mov.l 1f,r0; \
  125. bsrf r0; \
  126. nop; \
  127. 0: bra 2f; \
  128. mov r0,r2; \
  129. .align 2; \
  130. 1: .long __local_enable_asynccancel - 0b; \
  131. 2:
  132. # define CDISABLE \
  133. mov.l 1f,r0; \
  134. bsrf r0; \
  135. mov r2,r4; \
  136. 0: bra 2f; \
  137. nop; \
  138. .align 2; \
  139. 1: .long __local_disable_asynccancel - 0b; \
  140. 2:
  141. # endif
  142. # ifndef __ASSEMBLER__
  143. # if defined FLOATING_STACKS && defined __UCLIBC_HAS_TLS__ && defined __PIC__
  144. # define SINGLE_THREAD_P \
  145. __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
  146. # else
  147. extern int __local_multiple_threads attribute_hidden;
  148. # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
  149. # endif
  150. # else
  151. # if !defined __PIC__
  152. # define SINGLE_THREAD_P \
  153. mov.l 1f,r0; \
  154. mov.l @r0,r0; \
  155. bra 2f; \
  156. tst r0,r0; \
  157. .align 2; \
  158. 1: .long __local_multiple_threads; \
  159. 2:
  160. # elif defined FLOATING_STACKS && defined __UCLIBC_HAS_TLS__
  161. # define SINGLE_THREAD_P \
  162. stc gbr,r0; \
  163. mov.w 0f,r1; \
  164. sub r1,r0; \
  165. mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
  166. bra 1f; \
  167. tst r0,r0; \
  168. 0: .word TLS_PRE_TCB_SIZE; \
  169. 1:
  170. # else
  171. # if !defined NOT_IN_libc || defined IS_IN_libpthread
  172. # define SINGLE_THREAD_P \
  173. mov r12,r2; \
  174. mov.l 0f,r12; \
  175. mova 0f,r0; \
  176. add r0,r12; \
  177. mov.l 1f,r0; \
  178. mov.l @(r0,r12),r0; \
  179. mov r2,r12; \
  180. bra 2f; \
  181. tst r0,r0; \
  182. .align 2; \
  183. 0: .long _GLOBAL_OFFSET_TABLE_; \
  184. 1: .long __local_multiple_threads@GOTOFF; \
  185. 2:
  186. # else
  187. # define SINGLE_THREAD_P \
  188. mov r12,r2; \
  189. mov.l 0f,r12; \
  190. mova 0f,r0; \
  191. add r0,r12; \
  192. mov.l 1f,r0; \
  193. mov.l @(r0,r12),r0; \
  194. mov.l @r0,r0; \
  195. mov r2,r12; \
  196. bra 2f; \
  197. tst r0,r0; \
  198. .align 2; \
  199. 0: .long _GLOBAL_OFFSET_TABLE_; \
  200. 1: .long __local_multiple_threads@GOT; \
  201. 2:
  202. # endif
  203. # endif
  204. # endif
  205. #elif !defined __ASSEMBLER__
  206. /* This code should never be used but we define it anyhow. */
  207. # define SINGLE_THREAD_P (1)
  208. #endif