1 //! mipsel Linux system calls.
2 //!
3 //! On mipsel, Linux indicates success or failure using `$a3` 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, A6, 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" /*$t0*/) _,
23 lateout("$9" /*$t1*/) _,
24 lateout("$10" /*$t2*/) _,
25 lateout("$11" /*$t3*/) _,
26 lateout("$12" /*$t4*/) _,
27 lateout("$13" /*$t5*/) _,
28 lateout("$14" /*$t6*/) _,
29 lateout("$15" /*$t7*/) _,
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" /*$t0*/) _,
51 lateout("$9" /*$t1*/) _,
52 lateout("$10" /*$t2*/) _,
53 lateout("$11" /*$t3*/) _,
54 lateout("$12" /*$t4*/) _,
55 lateout("$13" /*$t5*/) _,
56 lateout("$14" /*$t6*/) _,
57 lateout("$15" /*$t7*/) _,
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" /*$t0*/) _,
82 lateout("$9" /*$t1*/) _,
83 lateout("$10" /*$t2*/) _,
84 lateout("$11" /*$t3*/) _,
85 lateout("$12" /*$t4*/) _,
86 lateout("$13" /*$t5*/) _,
87 lateout("$14" /*$t6*/) _,
88 lateout("$15" /*$t7*/) _,
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(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" /*$t0*/) _,
125 lateout("$9" /*$t1*/) _,
126 lateout("$10" /*$t2*/) _,
127 lateout("$11" /*$t3*/) _,
128 lateout("$12" /*$t4*/) _,
129 lateout("$13" /*$t5*/) _,
130 lateout("$14" /*$t6*/) _,
131 lateout("$15" /*$t7*/) _,
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" /*$t0*/) _,
158 lateout("$9" /*$t1*/) _,
159 lateout("$10" /*$t2*/) _,
160 lateout("$11" /*$t3*/) _,
161 lateout("$12" /*$t4*/) _,
162 lateout("$13" /*$t5*/) _,
163 lateout("$14" /*$t6*/) _,
164 lateout("$15" /*$t7*/) _,
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" /*$t0*/) _,
193 lateout("$9" /*$t1*/) _,
194 lateout("$10" /*$t2*/) _,
195 lateout("$11" /*$t3*/) _,
196 lateout("$12" /*$t4*/) _,
197 lateout("$13" /*$t5*/) _,
198 lateout("$14" /*$t6*/) _,
199 lateout("$15" /*$t7*/) _,
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" /*$t0*/) _,
228 lateout("$9" /*$t1*/) _,
229 lateout("$10" /*$t2*/) _,
230 lateout("$11" /*$t3*/) _,
231 lateout("$12" /*$t4*/) _,
232 lateout("$13" /*$t5*/) _,
233 lateout("$14" /*$t6*/) _,
234 lateout("$15" /*$t7*/) _,
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" /*$t0*/) _,
264 lateout("$9" /*$t1*/) _,
265 lateout("$10" /*$t2*/) _,
266 lateout("$11" /*$t3*/) _,
267 lateout("$12" /*$t4*/) _,
268 lateout("$13" /*$t5*/) _,
269 lateout("$14" /*$t6*/) _,
270 lateout("$15" /*$t7*/) _,
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" /*$t0*/) _,
300 lateout("$9" /*$t1*/) _,
301 lateout("$10" /*$t2*/) _,
302 lateout("$11" /*$t3*/) _,
303 lateout("$12" /*$t4*/) _,
304 lateout("$13" /*$t5*/) _,
305 lateout("$14" /*$t6*/) _,
306 lateout("$15" /*$t7*/) _,
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 ".set noat",
331 "subu $sp, 32",
332 "sw {}, 16($sp)",
333 "syscall",
334 "addu $sp, 32",
335 ".set at",
336 in(reg) a4.to_asm(),
337 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
338 in("$4" /*$a0*/) a0.to_asm(),
339 in("$5" /*$a1*/) a1.to_asm(),
340 in("$6" /*$a2*/) a2.to_asm(),
341 inlateout("$7" /*$a3*/) a3.to_asm() => err,
342 lateout("$8" /*$t0*/) _,
343 lateout("$9" /*$t1*/) _,
344 lateout("$10" /*$t2*/) _,
345 lateout("$11" /*$t3*/) _,
346 lateout("$12" /*$t4*/) _,
347 lateout("$13" /*$t5*/) _,
348 lateout("$14" /*$t6*/) _,
349 lateout("$15" /*$t7*/) _,
350 lateout("$24" /*$t8*/) _,
351 lateout("$25" /*$t9*/) _,
352 options(preserves_flags)
353 );
354 FromAsm::from_asm(if err != 0 {
355 (x0 as usize).wrapping_neg() as *mut _
356 } else {
357 x0
358 })
359 }
360
361 #[inline]
syscall5_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>362 pub(in crate::backend) unsafe fn syscall5_readonly(
363 nr: SyscallNumber<'_>,
364 a0: ArgReg<'_, A0>,
365 a1: ArgReg<'_, A1>,
366 a2: ArgReg<'_, A2>,
367 a3: ArgReg<'_, A3>,
368 a4: ArgReg<'_, A4>,
369 ) -> RetReg<R0> {
370 let x0;
371 let err: usize;
372 asm!(
373 ".set noat",
374 "subu $sp, 32",
375 "sw {}, 16($sp)",
376 "syscall",
377 "addu $sp, 32",
378 ".set at",
379 in(reg) a4.to_asm(),
380 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
381 in("$4" /*$a0*/) a0.to_asm(),
382 in("$5" /*$a1*/) a1.to_asm(),
383 in("$6" /*$a2*/) a2.to_asm(),
384 inlateout("$7" /*$a3*/) a3.to_asm() => err,
385 lateout("$8" /*$t0*/) _,
386 lateout("$9" /*$t1*/) _,
387 lateout("$10" /*$t2*/) _,
388 lateout("$11" /*$t3*/) _,
389 lateout("$12" /*$t4*/) _,
390 lateout("$13" /*$t5*/) _,
391 lateout("$14" /*$t6*/) _,
392 lateout("$15" /*$t7*/) _,
393 lateout("$24" /*$t8*/) _,
394 lateout("$25" /*$t9*/) _,
395 options(preserves_flags, readonly)
396 );
397 FromAsm::from_asm(if err != 0 {
398 (x0 as usize).wrapping_neg() as *mut _
399 } else {
400 x0
401 })
402 }
403
404 #[inline]
syscall6( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, a5: ArgReg<'_, A5>, ) -> RetReg<R0>405 pub(in crate::backend) unsafe fn syscall6(
406 nr: SyscallNumber<'_>,
407 a0: ArgReg<'_, A0>,
408 a1: ArgReg<'_, A1>,
409 a2: ArgReg<'_, A2>,
410 a3: ArgReg<'_, A3>,
411 a4: ArgReg<'_, A4>,
412 a5: ArgReg<'_, A5>,
413 ) -> RetReg<R0> {
414 let x0;
415 let err: usize;
416 asm!(
417 ".set noat",
418 "subu $sp, 32",
419 "sw {}, 16($sp)",
420 "sw {}, 20($sp)",
421 "syscall",
422 "addu $sp, 32",
423 ".set at",
424 in(reg) a4.to_asm(),
425 in(reg) a5.to_asm(),
426 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
427 in("$4" /*$a0*/) a0.to_asm(),
428 in("$5" /*$a1*/) a1.to_asm(),
429 in("$6" /*$a2*/) a2.to_asm(),
430 inlateout("$7" /*$a3*/) a3.to_asm() => err,
431 lateout("$8" /*$t0*/) _,
432 lateout("$9" /*$t1*/) _,
433 lateout("$10" /*$t2*/) _,
434 lateout("$11" /*$t3*/) _,
435 lateout("$12" /*$t4*/) _,
436 lateout("$13" /*$t5*/) _,
437 lateout("$14" /*$t6*/) _,
438 lateout("$15" /*$t7*/) _,
439 lateout("$24" /*$t8*/) _,
440 lateout("$25" /*$t9*/) _,
441 options(preserves_flags)
442 );
443 FromAsm::from_asm(if err != 0 {
444 (x0 as usize).wrapping_neg() as *mut _
445 } else {
446 x0
447 })
448 }
449
450 #[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>451 pub(in crate::backend) unsafe fn syscall6_readonly(
452 nr: SyscallNumber<'_>,
453 a0: ArgReg<'_, A0>,
454 a1: ArgReg<'_, A1>,
455 a2: ArgReg<'_, A2>,
456 a3: ArgReg<'_, A3>,
457 a4: ArgReg<'_, A4>,
458 a5: ArgReg<'_, A5>,
459 ) -> RetReg<R0> {
460 let x0;
461 let err: usize;
462 asm!(
463 ".set noat",
464 "subu $sp, 32",
465 "sw {}, 16($sp)",
466 "sw {}, 20($sp)",
467 "syscall",
468 "addu $sp, 32",
469 ".set at",
470 in(reg) a4.to_asm(),
471 in(reg) a5.to_asm(),
472 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
473 in("$4" /*$a0*/) a0.to_asm(),
474 in("$5" /*$a1*/) a1.to_asm(),
475 in("$6" /*$a2*/) a2.to_asm(),
476 inlateout("$7" /*$a3*/) a3.to_asm() => err,
477 lateout("$8" /*$t0*/) _,
478 lateout("$9" /*$t1*/) _,
479 lateout("$10" /*$t2*/) _,
480 lateout("$11" /*$t3*/) _,
481 lateout("$12" /*$t4*/) _,
482 lateout("$13" /*$t5*/) _,
483 lateout("$14" /*$t6*/) _,
484 lateout("$15" /*$t7*/) _,
485 lateout("$24" /*$t8*/) _,
486 lateout("$25" /*$t9*/) _,
487 options(preserves_flags, readonly)
488 );
489 FromAsm::from_asm(if err != 0 {
490 (x0 as usize).wrapping_neg() as *mut _
491 } else {
492 x0
493 })
494 }
495
496 #[inline]
syscall7_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, a5: ArgReg<'_, A5>, a6: ArgReg<'_, A6>, ) -> RetReg<R0>497 pub(in crate::backend) unsafe fn syscall7_readonly(
498 nr: SyscallNumber<'_>,
499 a0: ArgReg<'_, A0>,
500 a1: ArgReg<'_, A1>,
501 a2: ArgReg<'_, A2>,
502 a3: ArgReg<'_, A3>,
503 a4: ArgReg<'_, A4>,
504 a5: ArgReg<'_, A5>,
505 a6: ArgReg<'_, A6>,
506 ) -> RetReg<R0> {
507 let x0;
508 let err: usize;
509 asm!(
510 ".set noat",
511 "subu $sp, 32",
512 "sw {}, 16($sp)",
513 "sw {}, 20($sp)",
514 "sw {}, 24($sp)",
515 "syscall",
516 "addu $sp, 32",
517 ".set at",
518 in(reg) a4.to_asm(),
519 in(reg) a5.to_asm(),
520 in(reg) a6.to_asm(),
521 inlateout("$2" /*$v0*/) nr.to_asm() => x0,
522 in("$4" /*$a0*/) a0.to_asm(),
523 in("$5" /*$a1*/) a1.to_asm(),
524 in("$6" /*$a2*/) a2.to_asm(),
525 inlateout("$7" /*$a3*/) a3.to_asm() => err,
526 lateout("$8" /*$t0*/) _,
527 lateout("$9" /*$t1*/) _,
528 lateout("$10" /*$t2*/) _,
529 lateout("$11" /*$t3*/) _,
530 lateout("$12" /*$t4*/) _,
531 lateout("$13" /*$t5*/) _,
532 lateout("$14" /*$t6*/) _,
533 lateout("$15" /*$t7*/) _,
534 lateout("$24" /*$t8*/) _,
535 lateout("$25" /*$t9*/) _,
536 options(preserves_flags, readonly)
537 );
538 FromAsm::from_asm(if err != 0 {
539 (x0 as usize).wrapping_neg() as *mut _
540 } else {
541 x0
542 })
543 }
544