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 {
11911191 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
11921192 [len] "r" (self.mapped.len),
11931193 : .{ .memory = true }),
1194 .x86_64 => asm volatile (
1195 \\ movq $11, %%rax # SYS_munmap
1196 \\ syscall
1197 \\ movq $60, %%rax # SYS_exit
1198 \\ movq $1, %%rdi
1199 \\ syscall
1194 .x86_64 => asm volatile (switch (target.abi) {
1195 .gnux32, .muslx32 =>
1196 \\ movl $0x4000000b, %%eax # SYS_munmap
1197 \\ syscall
1198 \\ movl $0x4000003c, %%eax # SYS_exit
1199 \\ 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 }
12001210 :
12011211 : [ptr] "{rdi}" (@intFromPtr(self.mapped.ptr)),
12021212 [len] "{rsi}" (self.mapped.len),
......@@ -1242,26 +1252,38 @@ const LinuxThreadImpl = struct {
12421252 // The bug was introduced in 46e12c07b3b9603c60fc1d421ff18618241cb081 and fixed in
12431253 // 7928eb0370d1133d0d8cd2f5ddfca19c309079d5.
12441254 .mips, .mipsel => asm volatile (
1245 \\ move $sp, $25
1246 \\ li $2, 4091 # SYS_munmap
1247 \\ move $4, %[ptr]
1248 \\ move $5, %[len]
1249 \\ syscall
1250 \\ li $2, 4001 # SYS_exit
1251 \\ li $4, 0
1252 \\ syscall
1255 \\ move $sp, $t9
1256 \\ li $v0, 4091 # SYS_munmap
1257 \\ move $a0, %[ptr]
1258 \\ move $a1, %[len]
1259 \\ syscall
1260 \\ li $v0, 4001 # SYS_exit
1261 \\ li $a0, 0
1262 \\ syscall
12531263 :
12541264 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
12551265 [len] "r" (self.mapped.len),
12561266 : .{ .memory = true }),
1257 .mips64, .mips64el => asm volatile (
1258 \\ li $2, 5011 # SYS_munmap
1259 \\ move $4, %[ptr]
1260 \\ move $5, %[len]
1261 \\ syscall
1262 \\ li $2, 5058 # SYS_exit
1263 \\ li $4, 0
1264 \\ syscall
1267 .mips64, .mips64el => asm volatile (switch (target.abi) {
1268 .gnuabin32, .muslabin32 =>
1269 \\ li $v0, 6011 # SYS_munmap
1270 \\ move $a0, %[ptr]
1271 \\ move $a1, %[len]
1272 \\ syscall
1273 \\ li $v0, 6058 # SYS_exit
1274 \\ 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 }
12651287 :
12661288 : [ptr] "r" (@intFromPtr(self.mapped.ptr)),
12671289 [len] "r" (self.mapped.len),
lib/std/os/linux/mips.zig+78-84
......@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;
55pub fn syscall0(number: SYS) u32 {
66 return asm volatile (
77 \\ syscall
8 \\ beq $7, $zero, 1f
9 \\ blez $2, 1f
10 \\ subu $2, $0, $2
11 \\ 1:
8 \\ beq $a3, $zero, 1f
9 \\ blez $v0, 1f
10 \\ subu $v0, $zero, $v0
11 \\1:
1212 : [ret] "={$2}" (-> u32),
1313 : [number] "{$2}" (@intFromEnum(number)),
1414 : .{ .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 {
1616
1717pub fn syscall_pipe(fd: *[2]i32) u32 {
1818 return asm volatile (
19 \\ .set noat
20 \\ .set noreorder
2119 \\ syscall
22 \\ beq $7, $zero, 1f
23 \\ nop
20 \\ beq $a3, $zero, 1f
21 \\ blez $v0, 2f
22 \\ subu $v0, $zero, $v0
2423 \\ b 2f
25 \\ subu $2, $0, $2
26 \\ 1:
27 \\ sw $2, 0($4)
28 \\ sw $3, 4($4)
29 \\ 2:
24 \\1:
25 \\ sw $v0, 0($a0)
26 \\ sw $v1, 4($a0)
27 \\2:
3028 : [ret] "={$2}" (-> u32),
3129 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
3230 [fd] "{$4}" (fd),
......@@ -36,10 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {
3634pub fn syscall1(number: SYS, arg1: u32) u32 {
3735 return asm volatile (
3836 \\ syscall
39 \\ beq $7, $zero, 1f
40 \\ blez $2, 1f
41 \\ subu $2, $0, $2
42 \\ 1:
37 \\ beq $a3, $zero, 1f
38 \\ blez $v0, 1f
39 \\ subu $v0, $zero, $v0
40 \\1:
4341 : [ret] "={$2}" (-> u32),
4442 : [number] "{$2}" (@intFromEnum(number)),
4543 [arg1] "{$4}" (arg1),
......@@ -49,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {
4947pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
5048 return asm volatile (
5149 \\ syscall
52 \\ beq $7, $zero, 1f
53 \\ blez $2, 1f
54 \\ subu $2, $0, $2
55 \\ 1:
50 \\ beq $a3, $zero, 1f
51 \\ blez $v0, 1f
52 \\ subu $v0, $zero, $v0
53 \\1:
5654 : [ret] "={$2}" (-> u32),
5755 : [number] "{$2}" (@intFromEnum(number)),
5856 [arg1] "{$4}" (arg1),
......@@ -63,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
6361pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
6462 return asm volatile (
6563 \\ syscall
66 \\ beq $7, $zero, 1f
67 \\ blez $2, 1f
68 \\ subu $2, $0, $2
69 \\ 1:
64 \\ beq $a3, $zero, 1f
65 \\ blez $v0, 1f
66 \\ subu $v0, $zero, $v0
67 \\1:
7068 : [ret] "={$2}" (-> u32),
7169 : [number] "{$2}" (@intFromEnum(number)),
7270 [arg1] "{$4}" (arg1),
......@@ -78,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
7876pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
7977 return asm volatile (
8078 \\ syscall
81 \\ beq $7, $zero, 1f
82 \\ blez $2, 1f
83 \\ subu $2, $0, $2
84 \\ 1:
79 \\ beq $a3, $zero, 1f
80 \\ blez $v0, 1f
81 \\ subu $v0, $zero, $v0
82 \\1:
8583 : [ret] "={$2}" (-> u32),
8684 : [number] "{$2}" (@intFromEnum(number)),
8785 [arg1] "{$4}" (arg1),
......@@ -91,17 +89,19 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
9189 : .{ .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 });
9290}
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
9495pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
9596 return asm volatile (
96 \\ .set noat
9797 \\ subu $sp, $sp, 24
9898 \\ sw %[arg5], 16($sp)
9999 \\ syscall
100100 \\ addu $sp, $sp, 24
101 \\ beq $7, $zero, 1f
102 \\ blez $2, 1f
103 \\ subu $2, $0, $2
104 \\ 1:
101 \\ beq $a3, $zero, 1f
102 \\ blez $v0, 1f
103 \\ subu $v0, $zero, $v0
104 \\1:
105105 : [ret] "={$2}" (-> u32),
106106 : [number] "{$2}" (@intFromEnum(number)),
107107 [arg1] "{$4}" (arg1),
......@@ -112,9 +112,6 @@ pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u
112112 : .{ .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 });
113113}
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
118115pub fn syscall6(
119116 number: SYS,
120117 arg1: u32,
......@@ -125,16 +122,15 @@ pub fn syscall6(
125122 arg6: u32,
126123) u32 {
127124 return asm volatile (
128 \\ .set noat
129125 \\ subu $sp, $sp, 24
130126 \\ sw %[arg5], 16($sp)
131127 \\ sw %[arg6], 20($sp)
132128 \\ syscall
133129 \\ addu $sp, $sp, 24
134 \\ beq $7, $zero, 1f
135 \\ blez $2, 1f
136 \\ subu $2, $0, $2
137 \\ 1:
130 \\ beq $a3, $zero, 1f
131 \\ blez $v0, 1f
132 \\ subu $v0, $zero, $v0
133 \\1:
138134 : [ret] "={$2}" (-> u32),
139135 : [number] "{$2}" (@intFromEnum(number)),
140136 [arg1] "{$4}" (arg1),
......@@ -157,17 +153,16 @@ pub fn syscall7(
157153 arg7: u32,
158154) u32 {
159155 return asm volatile (
160 \\ .set noat
161156 \\ subu $sp, $sp, 32
162157 \\ sw %[arg5], 16($sp)
163158 \\ sw %[arg6], 20($sp)
164159 \\ sw %[arg7], 24($sp)
165160 \\ syscall
166161 \\ addu $sp, $sp, 32
167 \\ beq $7, $zero, 1f
168 \\ blez $2, 1f
169 \\ subu $2, $0, $2
170 \\ 1:
162 \\ beq $a3, $zero, 1f
163 \\ blez $v0, 1f
164 \\ subu $v0, $zero, $v0
165 \\1:
171166 : [ret] "={$2}" (-> u32),
172167 : [number] "{$2}" (@intFromEnum(number)),
173168 [arg1] "{$4}" (arg1),
......@@ -182,52 +177,51 @@ pub fn syscall7(
182177
183178pub fn clone() callconv(.naked) u32 {
184179 // __clone(func, stack, flags, arg, ptid, tls, ctid)
185 // 3, 4, 5, 6, 7, 8, 9
180 // a0, a1, a2, a3, +0, +4, +8
186181 //
187182 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
188 // 2 4, 5, 6, 7, 8
183 // v0 a0, a1, a2, a3, +0
189184 asm volatile (
190 \\ # Save function pointer and argument pointer on new thread stack
191 \\ and $5, $5, -8
192 \\ subu $5, $5, 16
193 \\ sw $4, 0($5)
194 \\ sw $7, 4($5)
195 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
196 \\ move $4, $6
197 \\ lw $6, 16($sp)
198 \\ lw $7, 20($sp)
199 \\ lw $9, 24($sp)
200 \\ subu $sp, $sp, 16
201 \\ sw $9, 16($sp)
202 \\ li $2, 4120 # SYS_clone
203 \\ syscall
204 \\ beq $7, $0, 1f
205 \\ nop
206 \\ addu $sp, $sp, 16
207 \\ jr $ra
208 \\ subu $2, $0, $2
209 \\1:
210 \\ beq $2, $0, 1f
211 \\ nop
212 \\ addu $sp, $sp, 16
213 \\ jr $ra
214 \\ nop
185 \\ # Save function pointer and argument pointer on new thread stack
186 \\ and $a1, $a1, -8
187 \\ subu $a1, $a1, 16
188 \\ sw $a0, 0($a1)
189 \\ sw $a3, 4($a1)
190 \\
191 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
192 \\ move $a0, $a2
193 \\ lw $a2, 16($sp)
194 \\ lw $a3, 20($sp)
195 \\ lw $t1, 24($sp)
196 \\ subu $sp, $sp, 16
197 \\ sw $t1, 16($sp)
198 \\ li $v0, 4120 # SYS_clone
199 \\ syscall
200 \\ beq $a3, $zero, 1f
201 \\ blez $v0, 2f
202 \\ subu $v0, $zero, $v0
203 \\ b 2f
215204 \\1:
205 \\ beq $v0, $zero, 3f
206 \\2:
207 \\ addu $sp, $sp, 16
208 \\ jr $ra
209 \\3:
216210 );
217211 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
218 \\ .cfi_undefined $ra
212 \\ .cfi_undefined $ra
219213 );
220214 asm volatile (
221 \\ move $fp, $zero
222 \\ move $ra, $zero
215 \\ move $fp, $zero
216 \\ move $ra, $zero
223217 \\
224 \\ lw $25, 0($sp)
225 \\ lw $4, 4($sp)
226 \\ jalr $25
227 \\ nop
228 \\ move $4, $2
229 \\ li $2, 4001 # SYS_exit
230 \\ syscall
218 \\ lw $t9, 0($sp)
219 \\ lw $a0, 4($sp)
220 \\ jalr $t9
221 \\
222 \\ move $a0, $v0
223 \\ li $v0, 4001 # SYS_exit
224 \\ syscall
231225 );
232226}
233227
lib/std/os/linux/mips64.zig+60-91
......@@ -5,10 +5,10 @@ const SYS = std.os.linux.SYS;
55pub fn syscall0(number: SYS) u64 {
66 return asm volatile (
77 \\ syscall
8 \\ beq $7, $zero, 1f
9 \\ blez $2, 1f
10 \\ dsubu $2, $0, $2
11 \\ 1:
8 \\ beq $a3, $zero, 1f
9 \\ blez $v0, 1f
10 \\ dsubu $v0, $zero, $v0
11 \\1:
1212 : [ret] "={$2}" (-> u64),
1313 : [number] "{$2}" (@intFromEnum(number)),
1414 : .{ .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 {
1616
1717pub fn syscall_pipe(fd: *[2]i32) u64 {
1818 return asm volatile (
19 \\ .set noat
20 \\ .set noreorder
2119 \\ syscall
22 \\ beq $7, $zero, 1f
23 \\ nop
20 \\ beq $a3, $zero, 1f
21 \\ blez $v0, 2f
22 \\ dsubu $v0, $zero, $v0
2423 \\ b 2f
25 \\ subu $2, $0, $2
26 \\ 1:
27 \\ sw $2, 0($4)
28 \\ sw $3, 4($4)
29 \\ 2:
24 \\1:
25 \\ sw $v0, 0($a0)
26 \\ sw $v1, 4($a0)
27 \\2:
3028 : [ret] "={$2}" (-> u64),
3129 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
3230 [fd] "{$4}" (fd),
......@@ -36,11 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u64 {
3634pub fn syscall1(number: SYS, arg1: u64) u64 {
3735 return asm volatile (
3836 \\ syscall
39 \\ beq $7, $zero, 1f
40 \\ blez $2, 1f
41 \\ nop
42 \\ dsubu $2, $0, $2
43 \\ 1:
37 \\ beq $a3, $zero, 1f
38 \\ blez $v0, 1f
39 \\ dsubu $v0, $zero, $v0
40 \\1:
4441 : [ret] "={$2}" (-> u64),
4542 : [number] "{$2}" (@intFromEnum(number)),
4643 [arg1] "{$4}" (arg1),
......@@ -50,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u64) u64 {
5047pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
5148 return asm volatile (
5249 \\ syscall
53 \\ beq $7, $zero, 1f
54 \\ blez $2, 1f
55 \\ dsubu $2, $0, $2
56 \\ 1:
50 \\ beq $a3, $zero, 1f
51 \\ blez $v0, 1f
52 \\ dsubu $v0, $zero, $v0
53 \\1:
5754 : [ret] "={$2}" (-> u64),
5855 : [number] "{$2}" (@intFromEnum(number)),
5956 [arg1] "{$4}" (arg1),
......@@ -64,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u64, arg2: u64) u64 {
6461pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
6562 return asm volatile (
6663 \\ syscall
67 \\ beq $7, $zero, 1f
68 \\ blez $2, 1f
69 \\ dsubu $2, $0, $2
70 \\ 1:
64 \\ beq $a3, $zero, 1f
65 \\ blez $v0, 1f
66 \\ dsubu $v0, $zero, $v0
67 \\1:
7168 : [ret] "={$2}" (-> u64),
7269 : [number] "{$2}" (@intFromEnum(number)),
7370 [arg1] "{$4}" (arg1),
......@@ -79,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u64, arg2: u64, arg3: u64) u64 {
7976pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
8077 return asm volatile (
8178 \\ syscall
82 \\ beq $7, $zero, 1f
83 \\ blez $2, 1f
84 \\ dsubu $2, $0, $2
85 \\ 1:
79 \\ beq $a3, $zero, 1f
80 \\ blez $v0, 1f
81 \\ dsubu $v0, $zero, $v0
82 \\1:
8683 : [ret] "={$2}" (-> u64),
8784 : [number] "{$2}" (@intFromEnum(number)),
8885 [arg1] "{$4}" (arg1),
......@@ -95,10 +92,10 @@ pub fn syscall4(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64) u64 {
9592pub fn syscall5(number: SYS, arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) u64 {
9693 return asm volatile (
9794 \\ syscall
98 \\ beq $7, $zero, 1f
99 \\ blez $2, 1f
100 \\ dsubu $2, $0, $2
101 \\ 1:
95 \\ beq $a3, $zero, 1f
96 \\ blez $v0, 1f
97 \\ dsubu $v0, $zero, $v0
98 \\1:
10299 : [ret] "={$2}" (-> u64),
103100 : [number] "{$2}" (@intFromEnum(number)),
104101 [arg1] "{$4}" (arg1),
......@@ -120,37 +117,10 @@ pub fn syscall6(
120117) u64 {
121118 return asm volatile (
122119 \\ syscall
123 \\ beq $7, $zero, 1f
124 \\ blez $2, 1f
125 \\ dsubu $2, $0, $2
126 \\ 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:
120 \\ beq $a3, $zero, 1f
121 \\ blez $v0, 1f
122 \\ dsubu $v0, $zero, $v0
123 \\1:
154124 : [ret] "={$2}" (-> u64),
155125 : [number] "{$2}" (@intFromEnum(number)),
156126 [arg1] "{$4}" (arg1),
......@@ -159,39 +129,38 @@ pub fn syscall7(
159129 [arg4] "{$7}" (arg4),
160130 [arg5] "{$8}" (arg5),
161131 [arg6] "{$9}" (arg6),
162 [arg7] "{$10}" (arg7),
163132 : .{ .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 });
164133}
165134
166135pub fn clone() callconv(.naked) u64 {
167136 // __clone(func, stack, flags, arg, ptid, tls, ctid)
168 // 3, 4, 5, 6, 7, 8, 9
137 // a0, a1, a2, a3, a4, a5, a6
169138 //
170139 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
171 // 2 4, 5, 6, 7, 8
140 // v0 a0, a1, a2, a3, a4
172141 asm volatile (
173142 \\ # Save function pointer and argument pointer on new thread stack
174 \\ and $5, $5, -16
175 \\ dsubu $5, $5, 16
176 \\ sd $4, 0($5)
177 \\ sd $7, 8($5)
143 \\ and $a1, $a1, -16
144 \\ dsubu $a1, $a1, 16
145 \\ sd $a0, 0($a1)
146 \\ sd $a3, 8($a1)
147 \\
178148 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
179 \\ move $4, $6
180 \\ move $6, $8
181 \\ move $7, $9
182 \\ move $8, $10
183 \\ li $2, 5055 # SYS_clone
149 \\ move $a0, $a2
150 \\ move $a2, $a4
151 \\ move $a3, $a5
152 \\ move $a4, $a6
153 \\ li $v0, 5055 # SYS_clone
184154 \\ syscall
185 \\ beq $7, $0, 1f
186 \\ nop
187 \\ jr $ra
188 \\ dsubu $2, $0, $2
155 \\ beq $a3, $zero, 1f
156 \\ blez $v0, 2f
157 \\ dsubu $v0, $zero, $v0
158 \\ b 2f
189159 \\1:
190 \\ beq $2, $0, 1f
191 \\ nop
160 \\ beq $v0, $zero, 3f
161 \\2:
192162 \\ jr $ra
193 \\ nop
194 \\1:
163 \\3:
195164 );
196165 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
197166 \\ .cfi_undefined $ra
......@@ -200,12 +169,12 @@ pub fn clone() callconv(.naked) u64 {
200169 \\ move $fp, $zero
201170 \\ move $ra, $zero
202171 \\
203 \\ ld $25, 0($sp)
204 \\ ld $4, 8($sp)
205 \\ jalr $25
206 \\ nop
207 \\ move $4, $2
208 \\ li $2, 5058 # SYS_exit
172 \\ ld $t9, 0($sp)
173 \\ ld $a0, 8($sp)
174 \\ jalr $t9
175 \\
176 \\ move $a0, $v0
177 \\ li $v0, 5058 # SYS_exit
209178 \\ syscall
210179 );
211180}
lib/std/os/linux/mipsn32.zig+60-93
......@@ -1,5 +1,3 @@
1// TODO: A lot of this file is very likely wrong.
2
31const builtin = @import("builtin");
42const std = @import("../../std.zig");
53const SYS = std.os.linux.SYS;
......@@ -7,10 +5,10 @@ const SYS = std.os.linux.SYS;
75pub fn syscall0(number: SYS) u32 {
86 return asm volatile (
97 \\ syscall
10 \\ beq $7, $zero, 1f
11 \\ blez $2, 1f
12 \\ dsubu $2, $0, $2
13 \\ 1:
8 \\ beq $a3, $zero, 1f
9 \\ blez $v0, 1f
10 \\ subu $v0, $zero, $v0
11 \\1:
1412 : [ret] "={$2}" (-> u32),
1513 : [number] "{$2}" (@intFromEnum(number)),
1614 : .{ .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 {
1816
1917pub fn syscall_pipe(fd: *[2]i32) u32 {
2018 return asm volatile (
21 \\ .set noat
22 \\ .set noreorder
2319 \\ syscall
24 \\ beq $7, $zero, 1f
25 \\ nop
20 \\ beq $a3, $zero, 1f
21 \\ blez $v0, 2f
22 \\ subu $v0, $zero, $v0
2623 \\ b 2f
27 \\ subu $2, $0, $2
28 \\ 1:
29 \\ sw $2, 0($4)
30 \\ sw $3, 4($4)
31 \\ 2:
24 \\1:
25 \\ sw $v0, 0($a0)
26 \\ sw $v1, 4($a0)
27 \\2:
3228 : [ret] "={$2}" (-> u32),
3329 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
3430 [fd] "{$4}" (fd),
......@@ -38,11 +34,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {
3834pub fn syscall1(number: SYS, arg1: u32) u32 {
3935 return asm volatile (
4036 \\ syscall
41 \\ beq $7, $zero, 1f
42 \\ blez $2, 1f
43 \\ nop
44 \\ dsubu $2, $0, $2
45 \\ 1:
37 \\ beq $a3, $zero, 1f
38 \\ blez $v0, 1f
39 \\ subu $v0, $zero, $v0
40 \\1:
4641 : [ret] "={$2}" (-> u32),
4742 : [number] "{$2}" (@intFromEnum(number)),
4843 [arg1] "{$4}" (arg1),
......@@ -52,10 +47,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {
5247pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
5348 return asm volatile (
5449 \\ syscall
55 \\ beq $7, $zero, 1f
56 \\ blez $2, 1f
57 \\ dsubu $2, $0, $2
58 \\ 1:
50 \\ beq $a3, $zero, 1f
51 \\ blez $v0, 1f
52 \\ subu $v0, $zero, $v0
53 \\1:
5954 : [ret] "={$2}" (-> u32),
6055 : [number] "{$2}" (@intFromEnum(number)),
6156 [arg1] "{$4}" (arg1),
......@@ -66,10 +61,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
6661pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
6762 return asm volatile (
6863 \\ syscall
69 \\ beq $7, $zero, 1f
70 \\ blez $2, 1f
71 \\ dsubu $2, $0, $2
72 \\ 1:
64 \\ beq $a3, $zero, 1f
65 \\ blez $v0, 1f
66 \\ subu $v0, $zero, $v0
67 \\1:
7368 : [ret] "={$2}" (-> u32),
7469 : [number] "{$2}" (@intFromEnum(number)),
7570 [arg1] "{$4}" (arg1),
......@@ -81,10 +76,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
8176pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
8277 return asm volatile (
8378 \\ syscall
84 \\ beq $7, $zero, 1f
85 \\ blez $2, 1f
86 \\ dsubu $2, $0, $2
87 \\ 1:
79 \\ beq $a3, $zero, 1f
80 \\ blez $v0, 1f
81 \\ subu $v0, $zero, $v0
82 \\1:
8883 : [ret] "={$2}" (-> u32),
8984 : [number] "{$2}" (@intFromEnum(number)),
9085 [arg1] "{$4}" (arg1),
......@@ -97,10 +92,10 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
9792pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
9893 return asm volatile (
9994 \\ syscall
100 \\ beq $7, $zero, 1f
101 \\ blez $2, 1f
102 \\ dsubu $2, $0, $2
103 \\ 1:
95 \\ beq $a3, $zero, 1f
96 \\ blez $v0, 1f
97 \\ subu $v0, $zero, $v0
98 \\1:
10499 : [ret] "={$2}" (-> u32),
105100 : [number] "{$2}" (@intFromEnum(number)),
106101 [arg1] "{$4}" (arg1),
......@@ -122,37 +117,10 @@ pub fn syscall6(
122117) u32 {
123118 return asm volatile (
124119 \\ syscall
125 \\ beq $7, $zero, 1f
126 \\ blez $2, 1f
127 \\ dsubu $2, $0, $2
128 \\ 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:
120 \\ beq $a3, $zero, 1f
121 \\ blez $v0, 1f
122 \\ subu $v0, $zero, $v0
123 \\1:
156124 : [ret] "={$2}" (-> u32),
157125 : [number] "{$2}" (@intFromEnum(number)),
158126 [arg1] "{$4}" (arg1),
......@@ -161,39 +129,38 @@ pub fn syscall7(
161129 [arg4] "{$7}" (arg4),
162130 [arg5] "{$8}" (arg5),
163131 [arg6] "{$9}" (arg6),
164 [arg7] "{$10}" (arg7),
165132 : .{ .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 });
166133}
167134
168135pub fn clone() callconv(.naked) u32 {
169136 // __clone(func, stack, flags, arg, ptid, tls, ctid)
170 // 3, 4, 5, 6, 7, 8, 9
137 // a0, a1, a2, a3, a4, a5, a6
171138 //
172139 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
173 // 2 4, 5, 6, 7, 8
140 // v0 a0, a1, a2, a3, a4
174141 asm volatile (
175142 \\ # Save function pointer and argument pointer on new thread stack
176 \\ and $5, $5, -16
177 \\ dsubu $5, $5, 16
178 \\ sd $4, 0($5)
179 \\ sd $7, 8($5)
143 \\ and $a1, $a1, -16
144 \\ subu $a1, $a1, 16
145 \\ sw $a0, 0($a1)
146 \\ sw $a3, 4($a1)
147 \\
180148 \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
181 \\ move $4, $6
182 \\ move $6, $8
183 \\ move $7, $9
184 \\ move $8, $10
185 \\ li $2, 5055 # SYS_clone
149 \\ move $a0, $a2
150 \\ move $a2, $a4
151 \\ move $a3, $a5
152 \\ move $a4, $a6
153 \\ li $v0, 6055 # SYS_clone
186154 \\ syscall
187 \\ beq $7, $0, 1f
188 \\ nop
189 \\ jr $ra
190 \\ dsubu $2, $0, $2
155 \\ beq $a3, $zero, 1f
156 \\ blez $v0, 2f
157 \\ subu $v0, $zero, $v0
158 \\ b 2f
191159 \\1:
192 \\ beq $2, $0, 1f
193 \\ nop
160 \\ beq $v0, $zero, 3f
161 \\2:
194162 \\ jr $ra
195 \\ nop
196 \\1:
163 \\3:
197164 );
198165 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
199166 \\ .cfi_undefined $ra
......@@ -202,12 +169,12 @@ pub fn clone() callconv(.naked) u32 {
202169 \\ move $fp, $zero
203170 \\ move $ra, $zero
204171 \\
205 \\ ld $25, 0($sp)
206 \\ ld $4, 8($sp)
207 \\ jalr $25
208 \\ nop
209 \\ move $4, $2
210 \\ li $2, 5058 # SYS_exit
172 \\ ld $t9, 0($sp)
173 \\ ld $a0, 4($sp)
174 \\ jalr $t9
175 \\
176 \\ move $a0, $v0
177 \\ li $v0, 6058 # SYS_exit
211178 \\ syscall
212179 );
213180}
lib/std/os/linux/x32.zig+17-19
......@@ -1,5 +1,3 @@
1// TODO: A lot of this file is very likely wrong.
2
31const builtin = @import("builtin");
42const std = @import("../../std.zig");
53const SYS = std.os.linux.SYS;
......@@ -84,20 +82,20 @@ pub fn syscall6(
8482
8583pub fn clone() callconv(.naked) u32 {
8684 asm volatile (
87 \\ movl $56,%%eax // SYS_clone
88 \\ movq %%rdi,%%r11
89 \\ movq %%rdx,%%rdi
90 \\ movq %%r8,%%rdx
91 \\ movq %%r9,%%r8
92 \\ movq 8(%%rsp),%%r10
93 \\ movq %%r11,%%r9
94 \\ andq $-16,%%rsi
95 \\ subq $8,%%rsi
96 \\ movq %%rcx,(%%rsi)
85 \\ movl $0x40000038,%%eax // SYS_clone
86 \\ mov %%rdi,%%r11
87 \\ mov %%rdx,%%rdi
88 \\ mov %%r8,%%rdx
89 \\ mov %%r9,%%r8
90 \\ mov 8(%%rsp),%%r10
91 \\ mov %%r11,%%r9
92 \\ and $-16,%%rsi
93 \\ sub $8,%%rsi
94 \\ mov %%rcx,(%%rsi)
9795 \\ syscall
98 \\ testq %%rax,%%rax
96 \\ test %%eax,%%eax
9997 \\ jz 1f
100 \\ retq
98 \\ ret
10199 \\
102100 \\1:
103101 );
......@@ -105,12 +103,12 @@ pub fn clone() callconv(.naked) u32 {
105103 \\ .cfi_undefined %%rip
106104 );
107105 asm volatile (
108 \\ xorl %%ebp,%%ebp
106 \\ xor %%ebp,%%ebp
109107 \\
110 \\ popq %%rdi
111 \\ callq *%%r9
112 \\ movl %%eax,%%edi
113 \\ movl $60,%%eax // SYS_exit
108 \\ pop %%rdi
109 \\ call *%%r9
110 \\ mov %%eax,%%edi
111 \\ movl $0x4000003c,%%eax // SYS_exit
114112 \\ syscall
115113 \\
116114 );
lib/std/pie.zig+27-13
......@@ -121,24 +121,38 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
121121 \\ .hidden _DYNAMIC
122122 \\ bal 1f
123123 \\ .gpword _DYNAMIC
124 \\ 1:
124 \\1:
125125 \\ lw %[ret], 0($ra)
126 \\ nop
126127 \\ addu %[ret], %[ret], $gp
127128 : [ret] "=r" (-> [*]const elf.Dyn),
128129 :
129130 : .{ .lr = true }),
130 .mips64, .mips64el => asm volatile (
131 \\ .weak _DYNAMIC
132 \\ .hidden _DYNAMIC
133 \\ .balign 8
134 \\ bal 1f
135 \\ .gpdword _DYNAMIC
136 \\ 1:
137 \\ ld %[ret], 0($ra)
138 \\ daddu %[ret], %[ret], $gp
139 : [ret] "=r" (-> [*]const elf.Dyn),
140 :
141 : .{ .lr = true }),
131 .mips64, .mips64el => switch (builtin.abi) {
132 .gnuabin32, .muslabin32 => asm volatile (
133 \\ .weak _DYNAMIC
134 \\ .hidden _DYNAMIC
135 \\ bal 1f
136 \\ .gpword _DYNAMIC
137 \\1:
138 \\ lw %[ret], 0($ra)
139 \\ addu %[ret], %[ret], $gp
140 : [ret] "=r" (-> [*]const elf.Dyn),
141 :
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 },
142156 .powerpc, .powerpcle => asm volatile (
143157 \\ .weak _DYNAMIC
144158 \\ .hidden _DYNAMIC
lib/std/start.zig+48-27
......@@ -325,43 +325,64 @@ fn _start() callconv(.naked) noreturn {
325325 \\ jsr (%%pc, %%a0)
326326 ,
327327 .mips, .mipsel =>
328 \\ move $fp, $0
328 \\ move $fp, $zero
329329 \\ bal 1f
330330 \\ .gpword .
331331 \\ .gpword %[posixCallMainAndExit]
332 \\ 1:
332 \\1:
333333 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
334334 \\ lw $gp, 0($ra)
335 \\ nop
335336 \\ subu $gp, $ra, $gp
336 \\ lw $25, 4($ra)
337 \\ addu $25, $25, $gp
338 \\ move $ra, $0
337 \\ lw $t9, 4($ra)
338 \\ nop
339 \\ addu $t9, $t9, $gp
340 \\ move $ra, $zero
339341 \\ move $a0, $sp
340342 \\ and $sp, -8
341343 \\ subu $sp, $sp, 16
342 \\ jalr $25
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
344 \\ jalr $t9
364345 ,
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 },
365386 .powerpc, .powerpcle =>
366387 // Set up the initial stack frame, and clear the back chain pointer.
367388 // r1 = SP, r31 = FP