syscalls.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #ifndef _BITS_SYSCALLS_H
  2. #define _BITS_SYSCALLS_H
  3. #ifndef _SYSCALL_H
  4. # error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
  5. #endif
  6. #include <errno.h>
  7. /* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
  8. * header files. It also defines the traditional `SYS_<name>' macros for older
  9. * programs. */
  10. #include <bits/sysnum.h>
  11. #ifndef __ASSEMBLER__
  12. /* Linux takes system call arguments in registers:
  13. syscall number %d0 call-clobbered
  14. arg 1 %d1 call-clobbered
  15. arg 2 %d2 call-saved
  16. arg 3 %d3 call-saved
  17. arg 4 %d4 call-saved
  18. arg 5 %d5 call-saved
  19. The stack layout upon entering the function is:
  20. 20(%sp) Arg# 5
  21. 16(%sp) Arg# 4
  22. 12(%sp) Arg# 3
  23. 8(%sp) Arg# 2
  24. 4(%sp) Arg# 1
  25. (%sp) Return address
  26. (Of course a function with say 3 arguments does not have entries for
  27. arguments 4 and 5.)
  28. Separate move's are faster than movem, but need more space. Since
  29. speed is more important, we don't use movem. Since %a0 and %a1 are
  30. scratch registers, we can use them for saving as well. */
  31. #define __syscall_return(type, res) \
  32. do { \
  33. if ((unsigned long)(res) >= (unsigned long)(-125)) { \
  34. /* avoid using res which is declared to be in register d0; \
  35. errno might expand to a function call and clobber it. */ \
  36. int __err = -(res); \
  37. __set_errno(__err); \
  38. res = -1; \
  39. } \
  40. return (type) (res); \
  41. } while (0)
  42. #define _syscall0(type, name) \
  43. type name(void) \
  44. { \
  45. long __res; \
  46. __asm__ __volatile__ ( \
  47. "movel %1, %%d0\n\t" \
  48. "trap #0\n\t" \
  49. "movel %%d0, %0" \
  50. : "=g" (__res) \
  51. : "i" (__NR_##name) \
  52. : "cc", "%d0"); \
  53. __syscall_return(type, __res); \
  54. }
  55. #define _syscall1(type, name, atype, a) \
  56. type name(atype a) \
  57. { \
  58. long __res; \
  59. __asm__ __volatile__ ( \
  60. "movel %2, %%d1\n\t" \
  61. "movel %1, %%d0\n\t" \
  62. "trap #0\n\t" \
  63. "movel %%d0, %0" \
  64. : "=g" (__res) \
  65. : "i" (__NR_##name), \
  66. "g" ((long)a) \
  67. : "cc", "%d0", "%d1"); \
  68. __syscall_return(type, __res); \
  69. }
  70. #define _syscall2(type, name, atype, a, btype, b) \
  71. type name(atype a, btype b) \
  72. { \
  73. long __res; \
  74. __asm__ __volatile__ ( \
  75. "movel %3, %%d2\n\t" \
  76. "movel %2, %%d1\n\t" \
  77. "movel %1, %%d0\n\t" \
  78. "trap #0\n\t" \
  79. "movel %%d0, %0" \
  80. : "=g" (__res) \
  81. : "i" (__NR_##name), \
  82. "a" ((long)a), \
  83. "g" ((long)b) \
  84. : "cc", "%d0", "%d1", "%d2"); \
  85. __syscall_return(type, __res); \
  86. }
  87. #define _syscall3(type, name, atype, a, btype, b, ctype, c) \
  88. type name(atype a, btype b, ctype c) \
  89. { \
  90. long __res; \
  91. __asm__ __volatile__ ( \
  92. "movel %4, %%d3\n\t" \
  93. "movel %3, %%d2\n\t" \
  94. "movel %2, %%d1\n\t" \
  95. "movel %1, %%d0\n\t" \
  96. "trap #0\n\t" \
  97. "movel %%d0, %0" \
  98. : "=g" (__res) \
  99. : "i" (__NR_##name), \
  100. "a" ((long)a), \
  101. "a" ((long)b), \
  102. "g" ((long)c) \
  103. : "cc", "%d0", "%d1", "%d2", "%d3"); \
  104. __syscall_return(type, __res); \
  105. }
  106. #define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \
  107. type name(atype a, btype b, ctype c, dtype d) \
  108. { \
  109. long __res; \
  110. __asm__ __volatile__ ( \
  111. "movel %5, %%d4\n\t" \
  112. "movel %4, %%d3\n\t" \
  113. "movel %3, %%d2\n\t" \
  114. "movel %2, %%d1\n\t" \
  115. "movel %1, %%d0\n\t" \
  116. "trap #0\n\t" \
  117. "movel %%d0, %0" \
  118. : "=g" (__res) \
  119. : "i" (__NR_##name), \
  120. "a" ((long)a), \
  121. "a" ((long)b), \
  122. "a" ((long)c), \
  123. "g" ((long)d) \
  124. : "cc", "%d0", "%d1", "%d2", "%d3", \
  125. "%d4"); \
  126. __syscall_return(type, __res); \
  127. }
  128. #define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e) \
  129. type name(atype a, btype b, ctype c, dtype d, etype e) \
  130. { \
  131. long __res; \
  132. __asm__ __volatile__ ( \
  133. "movel %6, %%d5\n\t" \
  134. "movel %5, %%d4\n\t" \
  135. "movel %4, %%d3\n\t" \
  136. "movel %3, %%d2\n\t" \
  137. "movel %2, %%d1\n\t" \
  138. "movel %1, %%d0\n\t" \
  139. "trap #0\n\t" \
  140. "movel %%d0, %0" \
  141. : "=g" (__res) \
  142. : "i" (__NR_##name), \
  143. "a" ((long)a), \
  144. "a" ((long)b), \
  145. "a" ((long)c), \
  146. "a" ((long)d), \
  147. "g" ((long)e) \
  148. : "cc", "%d0", "%d1", "%d2", "%d3", \
  149. "%d4", "%d5"); \
  150. __syscall_return(type, __res); \
  151. }
  152. #define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \
  153. type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \
  154. { \
  155. long __res; \
  156. __asm__ __volatile__ ( \
  157. "movel %7, %%a0\n\t" \
  158. "movel %6, %%d5\n\t" \
  159. "movel %5, %%d4\n\t" \
  160. "movel %4, %%d3\n\t" \
  161. "movel %3, %%d2\n\t" \
  162. "movel %2, %%d1\n\t" \
  163. "movel %1, %%d0\n\t" \
  164. "trap #0\n\t" \
  165. "movel %%d0, %0" \
  166. : "=g" (__res) \
  167. : "i" (__NR_##name), \
  168. "a" ((long)a), \
  169. "a" ((long)b), \
  170. "a" ((long)c), \
  171. "a" ((long)d), \
  172. "g" ((long)e), \
  173. "g" ((long)f) \
  174. : "cc", "%d0", "%d1", "%d2", "%d3", \
  175. "%d4", "%d5", "%a0"); \
  176. __syscall_return(type, __res); \
  177. }
  178. #endif /* __ASSEMBLER__ */
  179. #endif /* _BITS_SYSCALLS_H */