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