sysdep-cancel.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /* cancellable system calls for Linux/HPPA.
  2. Copyright (C) 2003 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Carlos O'Donell <carlos@baldric.uwo.ca>, 2003.
  5. The GNU C Library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. The GNU C Library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with the GNU C Library; if not, write to the Free
  15. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  16. 02111-1307 USA. */
  17. #include <sysdep.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. # ifndef NO_ERROR
  23. # define NO_ERROR -0x1000
  24. # endif
  25. # undef PSEUDO
  26. # define PSEUDO(name, syscall_name, args) \
  27. ENTRY (name) \
  28. SINGLE_THREAD_P ASM_LINE_SEP \
  29. cmpib,<> 0,%ret0,Lpseudo_cancel ASM_LINE_SEP \
  30. nop ASM_LINE_SEP \
  31. DO_CALL(syscall_name, args) ASM_LINE_SEP \
  32. /* DONE! */ ASM_LINE_SEP \
  33. bv 0(2) ASM_LINE_SEP \
  34. nop ASM_LINE_SEP \
  35. Lpseudo_cancel: ASM_LINE_SEP \
  36. /* store return ptr */ ASM_LINE_SEP \
  37. stw %rp, -20(%sr0,%sp) ASM_LINE_SEP \
  38. /* save syscall args */ ASM_LINE_SEP \
  39. PUSHARGS_##args /* MACRO */ ASM_LINE_SEP \
  40. STW_PIC ASM_LINE_SEP \
  41. CENABLE /* FUNC CALL */ ASM_LINE_SEP \
  42. ldo 64(%sp), %sp ASM_LINE_SEP \
  43. ldo -64(%sp), %sp ASM_LINE_SEP \
  44. LDW_PIC ASM_LINE_SEP \
  45. /* restore syscall args */ ASM_LINE_SEP \
  46. POPARGS_##args ASM_LINE_SEP \
  47. /* save r4 in arg0 stack slot */ ASM_LINE_SEP \
  48. stw %r4, -36(%sr0,%sp) ASM_LINE_SEP \
  49. /* save mask from cenable */ ASM_LINE_SEP \
  50. copy %ret0, %r4 ASM_LINE_SEP \
  51. ble 0x100(%sr2,%r0) ASM_LINE_SEP \
  52. ldi SYS_ify (syscall_name), %r20 ASM_LINE_SEP \
  53. LDW_PIC ASM_LINE_SEP \
  54. /* pass mask as arg0 to cdisable */ ASM_LINE_SEP \
  55. copy %r4, %r26 ASM_LINE_SEP \
  56. copy %ret0, %r4 ASM_LINE_SEP \
  57. CDISABLE ASM_LINE_SEP \
  58. ldo 64(%sp), %sp ASM_LINE_SEP \
  59. ldo -64(%sp), %sp ASM_LINE_SEP \
  60. LDW_PIC ASM_LINE_SEP \
  61. /* compare error */ ASM_LINE_SEP \
  62. ldi NO_ERROR,%r1 ASM_LINE_SEP \
  63. /* branch if no error */ ASM_LINE_SEP \
  64. cmpb,>>=,n %r1,%r4,Lpre_end ASM_LINE_SEP \
  65. nop ASM_LINE_SEP \
  66. SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
  67. ldo 64(%sp), %sp ASM_LINE_SEP \
  68. ldo -64(%sp), %sp ASM_LINE_SEP \
  69. /* No need to LDW_PIC */ ASM_LINE_SEP \
  70. /* make syscall res value positive */ ASM_LINE_SEP \
  71. sub %r0, %r4, %r4 ASM_LINE_SEP \
  72. /* store into errno location */ ASM_LINE_SEP \
  73. stw %r4, 0(%sr0,%ret0) ASM_LINE_SEP \
  74. /* return -1 */ ASM_LINE_SEP \
  75. ldo -1(%r0), %ret0 ASM_LINE_SEP \
  76. Lpre_end: ASM_LINE_SEP \
  77. ldw -20(%sr0,%sp), %rp ASM_LINE_SEP \
  78. /* No need to LDW_PIC */ ASM_LINE_SEP \
  79. ldw -36(%sr0,%sp), %r4 ASM_LINE_SEP
  80. /* Save arguments into our frame */
  81. # define PUSHARGS_0 /* nothing to do */
  82. # define PUSHARGS_1 PUSHARGS_0 stw %r26, -36(%sr0,%sp) ASM_LINE_SEP
  83. # define PUSHARGS_2 PUSHARGS_1 stw %r25, -40(%sr0,%sp) ASM_LINE_SEP
  84. # define PUSHARGS_3 PUSHARGS_2 stw %r24, -44(%sr0,%sp) ASM_LINE_SEP
  85. # define PUSHARGS_4 PUSHARGS_3 stw %r23, -48(%sr0,%sp) ASM_LINE_SEP
  86. # define PUSHARGS_5 PUSHARGS_4 /* Args are on the stack... */
  87. # define PUSHARGS_6 PUSHARGS_5
  88. /* Bring them back from the stack */
  89. # define POPARGS_0 /* nothing to do */
  90. # define POPARGS_1 POPARGS_0 ldw -36(%sr0,%sp), %r26 ASM_LINE_SEP
  91. # define POPARGS_2 POPARGS_1 ldw -40(%sr0,%sp), %r25 ASM_LINE_SEP
  92. # define POPARGS_3 POPARGS_2 ldw -44(%sr0,%sp), %r24 ASM_LINE_SEP
  93. # define POPARGS_4 POPARGS_3 ldw -48(%sr0,%sp), %r23 ASM_LINE_SEP
  94. # define POPARGS_5 POPARGS_4 ldw -52(%sr0,%sp), %r22 ASM_LINE_SEP
  95. # define POPARGS_6 POPARGS_5 ldw -54(%sr0,%sp), %r21 ASM_LINE_SEP
  96. # ifdef IS_IN_libpthread
  97. # ifdef __PIC__
  98. # define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \
  99. bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP
  100. # define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \
  101. bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP
  102. # else
  103. # define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \
  104. bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP
  105. # define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \
  106. bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP
  107. # endif
  108. # elif !defined NOT_IN_libc
  109. # ifdef __PIC__
  110. # define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \
  111. bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP
  112. # define CDISABLE .import __libc_disable_asynccancel,code ASM_LINE_SEP \
  113. bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP
  114. # else
  115. # define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \
  116. bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP
  117. # define CDISABLE .import __libc_disable_asynccancel,code ASM_LINE_SEP \
  118. bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP
  119. # endif
  120. # else
  121. # ifdef __PIC__
  122. # define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \
  123. bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP
  124. # define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \
  125. bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP
  126. # else
  127. # define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \
  128. bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP
  129. # define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \
  130. bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP
  131. # endif
  132. # endif
  133. /* p_header.multiple_threads is +12 from the pthread_descr struct start,
  134. We could have called __get_cr27() but we really want less overhead */
  135. # define MULTIPLE_THREADS_OFFSET 0xC
  136. /* cr27 has been initialized to 0x0 by kernel */
  137. # define NO_THREAD_CR27 0x0
  138. # ifdef IS_IN_libpthread
  139. # define __local_multiple_threads __pthread_multiple_threads
  140. # elif !defined NOT_IN_libc
  141. # define __local_multiple_threads __libc_multiple_threads
  142. # else
  143. # define __local_multiple_threads __librt_multiple_threads
  144. # endif
  145. # ifndef __ASSEMBLER__
  146. extern int __local_multiple_threads attribute_hidden;
  147. # define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
  148. # else
  149. /* This ALT version requires newer kernel support */
  150. # define SINGLE_THREAD_P_MFCTL \
  151. mfctl %cr27, %ret0 ASM_LINE_SEP \
  152. cmpib,= NO_THREAD_CR27,%ret0,Lstp ASM_LINE_SEP \
  153. nop ASM_LINE_SEP \
  154. ldw MULTIPLE_THREADS_OFFSET(%sr0,%ret0),%ret0 ASM_LINE_SEP \
  155. Lstp: ASM_LINE_SEP
  156. # ifdef __PIC__
  157. /* Slower version uses GOT to get value of __local_multiple_threads */
  158. # define SINGLE_THREAD_P \
  159. addil LT%__local_multiple_threads, %r19 ASM_LINE_SEP \
  160. ldw RT%__local_multiple_threads(%sr0,%r1), %ret0 ASM_LINE_SEP \
  161. ldw 0(%sr0,%ret0), %ret0 ASM_LINE_SEP
  162. # else
  163. /* Slow non-pic version using DP */
  164. # define SINGLE_THREAD_P \
  165. addil LR%__local_multiple_threads-$global$,%r27 ASM_LINE_SEP \
  166. ldw RR%__local_multiple_threads-$global$(%sr0,%r1),%ret0 ASM_LINE_SEP
  167. # endif
  168. # endif
  169. #elif !defined __ASSEMBLER__
  170. /* This code should never be used but we define it anyhow. */
  171. # define SINGLE_THREAD_P (1)
  172. #endif
  173. /* !defined NOT_IN_libc || defined IS_IN_libpthread */