1 //! mips64el Linux system calls.
2 //!
3 //! On mips64el, Linux indicates success or failure using `$a3` (`$7`) rather
4 //! than by returning a negative error code as most other architectures do.
5 //!
6 //! Mips-family platforms have a special calling convention for `__NR_pipe`,
7 //! however we use `__NR_pipe2` instead to avoid having to implement it.
8
9 use crate::backend::reg::{
10 ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0,
11 };
12 use core::arch::asm;
13
14 #[inline]
syscall0_readonly(nr: SyscallNumber) -> RetReg<R0>15 pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber) -> RetReg<R0> {
16 let x0;
17 let err: usize;
18 asm!(
19 "syscall",
20 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
21 lateout("$7" /*$a3*/) err,
22 lateout("$8" /*$a4*/) _,
23 lateout("$9" /*$a5*/) _,
24 lateout("$10" /*$a6*/) _,
25 lateout("$11" /*$a7*/) _,
26 lateout("$12" /*$t0*/) _,
27 lateout("$13" /*$t1*/) _,
28 lateout("$14" /*$t2*/) _,
29 lateout("$15" /*$t3*/) _,
30 lateout("$24" /*$t8*/) _,
31 lateout("$25" /*$t9*/) _,
32 options(nostack, preserves_flags, readonly)
33 );
34 FromAsm::from_asm(if err != 0 {
35 (x0 as usize).wrapping_neg() as *mut _
36 } else {
37 x0
38 })
39 }
40
41 #[inline]
syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0>42 pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
43 let x0;
44 let err: usize;
45 asm!(
46 "syscall",
47 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
48 in("$4" /*$a0*/) a0.to_asm(),
49 lateout("$7" /*$a3*/) err,
50 lateout("$8" /*$a4*/) _,
51 lateout("$9" /*$a5*/) _,
52 lateout("$10" /*$a6*/) _,
53 lateout("$11" /*$a7*/) _,
54 lateout("$12" /*$t0*/) _,
55 lateout("$13" /*$t1*/) _,
56 lateout("$14" /*$t2*/) _,
57 lateout("$15" /*$t3*/) _,
58 lateout("$24" /*$t8*/) _,
59 lateout("$25" /*$t9*/) _,
60 options(nostack, preserves_flags)
61 );
62 FromAsm::from_asm(if err != 0 {
63 (x0 as usize).wrapping_neg() as *mut _
64 } else {
65 x0
66 })
67 }
68
69 #[inline]
syscall1_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, ) -> RetReg<R0>70 pub(in crate::backend) unsafe fn syscall1_readonly(
71 nr: SyscallNumber<'_>,
72 a0: ArgReg<'_, A0>,
73 ) -> RetReg<R0> {
74 let x0;
75 let err: usize;
76 asm!(
77 "syscall",
78 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
79 in("$4" /*$a0*/) a0.to_asm(),
80 lateout("$7" /*$a3*/) err,
81 lateout("$8" /*$a4*/) _,
82 lateout("$9" /*$a5*/) _,
83 lateout("$10" /*$a6*/) _,
84 lateout("$11" /*$a7*/) _,
85 lateout("$12" /*$t0*/) _,
86 lateout("$13" /*$t1*/) _,
87 lateout("$14" /*$t2*/) _,
88 lateout("$15" /*$t3*/) _,
89 lateout("$24" /*$t8*/) _,
90 lateout("$25" /*$t9*/) _,
91 options(nostack, preserves_flags, readonly)
92 );
93 FromAsm::from_asm(if err != 0 {
94 (x0 as usize).wrapping_neg() as *mut _
95 } else {
96 x0
97 })
98 }
99
100 #[inline]
syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> !101 pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! {
102 asm!(
103 "syscall",
104 in("$2" /*$v0*/) nr.to_asm(),
105 in("$4" /*$a0*/) a0.to_asm(),
106 options(nostack, noreturn)
107 )
108 }
109
110 #[inline]
syscall2( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, ) -> RetReg<R0>111 pub(in crate::backend) unsafe fn syscall2(
112 nr: SyscallNumber<'_>,
113 a0: ArgReg<'_, A0>,
114 a1: ArgReg<'_, A1>,
115 ) -> RetReg<R0> {
116 let x0;
117 let err: usize;
118 asm!(
119 "syscall",
120 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
121 in("$4" /*$a0*/) a0.to_asm(),
122 in("$5" /*$a1*/) a1.to_asm(),
123 lateout("$7" /*$a3*/) err,
124 lateout("$8" /*$a4*/) _,
125 lateout("$9" /*$a5*/) _,
126 lateout("$10" /*$a6*/) _,
127 lateout("$11" /*$a7*/) _,
128 lateout("$12" /*$t0*/) _,
129 lateout("$13" /*$t1*/) _,
130 lateout("$14" /*$t2*/) _,
131 lateout("$15" /*$t3*/) _,
132 lateout("$24" /*$t8*/) _,
133 lateout("$25" /*$t9*/) _,
134 options(nostack, preserves_flags)
135 );
136 FromAsm::from_asm(if err != 0 {
137 (x0 as usize).wrapping_neg() as *mut _
138 } else {
139 x0
140 })
141 }
142
143 #[inline]
syscall2_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, ) -> RetReg<R0>144 pub(in crate::backend) unsafe fn syscall2_readonly(
145 nr: SyscallNumber<'_>,
146 a0: ArgReg<'_, A0>,
147 a1: ArgReg<'_, A1>,
148 ) -> RetReg<R0> {
149 let x0;
150 let err: usize;
151 asm!(
152 "syscall",
153 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
154 in("$4" /*$a0*/) a0.to_asm(),
155 in("$5" /*$a1*/) a1.to_asm(),
156 lateout("$7" /*$a3*/) err,
157 lateout("$8" /*$a4*/) _,
158 lateout("$9" /*$a5*/) _,
159 lateout("$10" /*$a6*/) _,
160 lateout("$11" /*$a7*/) _,
161 lateout("$12" /*$t0*/) _,
162 lateout("$13" /*$t1*/) _,
163 lateout("$14" /*$t2*/) _,
164 lateout("$15" /*$t3*/) _,
165 lateout("$24" /*$t8*/) _,
166 lateout("$25" /*$t9*/) _,
167 options(nostack, preserves_flags, readonly)
168 );
169 FromAsm::from_asm(if err != 0 {
170 (x0 as usize).wrapping_neg() as *mut _
171 } else {
172 x0
173 })
174 }
175
176 #[inline]
syscall3( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, ) -> RetReg<R0>177 pub(in crate::backend) unsafe fn syscall3(
178 nr: SyscallNumber<'_>,
179 a0: ArgReg<'_, A0>,
180 a1: ArgReg<'_, A1>,
181 a2: ArgReg<'_, A2>,
182 ) -> RetReg<R0> {
183 let x0;
184 let err: usize;
185 asm!(
186 "syscall",
187 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
188 in("$4" /*$a0*/) a0.to_asm(),
189 in("$5" /*$a1*/) a1.to_asm(),
190 in("$6" /*$a2*/) a2.to_asm(),
191 lateout("$7" /*$a3*/) err,
192 lateout("$8" /*$a4*/) _,
193 lateout("$9" /*$a5*/) _,
194 lateout("$10" /*$a6*/) _,
195 lateout("$11" /*$a7*/) _,
196 lateout("$12" /*$t0*/) _,
197 lateout("$13" /*$t1*/) _,
198 lateout("$14" /*$t2*/) _,
199 lateout("$15" /*$t3*/) _,
200 lateout("$24" /*$t8*/) _,
201 lateout("$25" /*$t9*/) _,
202 options(nostack, preserves_flags)
203 );
204 FromAsm::from_asm(if err != 0 {
205 (x0 as usize).wrapping_neg() as *mut _
206 } else {
207 x0
208 })
209 }
210
211 #[inline]
syscall3_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, ) -> RetReg<R0>212 pub(in crate::backend) unsafe fn syscall3_readonly(
213 nr: SyscallNumber<'_>,
214 a0: ArgReg<'_, A0>,
215 a1: ArgReg<'_, A1>,
216 a2: ArgReg<'_, A2>,
217 ) -> RetReg<R0> {
218 let x0;
219 let err: usize;
220 asm!(
221 "syscall",
222 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
223 in("$4" /*$a0*/) a0.to_asm(),
224 in("$5" /*$a1*/) a1.to_asm(),
225 in("$6" /*$a2*/) a2.to_asm(),
226 lateout("$7" /*$a3*/) err,
227 lateout("$8" /*$a4*/) _,
228 lateout("$9" /*$a5*/) _,
229 lateout("$10" /*$a6*/) _,
230 lateout("$11" /*$a7*/) _,
231 lateout("$12" /*$t0*/) _,
232 lateout("$13" /*$t1*/) _,
233 lateout("$14" /*$t2*/) _,
234 lateout("$15" /*$t3*/) _,
235 lateout("$24" /*$t8*/) _,
236 lateout("$25" /*$t9*/) _,
237 options(nostack, preserves_flags, readonly)
238 );
239 FromAsm::from_asm(if err != 0 {
240 (x0 as usize).wrapping_neg() as *mut _
241 } else {
242 x0
243 })
244 }
245
246 #[inline]
syscall4( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, ) -> RetReg<R0>247 pub(in crate::backend) unsafe fn syscall4(
248 nr: SyscallNumber<'_>,
249 a0: ArgReg<'_, A0>,
250 a1: ArgReg<'_, A1>,
251 a2: ArgReg<'_, A2>,
252 a3: ArgReg<'_, A3>,
253 ) -> RetReg<R0> {
254 let x0;
255 let err: usize;
256 asm!(
257 "syscall",
258 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
259 in("$4" /*$a0*/) a0.to_asm(),
260 in("$5" /*$a1*/) a1.to_asm(),
261 in("$6" /*$a2*/) a2.to_asm(),
262 inlateout("$7" /*$a3*/) a3.to_asm() => err,
263 lateout("$8" /*$a4*/) _,
264 lateout("$9" /*$a5*/) _,
265 lateout("$10" /*$a6*/) _,
266 lateout("$11" /*$a7*/) _,
267 lateout("$12" /*$t0*/) _,
268 lateout("$13" /*$t1*/) _,
269 lateout("$14" /*$t2*/) _,
270 lateout("$15" /*$t3*/) _,
271 lateout("$24" /*$t8*/) _,
272 lateout("$25" /*$t9*/) _,
273 options(nostack, preserves_flags)
274 );
275 FromAsm::from_asm(if err != 0 {
276 (x0 as usize).wrapping_neg() as *mut _
277 } else {
278 x0
279 })
280 }
281
282 #[inline]
syscall4_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, ) -> RetReg<R0>283 pub(in crate::backend) unsafe fn syscall4_readonly(
284 nr: SyscallNumber<'_>,
285 a0: ArgReg<'_, A0>,
286 a1: ArgReg<'_, A1>,
287 a2: ArgReg<'_, A2>,
288 a3: ArgReg<'_, A3>,
289 ) -> RetReg<R0> {
290 let x0;
291 let err: usize;
292 asm!(
293 "syscall",
294 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
295 in("$4" /*$a0*/) a0.to_asm(),
296 in("$5" /*$a1*/) a1.to_asm(),
297 in("$6" /*$a2*/) a2.to_asm(),
298 inlateout("$7" /*$a3*/) a3.to_asm() => err,
299 lateout("$8" /*$a4*/) _,
300 lateout("$9" /*$a5*/) _,
301 lateout("$10" /*$a6*/) _,
302 lateout("$11" /*$a7*/) _,
303 lateout("$12" /*$t0*/) _,
304 lateout("$13" /*$t1*/) _,
305 lateout("$14" /*$t2*/) _,
306 lateout("$15" /*$t3*/) _,
307 lateout("$24" /*$t8*/) _,
308 lateout("$25" /*$t9*/) _,
309 options(nostack, preserves_flags, readonly)
310 );
311 FromAsm::from_asm(if err != 0 {
312 (x0 as usize).wrapping_neg() as *mut _
313 } else {
314 x0
315 })
316 }
317
318 #[inline]
syscall5( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>319 pub(in crate::backend) unsafe fn syscall5(
320 nr: SyscallNumber<'_>,
321 a0: ArgReg<'_, A0>,
322 a1: ArgReg<'_, A1>,
323 a2: ArgReg<'_, A2>,
324 a3: ArgReg<'_, A3>,
325 a4: ArgReg<'_, A4>,
326 ) -> RetReg<R0> {
327 let x0;
328 let err: usize;
329 asm!(
330 "syscall",
331 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
332 in("$4" /*$a0*/) a0.to_asm(),
333 in("$5" /*$a1*/) a1.to_asm(),
334 in("$6" /*$a2*/) a2.to_asm(),
335 inlateout("$7" /*$a3*/) a3.to_asm() => err,
336 inlateout("$8" /*$a4*/) a4.to_asm() => _,
337 lateout("$9" /*$a5*/) _,
338 lateout("$10" /*$a6*/) _,
339 lateout("$11" /*$a7*/) _,
340 lateout("$12" /*$t0*/) _,
341 lateout("$13" /*$t1*/) _,
342 lateout("$14" /*$t2*/) _,
343 lateout("$15" /*$t3*/) _,
344 lateout("$24" /*$t8*/) _,
345 lateout("$25" /*$t9*/) _,
346 options(nostack, preserves_flags)
347 );
348 FromAsm::from_asm(if err != 0 {
349 (x0 as usize).wrapping_neg() as *mut _
350 } else {
351 x0
352 })
353 }
354
355 #[inline]
syscall5_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>356 pub(in crate::backend) unsafe fn syscall5_readonly(
357 nr: SyscallNumber<'_>,
358 a0: ArgReg<'_, A0>,
359 a1: ArgReg<'_, A1>,
360 a2: ArgReg<'_, A2>,
361 a3: ArgReg<'_, A3>,
362 a4: ArgReg<'_, A4>,
363 ) -> RetReg<R0> {
364 let x0;
365 let err: usize;
366 asm!(
367 "syscall",
368 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
369 in("$4" /*$a0*/) a0.to_asm(),
370 in("$5" /*$a1*/) a1.to_asm(),
371 in("$6" /*$a2*/) a2.to_asm(),
372 inlateout("$7" /*$a3*/) a3.to_asm() => err,
373 inlateout("$8" /*$a4*/) a4.to_asm() => _,
374 lateout("$9" /*$a5*/) _,
375 lateout("$10" /*$a6*/) _,
376 lateout("$11" /*$a7*/) _,
377 lateout("$12" /*$t0*/) _,
378 lateout("$13" /*$t1*/) _,
379 lateout("$14" /*$t2*/) _,
380 lateout("$15" /*$t3*/) _,
381 lateout("$24" /*$t8*/) _,
382 lateout("$25" /*$t9*/) _,
383 options(nostack, preserves_flags, readonly)
384 );
385 FromAsm::from_asm(if err != 0 {
386 (x0 as usize).wrapping_neg() as *mut _
387 } else {
388 x0
389 })
390 }
391
392 #[inline]
syscall6( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, a5: ArgReg<'_, A5>, ) -> RetReg<R0>393 pub(in crate::backend) unsafe fn syscall6(
394 nr: SyscallNumber<'_>,
395 a0: ArgReg<'_, A0>,
396 a1: ArgReg<'_, A1>,
397 a2: ArgReg<'_, A2>,
398 a3: ArgReg<'_, A3>,
399 a4: ArgReg<'_, A4>,
400 a5: ArgReg<'_, A5>,
401 ) -> RetReg<R0> {
402 let x0;
403 let err: usize;
404 asm!(
405 "syscall",
406 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
407 in("$4" /*$a0*/) a0.to_asm(),
408 in("$5" /*$a1*/) a1.to_asm(),
409 in("$6" /*$a2*/) a2.to_asm(),
410 inlateout("$7" /*$a3*/) a3.to_asm() => err,
411 inlateout("$8" /*$a4*/) a4.to_asm() => _,
412 inlateout("$9" /*$a5*/) a5.to_asm() => _,
413 lateout("$10" /*$a6*/) _,
414 lateout("$11" /*$a7*/) _,
415 lateout("$12" /*$t0*/) _,
416 lateout("$13" /*$t1*/) _,
417 lateout("$14" /*$t2*/) _,
418 lateout("$15" /*$t3*/) _,
419 lateout("$24" /*$t8*/) _,
420 lateout("$25" /*$t9*/) _,
421 options(nostack, preserves_flags)
422 );
423 FromAsm::from_asm(if err != 0 {
424 (x0 as usize).wrapping_neg() as *mut _
425 } else {
426 x0
427 })
428 }
429
430 #[inline]
syscall6_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, a5: ArgReg<'_, A5>, ) -> RetReg<R0>431 pub(in crate::backend) unsafe fn syscall6_readonly(
432 nr: SyscallNumber<'_>,
433 a0: ArgReg<'_, A0>,
434 a1: ArgReg<'_, A1>,
435 a2: ArgReg<'_, A2>,
436 a3: ArgReg<'_, A3>,
437 a4: ArgReg<'_, A4>,
438 a5: ArgReg<'_, A5>,
439 ) -> RetReg<R0> {
440 let x0;
441 let err: usize;
442 asm!(
443 "syscall",
444 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
445 in("$4" /*$a0*/) a0.to_asm(),
446 in("$5" /*$a1*/) a1.to_asm(),
447 in("$6" /*$a2*/) a2.to_asm(),
448 inlateout("$7" /*$a3*/) a3.to_asm() => err,
449 inlateout("$8" /*$a4*/) a4.to_asm() => _,
450 inlateout("$9" /*$a5*/) a5.to_asm() => _,
451 lateout("$10" /*$a6*/) _,
452 lateout("$11" /*$a7*/) _,
453 lateout("$12" /*$t0*/) _,
454 lateout("$13" /*$t1*/) _,
455 lateout("$14" /*$t2*/) _,
456 lateout("$15" /*$t3*/) _,
457 lateout("$24" /*$t8*/) _,
458 lateout("$25" /*$t9*/) _,
459 options(nostack, preserves_flags, readonly)
460 );
461 FromAsm::from_asm(if err != 0 {
462 (x0 as usize).wrapping_neg() as *mut _
463 } else {
464 x0
465 })
466 }
467