syscalls.h 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /* Copyright (C) 1992, 1995, 1996, 2000, 2003, 2004, 2006
  2. Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. Contributed by Brendan Kehoe (brendan@zen.org).
  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. #ifndef _BITS_SYSCALLS_H
  18. #define _BITS_SYSCALLS_H
  19. #ifndef _SYSCALL_H
  20. # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
  21. #endif
  22. #ifndef __ASSEMBLER__
  23. #define INLINE_SYSCALL_NCS(name, nr, args...) \
  24. (__extension__ \
  25. ({ \
  26. long _sc_ret, _sc_err; \
  27. inline_syscall##nr(name, args); \
  28. if (unlikely (_sc_err)) \
  29. { \
  30. __set_errno (_sc_ret); \
  31. _sc_ret = -1L; \
  32. } \
  33. _sc_ret; \
  34. }) \
  35. )
  36. #define INTERNAL_SYSCALL_NCS(name, err_out, nr, args...) \
  37. (__extension__ \
  38. ({ \
  39. long _sc_ret, _sc_err; \
  40. inline_syscall##nr(name, args); \
  41. err_out = _sc_err; \
  42. _sc_ret; \
  43. }) \
  44. )
  45. #define INTERNAL_SYSCALL_DECL(err) long int err
  46. #define INTERNAL_SYSCALL_ERROR_P(val, err) err
  47. #define INTERNAL_SYSCALL_ERRNO(val, err) val
  48. #define inline_syscall_clobbers \
  49. "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \
  50. "$22", "$23", "$24", "$25", "$27", "$28", "memory"
  51. /* If TLS is in use, we have a conflict between the PAL_rduniq primitive,
  52. as modeled within GCC, and explicit use of the R0 register. If we use
  53. the register via the asm, the scheduler may place the PAL_rduniq insn
  54. before we've copied the data from R0 into _sc_ret. If this happens
  55. we'll get a reload abort, since R0 is live at the same time it is
  56. needed for the PAL_rduniq.
  57. Solve this by using the "v" constraint instead of an asm for the syscall
  58. output. We don't do this unconditionally to allow compilation with
  59. older compilers. */
  60. #ifdef HAVE___THREAD
  61. #define inline_syscall_r0_asm
  62. #define inline_syscall_r0_out_constraint "=v"
  63. #else
  64. #define inline_syscall_r0_asm __asm__("$0")
  65. #define inline_syscall_r0_out_constraint "=r"
  66. #endif
  67. /* It is moderately important optimization-wise to limit the lifetime
  68. of the hard-register variables as much as possible. Thus we copy
  69. in/out as close to the asm as possible. */
  70. #define inline_syscall0(name, args...) \
  71. { \
  72. register long _sc_0 inline_syscall_r0_asm; \
  73. register long _sc_19 __asm__("$19"); \
  74. \
  75. _sc_0 = name; \
  76. __asm__ __volatile__ \
  77. ("callsys # %0 %1 <= %2" \
  78. : inline_syscall_r0_out_constraint (_sc_0), \
  79. "=r"(_sc_19) \
  80. : "0"(_sc_0) \
  81. : inline_syscall_clobbers, \
  82. "$16", "$17", "$18", "$20", "$21"); \
  83. _sc_ret = _sc_0, _sc_err = _sc_19; \
  84. }
  85. #define inline_syscall1(name,arg1) \
  86. { \
  87. register long _sc_0 inline_syscall_r0_asm; \
  88. register long _sc_16 __asm__("$16"); \
  89. register long _sc_19 __asm__("$19"); \
  90. register long _tmp_16 = (long) (arg1); \
  91. \
  92. _sc_0 = name; \
  93. _sc_16 = _tmp_16; \
  94. __asm__ __volatile__ \
  95. ("callsys # %0 %1 <= %2 %3" \
  96. : inline_syscall_r0_out_constraint (_sc_0), \
  97. "=r"(_sc_19), "=r"(_sc_16) \
  98. : "0"(_sc_0), "2"(_sc_16) \
  99. : inline_syscall_clobbers, \
  100. "$17", "$18", "$20", "$21"); \
  101. _sc_ret = _sc_0, _sc_err = _sc_19; \
  102. }
  103. #define inline_syscall2(name,arg1,arg2) \
  104. { \
  105. register long _sc_0 inline_syscall_r0_asm; \
  106. register long _sc_16 __asm__("$16"); \
  107. register long _sc_17 __asm__("$17"); \
  108. register long _sc_19 __asm__("$19"); \
  109. register long _tmp_16 = (long) (arg1); \
  110. register long _tmp_17 = (long) (arg2); \
  111. \
  112. _sc_0 = name; \
  113. _sc_16 = _tmp_16; \
  114. _sc_17 = _tmp_17; \
  115. __asm__ __volatile__ \
  116. ("callsys # %0 %1 <= %2 %3 %4" \
  117. : inline_syscall_r0_out_constraint (_sc_0), \
  118. "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17) \
  119. : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17) \
  120. : inline_syscall_clobbers, \
  121. "$18", "$20", "$21"); \
  122. _sc_ret = _sc_0, _sc_err = _sc_19; \
  123. }
  124. #define inline_syscall3(name,arg1,arg2,arg3) \
  125. { \
  126. register long _sc_0 inline_syscall_r0_asm; \
  127. register long _sc_16 __asm__("$16"); \
  128. register long _sc_17 __asm__("$17"); \
  129. register long _sc_18 __asm__("$18"); \
  130. register long _sc_19 __asm__("$19"); \
  131. register long _tmp_16 = (long) (arg1); \
  132. register long _tmp_17 = (long) (arg2); \
  133. register long _tmp_18 = (long) (arg3); \
  134. \
  135. _sc_0 = name; \
  136. _sc_16 = _tmp_16; \
  137. _sc_17 = _tmp_17; \
  138. _sc_18 = _tmp_18; \
  139. __asm__ __volatile__ \
  140. ("callsys # %0 %1 <= %2 %3 %4 %5" \
  141. : inline_syscall_r0_out_constraint (_sc_0), \
  142. "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
  143. "=r"(_sc_18) \
  144. : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \
  145. "4"(_sc_18) \
  146. : inline_syscall_clobbers, "$20", "$21"); \
  147. _sc_ret = _sc_0, _sc_err = _sc_19; \
  148. }
  149. #define inline_syscall4(name,arg1,arg2,arg3,arg4) \
  150. { \
  151. register long _sc_0 inline_syscall_r0_asm; \
  152. register long _sc_16 __asm__("$16"); \
  153. register long _sc_17 __asm__("$17"); \
  154. register long _sc_18 __asm__("$18"); \
  155. register long _sc_19 __asm__("$19"); \
  156. register long _tmp_16 = (long) (arg1); \
  157. register long _tmp_17 = (long) (arg2); \
  158. register long _tmp_18 = (long) (arg3); \
  159. register long _tmp_19 = (long) (arg4); \
  160. \
  161. _sc_0 = name; \
  162. _sc_16 = _tmp_16; \
  163. _sc_17 = _tmp_17; \
  164. _sc_18 = _tmp_18; \
  165. _sc_19 = _tmp_19; \
  166. __asm__ __volatile__ \
  167. ("callsys # %0 %1 <= %2 %3 %4 %5 %6" \
  168. : inline_syscall_r0_out_constraint (_sc_0), \
  169. "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
  170. "=r"(_sc_18) \
  171. : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \
  172. "4"(_sc_18), "1"(_sc_19) \
  173. : inline_syscall_clobbers, "$20", "$21"); \
  174. _sc_ret = _sc_0, _sc_err = _sc_19; \
  175. }
  176. #define inline_syscall5(name,arg1,arg2,arg3,arg4,arg5) \
  177. { \
  178. register long _sc_0 inline_syscall_r0_asm; \
  179. register long _sc_16 __asm__("$16"); \
  180. register long _sc_17 __asm__("$17"); \
  181. register long _sc_18 __asm__("$18"); \
  182. register long _sc_19 __asm__("$19"); \
  183. register long _sc_20 __asm__("$20"); \
  184. register long _tmp_16 = (long) (arg1); \
  185. register long _tmp_17 = (long) (arg2); \
  186. register long _tmp_18 = (long) (arg3); \
  187. register long _tmp_19 = (long) (arg4); \
  188. register long _tmp_20 = (long) (arg5); \
  189. \
  190. _sc_0 = name; \
  191. _sc_16 = _tmp_16; \
  192. _sc_17 = _tmp_17; \
  193. _sc_18 = _tmp_18; \
  194. _sc_19 = _tmp_19; \
  195. _sc_20 = _tmp_20; \
  196. __asm__ __volatile__ \
  197. ("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7" \
  198. : inline_syscall_r0_out_constraint (_sc_0), \
  199. "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
  200. "=r"(_sc_18), "=r"(_sc_20) \
  201. : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), \
  202. "4"(_sc_18), "1"(_sc_19), "5"(_sc_20) \
  203. : inline_syscall_clobbers, "$21"); \
  204. _sc_ret = _sc_0, _sc_err = _sc_19; \
  205. }
  206. #define inline_syscall6(name,arg1,arg2,arg3,arg4,arg5,arg6) \
  207. { \
  208. register long _sc_0 inline_syscall_r0_asm; \
  209. register long _sc_16 __asm__("$16"); \
  210. register long _sc_17 __asm__("$17"); \
  211. register long _sc_18 __asm__("$18"); \
  212. register long _sc_19 __asm__("$19"); \
  213. register long _sc_20 __asm__("$20"); \
  214. register long _sc_21 __asm__("$21"); \
  215. register long _tmp_16 = (long) (arg1); \
  216. register long _tmp_17 = (long) (arg2); \
  217. register long _tmp_18 = (long) (arg3); \
  218. register long _tmp_19 = (long) (arg4); \
  219. register long _tmp_20 = (long) (arg5); \
  220. register long _tmp_21 = (long) (arg6); \
  221. \
  222. _sc_0 = name; \
  223. _sc_16 = _tmp_16; \
  224. _sc_17 = _tmp_17; \
  225. _sc_18 = _tmp_18; \
  226. _sc_19 = _tmp_19; \
  227. _sc_20 = _tmp_20; \
  228. _sc_21 = _tmp_21; \
  229. __asm__ __volatile__ \
  230. ("callsys # %0 %1 <= %2 %3 %4 %5 %6 %7 %8" \
  231. : inline_syscall_r0_out_constraint (_sc_0), \
  232. "=r"(_sc_19), "=r"(_sc_16), "=r"(_sc_17), \
  233. "=r"(_sc_18), "=r"(_sc_20), "=r"(_sc_21) \
  234. : "0"(_sc_0), "2"(_sc_16), "3"(_sc_17), "4"(_sc_18), \
  235. "1"(_sc_19), "5"(_sc_20), "6"(_sc_21) \
  236. : inline_syscall_clobbers); \
  237. _sc_ret = _sc_0, _sc_err = _sc_19; \
  238. }
  239. #endif /* __ASSEMBLER__ */
  240. #endif /* _BITS_SYSCALLS_H */