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