]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h
mips: Consolidate INTERNAL_VSYSCALL_CALL
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / mips / mips64 / n32 / sysdep.h
CommitLineData
04277e02 1/* Copyright (C) 2000-2019 Free Software Foundation, Inc.
be122291
AO
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
ab84e3ff 15 License along with the GNU C Library. If not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
be122291
AO
17
18#ifndef _LINUX_MIPS_SYSDEP_H
19#define _LINUX_MIPS_SYSDEP_H 1
20
21/* There is some commonality. */
b8386c28 22#include <sysdeps/unix/sysv/linux/mips/sysdep.h>
fb1cf108 23#include <sysdeps/unix/sysv/linux/sysdep.h>
be122291
AO
24#include <sysdeps/unix/mips/mips64/n32/sysdep.h>
25
8c276674
DJ
26#include <tls.h>
27
340f7976
JM
28/* In order to get __set_errno() definition in INLINE_SYSCALL. */
29#ifndef __ASSEMBLER__
30#include <errno.h>
31#endif
32
be122291
AO
33/* For Linux we can use the system call table in the header file
34 /usr/include/asm/unistd.h
35 of the kernel. But these symbols do not follow the SYS_* syntax
36 so we have to redefine the `SYS_ify' macro here. */
37#undef SYS_ify
2aee8949 38#define SYS_ify(syscall_name) __NR_##syscall_name
be122291 39
66a1dc87
RM
40#ifdef __ASSEMBLER__
41
42/* We don't want the label for the error handler to be visible in the symbol
43 table when we define it here. */
66a1dc87 44# define SYSCALL_ERROR_LABEL 99b
66a1dc87
RM
45
46#else /* ! __ASSEMBLER__ */
be122291 47
ffd39823
DJ
48/* Convert X to a long long, without losing any bits if it is one
49 already or warning if it is a 32-bit pointer. */
50#define ARGIFY(X) ((long long) (__typeof__ ((X) - (X))) (X))
51
be122291
AO
52/* Define a macro which expands into the inline wrapper code for a system
53 call. */
54#undef INLINE_SYSCALL
29bfb065 55#define INLINE_SYSCALL(name, nr, args...) \
e0c349b4
JM
56 ({ INTERNAL_SYSCALL_DECL (_sc_err); \
57 long result_var = INTERNAL_SYSCALL (name, _sc_err, nr, args); \
58 if ( INTERNAL_SYSCALL_ERROR_P (result_var, _sc_err) ) \
29bfb065 59 { \
e0c349b4 60 __set_errno (INTERNAL_SYSCALL_ERRNO (result_var, _sc_err)); \
29bfb065
MR
61 result_var = -1L; \
62 } \
be122291
AO
63 result_var; })
64
65#undef INTERNAL_SYSCALL_DECL
6eb43a28 66#define INTERNAL_SYSCALL_DECL(err) long err __attribute__ ((unused))
be122291
AO
67
68#undef INTERNAL_SYSCALL_ERROR_P
6eb43a28 69#define INTERNAL_SYSCALL_ERROR_P(val, err) ((void) (val), (long) (err))
be122291
AO
70
71#undef INTERNAL_SYSCALL_ERRNO
6eb43a28 72#define INTERNAL_SYSCALL_ERRNO(val, err) ((void) (err), val)
be122291 73
b82ba2f0
MR
74/* Note that the original Linux syscall restart convention required the
75 instruction immediately preceding SYSCALL to initialize $v0 with the
76 syscall number. Then if a restart triggered, $v0 would have been
77 clobbered by the syscall interrupted, and needed to be reinititalized.
78 The kernel would decrement the PC by 4 before switching back to the
79 user mode so that $v0 had been reloaded before SYSCALL was executed
80 again. This implied the place $v0 was loaded from must have been
81 preserved across a syscall, e.g. an immediate, static register, stack
82 slot, etc.
83
84 The convention was relaxed in Linux with a change applied to the kernel
85 GIT repository as commit 96187fb0bc30cd7919759d371d810e928048249d, that
86 first appeared in the 2.6.36 release. Since then the kernel has had
87 code that reloads $v0 upon syscall restart and resumes right at the
88 SYSCALL instruction, so no special arrangement is needed anymore.
89
90 For backwards compatibility with existing kernel binaries we support
91 the old convention by choosing the instruction preceding SYSCALL
92 carefully. This also means we have to force a 32-bit encoding of the
93 microMIPS MOVE instruction if one is used. */
94
95#ifdef __mips_micromips
96# define MOVE32 "move32"
97#else
98# define MOVE32 "move"
99#endif
100
be122291 101#undef INTERNAL_SYSCALL
b82ba2f0
MR
102#define INTERNAL_SYSCALL(name, err, nr, args...) \
103 internal_syscall##nr ("li\t%0, %2\t\t\t# " #name "\n\t", \
104 "IK" (SYS_ify (name)), \
105 0, err, args)
be122291 106
6428ce3c 107#undef INTERNAL_SYSCALL_NCS
b82ba2f0
MR
108#define INTERNAL_SYSCALL_NCS(number, err, nr, args...) \
109 internal_syscall##nr (MOVE32 "\t%0, %2\n\t", \
110 "r" (__s0), \
111 number, err, args)
6428ce3c 112
b82ba2f0 113#define internal_syscall0(v0_init, input, number, err, dummy...) \
29bfb065 114({ \
be122291
AO
115 long _sys_result; \
116 \
117 { \
f9834ea4 118 register long long __s0 asm ("$16") __attribute__ ((unused)) \
b82ba2f0 119 = (number); \
f9834ea4
MR
120 register long long __v0 asm ("$2"); \
121 register long long __a3 asm ("$7"); \
29bfb065
MR
122 __asm__ volatile ( \
123 ".set\tnoreorder\n\t" \
b82ba2f0 124 v0_init \
29bfb065
MR
125 "syscall\n\t" \
126 ".set reorder" \
127 : "=r" (__v0), "=r" (__a3) \
6428ce3c 128 : input \
29bfb065 129 : __SYSCALL_CLOBBERS); \
be122291
AO
130 err = __a3; \
131 _sys_result = __v0; \
132 } \
133 _sys_result; \
134})
135
b82ba2f0 136#define internal_syscall1(v0_init, input, number, err, arg1) \
29bfb065 137({ \
be122291
AO
138 long _sys_result; \
139 \
140 { \
f9834ea4 141 register long long __s0 asm ("$16") __attribute__ ((unused)) \
b82ba2f0 142 = (number); \
f9834ea4
MR
143 register long long __v0 asm ("$2"); \
144 register long long __a0 asm ("$4") = ARGIFY (arg1); \
145 register long long __a3 asm ("$7"); \
29bfb065
MR
146 __asm__ volatile ( \
147 ".set\tnoreorder\n\t" \
b82ba2f0 148 v0_init \
29bfb065
MR
149 "syscall\n\t" \
150 ".set reorder" \
151 : "=r" (__v0), "=r" (__a3) \
152 : input, "r" (__a0) \
153 : __SYSCALL_CLOBBERS); \
be122291
AO
154 err = __a3; \
155 _sys_result = __v0; \
156 } \
157 _sys_result; \
158})
159
b82ba2f0 160#define internal_syscall2(v0_init, input, number, err, arg1, arg2) \
29bfb065 161({ \
be122291
AO
162 long _sys_result; \
163 \
164 { \
f9834ea4 165 register long long __s0 asm ("$16") __attribute__ ((unused)) \
b82ba2f0 166 = (number); \
f9834ea4
MR
167 register long long __v0 asm ("$2"); \
168 register long long __a0 asm ("$4") = ARGIFY (arg1); \
169 register long long __a1 asm ("$5") = ARGIFY (arg2); \
170 register long long __a3 asm ("$7"); \
29bfb065
MR
171 __asm__ volatile ( \
172 ".set\tnoreorder\n\t" \
b82ba2f0 173 v0_init \
29bfb065
MR
174 "syscall\n\t" \
175 ".set\treorder" \
176 : "=r" (__v0), "=r" (__a3) \
6428ce3c 177 : input, "r" (__a0), "r" (__a1) \
29bfb065 178 : __SYSCALL_CLOBBERS); \
be122291
AO
179 err = __a3; \
180 _sys_result = __v0; \
181 } \
182 _sys_result; \
183})
184
b82ba2f0
MR
185#define internal_syscall3(v0_init, input, number, err, \
186 arg1, arg2, arg3) \
29bfb065 187({ \
be122291
AO
188 long _sys_result; \
189 \
190 { \
f9834ea4 191 register long long __s0 asm ("$16") __attribute__ ((unused)) \
b82ba2f0 192 = (number); \
f9834ea4
MR
193 register long long __v0 asm ("$2"); \
194 register long long __a0 asm ("$4") = ARGIFY (arg1); \
195 register long long __a1 asm ("$5") = ARGIFY (arg2); \
196 register long long __a2 asm ("$6") = ARGIFY (arg3); \
197 register long long __a3 asm ("$7"); \
29bfb065
MR
198 __asm__ volatile ( \
199 ".set\tnoreorder\n\t" \
b82ba2f0 200 v0_init \
29bfb065
MR
201 "syscall\n\t" \
202 ".set\treorder" \
203 : "=r" (__v0), "=r" (__a3) \
6428ce3c 204 : input, "r" (__a0), "r" (__a1), "r" (__a2) \
29bfb065 205 : __SYSCALL_CLOBBERS); \
be122291
AO
206 err = __a3; \
207 _sys_result = __v0; \
208 } \
209 _sys_result; \
210})
211
b82ba2f0
MR
212#define internal_syscall4(v0_init, input, number, err, \
213 arg1, arg2, arg3, arg4) \
29bfb065 214({ \
be122291
AO
215 long _sys_result; \
216 \
217 { \
f9834ea4 218 register long long __s0 asm ("$16") __attribute__ ((unused)) \
b82ba2f0 219 = (number); \
f9834ea4
MR
220 register long long __v0 asm ("$2"); \
221 register long long __a0 asm ("$4") = ARGIFY (arg1); \
222 register long long __a1 asm ("$5") = ARGIFY (arg2); \
223 register long long __a2 asm ("$6") = ARGIFY (arg3); \
224 register long long __a3 asm ("$7") = ARGIFY (arg4); \
29bfb065
MR
225 __asm__ volatile ( \
226 ".set\tnoreorder\n\t" \
b82ba2f0 227 v0_init \
29bfb065
MR
228 "syscall\n\t" \
229 ".set\treorder" \
230 : "=r" (__v0), "+r" (__a3) \
231 : input, "r" (__a0), "r" (__a1), "r" (__a2) \
232 : __SYSCALL_CLOBBERS); \
be122291
AO
233 err = __a3; \
234 _sys_result = __v0; \
235 } \
236 _sys_result; \
237})
238
b82ba2f0
MR
239#define internal_syscall5(v0_init, input, number, err, \
240 arg1, arg2, arg3, arg4, arg5) \
29bfb065 241({ \
be122291
AO
242 long _sys_result; \
243 \
244 { \
f9834ea4 245 register long long __s0 asm ("$16") __attribute__ ((unused)) \
b82ba2f0 246 = (number); \
f9834ea4
MR
247 register long long __v0 asm ("$2"); \
248 register long long __a0 asm ("$4") = ARGIFY (arg1); \
249 register long long __a1 asm ("$5") = ARGIFY (arg2); \
250 register long long __a2 asm ("$6") = ARGIFY (arg3); \
251 register long long __a3 asm ("$7") = ARGIFY (arg4); \
252 register long long __a4 asm ("$8") = ARGIFY (arg5); \
29bfb065
MR
253 __asm__ volatile ( \
254 ".set\tnoreorder\n\t" \
b82ba2f0 255 v0_init \
29bfb065
MR
256 "syscall\n\t" \
257 ".set\treorder" \
258 : "=r" (__v0), "+r" (__a3) \
6428ce3c 259 : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4) \
29bfb065 260 : __SYSCALL_CLOBBERS); \
be122291
AO
261 err = __a3; \
262 _sys_result = __v0; \
263 } \
264 _sys_result; \
265})
266
b82ba2f0
MR
267#define internal_syscall6(v0_init, input, number, err, \
268 arg1, arg2, arg3, arg4, arg5, arg6) \
29bfb065 269({ \
be122291
AO
270 long _sys_result; \
271 \
272 { \
f9834ea4 273 register long long __s0 asm ("$16") __attribute__ ((unused)) \
b82ba2f0 274 = (number); \
f9834ea4
MR
275 register long long __v0 asm ("$2"); \
276 register long long __a0 asm ("$4") = ARGIFY (arg1); \
277 register long long __a1 asm ("$5") = ARGIFY (arg2); \
278 register long long __a2 asm ("$6") = ARGIFY (arg3); \
279 register long long __a3 asm ("$7") = ARGIFY (arg4); \
280 register long long __a4 asm ("$8") = ARGIFY (arg5); \
281 register long long __a5 asm ("$9") = ARGIFY (arg6); \
29bfb065
MR
282 __asm__ volatile ( \
283 ".set\tnoreorder\n\t" \
b82ba2f0 284 v0_init \
29bfb065
MR
285 "syscall\n\t" \
286 ".set\treorder" \
287 : "=r" (__v0), "+r" (__a3) \
6428ce3c
DJ
288 : input, "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), \
289 "r" (__a5) \
29bfb065 290 : __SYSCALL_CLOBBERS); \
be122291
AO
291 err = __a3; \
292 _sys_result = __v0; \
293 } \
294 _sys_result; \
295})
296
145f3f8a 297#define __SYSCALL_CLOBBERS "$1", "$3", "$10", "$11", "$12", "$13", \
f1297d79 298 "$14", "$15", "$24", "$25", "hi", "lo", "memory"
b39d84ad 299
be122291
AO
300#endif /* __ASSEMBLER__ */
301
908afa83
DJ
302/* Pointer mangling is not yet supported for MIPS. */
303#define PTR_MANGLE(var) (void) (var)
304#define PTR_DEMANGLE(var) (void) (var)
305
be122291 306#endif /* linux/mips/sysdep.h */