syscalls.h 4.7 KB

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