(INTERNAL_SYSCALL, INTERNAL_SYSCALL_DECL, INTERNAL_SYSCALL_ERRNO,
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / linux / mips / sysdep.h
1 /* Copyright (C) 2000 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, write to the Free
16    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
17    02111-1307 USA.  */
18
19 #ifndef _LINUX_MIPS_SYSDEP_H
20 #define _LINUX_MIPS_SYSDEP_H 1
21
22 /* There is some commonality.  */
23 #include <sysdeps/unix/mips/sysdep.h>
24
25 /* For Linux we can use the system call table in the header file
26         /usr/include/asm/unistd.h
27    of the kernel.  But these symbols do not follow the SYS_* syntax
28    so we have to redefine the `SYS_ify' macro here.  */
29 #undef SYS_ify
30 #ifdef __STDC__
31 # define SYS_ify(syscall_name)  __NR_##syscall_name
32 #else
33 # define SYS_ify(syscall_name)  __NR_/**/syscall_name
34 #endif
35
36 #ifndef __ASSEMBLER__
37
38 /* Define a macro which expands into the inline wrapper code for a system
39    call.  */
40 #undef INLINE_SYSCALL
41 #define INLINE_SYSCALL(name, nr, args...)                               \
42   ({ INTERNAL_SYSCALL_DECL(err);                                        \
43      long result_var = INTERNAL_SYSCALL (name, err, nr, args);          \
44      if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) )                  \
45        {                                                                \
46          __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err));        \
47          result_var = -1L;                                              \
48        }                                                                \
49      result_var; })
50
51 #undef INTERNAL_SYSCALL_DECL
52 #define INTERNAL_SYSCALL_DECL(err) long err
53
54 #undef INTERNAL_SYSCALL_ERROR_P
55 #define INTERNAL_SYSCALL_ERROR_P(val, err)   ((long) (err))
56
57 #undef INTERNAL_SYSCALL_ERRNO
58 #define INTERNAL_SYSCALL_ERRNO(val, err)     (val)
59
60 #undef INTERNAL_SYSCALL
61 #define INTERNAL_SYSCALL(name, err, nr, args...) internal_syscall##nr(name, err, args)
62
63 #define internal_syscall0(name, err, dummy...)                          \
64 ({                                                                      \
65         long _sys_result;                                               \
66                                                                         \
67         {                                                               \
68         register long __v0 asm("$2");                                   \
69         register long __a3 asm("$7");                                   \
70         __asm__ volatile (                                              \
71         ".set\tnoreorder\n\t"                                           \
72         "li\t$2, %2\t\t\t# " #name "\n\t"                               \
73         "syscall\n\t"                                                   \
74         ".set reorder"                                                  \
75         : "=r" (__v0), "=r" (__a3)                                      \
76         : "i" (SYS_ify(name))                                           \
77         : __SYSCALL_CLOBBERS);                                          \
78         err = __a3;                                                     \
79         _sys_result = __v0;                                             \
80         }                                                               \
81         _sys_result;                                                    \
82 })
83
84 #define internal_syscall1(name, err, arg1)                              \
85 ({                                                                      \
86         long _sys_result;                                               \
87                                                                         \
88         {                                                               \
89         register long __v0 asm("$2");                                   \
90         register long __a0 asm("$4") = (long) arg1;                     \
91         register long __a3 asm("$7");                                   \
92         __asm__ volatile (                                              \
93         ".set\tnoreorder\n\t"                                           \
94         "li\t$2, %3\t\t\t# " #name "\n\t"                               \
95         "syscall\n\t"                                                   \
96         ".set reorder"                                                  \
97         : "=r" (__v0), "=r" (__a3)                                      \
98         : "r" (__a0), "i" (SYS_ify(name))                               \
99         : __SYSCALL_CLOBBERS);                                          \
100         err = __a3;                                                     \
101         _sys_result = __v0;                                             \
102         }                                                               \
103         _sys_result;                                                    \
104 })
105
106 #define internal_syscall2(name, err, arg1, arg2)                        \
107 ({                                                                      \
108         long _sys_result;                                               \
109                                                                         \
110         {                                                               \
111         register long __v0 asm("$2");                                   \
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         "li\t$2, %4\t\t\t# " #name "\n\t"                               \
118         "syscall\n\t"                                                   \
119         ".set\treorder"                                                 \
120         : "=r" (__v0), "=r" (__a3)                                      \
121         : "r" (__a0), "r" (__a1), "i" (SYS_ify(name))                   \
122         : __SYSCALL_CLOBBERS);                                          \
123         err = __a3;                                                     \
124         _sys_result = __v0;                                             \
125         }                                                               \
126         _sys_result;                                                    \
127 })
128
129 #define internal_syscall3(name, err, arg1, arg2, arg3)                  \
130 ({                                                                      \
131         long _sys_result;                                               \
132                                                                         \
133         {                                                               \
134         register long __v0 asm("$2");                                   \
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         "li\t$2, %5\t\t\t# " #name "\n\t"                               \
142         "syscall\n\t"                                                   \
143         ".set\treorder"                                                 \
144         : "=r" (__v0), "=r" (__a3)                                      \
145         : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name))       \
146         : __SYSCALL_CLOBBERS);                                          \
147         err = __a3;                                                     \
148         _sys_result = __v0;                                             \
149         }                                                               \
150         _sys_result;                                                    \
151 })
152
153 #define internal_syscall4(name, err, arg1, arg2, arg3, arg4)            \
154 ({                                                                      \
155         long _sys_result;                                               \
156                                                                         \
157         {                                                               \
158         register long __v0 asm("$2");                                   \
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         "li\t$2, %5\t\t\t# " #name "\n\t"                               \
166         "syscall\n\t"                                                   \
167         ".set\treorder"                                                 \
168         : "=r" (__v0), "+r" (__a3)                                      \
169         : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name))       \
170         : __SYSCALL_CLOBBERS);                                          \
171         err = __a3;                                                     \
172         _sys_result = __v0;                                             \
173         }                                                               \
174         _sys_result;                                                    \
175 })
176
177 #define internal_syscall5(name, err, arg1, arg2, arg3, arg4, arg5)      \
178 ({                                                                      \
179         long _sys_result;                                               \
180                                                                         \
181         {                                                               \
182         register long __v0 asm("$2");                                   \
183         register long __a0 asm("$4") = (long) arg1;                     \
184         register long __a1 asm("$5") = (long) arg2;                     \
185         register long __a2 asm("$6") = (long) arg3;                     \
186         register long __a3 asm("$7") = (long) arg4;                     \
187         __asm__ volatile (                                              \
188         ".set\tnoreorder\n\t"                                           \
189         "lw\t$2, %6\n\t"                                                \
190         "subu\t$29, 32\n\t"                                             \
191         "sw\t$2, 16($29)\n\t"                                           \
192         "li\t$2, %5\t\t\t# " #name "\n\t"                               \
193         "syscall\n\t"                                                   \
194         "addiu\t$29, 32\n\t"                                            \
195         ".set\treorder"                                                 \
196         : "=r" (__v0), "+r" (__a3)                                      \
197         : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)),      \
198           "m" ((long)arg5)                                              \
199         : __SYSCALL_CLOBBERS);                                          \
200         err = __a3;                                                     \
201         _sys_result = __v0;                                             \
202         }                                                               \
203         _sys_result;                                                    \
204 })
205
206 #define internal_syscall6(name, err, arg1, arg2, arg3, arg4, arg5, arg6)\
207 ({                                                                      \
208         long _sys_result;                                               \
209                                                                         \
210         {                                                               \
211         register long __v0 asm("$2");                                   \
212         register long __a0 asm("$4") = (long) arg1;                     \
213         register long __a1 asm("$5") = (long) arg2;                     \
214         register long __a2 asm("$6") = (long) arg3;                     \
215         register long __a3 asm("$7") = (long) arg4;                     \
216         __asm__ volatile (                                              \
217         ".set\tnoreorder\n\t"                                           \
218         "lw\t$2, %6\n\t"                                                \
219         "lw\t$8, %7\n\t"                                                \
220         "subu\t$29, 32\n\t"                                             \
221         "sw\t$2, 16($29)\n\t"                                           \
222         "sw\t$8, 20($29)\n\t"                                           \
223         "li\t$2, %5\t\t\t# " #name "\n\t"                               \
224         "syscall\n\t"                                                   \
225         "addiu\t$29, 32\n\t"                                            \
226         ".set\treorder"                                                 \
227         : "=r" (__v0), "+r" (__a3)                                      \
228         : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)),      \
229           "m" ((long)arg5), "m" ((long)arg6)                            \
230         : __SYSCALL_CLOBBERS);                                          \
231         err = __a3;                                                     \
232         _sys_result = __v0;                                             \
233         }                                                               \
234         _sys_result;                                                    \
235 })
236
237 #define internal_syscall7(name, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\
238 ({                                                                      \
239         long _sys_result;                                               \
240                                                                         \
241         {                                                               \
242         register long __v0 asm("$2");                                   \
243         register long __a0 asm("$4") = (long) arg1;                     \
244         register long __a1 asm("$5") = (long) arg2;                     \
245         register long __a2 asm("$6") = (long) arg3;                     \
246         register long __a3 asm("$7") = (long) arg4;                     \
247         __asm__ volatile (                                              \
248         ".set\tnoreorder\n\t"                                           \
249         "lw\t$2, %6\n\t"                                                \
250         "lw\t$8, %7\n\t"                                                \
251         "lw\t$9, %8\n\t"                                                \
252         "subu\t$29, 32\n\t"                                             \
253         "sw\t$2, 16($29)\n\t"                                           \
254         "sw\t$8, 20($29)\n\t"                                           \
255         "sw\t$9, 24($29)\n\t"                                           \
256         "li\t$2, %5\t\t\t# " #name "\n\t"                               \
257         "syscall\n\t"                                                   \
258         "addiu\t$29, 32\n\t"                                            \
259         ".set\treorder"                                                 \
260         : "=r" (__v0), "+r" (__a3)                                      \
261         : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)),      \
262           "m" ((long)arg5), "m" ((long)arg6), "m" ((long)arg7)          \
263         : __SYSCALL_CLOBBERS);                                          \
264         err = __a3;                                                     \
265         _sys_result = __v0;                                             \
266         }                                                               \
267         _sys_result;                                                    \
268 })
269
270 #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25"
271
272 #endif /* __ASSEMBLER__ */
273
274 #endif /* linux/mips/sysdep.h */