authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-18 22:26:09+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-10-18 22:26:09+02:00
log6bf5b7f2b40be1a92c66fed05e53815b3ab07733
tree0d669a74a75571726056f406c79d69a5fe415c3d
parent1466401c153e991cd7cddb0c39b1cd361476e8e5
parent3585f79f447a7bdac59dc06dd33ca374e2345900
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #25622 from alexrp/inline-asm-fixes

`std`: some miscellaneous inline asm fixes for mips, mips64, mipsn32, and x32

7 files changed, 334 insertions(+), 349 deletions(-)

lib/std/Thread.zig+44-22
...@@ -1191,12 +1191,22 @@ const LinuxThreadImpl = struct {...@@ -1191,12 +1191,22 @@ const LinuxThreadImpl = struct {
1191 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),1191 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
1192 [len] "r" (self.mapped.len),1192 [len] "r" (self.mapped.len),
1193 : .{ .memory = true }),1193 : .{ .memory = true }),
1194 .x86_64 => asm volatile (1194 .x86_64 => asm volatile (switch (target.abi) {
1195 \\ movq $11, %%rax # SYS_munmap1195 .gnux32, .muslx32 =>
1196 \\ syscall1196 \\ movl $0x4000000b, %%eax # SYS_munmap
1197 \\ movq $60, %%rax # SYS_exit1197 \\ syscall
1198 \\ movq $1, %%rdi1198 \\ movl $0x4000003c, %%eax # SYS_exit
1199 \\ syscall1199 \\ xor %%rdi, %%rdi
1200 \\ syscall
1201 ,
1202 else =>
1203 \\ movl $11, %%eax # SYS_munmap
1204 \\ syscall
1205 \\ movl $60, %%eax # SYS_exit
1206 \\ xor %%rdi, %%rdi
1207 \\ syscall
1208 ,
1209 }
1200 :1210 :
1201 : [ptr] "{rdi}" (@intFromPtr(self.mapped.ptr)),1211 : [ptr] "{rdi}" (@intFromPtr(self.mapped.ptr)),
1202 [len] "{rsi}" (self.mapped.len),1212 [len] "{rsi}" (self.mapped.len),
...@@ -1242,26 +1252,38 @@ const LinuxThreadImpl = struct {...@@ -1242,26 +1252,38 @@ const LinuxThreadImpl = struct {
1242 // The bug was introduced in 46e12c07b3b9603c60fc1d421ff18618241cb081 and fixed in1252 // The bug was introduced in 46e12c07b3b9603c60fc1d421ff18618241cb081 and fixed in
1243 // 7928eb0370d1133d0d8cd2f5ddfca19c309079d5.1253 // 7928eb0370d1133d0d8cd2f5ddfca19c309079d5.
1244 .mips, .mipsel => asm volatile (1254 .mips, .mipsel => asm volatile (
1245 \\ move $sp, $251255 \\ move $sp, $t9
1246 \\ li $2, 4091 # SYS_munmap1256 \\ li $v0, 4091 # SYS_munmap
1247 \\ move $4, %[ptr]1257 \\ move $a0, %[ptr]
1248 \\ move $5, %[len]1258 \\ move $a1, %[len]
1249 \\ syscall1259 \\ syscall
1250 \\ li $2, 4001 # SYS_exit1260 \\ li $v0, 4001 # SYS_exit
1251 \\ li $4, 01261 \\ li $a0, 0
1252 \\ syscall1262 \\ syscall
1253 :1263 :
1254 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),1264 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
1255 [len] "r" (self.mapped.len),1265 [len] "r" (self.mapped.len),
1256 : .{ .memory = true }),1266 : .{ .memory = true }),
1257 .mips64, .mips64el => asm volatile (1267 .mips64, .mips64el => asm volatile (switch (target.abi) {
1258 \\ li $2, 5011 # SYS_munmap1268 .gnuabin32, .muslabin32 =>
1259 \\ move $4, %[ptr]1269 \\ li $v0, 6011 # SYS_munmap
1260 \\ move $5, %[len]1270 \\ move $a0, %[ptr]
1261 \\ syscall1271 \\ move $a1, %[len]
1262 \\ li $2, 5058 # SYS_exit1272 \\ syscall
1263 \\ li $4, 01273 \\ li $v0, 6058 # SYS_exit
1264 \\ syscall1274 \\ li $a0, 0
1275 \\ syscall
1276 ,
1277 else =>
1278 \\ li $v0, 5011 # SYS_munmap
1279 \\ move $a0, %[ptr]
1280 \\ move $a1, %[len]
1281 \\ syscall
1282 \\ li $v0, 5058 # SYS_exit
1283 \\ li $a0, 0
1284 \\ syscall
1285 ,
1286 }
1265 :1287 :
1266 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),1288 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
1267 [len] "r" (self.mapped.len),1289 [len] "r" (self.mapped.len),
lib/std/os/linux/mips.zig+78-84
...@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;...@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;
5pub fn syscall0(number: SYS) u32 {5pub fn syscall0(number: SYS) u32 {
6 return asm volatile (6 return asm volatile (
7 \\ syscall7 \\ syscall
8 \\ beq $7, $zero, 1f8 \\ beq $a3, $zero, 1f
9 \\ blez $2, 1f9 \\ blez $v0, 1f
10 \\ subu $2, $0, $210 \\ subu $v0, $zero, $v0
11 \\ 1:11 \\1:
12 : [ret] "={$2}" (-> u32),12 : [ret] "={$2}" (-> u32),
13 : [number] "{$2}" (@intFromEnum(number)),13 : [number] "{$2}" (@intFromEnum(number)),
14 : .{ .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 });14 : .{ .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 });
...@@ -16,17 +16,15 @@ pub fn syscall0(number: SYS) u32 {...@@ -16,17 +16,15 @@ pub fn syscall0(number: SYS) u32 {
1616
17pub fn syscall_pipe(fd: *[2]i32) u32 {17pub fn syscall_pipe(fd: *[2]i32) u32 {
18 return asm volatile (18 return asm volatile (
19 \\ .set noat
20 \\ .set noreorder
21 \\ syscall19 \\ syscall
22 \\ beq $7, $zero, 1f20 \\ beq $a3, $zero, 1f
23 \\ nop21 \\ blez $v0, 2f
22 \\ subu $v0, $zero, $v0
24 \\ b 2f23 \\ b 2f
25 \\ subu $2, $0, $224 \\1:
26 \\ 1:25 \\ sw $v0, 0($a0)
27 \\ sw $2, 0($4)26 \\ sw $v1, 4($a0)
28 \\ sw $3, 4($4)27 \\2:
29 \\ 2:
30 : [ret] "={$2}" (-> u32),28 : [ret] "={$2}" (-> u32),
31 : [number] "{$2}" (@intFromEnum(SYS.pipe)),29 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
32 [fd] "{$4}" (fd),30 [fd] "{$4}" (fd),
...@@ -36,10 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {...@@ -36,10 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {
36pub fn syscall1(number: SYS, arg1: u32) u32 {34pub fn syscall1(number: SYS, arg1: u32) u32 {
37 return asm volatile (35 return asm volatile (
38 \\ syscall36 \\ syscall
39 \\ beq $7, $zero, 1f37 \\ beq $a3, $zero, 1f
40 \\ blez $2, 1f38 \\ blez $v0, 1f
41 \\ subu $2, $0, $239 \\ subu $v0, $zero, $v0
42 \\ 1:40 \\1:
43 : [ret] "={$2}" (-> u32),41 : [ret] "={$2}" (-> u32),
44 : [number] "{$2}" (@intFromEnum(number)),42 : [number] "{$2}" (@intFromEnum(number)),
45 [arg1] "{$4}" (arg1),43 [arg1] "{$4}" (arg1),
...@@ -49,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {...@@ -49,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {
49pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {47pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
50 return asm volatile (48 return asm volatile (
51 \\ syscall49 \\ syscall
52 \\ beq $7, $zero, 1f50 \\ beq $a3, $zero, 1f
53 \\ blez $2, 1f51 \\ blez $v0, 1f
54 \\ subu $2, $0, $252 \\ subu $v0, $zero, $v0
55 \\ 1:53 \\1:
56 : [ret] "={$2}" (-> u32),54 : [ret] "={$2}" (-> u32),
57 : [number] "{$2}" (@intFromEnum(number)),55 : [number] "{$2}" (@intFromEnum(number)),
58 [arg1] "{$4}" (arg1),56 [arg1] "{$4}" (arg1),
...@@ -63,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {...@@ -63,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
63pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {61pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
64 return asm volatile (62 return asm volatile (
65 \\ syscall63 \\ syscall
66 \\ beq $7, $zero, 1f64 \\ beq $a3, $zero, 1f
67 \\ blez $2, 1f65 \\ blez $v0, 1f
68 \\ subu $2, $0, $266 \\ subu $v0, $zero, $v0
69 \\ 1:67 \\1:
70 : [ret] "={$2}" (-> u32),68 : [ret] "={$2}" (-> u32),
71 : [number] "{$2}" (@intFromEnum(number)),69 : [number] "{$2}" (@intFromEnum(number)),
72 [arg1] "{$4}" (arg1),70 [arg1] "{$4}" (arg1),
...@@ -78,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {...@@ -78,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
78pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {76pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
79 return asm volatile (77 return asm volatile (
80 \\ syscall78 \\ syscall
81 \\ beq $7, $zero, 1f79 \\ beq $a3, $zero, 1f
82 \\ blez $2, 1f80 \\ blez $v0, 1f
83 \\ subu $2, $0, $281 \\ subu $v0, $zero, $v0
84 \\ 1:82 \\1:
85 : [ret] "={$2}" (-> u32),83 : [ret] "={$2}" (-> u32),
86 : [number] "{$2}" (@intFromEnum(number)),84 : [number] "{$2}" (@intFromEnum(number)),
87 [arg1] "{$4}" (arg1),85 [arg1] "{$4}" (arg1),
...@@ -91,17 +89,19 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {...@@ -91,17 +89,19 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
91 : .{ .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 });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 });
92}90}
9391
92// NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
93// the first four arguments even though they're passed in $a0-$a3.
94
94pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {95pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
95 return asm volatile (96 return asm volatile (
96 \\ .set noat
97 \\ subu $sp, $sp, 2497 \\ subu $sp, $sp, 24
98 \\ sw %[arg5], 16($sp)98 \\ sw %[arg5], 16($sp)
99 \\ syscall99 \\ syscall
100 \\ addu $sp, $sp, 24100 \\ addu $sp, $sp, 24
101 \\ beq $7, $zero, 1f101 \\ beq $a3, $zero, 1f
102 \\ blez $2, 1f102 \\ blez $v0, 1f
103 \\ subu $2, $0, $2103 \\ subu $v0, $zero, $v0
104 \\ 1:104 \\1:
105 : [ret] "={$2}" (-> u32),105 : [ret] "={$2}" (-> u32),
106 : [number] "{$2}" (@intFromEnum(number)),106 : [number] "{$2}" (@intFromEnum(number)),
107 [arg1] "{$4}" (arg1),107 [arg1] "{$4}" (arg1),
...@@ -112,9 +112,6 @@ pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u...@@ -112,9 +112,6 @@ pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u
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 });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}113}
114114
115// NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
116// the first four arguments even though they're passed in $a0-$a3.
117
118pub fn syscall6(115pub fn syscall6(
119 number: SYS,116 number: SYS,
120 arg1: u32,117 arg1: u32,
...@@ -125,16 +122,15 @@ pub fn syscall6(...@@ -125,16 +122,15 @@ pub fn syscall6(
125 arg6: u32,122 arg6: u32,
126) u32 {123) u32 {
127 return asm volatile (124 return asm volatile (
128 \\ .set noat
129 \\ subu $sp, $sp, 24125 \\ subu $sp, $sp, 24
130 \\ sw %[arg5], 16($sp)126 \\ sw %[arg5], 16($sp)
131 \\ sw %[arg6], 20($sp)127 \\ sw %[arg6], 20($sp)
132 \\ syscall128 \\ syscall
133 \\ addu $sp, $sp, 24129 \\ addu $sp, $sp, 24
134 \\ beq $7, $zero, 1f130 \\ beq $a3, $zero, 1f
135 \\ blez $2, 1f131 \\ blez $v0, 1f
136 \\ subu $2, $0, $2132 \\ subu $v0, $zero, $v0
137 \\ 1:133 \\1:
138 : [ret] "={$2}" (-> u32),134 : [ret] "={$2}" (-> u32),
139 : [number] "{$2}" (@intFromEnum(number)),135 : [number] "{$2}" (@intFromEnum(number)),
140 [arg1] "{$4}" (arg1),136 [arg1] "{$4}" (arg1),
...@@ -157,17 +153,16 @@ pub fn syscall7(...@@ -157,17 +153,16 @@ pub fn syscall7(
157 arg7: u32,153 arg7: u32,
158) u32 {154) u32 {
159 return asm volatile (155 return asm volatile (
160 \\ .set noat
161 \\ subu $sp, $sp, 32156 \\ subu $sp, $sp, 32
162 \\ sw %[arg5], 16($sp)157 \\ sw %[arg5], 16($sp)
163 \\ sw %[arg6], 20($sp)158 \\ sw %[arg6], 20($sp)
164 \\ sw %[arg7], 24($sp)159 \\ sw %[arg7], 24($sp)
165 \\ syscall160 \\ syscall
166 \\ addu $sp, $sp, 32161 \\ addu $sp, $sp, 32
167 \\ beq $7, $zero, 1f162 \\ beq $a3, $zero, 1f
168 \\ blez $2, 1f163 \\ blez $v0, 1f
169 \\ subu $2, $0, $2164 \\ subu $v0, $zero, $v0
170 \\ 1:165 \\1:
171 : [ret] "={$2}" (-> u32),166 : [ret] "={$2}" (-> u32),
172 : [number] "{$2}" (@intFromEnum(number)),167 : [number] "{$2}" (@intFromEnum(number)),
173 [arg1] "{$4}" (arg1),168 [arg1] "{$4}" (arg1),
...@@ -182,52 +177,51 @@ pub fn syscall7(...@@ -182,52 +177,51 @@ pub fn syscall7(
182177
183pub fn clone() callconv(.naked) u32 {178pub fn clone() callconv(.naked) u32 {
184 // __clone(func, stack, flags, arg, ptid, tls, ctid)179 // __clone(func, stack, flags, arg, ptid, tls, ctid)
185 // 3, 4, 5, 6, 7, 8, 9180 // a0, a1, a2, a3, +0, +4, +8
186 //181 //
187 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)182 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
188 // 2 4, 5, 6, 7, 8183 // v0 a0, a1, a2, a3, +0
189 asm volatile (184 asm volatile (
190 \\ # Save function pointer and argument pointer on new thread stack185 \\ # Save function pointer and argument pointer on new thread stack
191 \\ and $5, $5, -8186 \\ and $a1, $a1, -8
192 \\ subu $5, $5, 16187 \\ subu $a1, $a1, 16
193 \\ sw $4, 0($5)188 \\ sw $a0, 0($a1)
194 \\ sw $7, 4($5)189 \\ sw $a3, 4($a1)
195 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)190 \\
196 \\ move $4, $6191 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
197 \\ lw $6, 16($sp)192 \\ move $a0, $a2
198 \\ lw $7, 20($sp)193 \\ lw $a2, 16($sp)
199 \\ lw $9, 24($sp)194 \\ lw $a3, 20($sp)
200 \\ subu $sp, $sp, 16195 \\ lw $t1, 24($sp)
201 \\ sw $9, 16($sp)196 \\ subu $sp, $sp, 16
202 \\ li $2, 4120 # SYS_clone197 \\ sw $t1, 16($sp)
203 \\ syscall198 \\ li $v0, 4120 # SYS_clone
204 \\ beq $7, $0, 1f199 \\ syscall
205 \\ nop200 \\ beq $a3, $zero, 1f
206 \\ addu $sp, $sp, 16201 \\ blez $v0, 2f
207 \\ jr $ra202 \\ subu $v0, $zero, $v0
208 \\ subu $2, $0, $2203 \\ b 2f
209 \\1:
210 \\ beq $2, $0, 1f
211 \\ nop
212 \\ addu $sp, $sp, 16
213 \\ jr $ra
214 \\ nop
215 \\1:204 \\1:
205 \\ beq $v0, $zero, 3f
206 \\2:
207 \\ addu $sp, $sp, 16
208 \\ jr $ra
209 \\3:
216 );210 );
217 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (211 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
218 \\ .cfi_undefined $ra212 \\ .cfi_undefined $ra
219 );213 );
220 asm volatile (214 asm volatile (
221 \\ move $fp, $zero215 \\ move $fp, $zero
222 \\ move $ra, $zero216 \\ move $ra, $zero
223 \\217 \\
224 \\ lw $25, 0($sp)218 \\ lw $t9, 0($sp)
225 \\ lw $4, 4($sp)219 \\ lw $a0, 4($sp)
226 \\ jalr $25220 \\ jalr $t9
227 \\ nop221 \\
228 \\ move $4, $2222 \\ move $a0, $v0
229 \\ li $2, 4001 # SYS_exit223 \\ li $v0, 4001 # SYS_exit
230 \\ syscall224 \\ syscall
231 );225 );
232}226}
233227
lib/std/os/linux/mips64.zig+60-91
...@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;...@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;
5pub fn syscall0(number: SYS) u64 {5pub fn syscall0(number: SYS) u64 {
6 return asm volatile (6 return asm volatile (
7 \\ syscall7 \\ syscall
8 \\ beq $7, $zero, 1f8 \\ beq $a3, $zero, 1f
9 \\ blez $2, 1f9 \\ blez $v0, 1f
10 \\ dsubu $2, $0, $210 \\ dsubu $v0, $zero, $v0
11 \\ 1:11 \\1:
12 : [ret] "={$2}" (-> u64),12 : [ret] "={$2}" (-> u64),
13 : [number] "{$2}" (@intFromEnum(number)),13 : [number] "{$2}" (@intFromEnum(number)),
14 : .{ .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 });14 : .{ .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 });
...@@ -16,17 +16,15 @@ pub fn syscall0(number: SYS) u64 {...@@ -16,17 +16,15 @@ pub fn syscall0(number: SYS) u64 {
1616
17pub fn syscall_pipe(fd: *[2]i32) u64 {17pub fn syscall_pipe(fd: *[2]i32) u64 {
18 return asm volatile (18 return asm volatile (
19 \\ .set noat
20 \\ .set noreorder
21 \\ syscall19 \\ syscall
22 \\ beq $7, $zero, 1f20 \\ beq $a3, $zero, 1f
23 \\ nop21 \\ blez $v0, 2f
22 \\ dsubu $v0, $zero, $v0
24 \\ b 2f23 \\ b 2f
25 \\ subu $2, $0, $224 \\1:
26 \\ 1:25 \\ sw $v0, 0($a0)
27 \\ sw $2, 0($4)26 \\ sw $v1, 4($a0)
28 \\ sw $3, 4($4)27 \\2:
29 \\ 2:
30 : [ret] "={$2}" (-> u64),28 : [ret] "={$2}" (-> u64),
31 : [number] "{$2}" (@intFromEnum(SYS.pipe)),29 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
32 [fd] "{$4}" (fd),30 [fd] "{$4}" (fd),
...@@ -36,11 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u64 {...@@ -36,11 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u64 {
36pub fn syscall1(number: SYS, arg1: u64) u64 {34pub fn syscall1(number: SYS, arg1: u64) u64 {
37 return asm volatile (35 return asm volatile (
38 \\ syscall36 \\ syscall
39 \\ beq $7, $zero, 1f37 \\ beq $a3, $zero, 1f
40 \\ blez $2, 1f38 \\ blez $v0, 1f
41 \\ nop39 \\ dsubu $v0, $zero, $v0
42 \\ dsubu $2, $0, $240 \\1:
43 \\ 1:
44 : [ret] "={$2}" (-> u64),41 : [ret] "={$2}" (-> u64),
45 : [number] "{$2}" (@intFromEnum(number)),42 : [number] "{$2}" (@intFromEnum(number)),
46 [arg1] "{$4}" (arg1),43 [arg1] "{$4}" (arg1),
...@@ -50,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u64) u64 {...@@ -50,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u64) u64 {
50pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {47pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
51 return asm volatile (48 return asm volatile (
52 \\ syscall49 \\ syscall
53 \\ beq $7, $zero, 1f50 \\ beq $a3, $zero, 1f
54 \\ blez $2, 1f51 \\ blez $v0, 1f
55 \\ dsubu $2, $0, $252 \\ dsubu $v0, $zero, $v0
56 \\ 1:53 \\1:
57 : [ret] "={$2}" (-> u64),54 : [ret] "={$2}" (-> u64),
58 : [number] "{$2}" (@intFromEnum(number)),55 : [number] "{$2}" (@intFromEnum(number)),
59 [arg1] "{$4}" (arg1),56 [arg1] "{$4}" (arg1),
...@@ -64,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {...@@ -64,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
64pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {61pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
65 return asm volatile (62 return asm volatile (
66 \\ syscall63 \\ syscall
67 \\ beq $7, $zero, 1f64 \\ beq $a3, $zero, 1f
68 \\ blez $2, 1f65 \\ blez $v0, 1f
69 \\ dsubu $2, $0, $266 \\ dsubu $v0, $zero, $v0
70 \\ 1:67 \\1:
71 : [ret] "={$2}" (-> u64),68 : [ret] "={$2}" (-> u64),
72 : [number] "{$2}" (@intFromEnum(number)),69 : [number] "{$2}" (@intFromEnum(number)),
73 [arg1] "{$4}" (arg1),70 [arg1] "{$4}" (arg1),
...@@ -79,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {...@@ -79,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
79pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {76pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
80 return asm volatile (77 return asm volatile (
81 \\ syscall78 \\ syscall
82 \\ beq $7, $zero, 1f79 \\ beq $a3, $zero, 1f
83 \\ blez $2, 1f80 \\ blez $v0, 1f
84 \\ dsubu $2, $0, $281 \\ dsubu $v0, $zero, $v0
85 \\ 1:82 \\1:
86 : [ret] "={$2}" (-> u64),83 : [ret] "={$2}" (-> u64),
87 : [number] "{$2}" (@intFromEnum(number)),84 : [number] "{$2}" (@intFromEnum(number)),
88 [arg1] "{$4}" (arg1),85 [arg1] "{$4}" (arg1),
...@@ -95,10 +92,10 @@ pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {...@@ -95,10 +92,10 @@ pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
95pub fn syscall5(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) u64 {92pub fn syscall5(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) u64 {
96 return asm volatile (93 return asm volatile (
97 \\ syscall94 \\ syscall
98 \\ beq $7, $zero, 1f95 \\ beq $a3, $zero, 1f
99 \\ blez $2, 1f96 \\ blez $v0, 1f
100 \\ dsubu $2, $0, $297 \\ dsubu $v0, $zero, $v0
101 \\ 1:98 \\1:
102 : [ret] "={$2}" (-> u64),99 : [ret] "={$2}" (-> u64),
103 : [number] "{$2}" (@intFromEnum(number)),100 : [number] "{$2}" (@intFromEnum(number)),
104 [arg1] "{$4}" (arg1),101 [arg1] "{$4}" (arg1),
...@@ -120,37 +117,10 @@ pub fn syscall6(...@@ -120,37 +117,10 @@ pub fn syscall6(
120) u64 {117) u64 {
121 return asm volatile (118 return asm volatile (
122 \\ syscall119 \\ syscall
123 \\ beq $7, $zero, 1f120 \\ beq $a3, $zero, 1f
124 \\ blez $2, 1f121 \\ blez $v0, 1f
125 \\ dsubu $2, $0, $2122 \\ dsubu $v0, $zero, $v0
126 \\ 1:123 \\1:
127 : [ret] "={$2}" (-> u64),
128 : [number] "{$2}" (@intFromEnum(number)),
129 [arg1] "{$4}" (arg1),
130 [arg2] "{$5}" (arg2),
131 [arg3] "{$6}" (arg3),
132 [arg4] "{$7}" (arg4),
133 [arg5] "{$8}" (arg5),
134 [arg6] "{$9}" (arg6),
135 : .{ .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 });
136}
137
138pub fn syscall7(
139 number: SYS,
140 arg1: u64,
141 arg2: u64,
142 arg3: u64,
143 arg4: u64,
144 arg5: u64,
145 arg6: u64,
146 arg7: u64,
147) u64 {
148 return asm volatile (
149 \\ syscall
150 \\ beq $7, $zero, 1f
151 \\ blez $2, 1f
152 \\ dsubu $2, $0, $2
153 \\ 1:
154 : [ret] "={$2}" (-> u64),124 : [ret] "={$2}" (-> u64),
155 : [number] "{$2}" (@intFromEnum(number)),125 : [number] "{$2}" (@intFromEnum(number)),
156 [arg1] "{$4}" (arg1),126 [arg1] "{$4}" (arg1),
...@@ -159,39 +129,38 @@ pub fn syscall7(...@@ -159,39 +129,38 @@ pub fn syscall7(
159 [arg4] "{$7}" (arg4),129 [arg4] "{$7}" (arg4),
160 [arg5] "{$8}" (arg5),130 [arg5] "{$8}" (arg5),
161 [arg6] "{$9}" (arg6),131 [arg6] "{$9}" (arg6),
162 [arg7] "{$10}" (arg7),
163 : .{ .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 });132 : .{ .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 });
164}133}
165134
166pub fn clone() callconv(.naked) u64 {135pub fn clone() callconv(.naked) u64 {
167 // __clone(func, stack, flags, arg, ptid, tls, ctid)136 // __clone(func, stack, flags, arg, ptid, tls, ctid)
168 // 3, 4, 5, 6, 7, 8, 9137 // a0, a1, a2, a3, a4, a5, a6
169 //138 //
170 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)139 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
171 // 2 4, 5, 6, 7, 8140 // v0 a0, a1, a2, a3, a4
172 asm volatile (141 asm volatile (
173 \\ # Save function pointer and argument pointer on new thread stack142 \\ # Save function pointer and argument pointer on new thread stack
174 \\ and $5, $5, -16143 \\ and $a1, $a1, -16
175 \\ dsubu $5, $5, 16144 \\ dsubu $a1, $a1, 16
176 \\ sd $4, 0($5)145 \\ sd $a0, 0($a1)
177 \\ sd $7, 8($5)146 \\ sd $a3, 8($a1)
147 \\
178 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)148 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
179 \\ move $4, $6149 \\ move $a0, $a2
180 \\ move $6, $8150 \\ move $a2, $a4
181 \\ move $7, $9151 \\ move $a3, $a5
182 \\ move $8, $10152 \\ move $a4, $a6
183 \\ li $2, 5055 # SYS_clone153 \\ li $v0, 5055 # SYS_clone
184 \\ syscall154 \\ syscall
185 \\ beq $7, $0, 1f155 \\ beq $a3, $zero, 1f
186 \\ nop156 \\ blez $v0, 2f
187 \\ jr $ra157 \\ dsubu $v0, $zero, $v0
188 \\ dsubu $2, $0, $2158 \\ b 2f
189 \\1:159 \\1:
190 \\ beq $2, $0, 1f160 \\ beq $v0, $zero, 3f
191 \\ nop161 \\2:
192 \\ jr $ra162 \\ jr $ra
193 \\ nop163 \\3:
194 \\1:
195 );164 );
196 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (165 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
197 \\ .cfi_undefined $ra166 \\ .cfi_undefined $ra
...@@ -200,12 +169,12 @@ pub fn clone() callconv(.naked) u64 {...@@ -200,12 +169,12 @@ pub fn clone() callconv(.naked) u64 {
200 \\ move $fp, $zero169 \\ move $fp, $zero
201 \\ move $ra, $zero170 \\ move $ra, $zero
202 \\171 \\
203 \\ ld $25, 0($sp)172 \\ ld $t9, 0($sp)
204 \\ ld $4, 8($sp)173 \\ ld $a0, 8($sp)
205 \\ jalr $25174 \\ jalr $t9
206 \\ nop175 \\
207 \\ move $4, $2176 \\ move $a0, $v0
208 \\ li $2, 5058 # SYS_exit177 \\ li $v0, 5058 # SYS_exit
209 \\ syscall178 \\ syscall
210 );179 );
211}180}
lib/std/os/linux/mipsn32.zig+60-93
...@@ -1,5 +1,3 @@...@@ -1,5 +1,3 @@
1// TODO: A lot of this file is very likely wrong.
2
3const builtin = @import("builtin");1const builtin = @import("builtin");
4const std = @import("../../std.zig");2const std = @import("../../std.zig");
5const SYS = std.os.linux.SYS;3const SYS = std.os.linux.SYS;
...@@ -7,10 +5,10 @@ const SYS = std.os.linux.SYS;...@@ -7,10 +5,10 @@ const SYS = std.os.linux.SYS;
7pub fn syscall0(number: SYS) u32 {5pub fn syscall0(number: SYS) u32 {
8 return asm volatile (6 return asm volatile (
9 \\ syscall7 \\ syscall
10 \\ beq $7, $zero, 1f8 \\ beq $a3, $zero, 1f
11 \\ blez $2, 1f9 \\ blez $v0, 1f
12 \\ dsubu $2, $0, $210 \\ subu $v0, $zero, $v0
13 \\ 1:11 \\1:
14 : [ret] "={$2}" (-> u32),12 : [ret] "={$2}" (-> u32),
15 : [number] "{$2}" (@intFromEnum(number)),13 : [number] "{$2}" (@intFromEnum(number)),
16 : .{ .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 });14 : .{ .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,17 +16,15 @@ pub fn syscall0(number: SYS) u32 {...@@ -18,17 +16,15 @@ pub fn syscall0(number: SYS) u32 {
1816
19pub fn syscall_pipe(fd: *[2]i32) u32 {17pub fn syscall_pipe(fd: *[2]i32) u32 {
20 return asm volatile (18 return asm volatile (
21 \\ .set noat
22 \\ .set noreorder
23 \\ syscall19 \\ syscall
24 \\ beq $7, $zero, 1f20 \\ beq $a3, $zero, 1f
25 \\ nop21 \\ blez $v0, 2f
22 \\ subu $v0, $zero, $v0
26 \\ b 2f23 \\ b 2f
27 \\ subu $2, $0, $224 \\1:
28 \\ 1:25 \\ sw $v0, 0($a0)
29 \\ sw $2, 0($4)26 \\ sw $v1, 4($a0)
30 \\ sw $3, 4($4)27 \\2:
31 \\ 2:
32 : [ret] "={$2}" (-> u32),28 : [ret] "={$2}" (-> u32),
33 : [number] "{$2}" (@intFromEnum(SYS.pipe)),29 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
34 [fd] "{$4}" (fd),30 [fd] "{$4}" (fd),
...@@ -38,11 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {...@@ -38,11 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {
38pub fn syscall1(number: SYS, arg1: u32) u32 {34pub fn syscall1(number: SYS, arg1: u32) u32 {
39 return asm volatile (35 return asm volatile (
40 \\ syscall36 \\ syscall
41 \\ beq $7, $zero, 1f37 \\ beq $a3, $zero, 1f
42 \\ blez $2, 1f38 \\ blez $v0, 1f
43 \\ nop39 \\ subu $v0, $zero, $v0
44 \\ dsubu $2, $0, $240 \\1:
45 \\ 1:
46 : [ret] "={$2}" (-> u32),41 : [ret] "={$2}" (-> u32),
47 : [number] "{$2}" (@intFromEnum(number)),42 : [number] "{$2}" (@intFromEnum(number)),
48 [arg1] "{$4}" (arg1),43 [arg1] "{$4}" (arg1),
...@@ -52,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {...@@ -52,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {
52pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {47pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
53 return asm volatile (48 return asm volatile (
54 \\ syscall49 \\ syscall
55 \\ beq $7, $zero, 1f50 \\ beq $a3, $zero, 1f
56 \\ blez $2, 1f51 \\ blez $v0, 1f
57 \\ dsubu $2, $0, $252 \\ subu $v0, $zero, $v0
58 \\ 1:53 \\1:
59 : [ret] "={$2}" (-> u32),54 : [ret] "={$2}" (-> u32),
60 : [number] "{$2}" (@intFromEnum(number)),55 : [number] "{$2}" (@intFromEnum(number)),
61 [arg1] "{$4}" (arg1),56 [arg1] "{$4}" (arg1),
...@@ -66,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {...@@ -66,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
66pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {61pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
67 return asm volatile (62 return asm volatile (
68 \\ syscall63 \\ syscall
69 \\ beq $7, $zero, 1f64 \\ beq $a3, $zero, 1f
70 \\ blez $2, 1f65 \\ blez $v0, 1f
71 \\ dsubu $2, $0, $266 \\ subu $v0, $zero, $v0
72 \\ 1:67 \\1:
73 : [ret] "={$2}" (-> u32),68 : [ret] "={$2}" (-> u32),
74 : [number] "{$2}" (@intFromEnum(number)),69 : [number] "{$2}" (@intFromEnum(number)),
75 [arg1] "{$4}" (arg1),70 [arg1] "{$4}" (arg1),
...@@ -81,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {...@@ -81,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
81pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {76pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
82 return asm volatile (77 return asm volatile (
83 \\ syscall78 \\ syscall
84 \\ beq $7, $zero, 1f79 \\ beq $a3, $zero, 1f
85 \\ blez $2, 1f80 \\ blez $v0, 1f
86 \\ dsubu $2, $0, $281 \\ subu $v0, $zero, $v0
87 \\ 1:82 \\1:
88 : [ret] "={$2}" (-> u32),83 : [ret] "={$2}" (-> u32),
89 : [number] "{$2}" (@intFromEnum(number)),84 : [number] "{$2}" (@intFromEnum(number)),
90 [arg1] "{$4}" (arg1),85 [arg1] "{$4}" (arg1),
...@@ -97,10 +92,10 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {...@@ -97,10 +92,10 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
97pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {92pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
98 return asm volatile (93 return asm volatile (
99 \\ syscall94 \\ syscall
100 \\ beq $7, $zero, 1f95 \\ beq $a3, $zero, 1f
101 \\ blez $2, 1f96 \\ blez $v0, 1f
102 \\ dsubu $2, $0, $297 \\ subu $v0, $zero, $v0
103 \\ 1:98 \\1:
104 : [ret] "={$2}" (-> u32),99 : [ret] "={$2}" (-> u32),
105 : [number] "{$2}" (@intFromEnum(number)),100 : [number] "{$2}" (@intFromEnum(number)),
106 [arg1] "{$4}" (arg1),101 [arg1] "{$4}" (arg1),
...@@ -122,37 +117,10 @@ pub fn syscall6(...@@ -122,37 +117,10 @@ pub fn syscall6(
122) u32 {117) u32 {
123 return asm volatile (118 return asm volatile (
124 \\ syscall119 \\ syscall
125 \\ beq $7, $zero, 1f120 \\ beq $a3, $zero, 1f
126 \\ blez $2, 1f121 \\ blez $v0, 1f
127 \\ dsubu $2, $0, $2122 \\ subu $v0, $zero, $v0
128 \\ 1:123 \\1:
129 : [ret] "={$2}" (-> u32),
130 : [number] "{$2}" (@intFromEnum(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 syscall7(
141 number: SYS,
142 arg1: u32,
143 arg2: u32,
144 arg3: u32,
145 arg4: u32,
146 arg5: u32,
147 arg6: u32,
148 arg7: u32,
149) u32 {
150 return asm volatile (
151 \\ syscall
152 \\ beq $7, $zero, 1f
153 \\ blez $2, 1f
154 \\ dsubu $2, $0, $2
155 \\ 1:
156 : [ret] "={$2}" (-> u32),124 : [ret] "={$2}" (-> u32),
157 : [number] "{$2}" (@intFromEnum(number)),125 : [number] "{$2}" (@intFromEnum(number)),
158 [arg1] "{$4}" (arg1),126 [arg1] "{$4}" (arg1),
...@@ -161,39 +129,38 @@ pub fn syscall7(...@@ -161,39 +129,38 @@ pub fn syscall7(
161 [arg4] "{$7}" (arg4),129 [arg4] "{$7}" (arg4),
162 [arg5] "{$8}" (arg5),130 [arg5] "{$8}" (arg5),
163 [arg6] "{$9}" (arg6),131 [arg6] "{$9}" (arg6),
164 [arg7] "{$10}" (arg7),
165 : .{ .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 });132 : .{ .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 });
166}133}
167134
168pub fn clone() callconv(.naked) u32 {135pub fn clone() callconv(.naked) u32 {
169 // __clone(func, stack, flags, arg, ptid, tls, ctid)136 // __clone(func, stack, flags, arg, ptid, tls, ctid)
170 // 3, 4, 5, 6, 7, 8, 9137 // a0, a1, a2, a3, a4, a5, a6
171 //138 //
172 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)139 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
173 // 2 4, 5, 6, 7, 8140 // v0 a0, a1, a2, a3, a4
174 asm volatile (141 asm volatile (
175 \\ # Save function pointer and argument pointer on new thread stack142 \\ # Save function pointer and argument pointer on new thread stack
176 \\ and $5, $5, -16143 \\ and $a1, $a1, -16
177 \\ dsubu $5, $5, 16144 \\ subu $a1, $a1, 16
178 \\ sd $4, 0($5)145 \\ sw $a0, 0($a1)
179 \\ sd $7, 8($5)146 \\ sw $a3, 4($a1)
147 \\
180 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)148 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
181 \\ move $4, $6149 \\ move $a0, $a2
182 \\ move $6, $8150 \\ move $a2, $a4
183 \\ move $7, $9151 \\ move $a3, $a5
184 \\ move $8, $10152 \\ move $a4, $a6
185 \\ li $2, 5055 # SYS_clone153 \\ li $v0, 6055 # SYS_clone
186 \\ syscall154 \\ syscall
187 \\ beq $7, $0, 1f155 \\ beq $a3, $zero, 1f
188 \\ nop156 \\ blez $v0, 2f
189 \\ jr $ra157 \\ subu $v0, $zero, $v0
190 \\ dsubu $2, $0, $2158 \\ b 2f
191 \\1:159 \\1:
192 \\ beq $2, $0, 1f160 \\ beq $v0, $zero, 3f
193 \\ nop161 \\2:
194 \\ jr $ra162 \\ jr $ra
195 \\ nop163 \\3:
196 \\1:
197 );164 );
198 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (165 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
199 \\ .cfi_undefined $ra166 \\ .cfi_undefined $ra
...@@ -202,12 +169,12 @@ pub fn clone() callconv(.naked) u32 {...@@ -202,12 +169,12 @@ pub fn clone() callconv(.naked) u32 {
202 \\ move $fp, $zero169 \\ move $fp, $zero
203 \\ move $ra, $zero170 \\ move $ra, $zero
204 \\171 \\
205 \\ ld $25, 0($sp)172 \\ ld $t9, 0($sp)
206 \\ ld $4, 8($sp)173 \\ ld $a0, 4($sp)
207 \\ jalr $25174 \\ jalr $t9
208 \\ nop175 \\
209 \\ move $4, $2176 \\ move $a0, $v0
210 \\ li $2, 5058 # SYS_exit177 \\ li $v0, 6058 # SYS_exit
211 \\ syscall178 \\ syscall
212 );179 );
213}180}
lib/std/os/linux/x32.zig+17-19
...@@ -1,5 +1,3 @@...@@ -1,5 +1,3 @@
1// TODO: A lot of this file is very likely wrong.
2
3const builtin = @import("builtin");1const builtin = @import("builtin");
4const std = @import("../../std.zig");2const std = @import("../../std.zig");
5const SYS = std.os.linux.SYS;3const SYS = std.os.linux.SYS;
...@@ -84,20 +82,20 @@ pub fn syscall6(...@@ -84,20 +82,20 @@ pub fn syscall6(
8482
85pub fn clone() callconv(.naked) u32 {83pub fn clone() callconv(.naked) u32 {
86 asm volatile (84 asm volatile (
87 \\ movl $56,%%eax // SYS_clone85 \\ movl $0x40000038,%%eax // SYS_clone
88 \\ movq %%rdi,%%r1186 \\ mov %%rdi,%%r11
89 \\ movq %%rdx,%%rdi87 \\ mov %%rdx,%%rdi
90 \\ movq %%r8,%%rdx88 \\ mov %%r8,%%rdx
91 \\ movq %%r9,%%r889 \\ mov %%r9,%%r8
92 \\ movq 8(%%rsp),%%r1090 \\ mov 8(%%rsp),%%r10
93 \\ movq %%r11,%%r991 \\ mov %%r11,%%r9
94 \\ andq $-16,%%rsi92 \\ and $-16,%%rsi
95 \\ subq $8,%%rsi93 \\ sub $8,%%rsi
96 \\ movq %%rcx,(%%rsi)94 \\ mov %%rcx,(%%rsi)
97 \\ syscall95 \\ syscall
98 \\ testq %%rax,%%rax96 \\ test %%eax,%%eax
99 \\ jz 1f97 \\ jz 1f
100 \\ retq98 \\ ret
101 \\99 \\
102 \\1:100 \\1:
103 );101 );
...@@ -105,12 +103,12 @@ pub fn clone() callconv(.naked) u32 {...@@ -105,12 +103,12 @@ pub fn clone() callconv(.naked) u32 {
105 \\ .cfi_undefined %%rip103 \\ .cfi_undefined %%rip
106 );104 );
107 asm volatile (105 asm volatile (
108 \\ xorl %%ebp,%%ebp106 \\ xor %%ebp,%%ebp
109 \\107 \\
110 \\ popq %%rdi108 \\ pop %%rdi
111 \\ callq *%%r9109 \\ call *%%r9
112 \\ movl %%eax,%%edi110 \\ mov %%eax,%%edi
113 \\ movl $60,%%eax // SYS_exit111 \\ movl $0x4000003c,%%eax // SYS_exit
114 \\ syscall112 \\ syscall
115 \\113 \\
116 );114 );
lib/std/pie.zig+27-13
...@@ -121,24 +121,38 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {...@@ -121,24 +121,38 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
121 \\ .hidden _DYNAMIC121 \\ .hidden _DYNAMIC
122 \\ bal 1f122 \\ bal 1f
123 \\ .gpword _DYNAMIC123 \\ .gpword _DYNAMIC
124 \\ 1:124 \\1:
125 \\ lw %[ret], 0($ra)125 \\ lw %[ret], 0($ra)
126 \\ nop
126 \\ addu %[ret], %[ret], $gp127 \\ addu %[ret], %[ret], $gp
127 : [ret] "=r" (-> [*]const elf.Dyn),128 : [ret] "=r" (-> [*]const elf.Dyn),
128 :129 :
129 : .{ .lr = true }),130 : .{ .lr = true }),
130 .mips64, .mips64el => asm volatile (131 .mips64, .mips64el => switch (builtin.abi) {
131 \\ .weak _DYNAMIC132 .gnuabin32, .muslabin32 => asm volatile (
132 \\ .hidden _DYNAMIC133 \\ .weak _DYNAMIC
133 \\ .balign 8134 \\ .hidden _DYNAMIC
134 \\ bal 1f135 \\ bal 1f
135 \\ .gpdword _DYNAMIC136 \\ .gpword _DYNAMIC
136 \\ 1:137 \\1:
137 \\ ld %[ret], 0($ra)138 \\ lw %[ret], 0($ra)
138 \\ daddu %[ret], %[ret], $gp139 \\ addu %[ret], %[ret], $gp
139 : [ret] "=r" (-> [*]const elf.Dyn),140 : [ret] "=r" (-> [*]const elf.Dyn),
140 :141 :
141 : .{ .lr = true }),142 : .{ .lr = true }),
143 else => asm volatile (
144 \\ .weak _DYNAMIC
145 \\ .hidden _DYNAMIC
146 \\ .balign 8
147 \\ bal 1f
148 \\ .gpdword _DYNAMIC
149 \\1:
150 \\ ld %[ret], 0($ra)
151 \\ daddu %[ret], %[ret], $gp
152 : [ret] "=r" (-> [*]const elf.Dyn),
153 :
154 : .{ .lr = true }),
155 },
142 .powerpc, .powerpcle => asm volatile (156 .powerpc, .powerpcle => asm volatile (
143 \\ .weak _DYNAMIC157 \\ .weak _DYNAMIC
144 \\ .hidden _DYNAMIC158 \\ .hidden _DYNAMIC
lib/std/start.zig+48-27
...@@ -325,43 +325,64 @@ fn _start() callconv(.naked) noreturn {...@@ -325,43 +325,64 @@ fn _start() callconv(.naked) noreturn {
325 \\ jsr (%%pc, %%a0)325 \\ jsr (%%pc, %%a0)
326 ,326 ,
327 .mips, .mipsel =>327 .mips, .mipsel =>
328 \\ move $fp, $0328 \\ move $fp, $zero
329 \\ bal 1f329 \\ bal 1f
330 \\ .gpword .330 \\ .gpword .
331 \\ .gpword %[posixCallMainAndExit]331 \\ .gpword %[posixCallMainAndExit]
332 \\ 1:332 \\1:
333 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.333 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
334 \\ lw $gp, 0($ra)334 \\ lw $gp, 0($ra)
335 \\ nop
335 \\ subu $gp, $ra, $gp336 \\ subu $gp, $ra, $gp
336 \\ lw $25, 4($ra)337 \\ lw $t9, 4($ra)
337 \\ addu $25, $25, $gp338 \\ nop
338 \\ move $ra, $0339 \\ addu $t9, $t9, $gp
340 \\ move $ra, $zero
339 \\ move $a0, $sp341 \\ move $a0, $sp
340 \\ and $sp, -8342 \\ and $sp, -8
341 \\ subu $sp, $sp, 16343 \\ subu $sp, $sp, 16
342 \\ jalr $25344 \\ jalr $t9
343 ,
344 .mips64, .mips64el =>
345 \\ move $fp, $0
346 // This is needed because early MIPS versions don't support misaligned loads. Without
347 // this directive, the hidden `nop` inserted to fill the delay slot after `bal` would
348 // cause the two doublewords to be aligned to 4 bytes instead of 8.
349 \\ .balign 8
350 \\ bal 1f
351 \\ .gpdword .
352 \\ .gpdword %[posixCallMainAndExit]
353 \\ 1:
354 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
355 \\ ld $gp, 0($ra)
356 \\ dsubu $gp, $ra, $gp
357 \\ ld $25, 8($ra)
358 \\ daddu $25, $25, $gp
359 \\ move $ra, $0
360 \\ move $a0, $sp
361 \\ and $sp, -16
362 \\ dsubu $sp, $sp, 16
363 \\ jalr $25
364 ,345 ,
346 .mips64, .mips64el => switch (builtin.abi) {
347 .gnuabin32, .muslabin32 =>
348 \\ move $fp, $zero
349 \\ bal 1f
350 \\ .gpword .
351 \\ .gpword %[posixCallMainAndExit]
352 \\1:
353 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
354 \\ lw $gp, 0($ra)
355 \\ subu $gp, $ra, $gp
356 \\ lw $t9, 4($ra)
357 \\ addu $t9, $t9, $gp
358 \\ move $ra, $zero
359 \\ move $a0, $sp
360 \\ and $sp, -8
361 \\ subu $sp, $sp, 16
362 \\ jalr $t9
363 ,
364 else =>
365 \\ move $fp, $zero
366 // This is needed because early MIPS versions don't support misaligned loads. Without
367 // this directive, the hidden `nop` inserted to fill the delay slot after `bal` would
368 // cause the two doublewords to be aligned to 4 bytes instead of 8.
369 \\ .balign 8
370 \\ bal 1f
371 \\ .gpdword .
372 \\ .gpdword %[posixCallMainAndExit]
373 \\1:
374 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
375 \\ ld $gp, 0($ra)
376 \\ dsubu $gp, $ra, $gp
377 \\ ld $t9, 8($ra)
378 \\ daddu $t9, $t9, $gp
379 \\ move $ra, $zero
380 \\ move $a0, $sp
381 \\ and $sp, -16
382 \\ dsubu $sp, $sp, 16
383 \\ jalr $t9
384 ,
385 },
365 .powerpc, .powerpcle =>386 .powerpc, .powerpcle =>
366 // Set up the initial stack frame, and clear the back chain pointer.387 // Set up the initial stack frame, and clear the back chain pointer.
367 // r1 = SP, r31 = FP388 // r1 = SP, r31 = FP