sysdep-cancel.h 4.6 KB

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