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