1//! x86-64 Linux system calls.
2
3use crate::backend::reg::{
4 ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0,
5};
6use core::arch::asm;
7
8#[cfg(target_pointer_width = "32")]
9compile_error!("x32 is not yet supported");
10
11#[inline]
12pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> {
13 let r0: *mut Opaque;
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(raw:r0)
22}
23
24#[inline]
25pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
26 let r0: *mut Opaque;
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(raw:r0)
36}
37
38#[inline]
39pub(in crate::backend) unsafe fn syscall1_readonly(
40 nr: SyscallNumber<'_>,
41 a0: ArgReg<'_, A0>,
42) -> RetReg<R0> {
43 let r0: *mut Opaque;
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(raw:r0)
53}
54
55#[inline]
56pub(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(noreturn)
62 )
63}
64
65#[inline]
66pub(in crate::backend) unsafe fn syscall2(
67 nr: SyscallNumber<'_>,
68 a0: ArgReg<'_, A0>,
69 a1: ArgReg<'_, A1>,
70) -> RetReg<R0> {
71 let r0: *mut Opaque;
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(raw:r0)
82}
83
84#[inline]
85pub(in crate::backend) unsafe fn syscall2_readonly(
86 nr: SyscallNumber<'_>,
87 a0: ArgReg<'_, A0>,
88 a1: ArgReg<'_, A1>,
89) -> RetReg<R0> {
90 let r0: *mut Opaque;
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(raw:r0)
101}
102
103#[inline]
104pub(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: *mut Opaque;
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(raw:r0)
122}
123
124#[inline]
125pub(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: *mut Opaque;
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(raw:r0)
143}
144
145#[inline]
146pub(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: *mut Opaque;
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(raw:r0)
166}
167
168#[inline]
169pub(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: *mut Opaque;
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(raw:r0)
189}
190
191#[inline]
192pub(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: *mut Opaque;
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(raw:r0)
214}
215
216#[inline]
217pub(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: *mut Opaque;
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(raw:r0)
239}
240
241#[inline]
242pub(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: *mut Opaque;
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(raw:r0)
266}
267
268#[inline]
269pub(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: *mut Opaque;
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(raw:r0)
293}
294