authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-18 01:56:20+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-10-18 11:16:31+02:00
logb8d776928a0b0092830ee632b1c57c8bcf9391ea
tree5f30b527977d152cad713f19018c69c7a71124c5
parentf3da54f53c1db1484b00657de18e3677358549cd
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std: make all MIPS inline asm safe for MIPS I

MIPS I has load hazards so we need to insert nops in a few places. This is not a problem for MIPS II and later. While doing this, I also touched up all the inline asm to use ABI register aliases and a consistent formatting convention. Also fixed a few places that didn't properly check if the syscall return value should be negated.

5 files changed, 223 insertions(+), 232 deletions(-)

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+64-67
......@@ -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,10 +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:
120 \\ beq $a3, $zero, 1f
121 \\ blez $v0, 1f
122 \\ dsubu $v0, $zero, $v0
123 \\1:
127124 : [ret] "={$2}" (-> u64),
128125 : [number] "{$2}" (@intFromEnum(number)),
129126 [arg1] "{$4}" (arg1),
......@@ -147,10 +144,10 @@ pub fn syscall7(
147144) u64 {
148145 return asm volatile (
149146 \\ syscall
150 \\ beq $7, $zero, 1f
151 \\ blez $2, 1f
152 \\ dsubu $2, $0, $2
153 \\ 1:
147 \\ beq $a3, $zero, 1f
148 \\ blez $v0, 1f
149 \\ dsubu $v0, $zero, $v0
150 \\1:
154151 : [ret] "={$2}" (-> u64),
155152 : [number] "{$2}" (@intFromEnum(number)),
156153 [arg1] "{$4}" (arg1),
......@@ -165,33 +162,33 @@ pub fn syscall7(
165162
166163pub fn clone() callconv(.naked) u64 {
167164 // __clone(func, stack, flags, arg, ptid, tls, ctid)
168 // 3, 4, 5, 6, 7, 8, 9
165 // a0, a1, a2, a3, a4, a5, a6
169166 //
170167 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
171 // 2 4, 5, 6, 7, 8
168 // v0 a0, a1, a2, a3, a4
172169 asm volatile (
173170 \\ # 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)
171 \\ and $a1, $a1, -16
172 \\ dsubu $a1, $a1, 16
173 \\ sd $a0, 0($a1)
174 \\ sd $a3, 8($a1)
175 \\
178176 \\ # 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
177 \\ move $a0, $a2
178 \\ move $a2, $a4
179 \\ move $a3, $a5
180 \\ move $a4, $a6
181 \\ li $v0, 5055 # SYS_clone
184182 \\ syscall
185 \\ beq $7, $0, 1f
186 \\ nop
187 \\ jr $ra
188 \\ dsubu $2, $0, $2
183 \\ beq $a3, $zero, 1f
184 \\ blez $v0, 2f
185 \\ dsubu $v0, $zero, $v0
186 \\ b 2f
189187 \\1:
190 \\ beq $2, $0, 1f
191 \\ nop
188 \\ beq $v0, $zero, 3f
189 \\2:
192190 \\ jr $ra
193 \\ nop
194 \\1:
191 \\3:
195192 );
196193 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
197194 \\ .cfi_undefined $ra
......@@ -200,12 +197,12 @@ pub fn clone() callconv(.naked) u64 {
200197 \\ move $fp, $zero
201198 \\ move $ra, $zero
202199 \\
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
200 \\ ld $t9, 0($sp)
201 \\ ld $a0, 8($sp)
202 \\ jalr $t9
203 \\
204 \\ move $a0, $v0
205 \\ li $v0, 5058 # SYS_exit
209206 \\ syscall
210207 );
211208}
lib/std/os/linux/mipsn32.zig+64-67
......@@ -7,10 +7,10 @@ const SYS = std.os.linux.SYS;
77pub fn syscall0(number: SYS) u32 {
88 return asm volatile (
99 \\ syscall
10 \\ beq $7, $zero, 1f
11 \\ blez $2, 1f
12 \\ dsubu $2, $0, $2
13 \\ 1:
10 \\ beq $a3, $zero, 1f
11 \\ blez $v0, 1f
12 \\ dsubu $v0, $zero, $v0
13 \\1:
1414 : [ret] "={$2}" (-> u32),
1515 : [number] "{$2}" (@intFromEnum(number)),
1616 : .{ .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 +18,15 @@ pub fn syscall0(number: SYS) u32 {
1818
1919pub fn syscall_pipe(fd: *[2]i32) u32 {
2020 return asm volatile (
21 \\ .set noat
22 \\ .set noreorder
2321 \\ syscall
24 \\ beq $7, $zero, 1f
25 \\ nop
22 \\ beq $a3, $zero, 1f
23 \\ blez $v0, 2f
24 \\ dsubu $v0, $zero, $v0
2625 \\ b 2f
27 \\ subu $2, $0, $2
28 \\ 1:
29 \\ sw $2, 0($4)
30 \\ sw $3, 4($4)
31 \\ 2:
26 \\1:
27 \\ sw $v0, 0($a0)
28 \\ sw $v1, 4($a0)
29 \\2:
3230 : [ret] "={$2}" (-> u32),
3331 : [number] "{$2}" (@intFromEnum(SYS.pipe)),
3432 [fd] "{$4}" (fd),
......@@ -38,11 +36,10 @@ pub fn syscall_pipe(fd: *[2]i32) u32 {
3836pub fn syscall1(number: SYS, arg1: u32) u32 {
3937 return asm volatile (
4038 \\ syscall
41 \\ beq $7, $zero, 1f
42 \\ blez $2, 1f
43 \\ nop
44 \\ dsubu $2, $0, $2
45 \\ 1:
39 \\ beq $a3, $zero, 1f
40 \\ blez $v0, 1f
41 \\ dsubu $v0, $zero, $v0
42 \\1:
4643 : [ret] "={$2}" (-> u32),
4744 : [number] "{$2}" (@intFromEnum(number)),
4845 [arg1] "{$4}" (arg1),
......@@ -52,10 +49,10 @@ pub fn syscall1(number: SYS, arg1: u32) u32 {
5249pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
5350 return asm volatile (
5451 \\ syscall
55 \\ beq $7, $zero, 1f
56 \\ blez $2, 1f
57 \\ dsubu $2, $0, $2
58 \\ 1:
52 \\ beq $a3, $zero, 1f
53 \\ blez $v0, 1f
54 \\ dsubu $v0, $zero, $v0
55 \\1:
5956 : [ret] "={$2}" (-> u32),
6057 : [number] "{$2}" (@intFromEnum(number)),
6158 [arg1] "{$4}" (arg1),
......@@ -66,10 +63,10 @@ pub fn syscall2(number: SYS, arg1: u32, arg2: u32) u32 {
6663pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
6764 return asm volatile (
6865 \\ syscall
69 \\ beq $7, $zero, 1f
70 \\ blez $2, 1f
71 \\ dsubu $2, $0, $2
72 \\ 1:
66 \\ beq $a3, $zero, 1f
67 \\ blez $v0, 1f
68 \\ dsubu $v0, $zero, $v0
69 \\1:
7370 : [ret] "={$2}" (-> u32),
7471 : [number] "{$2}" (@intFromEnum(number)),
7572 [arg1] "{$4}" (arg1),
......@@ -81,10 +78,10 @@ pub fn syscall3(number: SYS, arg1: u32, arg2: u32, arg3: u32) u32 {
8178pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
8279 return asm volatile (
8380 \\ syscall
84 \\ beq $7, $zero, 1f
85 \\ blez $2, 1f
86 \\ dsubu $2, $0, $2
87 \\ 1:
81 \\ beq $a3, $zero, 1f
82 \\ blez $v0, 1f
83 \\ dsubu $v0, $zero, $v0
84 \\1:
8885 : [ret] "={$2}" (-> u32),
8986 : [number] "{$2}" (@intFromEnum(number)),
9087 [arg1] "{$4}" (arg1),
......@@ -97,10 +94,10 @@ pub fn syscall4(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32) u32 {
9794pub fn syscall5(number: SYS, arg1: u32, arg2: u32, arg3: u32, arg4: u32, arg5: u32) u32 {
9895 return asm volatile (
9996 \\ syscall
100 \\ beq $7, $zero, 1f
101 \\ blez $2, 1f
102 \\ dsubu $2, $0, $2
103 \\ 1:
97 \\ beq $a3, $zero, 1f
98 \\ blez $v0, 1f
99 \\ dsubu $v0, $zero, $v0
100 \\1:
104101 : [ret] "={$2}" (-> u32),
105102 : [number] "{$2}" (@intFromEnum(number)),
106103 [arg1] "{$4}" (arg1),
......@@ -122,10 +119,10 @@ pub fn syscall6(
122119) u32 {
123120 return asm volatile (
124121 \\ syscall
125 \\ beq $7, $zero, 1f
126 \\ blez $2, 1f
127 \\ dsubu $2, $0, $2
128 \\ 1:
122 \\ beq $a3, $zero, 1f
123 \\ blez $v0, 1f
124 \\ dsubu $v0, $zero, $v0
125 \\1:
129126 : [ret] "={$2}" (-> u32),
130127 : [number] "{$2}" (@intFromEnum(number)),
131128 [arg1] "{$4}" (arg1),
......@@ -149,10 +146,10 @@ pub fn syscall7(
149146) u32 {
150147 return asm volatile (
151148 \\ syscall
152 \\ beq $7, $zero, 1f
153 \\ blez $2, 1f
154 \\ dsubu $2, $0, $2
155 \\ 1:
149 \\ beq $a3, $zero, 1f
150 \\ blez $v0, 1f
151 \\ dsubu $v0, $zero, $v0
152 \\1:
156153 : [ret] "={$2}" (-> u32),
157154 : [number] "{$2}" (@intFromEnum(number)),
158155 [arg1] "{$4}" (arg1),
......@@ -167,33 +164,33 @@ pub fn syscall7(
167164
168165pub fn clone() callconv(.naked) u32 {
169166 // __clone(func, stack, flags, arg, ptid, tls, ctid)
170 // 3, 4, 5, 6, 7, 8, 9
167 // a0, a1, a2, a3, a4, a5, a6
171168 //
172169 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
173 // 2 4, 5, 6, 7, 8
170 // v0 a0, a1, a2, a3, a4
174171 asm volatile (
175172 \\ # 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)
173 \\ and $a1, $a1, -16
174 \\ dsubu $a1, $a1, 16
175 \\ sd $a0, 0($a1)
176 \\ sd $a3, 8($a1)
177 \\
180178 \\ # 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
179 \\ move $a0, $a2
180 \\ move $a2, $a4
181 \\ move $a3, $a5
182 \\ move $a4, $a6
183 \\ li $v0, 5055 # SYS_clone
186184 \\ syscall
187 \\ beq $7, $0, 1f
188 \\ nop
189 \\ jr $ra
190 \\ dsubu $2, $0, $2
185 \\ beq $a3, $zero, 1f
186 \\ blez $v0, 2f
187 \\ dsubu $v0, $zero, $v0
188 \\ b 2f
191189 \\1:
192 \\ beq $2, $0, 1f
193 \\ nop
190 \\ beq $v0, $zero, 3f
191 \\2:
194192 \\ jr $ra
195 \\ nop
196 \\1:
193 \\3:
197194 );
198195 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
199196 \\ .cfi_undefined $ra
......@@ -202,12 +199,12 @@ pub fn clone() callconv(.naked) u32 {
202199 \\ move $fp, $zero
203200 \\ move $ra, $zero
204201 \\
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
202 \\ ld $t9, 0($sp)
203 \\ ld $a0, 8($sp)
204 \\ jalr $t9
205 \\
206 \\ move $a0, $v0
207 \\ li $v0, 5058 # SYS_exit
211208 \\ syscall
212209 );
213210}
lib/std/pie.zig+3-2
......@@ -121,8 +121,9 @@ 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 :
......@@ -133,7 +134,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
133134 \\ .balign 8
134135 \\ bal 1f
135136 \\ .gpdword _DYNAMIC
136 \\ 1:
137 \\1:
137138 \\ ld %[ret], 0($ra)
138139 \\ daddu %[ret], %[ret], $gp
139140 : [ret] "=r" (-> [*]const elf.Dyn),
lib/std/start.zig+14-12
......@@ -325,24 +325,26 @@ 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
344 \\ jalr $t9
343345 ,
344346 .mips64, .mips64el =>
345 \\ move $fp, $0
347 \\ move $fp, $zero
346348 // This is needed because early MIPS versions don't support misaligned loads. Without
347349 // this directive, the hidden `nop` inserted to fill the delay slot after `bal` would
348350 // cause the two doublewords to be aligned to 4 bytes instead of 8.
......@@ -350,17 +352,17 @@ fn _start() callconv(.naked) noreturn {
350352 \\ bal 1f
351353 \\ .gpdword .
352354 \\ .gpdword %[posixCallMainAndExit]
353 \\ 1:
355 \\1:
354356 // The `gp` register on MIPS serves a similar purpose to `r2` (ToC pointer) on PPC64.
355357 \\ ld $gp, 0($ra)
356358 \\ dsubu $gp, $ra, $gp
357 \\ ld $25, 8($ra)
358 \\ daddu $25, $25, $gp
359 \\ move $ra, $0
359 \\ ld $t9, 8($ra)
360 \\ daddu $t9, $t9, $gp
361 \\ move $ra, $zero
360362 \\ move $a0, $sp
361363 \\ and $sp, -16
362364 \\ dsubu $sp, $sp, 16
363 \\ jalr $25
365 \\ jalr $t9
364366 ,
365367 .powerpc, .powerpcle =>
366368 // Set up the initial stack frame, and clear the back chain pointer.