• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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