]>
Commit | Line | Data |
---|---|---|
87af90e7 AJ |
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 | |
3214b89b AJ |
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. | |
87af90e7 AJ |
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 | |
3214b89b | 12 | Lesser General Public License for more details. |
87af90e7 | 13 | |
3214b89b AJ |
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. */ | |
87af90e7 AJ |
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 | ||
c25d936b UD |
36 | #ifdef __ASSEMBLER__ |
37 | ||
38 | /* We don't want the label for the error handler to be visible in the symbol | |
39 | table when we define it here. */ | |
40 | #ifdef __PIC__ | |
41 | # define SYSCALL_ERROR_LABEL 99b | |
42 | #endif | |
43 | ||
44 | #else /* ! __ASSEMBLER__ */ | |
9da3df10 UD |
45 | |
46 | /* Define a macro which expands into the inline wrapper code for a system | |
47 | call. */ | |
48 | #undef INLINE_SYSCALL | |
49 | #define INLINE_SYSCALL(name, nr, args...) \ | |
50 | ({ INTERNAL_SYSCALL_DECL(err); \ | |
51 | long result_var = INTERNAL_SYSCALL (name, err, nr, args); \ | |
52 | if ( INTERNAL_SYSCALL_ERROR_P (result_var, err) ) \ | |
53 | { \ | |
54 | __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, err)); \ | |
55 | result_var = -1L; \ | |
56 | } \ | |
57 | result_var; }) | |
58 | ||
59 | #undef INTERNAL_SYSCALL_DECL | |
60 | #define INTERNAL_SYSCALL_DECL(err) long err | |
61 | ||
62 | #undef INTERNAL_SYSCALL_ERROR_P | |
63 | #define INTERNAL_SYSCALL_ERROR_P(val, err) ((long) (err)) | |
64 | ||
65 | #undef INTERNAL_SYSCALL_ERRNO | |
66 | #define INTERNAL_SYSCALL_ERRNO(val, err) (val) | |
67 | ||
68 | #undef INTERNAL_SYSCALL | |
69 | #define INTERNAL_SYSCALL(name, err, nr, args...) internal_syscall##nr(name, err, args) | |
70 | ||
71 | #define internal_syscall0(name, err, dummy...) \ | |
72 | ({ \ | |
73 | long _sys_result; \ | |
74 | \ | |
75 | { \ | |
76 | register long __v0 asm("$2"); \ | |
77 | register long __a3 asm("$7"); \ | |
78 | __asm__ volatile ( \ | |
79 | ".set\tnoreorder\n\t" \ | |
80 | "li\t$2, %2\t\t\t# " #name "\n\t" \ | |
81 | "syscall\n\t" \ | |
82 | ".set reorder" \ | |
83 | : "=r" (__v0), "=r" (__a3) \ | |
84 | : "i" (SYS_ify(name)) \ | |
85 | : __SYSCALL_CLOBBERS); \ | |
86 | err = __a3; \ | |
87 | _sys_result = __v0; \ | |
88 | } \ | |
89 | _sys_result; \ | |
90 | }) | |
91 | ||
92 | #define internal_syscall1(name, err, arg1) \ | |
93 | ({ \ | |
94 | long _sys_result; \ | |
95 | \ | |
96 | { \ | |
97 | register long __v0 asm("$2"); \ | |
98 | register long __a0 asm("$4") = (long) arg1; \ | |
99 | register long __a3 asm("$7"); \ | |
100 | __asm__ volatile ( \ | |
101 | ".set\tnoreorder\n\t" \ | |
102 | "li\t$2, %3\t\t\t# " #name "\n\t" \ | |
103 | "syscall\n\t" \ | |
104 | ".set reorder" \ | |
105 | : "=r" (__v0), "=r" (__a3) \ | |
106 | : "r" (__a0), "i" (SYS_ify(name)) \ | |
107 | : __SYSCALL_CLOBBERS); \ | |
108 | err = __a3; \ | |
109 | _sys_result = __v0; \ | |
110 | } \ | |
111 | _sys_result; \ | |
112 | }) | |
113 | ||
114 | #define internal_syscall2(name, err, arg1, arg2) \ | |
115 | ({ \ | |
116 | long _sys_result; \ | |
117 | \ | |
118 | { \ | |
119 | register long __v0 asm("$2"); \ | |
120 | register long __a0 asm("$4") = (long) arg1; \ | |
121 | register long __a1 asm("$5") = (long) arg2; \ | |
122 | register long __a3 asm("$7"); \ | |
123 | __asm__ volatile ( \ | |
124 | ".set\tnoreorder\n\t" \ | |
125 | "li\t$2, %4\t\t\t# " #name "\n\t" \ | |
126 | "syscall\n\t" \ | |
127 | ".set\treorder" \ | |
128 | : "=r" (__v0), "=r" (__a3) \ | |
129 | : "r" (__a0), "r" (__a1), "i" (SYS_ify(name)) \ | |
130 | : __SYSCALL_CLOBBERS); \ | |
131 | err = __a3; \ | |
132 | _sys_result = __v0; \ | |
133 | } \ | |
134 | _sys_result; \ | |
135 | }) | |
136 | ||
137 | #define internal_syscall3(name, err, arg1, arg2, arg3) \ | |
138 | ({ \ | |
139 | long _sys_result; \ | |
140 | \ | |
141 | { \ | |
142 | register long __v0 asm("$2"); \ | |
143 | register long __a0 asm("$4") = (long) arg1; \ | |
144 | register long __a1 asm("$5") = (long) arg2; \ | |
145 | register long __a2 asm("$6") = (long) arg3; \ | |
146 | register long __a3 asm("$7"); \ | |
147 | __asm__ volatile ( \ | |
148 | ".set\tnoreorder\n\t" \ | |
149 | "li\t$2, %5\t\t\t# " #name "\n\t" \ | |
150 | "syscall\n\t" \ | |
151 | ".set\treorder" \ | |
152 | : "=r" (__v0), "=r" (__a3) \ | |
153 | : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)) \ | |
154 | : __SYSCALL_CLOBBERS); \ | |
155 | err = __a3; \ | |
156 | _sys_result = __v0; \ | |
157 | } \ | |
158 | _sys_result; \ | |
159 | }) | |
160 | ||
161 | #define internal_syscall4(name, err, arg1, arg2, arg3, arg4) \ | |
162 | ({ \ | |
163 | long _sys_result; \ | |
164 | \ | |
165 | { \ | |
166 | register long __v0 asm("$2"); \ | |
167 | register long __a0 asm("$4") = (long) arg1; \ | |
168 | register long __a1 asm("$5") = (long) arg2; \ | |
169 | register long __a2 asm("$6") = (long) arg3; \ | |
170 | register long __a3 asm("$7") = (long) arg4; \ | |
171 | __asm__ volatile ( \ | |
172 | ".set\tnoreorder\n\t" \ | |
173 | "li\t$2, %5\t\t\t# " #name "\n\t" \ | |
174 | "syscall\n\t" \ | |
175 | ".set\treorder" \ | |
176 | : "=r" (__v0), "+r" (__a3) \ | |
177 | : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)) \ | |
178 | : __SYSCALL_CLOBBERS); \ | |
179 | err = __a3; \ | |
180 | _sys_result = __v0; \ | |
181 | } \ | |
182 | _sys_result; \ | |
183 | }) | |
184 | ||
185 | #define internal_syscall5(name, err, arg1, arg2, arg3, arg4, arg5) \ | |
186 | ({ \ | |
187 | long _sys_result; \ | |
188 | \ | |
189 | { \ | |
190 | register long __v0 asm("$2"); \ | |
191 | register long __a0 asm("$4") = (long) arg1; \ | |
192 | register long __a1 asm("$5") = (long) arg2; \ | |
193 | register long __a2 asm("$6") = (long) arg3; \ | |
194 | register long __a3 asm("$7") = (long) arg4; \ | |
195 | __asm__ volatile ( \ | |
196 | ".set\tnoreorder\n\t" \ | |
197 | "lw\t$2, %6\n\t" \ | |
198 | "subu\t$29, 32\n\t" \ | |
199 | "sw\t$2, 16($29)\n\t" \ | |
200 | "li\t$2, %5\t\t\t# " #name "\n\t" \ | |
201 | "syscall\n\t" \ | |
202 | "addiu\t$29, 32\n\t" \ | |
203 | ".set\treorder" \ | |
204 | : "=r" (__v0), "+r" (__a3) \ | |
205 | : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \ | |
206 | "m" ((long)arg5) \ | |
207 | : __SYSCALL_CLOBBERS); \ | |
208 | err = __a3; \ | |
209 | _sys_result = __v0; \ | |
210 | } \ | |
211 | _sys_result; \ | |
212 | }) | |
213 | ||
214 | #define internal_syscall6(name, err, arg1, arg2, arg3, arg4, arg5, arg6)\ | |
215 | ({ \ | |
216 | long _sys_result; \ | |
217 | \ | |
218 | { \ | |
219 | register long __v0 asm("$2"); \ | |
220 | register long __a0 asm("$4") = (long) arg1; \ | |
221 | register long __a1 asm("$5") = (long) arg2; \ | |
222 | register long __a2 asm("$6") = (long) arg3; \ | |
223 | register long __a3 asm("$7") = (long) arg4; \ | |
224 | __asm__ volatile ( \ | |
225 | ".set\tnoreorder\n\t" \ | |
226 | "lw\t$2, %6\n\t" \ | |
227 | "lw\t$8, %7\n\t" \ | |
228 | "subu\t$29, 32\n\t" \ | |
229 | "sw\t$2, 16($29)\n\t" \ | |
230 | "sw\t$8, 20($29)\n\t" \ | |
231 | "li\t$2, %5\t\t\t# " #name "\n\t" \ | |
232 | "syscall\n\t" \ | |
233 | "addiu\t$29, 32\n\t" \ | |
234 | ".set\treorder" \ | |
235 | : "=r" (__v0), "+r" (__a3) \ | |
236 | : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \ | |
237 | "m" ((long)arg5), "m" ((long)arg6) \ | |
238 | : __SYSCALL_CLOBBERS); \ | |
239 | err = __a3; \ | |
240 | _sys_result = __v0; \ | |
241 | } \ | |
242 | _sys_result; \ | |
243 | }) | |
244 | ||
245 | #define internal_syscall7(name, err, arg1, arg2, arg3, arg4, arg5, arg6, arg7)\ | |
246 | ({ \ | |
247 | long _sys_result; \ | |
248 | \ | |
249 | { \ | |
250 | register long __v0 asm("$2"); \ | |
251 | register long __a0 asm("$4") = (long) arg1; \ | |
252 | register long __a1 asm("$5") = (long) arg2; \ | |
253 | register long __a2 asm("$6") = (long) arg3; \ | |
254 | register long __a3 asm("$7") = (long) arg4; \ | |
255 | __asm__ volatile ( \ | |
256 | ".set\tnoreorder\n\t" \ | |
257 | "lw\t$2, %6\n\t" \ | |
258 | "lw\t$8, %7\n\t" \ | |
259 | "lw\t$9, %8\n\t" \ | |
260 | "subu\t$29, 32\n\t" \ | |
261 | "sw\t$2, 16($29)\n\t" \ | |
262 | "sw\t$8, 20($29)\n\t" \ | |
263 | "sw\t$9, 24($29)\n\t" \ | |
264 | "li\t$2, %5\t\t\t# " #name "\n\t" \ | |
265 | "syscall\n\t" \ | |
266 | "addiu\t$29, 32\n\t" \ | |
267 | ".set\treorder" \ | |
268 | : "=r" (__v0), "+r" (__a3) \ | |
269 | : "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \ | |
270 | "m" ((long)arg5), "m" ((long)arg6), "m" ((long)arg7) \ | |
271 | : __SYSCALL_CLOBBERS); \ | |
272 | err = __a3; \ | |
273 | _sys_result = __v0; \ | |
274 | } \ | |
275 | _sys_result; \ | |
276 | }) | |
277 | ||
278 | #define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", "$25" | |
279 | ||
280 | #endif /* __ASSEMBLER__ */ | |
281 | ||
87af90e7 | 282 | #endif /* linux/mips/sysdep.h */ |