1 //! arm Linux system calls, using thumb-mode.
2 //!
3 //! In thumb-mode, r7 is the frame pointer and is not permitted to be used in
4 //! an inline asm operand, so we have to use a different register and copy it
5 //! into r7 inside the inline asm.
6
7 use crate::backend::reg::{
8 ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0,
9 };
10 use core::arch::asm;
11
12 #[inline]
syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0>13 pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> {
14 let r0;
15 asm!(
16 "mov {tmp}, r7",
17 "mov r7, {nr}",
18 "svc 0",
19 "mov r7, {tmp}",
20 nr = in(reg) nr.to_asm(),
21 tmp = out(reg) _,
22 lateout("r0") r0,
23 options(nostack, preserves_flags, readonly)
24 );
25 FromAsm::from_asm(r0)
26 }
27
28 #[inline]
syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0>29 pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
30 let r0;
31 asm!(
32 "mov {tmp}, r7",
33 "mov r7, {nr}",
34 "svc 0",
35 "mov r7, {tmp}",
36 nr = in(reg) nr.to_asm(),
37 tmp = out(reg) _,
38 inlateout("r0") a0.to_asm() => r0,
39 options(nostack, preserves_flags)
40 );
41 FromAsm::from_asm(r0)
42 }
43
44 #[inline]
syscall1_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, ) -> RetReg<R0>45 pub(in crate::backend) unsafe fn syscall1_readonly(
46 nr: SyscallNumber<'_>,
47 a0: ArgReg<'_, A0>,
48 ) -> RetReg<R0> {
49 let r0;
50 asm!(
51 "mov {tmp}, r7",
52 "mov r7, {nr}",
53 "svc 0",
54 "mov r7, {tmp}",
55 nr = in(reg) nr.to_asm(),
56 tmp = out(reg) _,
57 inlateout("r0") a0.to_asm() => r0,
58 options(nostack, preserves_flags, readonly)
59 );
60 FromAsm::from_asm(r0)
61 }
62
63 #[inline]
syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> !64 pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! {
65 asm!(
66 "mov r7, {nr}",
67 "svc 0",
68 nr = in(reg) nr.to_asm(),
69 in("r0") a0.to_asm(),
70 options(noreturn)
71 )
72 }
73
74 #[inline]
syscall2( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, ) -> RetReg<R0>75 pub(in crate::backend) unsafe fn syscall2(
76 nr: SyscallNumber<'_>,
77 a0: ArgReg<'_, A0>,
78 a1: ArgReg<'_, A1>,
79 ) -> RetReg<R0> {
80 let r0;
81 asm!(
82 "mov {tmp}, r7",
83 "mov r7, {nr}",
84 "svc 0",
85 "mov r7, {tmp}",
86 nr = in(reg) nr.to_asm(),
87 tmp = out(reg) _,
88 inlateout("r0") a0.to_asm() => r0,
89 in("r1") a1.to_asm(),
90 options(nostack, preserves_flags)
91 );
92 FromAsm::from_asm(r0)
93 }
94
95 #[inline]
syscall2_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, ) -> RetReg<R0>96 pub(in crate::backend) unsafe fn syscall2_readonly(
97 nr: SyscallNumber<'_>,
98 a0: ArgReg<'_, A0>,
99 a1: ArgReg<'_, A1>,
100 ) -> RetReg<R0> {
101 let r0;
102 asm!(
103 "mov {tmp}, r7",
104 "mov r7, {nr}",
105 "svc 0",
106 "mov r7, {tmp}",
107 nr = in(reg) nr.to_asm(),
108 tmp = out(reg) _,
109 inlateout("r0") a0.to_asm() => r0,
110 in("r1") a1.to_asm(),
111 options(nostack, preserves_flags, readonly)
112 );
113 FromAsm::from_asm(r0)
114 }
115
116 #[inline]
syscall3( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, ) -> RetReg<R0>117 pub(in crate::backend) unsafe fn syscall3(
118 nr: SyscallNumber<'_>,
119 a0: ArgReg<'_, A0>,
120 a1: ArgReg<'_, A1>,
121 a2: ArgReg<'_, A2>,
122 ) -> RetReg<R0> {
123 let r0;
124 asm!(
125 "mov {tmp}, r7",
126 "mov r7, {nr}",
127 "svc 0",
128 "mov r7, {tmp}",
129 nr = in(reg) nr.to_asm(),
130 tmp = out(reg) _,
131 inlateout("r0") a0.to_asm() => r0,
132 in("r1") a1.to_asm(),
133 in("r2") a2.to_asm(),
134 options(nostack, preserves_flags)
135 );
136 FromAsm::from_asm(r0)
137 }
138
139 #[inline]
syscall3_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, ) -> RetReg<R0>140 pub(in crate::backend) unsafe fn syscall3_readonly(
141 nr: SyscallNumber<'_>,
142 a0: ArgReg<'_, A0>,
143 a1: ArgReg<'_, A1>,
144 a2: ArgReg<'_, A2>,
145 ) -> RetReg<R0> {
146 let r0;
147 asm!(
148 "mov {tmp}, r7",
149 "mov r7, {nr}",
150 "svc 0",
151 "mov r7, {tmp}",
152 nr = in(reg) nr.to_asm(),
153 tmp = out(reg) _,
154 inlateout("r0") a0.to_asm() => r0,
155 in("r1") a1.to_asm(),
156 in("r2") a2.to_asm(),
157 options(nostack, preserves_flags, readonly)
158 );
159 FromAsm::from_asm(r0)
160 }
161
162 #[inline]
syscall4( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, ) -> RetReg<R0>163 pub(in crate::backend) unsafe fn syscall4(
164 nr: SyscallNumber<'_>,
165 a0: ArgReg<'_, A0>,
166 a1: ArgReg<'_, A1>,
167 a2: ArgReg<'_, A2>,
168 a3: ArgReg<'_, A3>,
169 ) -> RetReg<R0> {
170 let r0;
171 asm!(
172 "mov {tmp}, r7",
173 "mov r7, {nr}",
174 "svc 0",
175 "mov r7, {tmp}",
176 nr = in(reg) nr.to_asm(),
177 tmp = out(reg) _,
178 inlateout("r0") a0.to_asm() => r0,
179 in("r1") a1.to_asm(),
180 in("r2") a2.to_asm(),
181 in("r3") a3.to_asm(),
182 options(nostack, preserves_flags)
183 );
184 FromAsm::from_asm(r0)
185 }
186
187 #[inline]
syscall4_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, ) -> RetReg<R0>188 pub(in crate::backend) unsafe fn syscall4_readonly(
189 nr: SyscallNumber<'_>,
190 a0: ArgReg<'_, A0>,
191 a1: ArgReg<'_, A1>,
192 a2: ArgReg<'_, A2>,
193 a3: ArgReg<'_, A3>,
194 ) -> RetReg<R0> {
195 let r0;
196 asm!(
197 "mov {tmp}, r7",
198 "mov r7, {nr}",
199 "svc 0",
200 "mov r7, {tmp}",
201 nr = in(reg) nr.to_asm(),
202 tmp = out(reg) _,
203 inlateout("r0") a0.to_asm() => r0,
204 in("r1") a1.to_asm(),
205 in("r2") a2.to_asm(),
206 in("r3") a3.to_asm(),
207 options(nostack, preserves_flags, readonly)
208 );
209 FromAsm::from_asm(r0)
210 }
211
212 #[inline]
syscall5( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>213 pub(in crate::backend) unsafe fn syscall5(
214 nr: SyscallNumber<'_>,
215 a0: ArgReg<'_, A0>,
216 a1: ArgReg<'_, A1>,
217 a2: ArgReg<'_, A2>,
218 a3: ArgReg<'_, A3>,
219 a4: ArgReg<'_, A4>,
220 ) -> RetReg<R0> {
221 let r0;
222 asm!(
223 "mov {tmp}, r7",
224 "mov r7, {nr}",
225 "svc 0",
226 "mov r7, {tmp}",
227 nr = in(reg) nr.to_asm(),
228 tmp = out(reg) _,
229 inlateout("r0") a0.to_asm() => r0,
230 in("r1") a1.to_asm(),
231 in("r2") a2.to_asm(),
232 in("r3") a3.to_asm(),
233 in("r4") a4.to_asm(),
234 options(nostack, preserves_flags)
235 );
236 FromAsm::from_asm(r0)
237 }
238
239 #[inline]
syscall5_readonly( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, ) -> RetReg<R0>240 pub(in crate::backend) unsafe fn syscall5_readonly(
241 nr: SyscallNumber<'_>,
242 a0: ArgReg<'_, A0>,
243 a1: ArgReg<'_, A1>,
244 a2: ArgReg<'_, A2>,
245 a3: ArgReg<'_, A3>,
246 a4: ArgReg<'_, A4>,
247 ) -> RetReg<R0> {
248 let r0;
249 asm!(
250 "mov {tmp}, r7",
251 "mov r7, {nr}",
252 "svc 0",
253 "mov r7, {tmp}",
254 nr = in(reg) nr.to_asm(),
255 tmp = out(reg) _,
256 inlateout("r0") a0.to_asm() => r0,
257 in("r1") a1.to_asm(),
258 in("r2") a2.to_asm(),
259 in("r3") a3.to_asm(),
260 in("r4") a4.to_asm(),
261 options(nostack, preserves_flags, readonly)
262 );
263 FromAsm::from_asm(r0)
264 }
265
266 #[inline]
syscall6( nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>, a1: ArgReg<'_, A1>, a2: ArgReg<'_, A2>, a3: ArgReg<'_, A3>, a4: ArgReg<'_, A4>, a5: ArgReg<'_, A5>, ) -> RetReg<R0>267 pub(in crate::backend) unsafe fn syscall6(
268 nr: SyscallNumber<'_>,
269 a0: ArgReg<'_, A0>,
270 a1: ArgReg<'_, A1>,
271 a2: ArgReg<'_, A2>,
272 a3: ArgReg<'_, A3>,
273 a4: ArgReg<'_, A4>,
274 a5: ArgReg<'_, A5>,
275 ) -> RetReg<R0> {
276 let r0;
277 asm!(
278 "mov {tmp}, r7",
279 "mov r7, {nr}",
280 "svc 0",
281 "mov r7, {tmp}",
282 nr = in(reg) nr.to_asm(),
283 tmp = out(reg) _,
284 inlateout("r0") a0.to_asm() => r0,
285 in("r1") a1.to_asm(),
286 in("r2") a2.to_asm(),
287 in("r3") a3.to_asm(),
288 in("r4") a4.to_asm(),
289 in("r5") a5.to_asm(),
290 options(nostack, preserves_flags)
291 );
292 FromAsm::from_asm(r0)
293 }
294
295 #[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>296 pub(in crate::backend) unsafe fn syscall6_readonly(
297 nr: SyscallNumber<'_>,
298 a0: ArgReg<'_, A0>,
299 a1: ArgReg<'_, A1>,
300 a2: ArgReg<'_, A2>,
301 a3: ArgReg<'_, A3>,
302 a4: ArgReg<'_, A4>,
303 a5: ArgReg<'_, A5>,
304 ) -> RetReg<R0> {
305 let r0;
306 asm!(
307 "mov {tmp}, r7",
308 "mov r7, {nr}",
309 "svc 0",
310 "mov r7, {tmp}",
311 nr = in(reg) nr.to_asm(),
312 tmp = out(reg) _,
313 inlateout("r0") a0.to_asm() => r0,
314 in("r1") a1.to_asm(),
315 in("r2") a2.to_asm(),
316 in("r3") a3.to_asm(),
317 in("r4") a4.to_asm(),
318 in("r5") a5.to_asm(),
319 options(nostack, preserves_flags, readonly)
320 );
321 FromAsm::from_asm(r0)
322 }
323