sysdep-cancel.h 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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, write to the Free
  13. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  14. 02111-1307 USA. */
  15. #include <sysdep.h>
  16. #include <tls.h>
  17. #include <pt-machine.h>
  18. #ifndef __ASSEMBLER__
  19. # include <linuxthreads/internals.h>
  20. #endif
  21. #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined IS_IN_librt
  22. # define _IMM12 #-12
  23. # define _IMM16 #-16
  24. # define _IMP16 #16
  25. # undef PSEUDO
  26. # define PSEUDO(name, syscall_name, args) \
  27. .text; \
  28. ENTRY (name); \
  29. SINGLE_THREAD_P; \
  30. bf .Lpseudo_cancel; \
  31. DO_CALL (syscall_name, args); \
  32. mov r0,r1; \
  33. mov _IMM12,r2; \
  34. shad r2,r1; \
  35. not r1,r1; \
  36. tst r1,r1; \
  37. bt .Lsyscall_error; \
  38. bra .Lpseudo_end; \
  39. nop; \
  40. .Lpseudo_cancel: \
  41. sts.l pr,@-r15; \
  42. add _IMM16,r15; \
  43. SAVE_ARGS_##args; \
  44. CENABLE; \
  45. LOAD_ARGS_##args; \
  46. add _IMP16,r15; \
  47. lds.l @r15+,pr; \
  48. DO_CALL(syscall_name, args); \
  49. SYSCALL_INST_PAD; \
  50. sts.l pr,@-r15; \
  51. mov.l r0,@-r15; \
  52. CDISABLE; \
  53. mov.l @r15+,r0; \
  54. lds.l @r15+,pr; \
  55. mov r0,r1; \
  56. mov _IMM12,r2; \
  57. shad r2,r1; \
  58. not r1,r1; \
  59. tst r1,r1; \
  60. bf .Lpseudo_end; \
  61. .Lsyscall_error: \
  62. SYSCALL_ERROR_HANDLER; \
  63. .Lpseudo_end:
  64. # undef PSEUDO_END
  65. # define PSEUDO_END(sym) \
  66. END (sym)
  67. # define SAVE_ARGS_0 /* Nothing. */
  68. # define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15)
  69. # define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15)
  70. # define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15)
  71. # define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15)
  72. # define SAVE_ARGS_5 SAVE_ARGS_4
  73. # define SAVE_ARGS_6 SAVE_ARGS_5
  74. # define LOAD_ARGS_0 /* Nothing. */
  75. # define LOAD_ARGS_1 LOAD_ARGS_0; mov.l @(0,r15),r4
  76. # define LOAD_ARGS_2 LOAD_ARGS_1; mov.l @(4,r15),r5
  77. # define LOAD_ARGS_3 LOAD_ARGS_2; mov.l @(8,r15),r6
  78. # define LOAD_ARGS_4 LOAD_ARGS_3; mov.l @(12,r15),r7
  79. # define LOAD_ARGS_5 LOAD_ARGS_4
  80. # define LOAD_ARGS_6 LOAD_ARGS_5
  81. # ifdef IS_IN_libpthread
  82. # define __local_enable_asynccancel __pthread_enable_asynccancel
  83. # define __local_disable_asynccancel __pthread_disable_asynccancel
  84. # define __local_multiple_threads __pthread_multiple_threads
  85. # elif !defined NOT_IN_libc
  86. # define __local_enable_asynccancel __libc_enable_asynccancel
  87. # define __local_disable_asynccancel __libc_disable_asynccancel
  88. # define __local_multiple_threads __libc_multiple_threads
  89. # else
  90. # define __local_enable_asynccancel __librt_enable_asynccancel
  91. # define __local_disable_asynccancel __librt_disable_asynccancel
  92. # define __local_multiple_threads __librt_multiple_threads
  93. # endif
  94. # if defined IS_IN_librt && defined __PIC__
  95. # define CENABLE \
  96. mov.l r12,@-r15; \
  97. mov.l 1f,r12; \
  98. mova 1f,r0; \
  99. add r0,r12; \
  100. mov.l 2f,r0; \
  101. bsrf r0; \
  102. nop; \
  103. 0: bra 3f; \
  104. mov r0,r2; \
  105. .align 2; \
  106. 1: .long _GLOBAL_OFFSET_TABLE_; \
  107. 2: .long __local_enable_asynccancel@PLT - (0b-.); \
  108. 3: mov.l @r15+,r12
  109. # define CDISABLE \
  110. mov.l r12,@-r15; \
  111. mov.l 1f,r12; \
  112. mova 1f,r0; \
  113. add r0,r12; \
  114. mov.l 2f,r0; \
  115. bsrf r0; \
  116. mov r2,r4; \
  117. 0: bra 3f; \
  118. nop; \
  119. .align 2; \
  120. 1: .long _GLOBAL_OFFSET_TABLE_; \
  121. 2: .long __local_disable_asynccancel@PLT - (0b-.); \
  122. 3: mov.l @r15+,r12
  123. # else
  124. # define CENABLE \
  125. mov.l 1f,r0; \
  126. bsrf r0; \
  127. nop; \
  128. 0: bra 2f; \
  129. mov r0,r2; \
  130. .align 2; \
  131. 1: .long __local_enable_asynccancel - 0b; \
  132. 2:
  133. # define CDISABLE \
  134. mov.l 1f,r0; \
  135. bsrf r0; \
  136. mov r2,r4; \
  137. 0: bra 2f; \
  138. nop; \
  139. .align 2; \
  140. 1: .long __local_disable_asynccancel - 0b; \
  141. 2:
  142. # endif
  143. # ifndef __ASSEMBLER__
  144. # if defined FLOATING_STACKS && USE___THREAD && defined __PIC__
  145. # define SINGLE_THREAD_P \
  146. __builtin_expect (THREAD_GETMEM (THREAD_SELF, p_multiple_threads) == 0, 1)
  147. # else
  148. extern int __local_multiple_threads attribute_hidden;
  149. # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
  150. # endif
  151. # else
  152. # if !defined __PIC__
  153. # define SINGLE_THREAD_P \
  154. mov.l 1f,r0; \
  155. mov.l @r0,r0; \
  156. bra 2f; \
  157. tst r0,r0; \
  158. .align 2; \
  159. 1: .long __local_multiple_threads; \
  160. 2:
  161. # elif defined FLOATING_STACKS && USE___THREAD
  162. # define SINGLE_THREAD_P \
  163. stc gbr,r0; \
  164. mov.w 0f,r1; \
  165. sub r1,r0; \
  166. mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
  167. bra 1f; \
  168. tst r0,r0; \
  169. 0: .word TLS_PRE_TCB_SIZE; \
  170. 1:
  171. # else
  172. # if !defined NOT_IN_libc || defined IS_IN_libpthread
  173. # define SINGLE_THREAD_P \
  174. mov r12,r2; \
  175. mov.l 0f,r12; \
  176. mova 0f,r0; \
  177. add r0,r12; \
  178. mov.l 1f,r0; \
  179. mov.l @(r0,r12),r0; \
  180. mov r2,r12; \
  181. bra 2f; \
  182. tst r0,r0; \
  183. .align 2; \
  184. 0: .long _GLOBAL_OFFSET_TABLE_; \
  185. 1: .long __local_multiple_threads@GOTOFF; \
  186. 2:
  187. # else
  188. # define SINGLE_THREAD_P \
  189. mov r12,r2; \
  190. mov.l 0f,r12; \
  191. mova 0f,r0; \
  192. add r0,r12; \
  193. mov.l 1f,r0; \
  194. mov.l @(r0,r12),r0; \
  195. mov.l @r0,r0; \
  196. mov r2,r12; \
  197. bra 2f; \
  198. tst r0,r0; \
  199. .align 2; \
  200. 0: .long _GLOBAL_OFFSET_TABLE_; \
  201. 1: .long __local_multiple_threads@GOT; \
  202. 2:
  203. # endif
  204. # endif
  205. # endif
  206. #elif !defined __ASSEMBLER__
  207. /* This code should never be used but we define it anyhow. */
  208. # define SINGLE_THREAD_P (1)
  209. #endif