]> git.proxmox.com Git - rustc.git/blob - vendor/rustix/src/backend/linux_raw/arch/outline/nr_last.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / vendor / rustix / src / backend / linux_raw / arch / outline / nr_last.rs
1 //! Syscall wrappers for platforms which pass the syscall number specially.
2 //!
3 //! Rustix aims to minimize the amount of assembly code it needs. To that end,
4 //! this code reorders syscall arguments as close as feasible to the actual
5 //! syscall convention before calling the assembly functions.
6 //!
7 //! Many architectures use a convention where the syscall number is passed in a
8 //! special register, with the regular syscall arguments passed in either the
9 //! same or similar registers as the platform C convention. This code
10 //! approximates that order by passing the regular syscall arguments first, and
11 //! the syscall number last. That way, the outline assembly code typically just
12 //! needs to move the syscall number to its special register, and leave the
13 //! other arguments mostly as they are.
14
15 #[cfg(target_arch = "mips")]
16 use crate::backend::reg::A6;
17 use crate::backend::reg::{ArgReg, RetReg, SyscallNumber, A0, A1, A2, A3, A4, A5, R0};
18
19 // First we declare the actual assembly routines with `*_nr_last` names and
20 // reordered arguments. If the signatures or calling conventions are ever
21 // changed, the symbol names should also be updated accordingly, to avoid
22 // collisions with other versions of this crate.
23 //
24 // We don't define `_readonly` versions of these because we have no way to tell
25 // Rust that calls to our outline assembly are readonly.
26 extern "C" {
27 fn rustix_syscall0_nr_last(nr: SyscallNumber<'_>) -> RetReg<R0>;
28 fn rustix_syscall1_nr_last(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> RetReg<R0>;
29 fn rustix_syscall1_noreturn_nr_last(a0: ArgReg<'_, A0>, nr: SyscallNumber<'_>) -> !;
30 fn rustix_syscall2_nr_last(
31 a0: ArgReg<'_, A0>,
32 a1: ArgReg<'_, A1>,
33 nr: SyscallNumber<'_>,
34 ) -> RetReg<R0>;
35 fn rustix_syscall3_nr_last(
36 a0: ArgReg<'_, A0>,
37 a1: ArgReg<'_, A1>,
38 a2: ArgReg<'_, A2>,
39 nr: SyscallNumber<'_>,
40 ) -> RetReg<R0>;
41 fn rustix_syscall4_nr_last(
42 a0: ArgReg<'_, A0>,
43 a1: ArgReg<'_, A1>,
44 a2: ArgReg<'_, A2>,
45 a3: ArgReg<'_, A3>,
46 nr: SyscallNumber<'_>,
47 ) -> RetReg<R0>;
48 fn rustix_syscall5_nr_last(
49 a0: ArgReg<'_, A0>,
50 a1: ArgReg<'_, A1>,
51 a2: ArgReg<'_, A2>,
52 a3: ArgReg<'_, A3>,
53 a4: ArgReg<'_, A4>,
54 nr: SyscallNumber<'_>,
55 ) -> RetReg<R0>;
56 fn rustix_syscall6_nr_last(
57 a0: ArgReg<'_, A0>,
58 a1: ArgReg<'_, A1>,
59 a2: ArgReg<'_, A2>,
60 a3: ArgReg<'_, A3>,
61 a4: ArgReg<'_, A4>,
62 a5: ArgReg<'_, A5>,
63 nr: SyscallNumber<'_>,
64 ) -> RetReg<R0>;
65 #[cfg(target_arch = "mips")]
66 fn rustix_syscall7_nr_last(
67 a0: ArgReg<'_, A0>,
68 a1: ArgReg<'_, A1>,
69 a2: ArgReg<'_, A2>,
70 a3: ArgReg<'_, A3>,
71 a4: ArgReg<'_, A4>,
72 a5: ArgReg<'_, A5>,
73 a6: ArgReg<'_, A6>,
74 nr: SyscallNumber<'_>,
75 ) -> RetReg<R0>;
76 }
77
78 // Then we define inline wrapper functions that do the reordering.
79
80 #[inline]
81 pub(in crate::backend) unsafe fn syscall0(nr: SyscallNumber<'_>) -> RetReg<R0> {
82 rustix_syscall0_nr_last(nr)
83 }
84 #[inline]
85 pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
86 rustix_syscall1_nr_last(a0, nr)
87 }
88 #[inline]
89 pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! {
90 rustix_syscall1_noreturn_nr_last(a0, nr)
91 }
92 #[inline]
93 pub(in crate::backend) unsafe fn syscall2(
94 nr: SyscallNumber<'_>,
95 a0: ArgReg<'_, A0>,
96 a1: ArgReg<'_, A1>,
97 ) -> RetReg<R0> {
98 rustix_syscall2_nr_last(a0, a1, nr)
99 }
100 #[inline]
101 pub(in crate::backend) unsafe fn syscall3(
102 nr: SyscallNumber<'_>,
103 a0: ArgReg<'_, A0>,
104 a1: ArgReg<'_, A1>,
105 a2: ArgReg<'_, A2>,
106 ) -> RetReg<R0> {
107 rustix_syscall3_nr_last(a0, a1, a2, nr)
108 }
109 #[inline]
110 pub(in crate::backend) unsafe fn syscall4(
111 nr: SyscallNumber<'_>,
112 a0: ArgReg<'_, A0>,
113 a1: ArgReg<'_, A1>,
114 a2: ArgReg<'_, A2>,
115 a3: ArgReg<'_, A3>,
116 ) -> RetReg<R0> {
117 rustix_syscall4_nr_last(a0, a1, a2, a3, nr)
118 }
119 #[inline]
120 pub(in crate::backend) unsafe fn syscall5(
121 nr: SyscallNumber<'_>,
122 a0: ArgReg<'_, A0>,
123 a1: ArgReg<'_, A1>,
124 a2: ArgReg<'_, A2>,
125 a3: ArgReg<'_, A3>,
126 a4: ArgReg<'_, A4>,
127 ) -> RetReg<R0> {
128 rustix_syscall5_nr_last(a0, a1, a2, a3, a4, nr)
129 }
130 #[inline]
131 pub(in crate::backend) unsafe fn syscall6(
132 nr: SyscallNumber<'_>,
133 a0: ArgReg<'_, A0>,
134 a1: ArgReg<'_, A1>,
135 a2: ArgReg<'_, A2>,
136 a3: ArgReg<'_, A3>,
137 a4: ArgReg<'_, A4>,
138 a5: ArgReg<'_, A5>,
139 ) -> RetReg<R0> {
140 rustix_syscall6_nr_last(a0, a1, a2, a3, a4, a5, nr)
141 }
142 #[cfg(target_arch = "mips")]
143 #[inline]
144 pub(in crate::backend) unsafe fn syscall7(
145 nr: SyscallNumber<'_>,
146 a0: ArgReg<'_, A0>,
147 a1: ArgReg<'_, A1>,
148 a2: ArgReg<'_, A2>,
149 a3: ArgReg<'_, A3>,
150 a4: ArgReg<'_, A4>,
151 a5: ArgReg<'_, A5>,
152 a6: ArgReg<'_, A6>,
153 ) -> RetReg<R0> {
154 rustix_syscall7_nr_last(a0, a1, a2, a3, a4, a5, a6, nr)
155 }
156
157 // Then we define the `_readonly` versions of the wrappers. We don't have
158 // separate `_readonly` implementations, so these can just be aliases to
159 // their non-`_readonly` counterparts.
160 #[cfg(target_arch = "mips")]
161 pub(in crate::backend) use syscall7 as syscall7_readonly;
162 pub(in crate::backend) use {
163 syscall0 as syscall0_readonly, syscall1 as syscall1_readonly, syscall2 as syscall2_readonly,
164 syscall3 as syscall3_readonly, syscall4 as syscall4_readonly, syscall5 as syscall5_readonly,
165 syscall6 as syscall6_readonly,
166 };