authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-08 02:52:48+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-09 16:56:23+02:00
log3b947932abbb9f14710c64e3afa6fa88947d1ed1
treef226bf066c77916ce2a0fda299bfefd227f33343
parent3822af14071ec2ffe03427079c343549f0143d9b
signaturebadge-check Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

std: avoid pointless delay slots and lr writes in inline assembly

And fill in some delay slots where we can't avoid them.

6 files changed, 53 insertions(+), 40 deletions(-)

lib/std/Thread.zig+32-32
...@@ -1166,29 +1166,29 @@ const LinuxThreadImpl = struct {...@@ -1166,29 +1166,29 @@ const LinuxThreadImpl = struct {
1166 posix.sigprocmask(std.posix.SIG.BLOCK, &std.os.linux.sigfillset(), null);1166 posix.sigprocmask(std.posix.SIG.BLOCK, &std.os.linux.sigfillset(), null);
1167 switch (target.cpu.arch) {1167 switch (target.cpu.arch) {
1168 .x86 => asm volatile (1168 .x86 => asm volatile (
1169 \\ movl $91, %%eax # SYS_munmap1169 \\ movl $91, %%eax # SYS_munmap
1170 \\ int $1281170 \\ int $128
1171 \\ movl $1, %%eax # SYS_exit1171 \\ movl $1, %%eax # SYS_exit
1172 \\ movl $0, %%ebx1172 \\ movl $0, %%ebx
1173 \\ int $1281173 \\ int $128
1174 :1174 :
1175 : [ptr] "{ebx}" (@intFromPtr(self.mapped.ptr)),1175 : [ptr] "{ebx}" (@intFromPtr(self.mapped.ptr)),
1176 [len] "{ecx}" (self.mapped.len),1176 [len] "{ecx}" (self.mapped.len),
1177 ),1177 ),
1178 .x86_64 => asm volatile (switch (target.abi) {1178 .x86_64 => asm volatile (switch (target.abi) {
1179 .gnux32, .muslx32, .x32 =>1179 .gnux32, .muslx32, .x32 =>
1180 \\ movl $0x4000000b, %%eax # SYS_munmap1180 \\ movl $0x4000000b, %%eax # SYS_munmap
1181 \\ syscall1181 \\ syscall
1182 \\ movl $0x4000003c, %%eax # SYS_exit1182 \\ movl $0x4000003c, %%eax # SYS_exit
1183 \\ xor %%rdi, %%rdi1183 \\ xor %%rdi, %%rdi
1184 \\ syscall1184 \\ syscall
1185 ,1185 ,
1186 else =>1186 else =>
1187 \\ movl $11, %%eax # SYS_munmap1187 \\ movl $11, %%eax # SYS_munmap
1188 \\ syscall1188 \\ syscall
1189 \\ movl $60, %%eax # SYS_exit1189 \\ movl $60, %%eax # SYS_exit
1190 \\ xor %%rdi, %%rdi1190 \\ xor %%rdi, %%rdi
1191 \\ syscall1191 \\ syscall
1192 ,1192 ,
1193 }1193 }
1194 :1194 :
...@@ -1196,21 +1196,21 @@ const LinuxThreadImpl = struct {...@@ -1196,21 +1196,21 @@ const LinuxThreadImpl = struct {
1196 [len] "{rsi}" (self.mapped.len),1196 [len] "{rsi}" (self.mapped.len),
1197 ),1197 ),
1198 .arm, .armeb, .thumb, .thumbeb => asm volatile (1198 .arm, .armeb, .thumb, .thumbeb => asm volatile (
1199 \\ mov r7, #91 // SYS_munmap1199 \\ mov r7, #91 // SYS_munmap
1200 \\ svc 01200 \\ svc 0
1201 \\ mov r7, #1 // SYS_exit1201 \\ mov r7, #1 // SYS_exit
1202 \\ mov r0, #01202 \\ mov r0, #0
1203 \\ svc 01203 \\ svc 0
1204 :1204 :
1205 : [ptr] "{r0}" (@intFromPtr(self.mapped.ptr)),1205 : [ptr] "{r0}" (@intFromPtr(self.mapped.ptr)),
1206 [len] "{r1}" (self.mapped.len),1206 [len] "{r1}" (self.mapped.len),
1207 ),1207 ),
1208 .aarch64, .aarch64_be => asm volatile (1208 .aarch64, .aarch64_be => asm volatile (
1209 \\ mov x8, #215 // SYS_munmap1209 \\ mov x8, #215 // SYS_munmap
1210 \\ svc 01210 \\ svc 0
1211 \\ mov x8, #93 // SYS_exit1211 \\ mov x8, #93 // SYS_exit
1212 \\ mov x0, #01212 \\ mov x0, #0
1213 \\ svc 01213 \\ svc 0
1214 :1214 :
1215 : [ptr] "{x0}" (@intFromPtr(self.mapped.ptr)),1215 : [ptr] "{x0}" (@intFromPtr(self.mapped.ptr)),
1216 [len] "{x1}" (self.mapped.len),1216 [len] "{x1}" (self.mapped.len),
...@@ -1236,21 +1236,21 @@ const LinuxThreadImpl = struct {...@@ -1236,21 +1236,21 @@ const LinuxThreadImpl = struct {
1236 [len] "{r1}" (self.mapped.len),1236 [len] "{r1}" (self.mapped.len),
1237 ),1237 ),
1238 .hexagon => asm volatile (1238 .hexagon => asm volatile (
1239 \\ r6 = #215 // SYS_munmap1239 \\ r6 = #215 // SYS_munmap
1240 \\ trap0(#1)1240 \\ trap0(#1)
1241 \\ r6 = #93 // SYS_exit1241 \\ r6 = #93 // SYS_exit
1242 \\ r0 = #01242 \\ r0 = #0
1243 \\ trap0(#1)1243 \\ trap0(#1)
1244 :1244 :
1245 : [ptr] "{r0}" (@intFromPtr(self.mapped.ptr)),1245 : [ptr] "{r0}" (@intFromPtr(self.mapped.ptr)),
1246 [len] "{r1}" (self.mapped.len),1246 [len] "{r1}" (self.mapped.len),
1247 ),1247 ),
1248 .hppa => asm volatile (1248 .hppa => asm volatile (
1249 \\ ldi 91, %%r20 /* SYS_munmap */
1250 \\ ble 0x100(%%sr2, %%r0)1249 \\ ble 0x100(%%sr2, %%r0)
1251 \\ ldi 1, %%r20 /* SYS_exit */1250 \\ ldi 91, %%r20 /* SYS_munmap */
1252 \\ ldi 0, %%r261251 \\ ldi 0, %%r26
1253 \\ ble 0x100(%%sr2, %%r0)1252 \\ ble 0x100(%%sr2, %%r0)
1253 \\ ldi 1, %%r20 /* SYS_exit */
1254 :1254 :
1255 : [ptr] "{r26}" (@intFromPtr(self.mapped.ptr)),1255 : [ptr] "{r26}" (@intFromPtr(self.mapped.ptr)),
1256 [len] "{r25}" (self.mapped.len),1256 [len] "{r25}" (self.mapped.len),
lib/std/debug/cpu_context.zig+5
...@@ -1039,6 +1039,7 @@ const Mips = extern struct {...@@ -1039,6 +1039,7 @@ const Mips = extern struct {
1039 \\ sd $fp, 240($t0)1039 \\ sd $fp, 240($t0)
1040 \\ sd $ra, 248($t0)1040 \\ sd $ra, 248($t0)
1041 \\ bal 1f1041 \\ bal 1f
1042 \\ nop
1042 \\1:1043 \\1:
1043 \\ sd $ra, 256($t0)1044 \\ sd $ra, 256($t0)
1044 \\ .set pop1045 \\ .set pop
...@@ -1080,6 +1081,7 @@ const Mips = extern struct {...@@ -1080,6 +1081,7 @@ const Mips = extern struct {
1080 \\ sw $fp, 120($t4)1081 \\ sw $fp, 120($t4)
1081 \\ sw $ra, 124($t4)1082 \\ sw $ra, 124($t4)
1082 \\ bal 1f1083 \\ bal 1f
1084 \\ nop
1083 \\1:1085 \\1:
1084 \\ sw $ra, 128($t4)1086 \\ sw $ra, 128($t4)
1085 \\ .set pop1087 \\ .set pop
...@@ -1164,6 +1166,7 @@ const Or1k = extern struct {...@@ -1164,6 +1166,7 @@ const Or1k = extern struct {
1164 \\ l.sw 120(r15), r301166 \\ l.sw 120(r15), r30
1165 \\ l.sw 124(r15), r311167 \\ l.sw 124(r15), r31
1166 \\ l.jal 1f1168 \\ l.jal 1f
1169 \\ l.nop
1167 \\1:1170 \\1:
1168 \\ l.sw 128(r15), r91171 \\ l.sw 128(r15), r9
1169 :1172 :
...@@ -1558,6 +1561,7 @@ const Sparc = extern struct {...@@ -1558,6 +1561,7 @@ const Sparc = extern struct {
1558 \\ stx %i6, [%l0 + 240]1561 \\ stx %i6, [%l0 + 240]
1559 \\ stx %i7, [%l0 + 248]1562 \\ stx %i7, [%l0 + 248]
1560 \\ call 1f1563 \\ call 1f
1564 \\ nop
1561 \\1:1565 \\1:
1562 \\ stx %o7, [%l0 + 256]1566 \\ stx %o7, [%l0 + 256]
1563 else1567 else
...@@ -1578,6 +1582,7 @@ const Sparc = extern struct {...@@ -1578,6 +1582,7 @@ const Sparc = extern struct {
1578 \\ std %i4, [%l0 + 112]1582 \\ std %i4, [%l0 + 112]
1579 \\ std %i6, [%l0 + 120]1583 \\ std %i6, [%l0 + 120]
1580 \\ call 1f1584 \\ call 1f
1585 \\ nop
1581 \\1:1586 \\1:
1582 \\ st %o7, [%l0 + 128]1587 \\ st %o7, [%l0 + 128]
1583 :1588 :
lib/std/os/linux/or1k.zig+3
...@@ -138,7 +138,9 @@ pub fn clone() callconv(.naked) u32 {...@@ -138,7 +138,9 @@ pub fn clone() callconv(.naked) u32 {
138 \\ l.sys 1138 \\ l.sys 1
139 \\ l.sfeqi r11, 0139 \\ l.sfeqi r11, 0
140 \\ l.bf 1f140 \\ l.bf 1f
141 \\ l.nop
141 \\ l.jr r9142 \\ l.jr r9
143 \\ l.nop
142 \\1:144 \\1:
143 );145 );
144 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (146 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
...@@ -151,6 +153,7 @@ pub fn clone() callconv(.naked) u32 {...@@ -151,6 +153,7 @@ pub fn clone() callconv(.naked) u32 {
151 \\ l.lwz r11, 0(r1)153 \\ l.lwz r11, 0(r1)
152 \\ l.lwz r3, 4(r1)154 \\ l.lwz r3, 4(r1)
153 \\ l.jalr r11155 \\ l.jalr r11
156 \\ l.nop
154 \\157 \\
155 \\ l.ori r3, r11, 0158 \\ l.ori r3, r11, 0
156 \\ l.ori r11, r0, 93 # SYS_exit159 \\ l.ori r11, r0, 93 # SYS_exit
lib/std/os/linux/tls.zig+1
...@@ -295,6 +295,7 @@ pub fn setThreadPointer(addr: usize) void {...@@ -295,6 +295,7 @@ pub fn setThreadPointer(addr: usize) void {
295 .hppa => {295 .hppa => {
296 asm volatile (296 asm volatile (
297 \\ ble 0xe0(%%sr2, %%r0)297 \\ ble 0xe0(%%sr2, %%r0)
298 \\ nop
298 :299 :
299 : [addr] "={r26}" (addr),300 : [addr] "={r26}" (addr),
300 : .{ .r29 = true });301 : .{ .r29 = true });
lib/std/pie.zig+2
...@@ -190,6 +190,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {...@@ -190,6 +190,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
190 \\ .weak _DYNAMIC190 \\ .weak _DYNAMIC
191 \\ .hidden _DYNAMIC191 \\ .hidden _DYNAMIC
192 \\ l.jal 1f192 \\ l.jal 1f
193 \\ l.nop
193 \\ .word _DYNAMIC - .194 \\ .word _DYNAMIC - .
194 \\1:195 \\1:
195 \\ l.lwz %[ret], 0(r9)196 \\ l.lwz %[ret], 0(r9)
...@@ -245,6 +246,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {...@@ -245,6 +246,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
245 \\ mov.l 1f, %[ret]246 \\ mov.l 1f, %[ret]
246 \\ add r0, %[ret]247 \\ add r0, %[ret]
247 \\ bra 2f248 \\ bra 2f
249 \\ nop
248 \\1:250 \\1:
249 \\ .balign 4251 \\ .balign 4
250 \\ .long DYNAMIC - .252 \\ .long DYNAMIC - .
lib/std/start.zig+10-8
...@@ -295,7 +295,7 @@ fn _start() callconv(.naked) noreturn {...@@ -295,7 +295,7 @@ fn _start() callconv(.naked) noreturn {
295 \\ r29 = and(r29, #-8)295 \\ r29 = and(r29, #-8)
296 \\ memw(r29 + #-8) = r29296 \\ memw(r29 + #-8) = r29
297 \\ r29 = add(r29, #-8)297 \\ r29 = add(r29, #-8)
298 \\ call %[posixCallMainAndExit]298 \\ jump %[posixCallMainAndExit]
299 ,299 ,
300 .kvx =>300 .kvx =>
301 \\ make $fp = 0301 \\ make $fp = 0
...@@ -327,7 +327,8 @@ fn _start() callconv(.naked) noreturn {...@@ -327,7 +327,8 @@ fn _start() callconv(.naked) noreturn {
327 \\ l.ori r9, r0, 0327 \\ l.ori r9, r0, 0
328 \\ l.ori r3, r1, 0328 \\ l.ori r3, r1, 0
329 \\ l.andi r1, r1, -4329 \\ l.andi r1, r1, -4
330 \\ l.jal %[posixCallMainAndExit]330 \\ l.j %[posixCallMainAndExit]
331 \\ l.nop
331 ,332 ,
332 .riscv32, .riscv32be, .riscv64, .riscv64be =>333 .riscv32, .riscv32be, .riscv64, .riscv64be =>
333 \\ li fp, 0334 \\ li fp, 0
...@@ -356,7 +357,7 @@ fn _start() callconv(.naked) noreturn {...@@ -356,7 +357,7 @@ fn _start() callconv(.naked) noreturn {
356 \\ or %%r1, %%r0, %%r0357 \\ or %%r1, %%r0, %%r0
357 \\ or %%r2, %%r31, %%r0358 \\ or %%r2, %%r31, %%r0
358 \\ clr %%r31, %%r31, 4<0>359 \\ clr %%r31, %%r31, 4<0>
359 \\ br.n %[posixCallMainAndExit]360 \\ br %[posixCallMainAndExit]
360 ,361 ,
361 .microblaze, .microblazeel =>362 .microblaze, .microblazeel =>
362 // r1 = SP, r15 = LR, r19 = FP, r20 = GP363 // r1 = SP, r15 = LR, r19 = FP, r20 = GP
...@@ -366,7 +367,7 @@ fn _start() callconv(.naked) noreturn {...@@ -366,7 +367,7 @@ fn _start() callconv(.naked) noreturn {
366 \\ addi r20, r20, _GLOBAL_OFFSET_TABLE_ + 8367 \\ addi r20, r20, _GLOBAL_OFFSET_TABLE_ + 8
367 \\ ori r5, r1, 0368 \\ ori r5, r1, 0
368 \\ andi r1, r1, -4369 \\ andi r1, r1, -4
369 \\ brlid r15, %[posixCallMainAndExit]370 \\ bri %[posixCallMainAndExit]
370 ,371 ,
371 .mips, .mipsel =>372 .mips, .mipsel =>
372 \\ move $fp, $zero373 \\ move $fp, $zero
...@@ -385,7 +386,7 @@ fn _start() callconv(.naked) noreturn {...@@ -385,7 +386,7 @@ fn _start() callconv(.naked) noreturn {
385 \\ move $a0, $sp386 \\ move $a0, $sp
386 \\ and $sp, -8387 \\ and $sp, -8
387 \\ subu $sp, $sp, 16388 \\ subu $sp, $sp, 16
388 \\ jalr $t9389 \\ jr $t9
389 ,390 ,
390 .mips64, .mips64el => switch (builtin.abi) {391 .mips64, .mips64el => switch (builtin.abi) {
391 .gnuabin32, .muslabin32, .abin32 =>392 .gnuabin32, .muslabin32, .abin32 =>
...@@ -403,7 +404,7 @@ fn _start() callconv(.naked) noreturn {...@@ -403,7 +404,7 @@ fn _start() callconv(.naked) noreturn {
403 \\ move $a0, $sp404 \\ move $a0, $sp
404 \\ and $sp, -16405 \\ and $sp, -16
405 \\ subu $sp, $sp, 16406 \\ subu $sp, $sp, 16
406 \\ jalr $t9407 \\ jr $t9
407 ,408 ,
408 else =>409 else =>
409 \\ move $fp, $zero410 \\ move $fp, $zero
...@@ -424,7 +425,7 @@ fn _start() callconv(.naked) noreturn {...@@ -424,7 +425,7 @@ fn _start() callconv(.naked) noreturn {
424 \\ move $a0, $sp425 \\ move $a0, $sp
425 \\ and $sp, -16426 \\ and $sp, -16
426 \\ dsubu $sp, $sp, 16427 \\ dsubu $sp, $sp, 16
427 \\ jalr $t9428 \\ jr $t9
428 ,429 ,
429 },430 },
430 .powerpc, .powerpcle =>431 .powerpc, .powerpcle =>
...@@ -476,7 +477,8 @@ fn _start() callconv(.naked) noreturn {...@@ -476,7 +477,8 @@ fn _start() callconv(.naked) noreturn {
476 \\ and r0, r15477 \\ and r0, r15
477 \\ mov.l 2f, r1478 \\ mov.l 2f, r1
478 \\1:479 \\1:
479 \\ bsrf r1480 \\ braf r1
481 \\ nop
480 \\2:482 \\2:
481 \\ .balign 4483 \\ .balign 4
482 \\ .long %[posixCallMainAndExit]@PCREL - (1b + 4 - .)484 \\ .long %[posixCallMainAndExit]@PCREL - (1b + 4 - .)