1const builtin = @import("builtin");
2const std = @import("../../std.zig");
3const SYS = std.os.linux.SYS;
4
5pub const syscall_arg_t = u32;
6
7pub fn syscall0(
8 number: SYS,
9) u32 {
10 return asm volatile ("trap0(#1)"
11 : [ret] "={r0}" (-> u32),
12 : [number] "{r6}" (@backingInt(number)),
13 : .{ .memory = true });
14}
15
16pub fn syscall1(
17 number: SYS,
18 arg1: syscall_arg_t,
19) u32 {
20 return asm volatile ("trap0(#1)"
21 : [ret] "={r0}" (-> u32),
22 : [number] "{r6}" (@backingInt(number)),
23 [arg1] "{r0}" (arg1),
24 : .{ .memory = true });
25}
26
27pub fn syscall2(
28 number: SYS,
29 arg1: syscall_arg_t,
30 arg2: syscall_arg_t,
31) u32 {
32 return asm volatile ("trap0(#1)"
33 : [ret] "={r0}" (-> u32),
34 : [number] "{r6}" (@backingInt(number)),
35 [arg1] "{r0}" (arg1),
36 [arg2] "{r1}" (arg2),
37 : .{ .memory = true });
38}
39
40pub fn syscall3(
41 number: SYS,
42 arg1: syscall_arg_t,
43 arg2: syscall_arg_t,
44 arg3: syscall_arg_t,
45) u32 {
46 return asm volatile ("trap0(#1)"
47 : [ret] "={r0}" (-> u32),
48 : [number] "{r6}" (@backingInt(number)),
49 [arg1] "{r0}" (arg1),
50 [arg2] "{r1}" (arg2),
51 [arg3] "{r2}" (arg3),
52 : .{ .memory = true });
53}
54
55pub fn syscall4(
56 number: SYS,
57 arg1: syscall_arg_t,
58 arg2: syscall_arg_t,
59 arg3: syscall_arg_t,
60 arg4: syscall_arg_t,
61) u32 {
62 return asm volatile ("trap0(#1)"
63 : [ret] "={r0}" (-> u32),
64 : [number] "{r6}" (@backingInt(number)),
65 [arg1] "{r0}" (arg1),
66 [arg2] "{r1}" (arg2),
67 [arg3] "{r2}" (arg3),
68 [arg4] "{r3}" (arg4),
69 : .{ .memory = true });
70}
71
72pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
73 return asm volatile ("trap0(#1)"
74 : [ret] "={r0}" (-> u32),
75 : [number] "{r6}" (@backingInt(number)),
76 [arg1] "{r0}" (arg1),
77 [arg2] "{r1}" (arg2),
78 [arg3] "{r2}" (arg3),
79 [arg4] "{r3}" (arg4),
80 [arg5] "{r4}" (arg5),
81 : .{ .memory = true });
82}
83
84pub fn syscall6(
85 number: SYS,
86 arg1: syscall_arg_t,
87 arg2: syscall_arg_t,
88 arg3: syscall_arg_t,
89 arg4: syscall_arg_t,
90 arg5: syscall_arg_t,
91 arg6: syscall_arg_t,
92) u32 {
93 return asm volatile ("trap0(#1)"
94 : [ret] "={r0}" (-> u32),
95 : [number] "{r6}" (@backingInt(number)),
96 [arg1] "{r0}" (arg1),
97 [arg2] "{r1}" (arg2),
98 [arg3] "{r2}" (arg3),
99 [arg4] "{r3}" (arg4),
100 [arg5] "{r4}" (arg5),
101 [arg6] "{r5}" (arg6),
102 : .{ .memory = true });
103}
104
105pub fn clone() callconv(.naked) u32 {
106 // __clone(func, stack, flags, arg, ptid, tls, ctid)
107 // r0, r1, r2, r3, r4, r5, +0
108 //
109 // syscall(SYS_clone, flags, stack, ptid, ctid, tls)
110 // r6 r0, r1, r2, r3, r4
111 asm volatile (
112 \\ allocframe(#8)
113 \\
114 \\ r11 = r0
115 \\ r10 = r3
116 \\
117 \\ r6 = #220 // SYS_clone
118 \\ r0 = r2
119 \\ r1 = and(r1, #-8)
120 \\ r2 = r4
121 \\ r3 = memw(r30 + #8)
122 \\ r4 = r5
123 \\ trap0(#1)
124 \\
125 \\ p0 = cmp.eq(r0, #0)
126 \\ if (!p0) dealloc_return
127 );
128 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
129 \\ .cfi_undefined r31
130 );
131 asm volatile (
132 \\ r30 = #0
133 \\ r31 = #0
134 \\
135 \\ r0 = r10
136 \\ callr r11
137 \\
138 \\ r6 = #93 // SYS_exit
139 \\ r0 = #0
140 \\ trap0(#1)
141 );
142}
143
144pub const time_t = i64;
145
146pub const VDSO = void;