syscalls.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. /* Linux takes system call arguments in registers:
  14. syscall number %d0 call-clobbered
  15. arg 1 %d1 call-clobbered
  16. arg 2 %d2 call-saved
  17. arg 3 %d3 call-saved
  18. arg 4 %d4 call-saved
  19. arg 5 %d5 call-saved
  20. arg 6 %a0 call-clobbered
  21. The stack layout upon entering the function is:
  22. 24(%sp) Arg# 6
  23. 20(%sp) Arg# 5
  24. 16(%sp) Arg# 4
  25. 12(%sp) Arg# 3
  26. 8(%sp) Arg# 2
  27. 4(%sp) Arg# 1
  28. (%sp) Return address
  29. (Of course a function with say 3 arguments does not have entries for
  30. arguments 4 and 5.)
  31. Separate move's are faster than movem, but need more space. Since
  32. speed is more important, we don't use movem. Since %a0 and %a1 are
  33. scratch registers, we can use them for saving as well. */
  34. /* Define a macro which expands inline into the wrapper code for a system
  35. call. This use is for internal calls that do not need to handle errors
  36. normally. It will never touch errno. This returns just what the kernel
  37. gave back. */
  38. #define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
  39. ({ unsigned int _sys_result; \
  40. { \
  41. /* Load argument values in temporary variables
  42. to perform side effects like function calls
  43. before the call used registers are set. */ \
  44. LOAD_ARGS_##nr (args) \
  45. LOAD_REGS_##nr \
  46. register int _d0 __asm__ ("%d0") = name; \
  47. __asm__ __volatile__ ("trap #0" \
  48. : "=d" (_d0) \
  49. : "0" (_d0) ASM_ARGS_##nr \
  50. : "memory"); \
  51. _sys_result = _d0; \
  52. } \
  53. (int) _sys_result; })
  54. #define LOAD_ARGS_0()
  55. #define LOAD_REGS_0
  56. #define ASM_ARGS_0
  57. #define LOAD_ARGS_1(a1) \
  58. LOAD_ARGS_0 () \
  59. int __arg1 = (int) (a1);
  60. #define LOAD_REGS_1 \
  61. register int _d1 __asm__ ("d1") = __arg1; \
  62. LOAD_REGS_0
  63. #define ASM_ARGS_1 ASM_ARGS_0, "d" (_d1)
  64. #define LOAD_ARGS_2(a1, a2) \
  65. LOAD_ARGS_1 (a1) \
  66. int __arg2 = (int) (a2);
  67. #define LOAD_REGS_2 \
  68. register int _d2 __asm__ ("d2") = __arg2; \
  69. LOAD_REGS_1
  70. #define ASM_ARGS_2 ASM_ARGS_1, "d" (_d2)
  71. #define LOAD_ARGS_3(a1, a2, a3) \
  72. LOAD_ARGS_2 (a1, a2) \
  73. int __arg3 = (int) (a3);
  74. #define LOAD_REGS_3 \
  75. register int _d3 __asm__ ("d3") = __arg3; \
  76. LOAD_REGS_2
  77. #define ASM_ARGS_3 ASM_ARGS_2, "d" (_d3)
  78. #define LOAD_ARGS_4(a1, a2, a3, a4) \
  79. LOAD_ARGS_3 (a1, a2, a3) \
  80. int __arg4 = (int) (a4);
  81. #define LOAD_REGS_4 \
  82. register int _d4 __asm__ ("d4") = __arg4; \
  83. LOAD_REGS_3
  84. #define ASM_ARGS_4 ASM_ARGS_3, "d" (_d4)
  85. #define LOAD_ARGS_5(a1, a2, a3, a4, a5) \
  86. LOAD_ARGS_4 (a1, a2, a3, a4) \
  87. int __arg5 = (int) (a5);
  88. #define LOAD_REGS_5 \
  89. register int _d5 __asm__ ("d5") = __arg5; \
  90. LOAD_REGS_4
  91. #define ASM_ARGS_5 ASM_ARGS_4, "d" (_d5)
  92. #define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6) \
  93. LOAD_ARGS_5 (a1, a2, a3, a4, a5) \
  94. int __arg6 = (int) (a6);
  95. #define LOAD_REGS_6 \
  96. register int _a0 __asm__ ("a0") = __arg6; \
  97. LOAD_REGS_5
  98. #define ASM_ARGS_6 ASM_ARGS_5, "a" (_a0)
  99. #endif /* __ASSEMBLER__ */
  100. #endif /* _BITS_SYSCALLS_H */