1 //! aarch64 Linux system calls.
2 
3 use crate::backend::reg::{
4     ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0,
5 };
6 use core::arch::asm;
7 
8 #[cfg(target_pointer_width = "32")]
9 compile_error!("arm64-ilp32 is not supported yet");
10 
11 #[inline]
syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0>12 pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> {
13     let r0;
14     asm!(
15         "svc 0",
16         in("x8") nr.to_asm(),
17         lateout("x0") r0,
18         options(nostack, preserves_flags, readonly)
19     );
20     FromAsm::from_asm(r0)
21 }
22 
23 #[inline]
syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0>24 pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
25     let r0;
26     asm!(
27         "svc 0",
28         in("x8") nr.to_asm(),
29         inlateout("x0") a0.to_asm() => r0,
30         options(nostack, preserves_flags)
31     );
32     FromAsm::from_asm(r0)
33 }
34 
35 #[inline]
syscall1_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, ) -> RetReg<R0>36 pub(in crate::backend) unsafe fn syscall1_readonly(
37     nr: SyscallNumber<'_>,
38     a0: ArgReg<'_, A0>,
39 ) -> RetReg<R0> {
40     let r0;
41     asm!(
42         "svc 0",
43         in("x8") nr.to_asm(),
44         inlateout("x0") a0.to_asm() => r0,
45         options(nostack, preserves_flags, readonly)
46     );
47     FromAsm::from_asm(r0)
48 }
49 
50 #[inline]
syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> !51 pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! {
52     asm!(
53         "svc 0",
54         in("x8") nr.to_asm(),
55         in("x0") a0.to_asm(),
56         options(nostack, noreturn)
57     )
58 }
59 
60 #[inline]
syscall2( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, ) -> RetReg<R0>61 pub(in crate::backend) unsafe fn syscall2(
62     nr: SyscallNumber<'_>,
63     a0: ArgReg<'_, A0>,
64     a1: ArgReg<'_, A1>,
65 ) -> RetReg<R0> {
66     let r0;
67     asm!(
68         "svc 0",
69         in("x8") nr.to_asm(),
70         inlateout("x0") a0.to_asm() => r0,
71         in("x1") a1.to_asm(),
72         options(nostack, preserves_flags)
73     );
74     FromAsm::from_asm(r0)
75 }
76 
77 #[inline]
syscall2_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, ) -> RetReg<R0>78 pub(in crate::backend) unsafe fn syscall2_readonly(
79     nr: SyscallNumber<'_>,
80     a0: ArgReg<'_, A0>,
81     a1: ArgReg<'_, A1>,
82 ) -> RetReg<R0> {
83     let r0;
84     asm!(
85         "svc 0",
86         in("x8") nr.to_asm(),
87         inlateout("x0") a0.to_asm() => r0,
88         in("x1") a1.to_asm(),
89         options(nostack, preserves_flags, readonly)
90     );
91     FromAsm::from_asm(r0)
92 }
93 
94 #[inline]
syscall3( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, ) -> RetReg<R0>95 pub(in crate::backend) unsafe fn syscall3(
96     nr: SyscallNumber<'_>,
97     a0: ArgReg<'_, A0>,
98     a1: ArgReg<'_, A1>,
99     a2: ArgReg<'_, A2>,
100 ) -> RetReg<R0> {
101     let r0;
102     asm!(
103         "svc 0",
104         in("x8") nr.to_asm(),
105         inlateout("x0") a0.to_asm() => r0,
106         in("x1") a1.to_asm(),
107         in("x2") a2.to_asm(),
108         options(nostack, preserves_flags)
109     );
110     FromAsm::from_asm(r0)
111 }
112 
113 #[inline]
syscall3_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, ) -> RetReg<R0>114 pub(in crate::backend) unsafe fn syscall3_readonly(
115     nr: SyscallNumber<'_>,
116     a0: ArgReg<'_, A0>,
117     a1: ArgReg<'_, A1>,
118     a2: ArgReg<'_, A2>,
119 ) -> RetReg<R0> {
120     let r0;
121     asm!(
122         "svc 0",
123         in("x8") nr.to_asm(),
124         inlateout("x0") a0.to_asm() => r0,
125         in("x1") a1.to_asm(),
126         in("x2") a2.to_asm(),
127         options(nostack, preserves_flags, readonly)
128     );
129     FromAsm::from_asm(r0)
130 }
131 
132 #[inline]
syscall4( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, ) -> RetReg<R0>133 pub(in crate::backend) unsafe fn syscall4(
134     nr: SyscallNumber<'_>,
135     a0: ArgReg<'_, A0>,
136     a1: ArgReg<'_, A1>,
137     a2: ArgReg<'_, A2>,
138     a3: ArgReg<'_, A3>,
139 ) -> RetReg<R0> {
140     let r0;
141     asm!(
142         "svc 0",
143         in("x8") nr.to_asm(),
144         inlateout("x0") a0.to_asm() => r0,
145         in("x1") a1.to_asm(),
146         in("x2") a2.to_asm(),
147         in("x3") a3.to_asm(),
148         options(nostack, preserves_flags)
149     );
150     FromAsm::from_asm(r0)
151 }
152 
153 #[inline]
syscall4_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, ) -> RetReg<R0>154 pub(in crate::backend) unsafe fn syscall4_readonly(
155     nr: SyscallNumber<'_>,
156     a0: ArgReg<'_, A0>,
157     a1: ArgReg<'_, A1>,
158     a2: ArgReg<'_, A2>,
159     a3: ArgReg<'_, A3>,
160 ) -> RetReg<R0> {
161     let r0;
162     asm!(
163         "svc 0",
164         in("x8") nr.to_asm(),
165         inlateout("x0") a0.to_asm() => r0,
166         in("x1") a1.to_asm(),
167         in("x2") a2.to_asm(),
168         in("x3") a3.to_asm(),
169         options(nostack, preserves_flags, readonly)
170     );
171     FromAsm::from_asm(r0)
172 }
173 
174 #[inline]
syscall5( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>175 pub(in crate::backend) unsafe fn syscall5(
176     nr: SyscallNumber<'_>,
177     a0: ArgReg<'_, A0>,
178     a1: ArgReg<'_, A1>,
179     a2: ArgReg<'_, A2>,
180     a3: ArgReg<'_, A3>,
181     a4: ArgReg<'_, A4>,
182 ) -> RetReg<R0> {
183     let r0;
184     asm!(
185         "svc 0",
186         in("x8") nr.to_asm(),
187         inlateout("x0") a0.to_asm() => r0,
188         in("x1") a1.to_asm(),
189         in("x2") a2.to_asm(),
190         in("x3") a3.to_asm(),
191         in("x4") a4.to_asm(),
192         options(nostack, preserves_flags)
193     );
194     FromAsm::from_asm(r0)
195 }
196 
197 #[inline]
syscall5_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>198 pub(in crate::backend) unsafe fn syscall5_readonly(
199     nr: SyscallNumber<'_>,
200     a0: ArgReg<'_, A0>,
201     a1: ArgReg<'_, A1>,
202     a2: ArgReg<'_, A2>,
203     a3: ArgReg<'_, A3>,
204     a4: ArgReg<'_, A4>,
205 ) -> RetReg<R0> {
206     let r0;
207     asm!(
208         "svc 0",
209         in("x8") nr.to_asm(),
210         inlateout("x0") a0.to_asm() => r0,
211         in("x1") a1.to_asm(),
212         in("x2") a2.to_asm(),
213         in("x3") a3.to_asm(),
214         in("x4") a4.to_asm(),
215         options(nostack, preserves_flags, readonly)
216     );
217     FromAsm::from_asm(r0)
218 }
219 
220 #[inline]
syscall6( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, a5: ArgReg<'_, A5>, ) -> RetReg<R0>221 pub(in crate::backend) unsafe fn syscall6(
222     nr: SyscallNumber<'_>,
223     a0: ArgReg<'_, A0>,
224     a1: ArgReg<'_, A1>,
225     a2: ArgReg<'_, A2>,
226     a3: ArgReg<'_, A3>,
227     a4: ArgReg<'_, A4>,
228     a5: ArgReg<'_, A5>,
229 ) -> RetReg<R0> {
230     let r0;
231     asm!(
232         "svc 0",
233         in("x8") nr.to_asm(),
234         inlateout("x0") a0.to_asm() => r0,
235         in("x1") a1.to_asm(),
236         in("x2") a2.to_asm(),
237         in("x3") a3.to_asm(),
238         in("x4") a4.to_asm(),
239         in("x5") a5.to_asm(),
240         options(nostack, preserves_flags)
241     );
242     FromAsm::from_asm(r0)
243 }
244 
245 #[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>246 pub(in crate::backend) unsafe fn syscall6_readonly(
247     nr: SyscallNumber<'_>,
248     a0: ArgReg<'_, A0>,
249     a1: ArgReg<'_, A1>,
250     a2: ArgReg<'_, A2>,
251     a3: ArgReg<'_, A3>,
252     a4: ArgReg<'_, A4>,
253     a5: ArgReg<'_, A5>,
254 ) -> RetReg<R0> {
255     let r0;
256     asm!(
257         "svc 0",
258         in("x8") nr.to_asm(),
259         inlateout("x0") a0.to_asm() => r0,
260         in("x1") a1.to_asm(),
261         in("x2") a2.to_asm(),
262         in("x3") a3.to_asm(),
263         in("x4") a4.to_asm(),
264         in("x5") a5.to_asm(),
265         options(nostack, preserves_flags, readonly)
266     );
267     FromAsm::from_asm(r0)
268 }
269