sysdep-cancel.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /* Copyright (C) 2003, 2004, 2005, 2006 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 <tls.h>
  16. #include <sysdep.h>
  17. #ifndef __ASSEMBLER__
  18. # include <pthreadP.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. .Lpseudo_start: \
  29. SINGLE_THREAD_P; \
  30. bf .Lpseudo_cancel; \
  31. .type __##syscall_name##_nocancel,@function; \
  32. .globl __##syscall_name##_nocancel; \
  33. __##syscall_name##_nocancel: \
  34. DO_CALL (syscall_name, args); \
  35. mov r0,r1; \
  36. mov _IMM12,r2; \
  37. shad r2,r1; \
  38. not r1,r1; \
  39. tst r1,r1; \
  40. bt .Lsyscall_error; \
  41. bra .Lpseudo_end; \
  42. nop; \
  43. .size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
  44. .Lpseudo_cancel: \
  45. sts.l pr,@-r15; \
  46. cfi_adjust_cfa_offset (4); \
  47. cfi_rel_offset (pr, 0); \
  48. add _IMM16,r15; \
  49. cfi_adjust_cfa_offset (16); \
  50. SAVE_ARGS_##args; \
  51. CENABLE; \
  52. LOAD_ARGS_##args; \
  53. add _IMP16,r15; \
  54. cfi_adjust_cfa_offset (-16); \
  55. lds.l @r15+,pr; \
  56. cfi_adjust_cfa_offset (-4); \
  57. cfi_restore (pr); \
  58. DO_CALL(syscall_name, args); \
  59. SYSCALL_INST_PAD; \
  60. sts.l pr,@-r15; \
  61. cfi_adjust_cfa_offset (4); \
  62. cfi_rel_offset (pr, 0); \
  63. mov.l r0,@-r15; \
  64. cfi_adjust_cfa_offset (4); \
  65. cfi_rel_offset (r0, 0); \
  66. CDISABLE; \
  67. mov.l @r15+,r0; \
  68. cfi_adjust_cfa_offset (-4); \
  69. lds.l @r15+,pr; \
  70. cfi_adjust_cfa_offset (-4); \
  71. cfi_restore (pr); \
  72. mov r0,r1; \
  73. mov _IMM12,r2; \
  74. shad r2,r1; \
  75. not r1,r1; \
  76. tst r1,r1; \
  77. bf .Lpseudo_end; \
  78. .Lsyscall_error: \
  79. SYSCALL_ERROR_HANDLER; \
  80. .Lpseudo_end:
  81. # undef PSEUDO_END
  82. # define PSEUDO_END(sym) \
  83. END (sym)
  84. # define SAVE_ARGS_0 /* Nothing. */
  85. # define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15); cfi_offset (r4,-4)
  86. # define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15); cfi_offset (r5,-8)
  87. # define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15); cfi_offset (r6,-12)
  88. # define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15); cfi_offset (r7,-16)
  89. # define SAVE_ARGS_5 SAVE_ARGS_4
  90. # define SAVE_ARGS_6 SAVE_ARGS_5
  91. # define LOAD_ARGS_0 /* Nothing. */
  92. # define LOAD_ARGS_1 LOAD_ARGS_0; mov.l @(0,r15),r4
  93. # define LOAD_ARGS_2 LOAD_ARGS_1; mov.l @(4,r15),r5
  94. # define LOAD_ARGS_3 LOAD_ARGS_2; mov.l @(8,r15),r6
  95. # define LOAD_ARGS_4 LOAD_ARGS_3; mov.l @(12,r15),r7
  96. # define LOAD_ARGS_5 LOAD_ARGS_4
  97. # define LOAD_ARGS_6 LOAD_ARGS_5
  98. # ifdef IS_IN_libpthread
  99. # define __local_enable_asynccancel __pthread_enable_asynccancel
  100. # define __local_disable_asynccancel __pthread_disable_asynccancel
  101. # elif !defined NOT_IN_libc
  102. # define __local_enable_asynccancel __libc_enable_asynccancel
  103. # define __local_disable_asynccancel __libc_disable_asynccancel
  104. # elif defined IS_IN_librt
  105. # define __local_enable_asynccancel __librt_enable_asynccancel
  106. # define __local_disable_asynccancel __librt_disable_asynccancel
  107. # else
  108. # error Unsupported library
  109. # endif
  110. # define CENABLE \
  111. mov.l 1f,r0; \
  112. bsrf r0; \
  113. nop; \
  114. 0: bra 2f; \
  115. mov r0,r2; \
  116. .align 2; \
  117. 1: .long __local_enable_asynccancel - 0b; \
  118. 2:
  119. # define CDISABLE \
  120. mov.l 1f,r0; \
  121. bsrf r0; \
  122. mov r2,r4; \
  123. 0: bra 2f; \
  124. nop; \
  125. .align 2; \
  126. 1: .long __local_disable_asynccancel - 0b; \
  127. 2:
  128. # ifndef __ASSEMBLER__
  129. # define SINGLE_THREAD_P \
  130. __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
  131. header.multiple_threads) == 0, 1)
  132. # else
  133. # define SINGLE_THREAD_P \
  134. stc gbr,r0; \
  135. mov.w 0f,r1; \
  136. sub r1,r0; \
  137. mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
  138. bra 1f; \
  139. tst r0,r0; \
  140. 0: .word TLS_PRE_TCB_SIZE; \
  141. 1:
  142. # endif
  143. #elif !defined __ASSEMBLER__
  144. # define SINGLE_THREAD_P (1)
  145. # define NO_CANCELLATION 1
  146. #endif
  147. #ifndef __ASSEMBLER__
  148. # define RTLD_SINGLE_THREAD_P \
  149. __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
  150. header.multiple_threads) == 0, 1)
  151. #endif