1const builtin = @import("builtin");
2const std = @import("../../std.zig");
3const SYS = std.os.linux.SYS;
4
5pub const syscall_arg_t = u64;
6
7pub fn syscall0(
8 number: SYS,
9) u64 {
10 return asm volatile (
11 \\ syscall
12 \\ beq $a3, $zero, 1f
13 \\ dsubu $v0, $zero, $v0
14 \\1:
15 : [ret] "={$2}" (-> u64),
16 : [number] "{$2}" (@backingInt(number)),
17 : .{ .r1 = true, .r3 = true, .r4 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
18}
19
20pub fn syscall1(
21 number: SYS,
22 arg1: syscall_arg_t,
23) u64 {
24 return asm volatile (
25 \\ syscall
26 \\ beq $a3, $zero, 1f
27 \\ dsubu $v0, $zero, $v0
28 \\1:
29 : [ret] "={$2}" (-> u64),
30 : [number] "{$2}" (@backingInt(number)),
31 [arg1] "{$4}" (arg1),
32 : .{ .r1 = true, .r3 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
33}
34
35pub fn syscall2(
36 number: SYS,
37 arg1: syscall_arg_t,
38 arg2: syscall_arg_t,
39) u64 {
40 return asm volatile (
41 \\ syscall
42 \\ beq $a3, $zero, 1f
43 \\ dsubu $v0, $zero, $v0
44 \\1:
45 : [ret] "={$2}" (-> u64),
46 : [number] "{$2}" (@backingInt(number)),
47 [arg1] "{$4}" (arg1),
48 [arg2] "{$5}" (arg2),
49 : .{ .r1 = true, .r3 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
50}
51
52pub fn syscall3(
53 number: SYS,
54 arg1: syscall_arg_t,
55 arg2: syscall_arg_t,
56 arg3: syscall_arg_t,
57) u64 {
58 return asm volatile (
59 \\ syscall
60 \\ beq $a3, $zero, 1f
61 \\ dsubu $v0, $zero, $v0
62 \\1:
63 : [ret] "={$2}" (-> u64),
64 : [number] "{$2}" (@backingInt(number)),
65 [arg1] "{$4}" (arg1),
66 [arg2] "{$5}" (arg2),
67 [arg3] "{$6}" (arg3),
68 : .{ .r1 = true, .r3 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
69}
70
71pub fn syscall4(
72 number: SYS,
73 arg1: syscall_arg_t,
74 arg2: syscall_arg_t,
75 arg3: syscall_arg_t,
76 arg4: syscall_arg_t,
77) u64 {
78 return asm volatile (
79 \\ syscall
80 \\ beq $a3, $zero, 1f
81 \\ dsubu $v0, $zero, $v0
82 \\1:
83 : [ret] "={$2}" (-> u64),
84 : [number] "{$2}" (@backingInt(number)),
85 [arg1] "{$4}" (arg1),
86 [arg2] "{$5}" (arg2),
87 [arg3] "{$6}" (arg3),
88 [arg4] "{$7}" (arg4),
89 : .{ .r1 = true, .r3 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
90}
91
92pub fn syscall5(
93 number: SYS,
94 arg1: syscall_arg_t,
95 arg2: syscall_arg_t,
96 arg3: syscall_arg_t,
97 arg4: syscall_arg_t,
98 arg5: syscall_arg_t,
99) u64 {
100 return asm volatile (
101 \\ syscall
102 \\ beq $a3, $zero, 1f
103 \\ dsubu $v0, $zero, $v0
104 \\1:
105 : [ret] "={$2}" (-> u64),
106 : [number] "{$2}" (@backingInt(number)),
107 [arg1] "{$4}" (arg1),
108 [arg2] "{$5}" (arg2),
109 [arg3] "{$6}" (arg3),
110 [arg4] "{$7}" (arg4),
111 [arg5] "{$8}" (arg5),
112 : .{ .r1 = true, .r3 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
113}
114
115pub fn syscall6(
116 number: SYS,
117 arg1: syscall_arg_t,
118 arg2: syscall_arg_t,
119 arg3: syscall_arg_t,
120 arg4: syscall_arg_t,
121 arg5: syscall_arg_t,
122 arg6: syscall_arg_t,
123) u64 {
124 return asm volatile (
125 \\ syscall
126 \\ beq $a3, $zero, 1f
127 \\ dsubu $v0, $zero, $v0
128 \\1:
129 : [ret] "={$2}" (-> u64),
130 : [number] "{$2}" (@backingInt(number)),
131 [arg1] "{$4}" (arg1),
132 [arg2] "{$5}" (arg2),
133 [arg3] "{$6}" (arg3),
134 [arg4] "{$7}" (arg4),
135 [arg5] "{$8}" (arg5),
136 [arg6] "{$9}" (arg6),
137 : .{ .r1 = true, .r3 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
138}
139
140pub fn syscall_pipe(
141 fd: *[2]std.os.linux.fd_t,
142) u64 {
143 return asm volatile (
144 \\ syscall
145 \\ beq $a3, $zero, 1f
146 \\ dsubu $v0, $zero, $v0
147 \\ b 2f
148 \\1:
149 \\ sw $v0, 0($a0)
150 \\ sw $v1, 4($a0)
151 \\2:
152 : [ret] "={$2}" (-> u64),
153 : [number] "{$2}" (@backingInt(SYS.pipe)),
154 [fd] "{$4}" (fd),
155 : .{ .r1 = true, .r3 = true, .r5 = true, .r6 = true, .r7 = true, .r8 = true, .r9 = true, .r10 = true, .r11 = true, .r12 = true, .r13 = true, .r14 = true, .r15 = true, .r24 = true, .r25 = true, .hi = true, .lo = true, .memory = true });
156}
157
158pub fn clone() callconv(.naked) u64 {
159 // __clone(func, stack, flags, arg, ptid, tls, ctid)
160 // a0, a1, a2, a3, a4, a5, a6
161 //
162 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
163 // v0 a0, a1, a2, a3, a4
164 asm volatile (
165 \\ # Save function pointer and argument pointer on new thread stack
166 \\ and $a1, $a1, -16
167 \\ dsubu $a1, $a1, 16
168 \\ sd $a0, 0($a1)
169 \\ sd $a3, 8($a1)
170 \\
171 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
172 \\ move $a0, $a2
173 \\ move $a2, $a4
174 \\ move $a3, $a5
175 \\ move $a4, $a6
176 \\ li $v0, 5055 # SYS_clone
177 \\ syscall
178 \\ beq $a3, $zero, 1f
179 \\ dsubu $v0, $zero, $v0
180 \\ b 2f
181 \\1:
182 \\ beq $v0, $zero, 3f
183 \\2:
184 \\ jr $ra
185 \\3:
186 );
187 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
188 \\ .cfi_undefined $ra
189 );
190 asm volatile (
191 \\ move $fp, $zero
192 \\ move $ra, $zero
193 \\
194 \\ ld $t9, 0($sp)
195 \\ ld $a0, 8($sp)
196 \\ jalr $t9
197 \\
198 \\ move $a0, $v0
199 \\ li $v0, 5058 # SYS_exit
200 \\ syscall
201 );
202}
203
204pub const VDSO = struct {
205 pub const CGT_SYM = "__vdso_clock_gettime";
206 pub const CGT_VER = "LINUX_2.6";
207};
208
209pub const time_t = i32;