sysdep.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. /* Copyright (C) 2000, 2002, 2003, 2004, 2005 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. #ifndef _LINUX_MIPS_MIPS32_SYSDEP_H
  16. #define _LINUX_MIPS_MIPS32_SYSDEP_H 1
  17. #include <sys/syscall.h>
  18. /* There is some commonality. */
  19. #include <sysdeps/mips/sysdep.h>
  20. /* For Linux we can use the system call table in the header file
  21. /usr/include/asm/unistd.h
  22. of the kernel. But these symbols do not follow the SYS_* syntax
  23. so we have to redefine the `SYS_ify' macro here. */
  24. #undef SYS_ify
  25. #ifdef __STDC__
  26. # define SYS_ify(syscall_name) __NR_##syscall_name
  27. #else
  28. # define SYS_ify(syscall_name) __NR_/**/syscall_name
  29. #endif
  30. #ifdef __ASSEMBLER__
  31. /* We don't want the label for the error handler to be visible in the symbol
  32. table when we define it here. */
  33. #ifdef __PIC__
  34. # define SYSCALL_ERROR_LABEL 99b
  35. #endif
  36. #else /* ! __ASSEMBLER__ */
  37. /* Define a macro which expands into the inline wrapper code for a system
  38. call. */
  39. #undef INLINE_SYSCALL
  40. #define INLINE_SYSCALL(name, nr, args...) \
  41. ({ INTERNAL_SYSCALL_DECL(err); \
  42. long result_var = INTERNAL_SYSCALL (name, err, nr, args); \
  43. if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \
  44. { \
  45. __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \
  46. result_var = -1L; \
  47. } \
  48. result_var; })
  49. #undef INTERNAL_SYSCALL_DECL
  50. #define INTERNAL_SYSCALL_DECL(err) long err
  51. #undef INTERNAL_SYSCALL_ERROR_P
  52. #define INTERNAL_SYSCALL_ERROR_P(val, err) ((long) (err))
  53. #undef INTERNAL_SYSCALL_ERRNO
  54. #define INTERNAL_SYSCALL_ERRNO(val, err) (val)
  55. #undef INTERNAL_SYSCALL
  56. #define INTERNAL_SYSCALL(name, err, nr, args...) \
  57. internal_syscall##nr (, "li\t$2, %2\t\t\t# " #name "\n\t", \
  58. "i" (SYS_ify (name)), err, args)
  59. #undef INTERNAL_SYSCALL_NCS
  60. #define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
  61. internal_syscall##nr (= number, , "r" (__v0), err, args)
  62. #undef internal_syscall0
  63. #define internal_syscall0(ncs_init, cs_init, input, err, dummy...) \
  64. ({ \
  65. long _sys_result; \
  66. \
  67. { \
  68. register long __v0 __asm__("$2") ncs_init; \
  69. register long __a3 __asm__("$7"); \
  70. __asm__ volatile ( \
  71. ".set\tnoreorder\n\t" \
  72. cs_init \
  73. "syscall\n\t" \
  74. ".set reorder" \
  75. : "=r" (__v0), "=r" (__a3) \
  76. : input \
  77. : __SYSCALL_CLOBBERS); \
  78. err = __a3; \
  79. _sys_result = __v0; \
  80. } \
  81. _sys_result; \
  82. })
  83. #undef internal_syscall1
  84. #define internal_syscall1(ncs_init, cs_init, input, err, arg1) \
  85. ({ \
  86. long _sys_result; \
  87. \
  88. { \
  89. register long __v0 __asm__("$2") ncs_init; \
  90. register long __a0 __asm__("$4") = (long) arg1; \
  91. register long __a3 __asm__("$7"); \
  92. __asm__ volatile ( \
  93. ".set\tnoreorder\n\t" \
  94. cs_init \
  95. "syscall\n\t" \
  96. ".set reorder" \
  97. : "=r" (__v0), "=r" (__a3) \
  98. : input, "r" (__a0) \
  99. : __SYSCALL_CLOBBERS); \
  100. err = __a3; \
  101. _sys_result = __v0; \
  102. } \
  103. _sys_result; \
  104. })
  105. #undef internal_syscall2
  106. #define internal_syscall2(ncs_init, cs_init, input, err, arg1, arg2) \
  107. ({ \
  108. long _sys_result; \
  109. \
  110. { \
  111. register long __v0 __asm__("$2") ncs_init; \
  112. register long __a0 __asm__("$4") = (long) arg1; \
  113. register long __a1 __asm__("$5") = (long) arg2; \
  114. register long __a3 __asm__("$7"); \
  115. __asm__ volatile ( \
  116. ".set\tnoreorder\n\t" \
  117. cs_init \
  118. "syscall\n\t" \
  119. ".set\treorder" \
  120. : "=r" (__v0), "=r" (__a3) \
  121. : input, "r" (__a0), "r" (__a1) \
  122. : __SYSCALL_CLOBBERS); \
  123. err = __a3; \
  124. _sys_result = __v0; \
  125. } \
  126. _sys_result; \
  127. })
  128. #undef internal_syscall3
  129. #define internal_syscall3(ncs_init, cs_init, input, err, arg1, arg2, arg3)\
  130. ({ \
  131. long _sys_result; \
  132. \
  133. { \
  134. register long __v0 __asm__("$2") ncs_init; \
  135. register long __a0 __asm__("$4") = (long) arg1; \
  136. register long __a1 __asm__("$5") = (long) arg2; \
  137. register long __a2 __asm__("$6") = (long) arg3; \
  138. register long __a3 __asm__("$7"); \
  139. __asm__ volatile ( \
  140. ".set\tnoreorder\n\t" \
  141. cs_init \
  142. "syscall\n\t" \
  143. ".set\treorder" \
  144. : "=r" (__v0), "=r" (__a3) \
  145. : input, "r" (__a0), "r" (__a1), "r" (__a2) \
  146. : __SYSCALL_CLOBBERS); \
  147. err = __a3; \
  148. _sys_result = __v0; \
  149. } \
  150. _sys_result; \
  151. })
  152. #undef internal_syscall4
  153. #define internal_syscall4(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4)\
  154. ({ \
  155. long _sys_result; \
  156. \
  157. { \
  158. register long __v0 __asm__("$2") ncs_init; \
  159. register long __a0 __asm__("$4") = (long) arg1; \
  160. register long __a1 __asm__("$5") = (long) arg2; \
  161. register long __a2 __asm__("$6") = (long) arg3; \
  162. register long __a3 __asm__("$7") = (long) arg4; \
  163. __asm__ volatile ( \
  164. ".set\tnoreorder\n\t" \
  165. cs_init \
  166. "syscall\n\t" \
  167. ".set\treorder" \
  168. : "=r" (__v0), "+r" (__a3) \
  169. : input, "r" (__a0), "r" (__a1), "r" (__a2) \
  170. : __SYSCALL_CLOBBERS); \
  171. err = __a3; \
  172. _sys_result = __v0; \
  173. } \
  174. _sys_result; \
  175. })
  176. /* We need to use a frame pointer for the functions in which we
  177. adjust $sp around the syscall, or debug information and unwind
  178. information will be $sp relative and thus wrong during the syscall. As
  179. of GCC 3.4.3, this is sufficient. */
  180. #define FORCE_FRAME_POINTER alloca (4)
  181. #undef internal_syscall5
  182. #define internal_syscall5(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5)\
  183. ({ \
  184. long _sys_result; \
  185. \
  186. FORCE_FRAME_POINTER; \
  187. { \
  188. register long __v0 __asm__("$2") ncs_init; \
  189. register long __a0 __asm__("$4") = (long) arg1; \
  190. register long __a1 __asm__("$5") = (long) arg2; \
  191. register long __a2 __asm__("$6") = (long) arg3; \
  192. register long __a3 __asm__("$7") = (long) arg4; \
  193. __asm__ volatile ( \
  194. ".set\tnoreorder\n\t" \
  195. "subu\t$29, 32\n\t" \
  196. "sw\t%6, 16($29)\n\t" \
  197. cs_init \
  198. "syscall\n\t" \
  199. "addiu\t$29, 32\n\t" \
  200. ".set\treorder" \
  201. : "=r" (__v0), "+r" (__a3) \
  202. : input, "r" (__a0), "r" (__a1), "r" (__a2), \
  203. "r" ((long)arg5) \
  204. : __SYSCALL_CLOBBERS); \
  205. err = __a3; \
  206. _sys_result = __v0; \
  207. } \
  208. _sys_result; \
  209. })
  210. #undef internal_syscall6
  211. #define internal_syscall6(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6)\
  212. ({ \
  213. long _sys_result; \
  214. \
  215. FORCE_FRAME_POINTER; \
  216. { \
  217. register long __v0 __asm__("$2") ncs_init; \
  218. register long __a0 __asm__("$4") = (long) arg1; \
  219. register long __a1 __asm__("$5") = (long) arg2; \
  220. register long __a2 __asm__("$6") = (long) arg3; \
  221. register long __a3 __asm__("$7") = (long) arg4; \
  222. __asm__ volatile ( \
  223. ".set\tnoreorder\n\t" \
  224. "subu\t$29, 32\n\t" \
  225. "sw\t%6, 16($29)\n\t" \
  226. "sw\t%7, 20($29)\n\t" \
  227. cs_init \
  228. "syscall\n\t" \
  229. "addiu\t$29, 32\n\t" \
  230. ".set\treorder" \
  231. : "=r" (__v0), "+r" (__a3) \
  232. : input, "r" (__a0), "r" (__a1), "r" (__a2), \
  233. "r" ((long)arg5), "r" ((long)arg6) \
  234. : __SYSCALL_CLOBBERS); \
  235. err = __a3; \
  236. _sys_result = __v0; \
  237. } \
  238. _sys_result; \
  239. })
  240. #undef internal_syscall7
  241. #define internal_syscall7(ncs_init, cs_init, input, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
  242. ({ \
  243. long _sys_result; \
  244. \
  245. FORCE_FRAME_POINTER; \
  246. { \
  247. register long __v0 __asm__("$2") ncs_init; \
  248. register long __a0 __asm__("$4") = (long) arg1; \
  249. register long __a1 __asm__("$5") = (long) arg2; \
  250. register long __a2 __asm__("$6") = (long) arg3; \
  251. register long __a3 __asm__("$7") = (long) arg4; \
  252. __asm__ volatile ( \
  253. ".set\tnoreorder\n\t" \
  254. "subu\t$29, 32\n\t" \
  255. "sw\t%6, 16($29)\n\t" \
  256. "sw\t%7, 20($29)\n\t" \
  257. "sw\t%8, 24($29)\n\t" \
  258. cs_init \
  259. "syscall\n\t" \
  260. "addiu\t$29, 32\n\t" \
  261. ".set\treorder" \
  262. : "=r" (__v0), "+r" (__a3) \
  263. : input, "r" (__a0), "r" (__a1), "r" (__a2), \
  264. "r" ((long)arg5), "r" ((long)arg6), "r" ((long)arg7) \
  265. : __SYSCALL_CLOBBERS); \
  266. err = __a3; \
  267. _sys_result = __v0; \
  268. } \
  269. _sys_result; \
  270. })
  271. #undef __SYSCALL_CLOBBERS
  272. #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
  273. "$14", "$15", "$24", "$25", "memory"
  274. #endif /* __ASSEMBLER__ */
  275. #endif /* sysdeps/unix/sysv/linux/mips/sysdep.h */