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