authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-10 22:18:25+02:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-08-10 22:18:25+02:00
log6217b02f2540e32acedee8d0f2f3830ea8ae0d28
treec96b867a46dc16a336d77c62cf9aad1fa7030c9a
parentf6e32d1b3a5de1626c3fdf5527b565dae1c501a0
parent8217f26ef8ddab9eb02a9d380d6509c39ac2d0f3

Merge pull request 'std: inline assembly cleanup and fixes' (#36459) from alexrp/zig:asm-cleanup into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/36459

28 files changed, 657 insertions(+), 737 deletions(-)

lib/libc/musl/src/thread/powerpc/clone.s+5-4
......@@ -16,8 +16,9 @@ __clone:
1616
1717# store non-volatile regs r30, r31 on stack in order to put our
1818# start func and its arg there
19stwu 30, -16(1)
20stw 31, 4(1)
19stwu 1, -16(1)
20stw 30, 8(1)
21stw 31, 12(1)
2122
2223# save r3 (func) into r30, and r6(arg) into r31
2324mr 30, 3
......@@ -51,8 +52,8 @@ cmpwi cr7, 3, 0
5152# if not 0, restore stack and return
5253beq cr7, 2f
5354
54lwz 30, 0(1)
55lwz 31, 4(1)
55lwz 30, 8(1)
56lwz 31, 12(1)
5657addi 1, 1, 16
5758
5859blr
lib/std/Thread.zig+51-57
......@@ -1166,29 +1166,29 @@ const LinuxThreadImpl = struct {
11661166 posix.sigprocmask(std.posix.SIG.BLOCK, &std.os.linux.sigfillset(), null);
11671167 switch (target.cpu.arch) {
11681168 .x86 => asm volatile (
1169 \\ movl $91, %%eax # SYS_munmap
1170 \\ int $128
1171 \\ movl $1, %%eax # SYS_exit
1172 \\ movl $0, %%ebx
1173 \\ int $128
1169 \\ movl $91, %%eax # SYS_munmap
1170 \\ int $128
1171 \\ movl $1, %%eax # SYS_exit
1172 \\ movl $0, %%ebx
1173 \\ int $128
11741174 :
11751175 : [ptr] "{ebx}" (@intFromPtr(self.mapped.ptr)),
11761176 [len] "{ecx}" (self.mapped.len),
11771177 ),
11781178 .x86_64 => asm volatile (switch (target.abi) {
11791179 .gnux32, .muslx32, .x32 =>
1180 \\ movl $0x4000000b, %%eax # SYS_munmap
1181 \\ syscall
1182 \\ movl $0x4000003c, %%eax # SYS_exit
1183 \\ xor %%rdi, %%rdi
1184 \\ syscall
1180 \\ movl $0x4000000b, %%eax # SYS_munmap
1181 \\ syscall
1182 \\ movl $0x4000003c, %%eax # SYS_exit
1183 \\ xor %%rdi, %%rdi
1184 \\ syscall
11851185 ,
11861186 else =>
1187 \\ movl $11, %%eax # SYS_munmap
1188 \\ syscall
1189 \\ movl $60, %%eax # SYS_exit
1190 \\ xor %%rdi, %%rdi
1191 \\ syscall
1187 \\ movl $11, %%eax # SYS_munmap
1188 \\ syscall
1189 \\ movl $60, %%eax # SYS_exit
1190 \\ xor %%rdi, %%rdi
1191 \\ syscall
11921192 ,
11931193 }
11941194 :
......@@ -1196,21 +1196,21 @@ const LinuxThreadImpl = struct {
11961196 [len] "{rsi}" (self.mapped.len),
11971197 ),
11981198 .arm, .armeb, .thumb, .thumbeb => asm volatile (
1199 \\ mov r7, #91 // SYS_munmap
1200 \\ svc 0
1201 \\ mov r7, #1 // SYS_exit
1202 \\ mov r0, #0
1203 \\ svc 0
1199 \\ mov r7, #91 // SYS_munmap
1200 \\ svc 0
1201 \\ mov r7, #1 // SYS_exit
1202 \\ mov r0, #0
1203 \\ svc 0
12041204 :
12051205 : [ptr] "{r0}" (@intFromPtr(self.mapped.ptr)),
12061206 [len] "{r1}" (self.mapped.len),
12071207 ),
12081208 .aarch64, .aarch64_be => asm volatile (
1209 \\ mov x8, #215 // SYS_munmap
1210 \\ svc 0
1211 \\ mov x8, #93 // SYS_exit
1212 \\ mov x0, #0
1213 \\ svc 0
1209 \\ mov x8, #215 // SYS_munmap
1210 \\ svc 0
1211 \\ mov x8, #93 // SYS_exit
1212 \\ mov x0, #0
1213 \\ svc 0
12141214 :
12151215 : [ptr] "{x0}" (@intFromPtr(self.mapped.ptr)),
12161216 [len] "{x1}" (self.mapped.len),
......@@ -1236,21 +1236,21 @@ const LinuxThreadImpl = struct {
12361236 [len] "{r1}" (self.mapped.len),
12371237 ),
12381238 .hexagon => asm volatile (
1239 \\ r6 = #215 // SYS_munmap
1240 \\ trap0(#1)
1241 \\ r6 = #93 // SYS_exit
1242 \\ r0 = #0
1243 \\ trap0(#1)
1239 \\ r6 = #215 // SYS_munmap
1240 \\ trap0(#1)
1241 \\ r6 = #93 // SYS_exit
1242 \\ r0 = #0
1243 \\ trap0(#1)
12441244 :
12451245 : [ptr] "{r0}" (@intFromPtr(self.mapped.ptr)),
12461246 [len] "{r1}" (self.mapped.len),
12471247 ),
12481248 .hppa => asm volatile (
1249 \\ ldi 91, %%r20 /* SYS_munmap */
12501249 \\ ble 0x100(%%sr2, %%r0)
1251 \\ ldi 1, %%r20 /* SYS_exit */
1250 \\ ldi 91, %%r20 /* SYS_munmap */
12521251 \\ ldi 0, %%r26
12531252 \\ ble 0x100(%%sr2, %%r0)
1253 \\ ldi 1, %%r20 /* SYS_exit */
12541254 :
12551255 : [ptr] "{r26}" (@intFromPtr(self.mapped.ptr)),
12561256 [len] "{r25}" (self.mapped.len),
......@@ -1275,12 +1275,7 @@ const LinuxThreadImpl = struct {
12751275 : [ptr] "{r5}" (@intFromPtr(self.mapped.ptr)),
12761276 [len] "{r6}" (self.mapped.len),
12771277 ),
1278 // We set `sp` to the address of the current function as a workaround for a Linux
1279 // kernel bug that caused syscalls to return EFAULT if the stack pointer is invalid.
1280 // The bug was introduced in 46e12c07b3b9603c60fc1d421ff18618241cb081 and fixed in
1281 // 7928eb0370d1133d0d8cd2f5ddfca19c309079d5.
12821278 .mips, .mipsel => asm volatile (
1283 \\ move $sp, $t9
12841279 \\ li $v0, 4091 # SYS_munmap
12851280 \\ syscall
12861281 \\ li $v0, 4001 # SYS_exit
......@@ -1314,37 +1309,36 @@ const LinuxThreadImpl = struct {
13141309 \\ l.ori r11, r0, 215 # SYS_munmap
13151310 \\ l.sys 1
13161311 \\ l.ori r11, r0, 93 # SYS_exit
1317 \\ l.ori r3, r0, r0
1312 \\ l.ori r3, r0, 0
13181313 \\ l.sys 1
13191314 :
13201315 : [ptr] "{r3}" (@intFromPtr(self.mapped.ptr)),
13211316 [len] "{r4}" (self.mapped.len),
13221317 ),
13231318 .powerpc, .powerpcle, .powerpc64, .powerpc64le => asm volatile (
1324 \\ li 0, 91 # SYS_munmap
1325 \\ sc
1326 \\ li 0, 1 # SYS_exit
1327 \\ li 3, 0
1328 \\ sc
1329 \\ blr
1319 \\ li 0, 91 # SYS_munmap
1320 \\ sc
1321 \\ li 0, 1 # SYS_exit
1322 \\ li 3, 0
1323 \\ sc
13301324 :
13311325 : [ptr] "{r3}" (@intFromPtr(self.mapped.ptr)),
13321326 [len] "{r4}" (self.mapped.len),
13331327 ),
13341328 .riscv32, .riscv64 => asm volatile (
1335 \\ li a7, 215 # SYS_munmap
1336 \\ ecall
1337 \\ li a7, 93 # SYS_exit
1338 \\ mv a0, zero
1339 \\ ecall
1329 \\ li a7, 215 # SYS_munmap
1330 \\ ecall
1331 \\ li a7, 93 # SYS_exit
1332 \\ mv a0, zero
1333 \\ ecall
13401334 :
13411335 : [ptr] "{a0}" (@intFromPtr(self.mapped.ptr)),
13421336 [len] "{a1}" (self.mapped.len),
13431337 ),
13441338 .s390x => asm volatile (
1345 \\ svc 91 # SYS_munmap
1346 \\ lghi %%r2, 0
1347 \\ svc 1 # SYS_exit
1339 \\ svc 91 # SYS_munmap
1340 \\ lghi %%r2, 0
1341 \\ svc 1 # SYS_exit
13481342 :
13491343 : [ptr] "{r2}" (@intFromPtr(self.mapped.ptr)),
13501344 [len] "{r3}" (self.mapped.len),
......@@ -1384,7 +1378,7 @@ const LinuxThreadImpl = struct {
13841378 : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)),
13851379 [len] "{g2}" (self.mapped.len),
13861380 [stack] "{g3}" (&sparc_exit_stack),
1387 : .{ .memory = true }),
1381 ),
13881382 .sparc64 => asm volatile (
13891383 \\ // Ensure that the kernel only has to flush the current register window.
13901384 \\ flushw
......@@ -1403,7 +1397,7 @@ const LinuxThreadImpl = struct {
14031397 : [ptr] "{g1}" (@intFromPtr(self.mapped.ptr)),
14041398 [len] "{g2}" (self.mapped.len),
14051399 [stack] "{g3}" (&sparc_exit_stack),
1406 : .{ .memory = true }),
1400 ),
14071401 .loongarch32, .loongarch64 => asm volatile (
14081402 \\ ori $a7, $zero, 215 # SYS_munmap
14091403 \\ syscall 0 # call munmap
......@@ -1413,7 +1407,7 @@ const LinuxThreadImpl = struct {
14131407 :
14141408 : [ptr] "{r4}" (@intFromPtr(self.mapped.ptr)),
14151409 [len] "{r5}" (self.mapped.len),
1416 : .{ .memory = true }),
1410 ),
14171411 .csky => asm volatile (
14181412 \\ movi r7, 215 # SYS_munmap
14191413 \\ trap 0
......@@ -1423,7 +1417,7 @@ const LinuxThreadImpl = struct {
14231417 :
14241418 : [ptr] "{r0}" (@intFromPtr(self.mapped.ptr)),
14251419 [len] "{r1}" (self.mapped.len),
1426 : .{ .memory = true }),
1420 ),
14271421 .xtensa, .xtensaeb => asm volatile (
14281422 \\ movi a2, 81 // SYS_munmap
14291423 \\ syscall
......@@ -1433,7 +1427,7 @@ const LinuxThreadImpl = struct {
14331427 :
14341428 : [ptr] "{a6}" (@intFromPtr(self.mapped.ptr)),
14351429 [len] "{a3}" (self.mapped.len),
1436 : .{ .memory = true }),
1430 ),
14371431 else => |cpu_arch| @compileError("Unsupported linux arch: " ++ @tagName(cpu_arch)),
14381432 }
14391433 unreachable;
lib/std/atomic.zig+19-2
......@@ -377,13 +377,16 @@ pub inline fn spinLoopHint() void {
377377 .aarch64_be,
378378 => asm volatile ("isb"),
379379
380 // `yield` was introduced in v6k but is also available on v6m.
381380 // https://www.keil.com/support/man/docs/armasm/armasm_dom1361289926796.htm
382381 .arm,
383382 .armeb,
383 => if (comptime builtin.cpu.has(.arm, .has_v6k)) {
384 asm volatile ("yield");
385 },
386
384387 .thumb,
385388 .thumbeb,
386 => if (comptime builtin.cpu.hasAny(.arm, &.{ .has_v6k, .has_v6m })) {
389 => if (comptime builtin.cpu.hasAny(.arm, &.{ .has_v6m, .thumb2 })) {
387390 asm volatile ("yield");
388391 },
389392
......@@ -392,6 +395,14 @@ pub inline fn spinLoopHint() void {
392395 .hexagon,
393396 => asm volatile ("pause(#1)"),
394397
398 .mips,
399 .mipsel,
400 .mips64,
401 .mips64el,
402 => if (comptime builtin.cpu.has(.mips, .mips32r2)) {
403 asm volatile ("pause");
404 },
405
395406 .riscv32,
396407 .riscv32be,
397408 .riscv64,
......@@ -400,6 +411,12 @@ pub inline fn spinLoopHint() void {
400411 asm volatile ("pause");
401412 },
402413
414 .sparc,
415 .sparc64,
416 => if (comptime builtin.cpu.hasAny(.sparc, &.{ .v8plus, .v9 })) {
417 asm volatile ("rd %%ccr, %%g0");
418 },
419
403420 else => {},
404421 }
405422}
lib/std/debug/Dwarf.zig+1-1
......@@ -1462,7 +1462,7 @@ pub fn ipRegNum(arch: std.Target.Cpu.Arch) ?u16 {
14621462 .powerpc, .powerpcle, .powerpc64, .powerpc64le => 67,
14631463 .riscv32, .riscv32be, .riscv64, .riscv64be => 65,
14641464 .s390x => 65,
1465 .sparc, .sparc64 => 32,
1465 .sparc, .sparc64 => 65,
14661466 .ve => 144,
14671467 .x86 => 8,
14681468 .x86_64 => 16,
lib/std/debug/cpu_context.zig+102-92
......@@ -349,6 +349,7 @@ const Alpha = extern struct {
349349 \\ stq $28, 0x0e0($0)
350350 \\ stq $29, 0x0e8($0)
351351 \\ stq $30, 0x0f0($0)
352 \\ stq $31, 0x0f8($0)
352353 \\
353354 \\ br $1, 1f
354355 \\1:
......@@ -463,10 +464,11 @@ const Arm = struct {
463464 \\ stm r0, {r0-r12}
464465 \\ str r13, [r0, #0x34]
465466 \\ str r14, [r0, #0x38]
466 \\ str r15, [r0, #0x3c]
467 \\ mov r1, pc
468 \\ str r1, [r0, #0x3c]
467469 :
468470 : [r] "{r0}" (&ctx.r),
469 : .{ .memory = true });
471 : .{ .r1 = true, .memory = true });
470472 return ctx;
471473 }
472474
......@@ -636,8 +638,8 @@ const Hexagon = extern struct {
636638/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
637639const Kvx = extern struct {
638640 r: [64]Gpr,
639 ra: Gpr,
640641 pc: Gpr,
642 ra: Gpr,
641643
642644 pub const Gpr = u64;
643645
......@@ -716,38 +718,38 @@ const Lanai = extern struct {
716718 pub inline fn current() Lanai {
717719 var ctx: Lanai = undefined;
718720 asm volatile (
719 \\ st %%r0, 0[r9]
720 \\ st %%r1, 4[r9]
721 \\ st %%r2, 8[r9]
722 \\ st %%r3, 12[r9]
723 \\ st %%r4, 16[r9]
724 \\ st %%r5, 20[r9]
725 \\ st %%r6, 24[r9]
726 \\ st %%r7, 28[r9]
727 \\ st %%r8, 32[r9]
728 \\ st %%r9, 36[r9]
729 \\ st %%r10, 40[r9]
730 \\ st %%r11, 44[r9]
731 \\ st %%r12, 48[r9]
732 \\ st %%r13, 52[r9]
733 \\ st %%r14, 56[r9]
734 \\ st %%r15, 60[r9]
735 \\ st %%r16, 64[r9]
736 \\ st %%r17, 68[r9]
737 \\ st %%r18, 72[r9]
738 \\ st %%r19, 76[r9]
739 \\ st %%r20, 80[r9]
740 \\ st %%r21, 84[r9]
741 \\ st %%r22, 88[r9]
742 \\ st %%r23, 92[r9]
743 \\ st %%r24, 96[r9]
744 \\ st %%r25, 100[r9]
745 \\ st %%r26, 104[r9]
746 \\ st %%r27, 108[r9]
747 \\ st %%r28, 112[r9]
748 \\ st %%r29, 116[r9]
749 \\ st %%r30, 120[r9]
750 \\ st %%r31, 124[r9]
721 \\ st %%r0, 0[%%r9]
722 \\ st %%r1, 4[%%r9]
723 \\ st %%r2, 8[%%r9]
724 \\ st %%r3, 12[%%r9]
725 \\ st %%r4, 16[%%r9]
726 \\ st %%r5, 20[%%r9]
727 \\ st %%r6, 24[%%r9]
728 \\ st %%r7, 28[%%r9]
729 \\ st %%r8, 32[%%r9]
730 \\ st %%r9, 36[%%r9]
731 \\ st %%r10, 40[%%r9]
732 \\ st %%r11, 44[%%r9]
733 \\ st %%r12, 48[%%r9]
734 \\ st %%r13, 52[%%r9]
735 \\ st %%r14, 56[%%r9]
736 \\ st %%r15, 60[%%r9]
737 \\ st %%r16, 64[%%r9]
738 \\ st %%r17, 68[%%r9]
739 \\ st %%r18, 72[%%r9]
740 \\ st %%r19, 76[%%r9]
741 \\ st %%r20, 80[%%r9]
742 \\ st %%r21, 84[%%r9]
743 \\ st %%r22, 88[%%r9]
744 \\ st %%r23, 92[%%r9]
745 \\ st %%r24, 96[%%r9]
746 \\ st %%r25, 100[%%r9]
747 \\ st %%r26, 104[%%r9]
748 \\ st %%r27, 108[%%r9]
749 \\ st %%r28, 112[%%r9]
750 \\ st %%r29, 116[%%r9]
751 \\ st %%r30, 120[%%r9]
752 \\ st %%r31, 124[%%r9]
751753 :
752754 : [ctx] "{r9}" (&ctx),
753755 : .{ .memory = true });
......@@ -763,7 +765,7 @@ const Lanai = extern struct {
763765
764766 pub fn dwarfRegisterBytes(ctx: *Lanai, register_num: u16) DwarfRegisterError![]u8 {
765767 switch (register_num) {
766 0...31 => return @ptrCast(&ctx.s[register_num]),
768 0...31 => return @ptrCast(&ctx.r[register_num]),
767769
768770 else => return error.InvalidRegister,
769771 }
......@@ -1039,6 +1041,7 @@ const Mips = extern struct {
10391041 \\ sd $fp, 240($t0)
10401042 \\ sd $ra, 248($t0)
10411043 \\ bal 1f
1044 \\ nop
10421045 \\1:
10431046 \\ sd $ra, 256($t0)
10441047 \\ .set pop
......@@ -1080,6 +1083,7 @@ const Mips = extern struct {
10801083 \\ sw $fp, 120($t4)
10811084 \\ sw $ra, 124($t4)
10821085 \\ bal 1f
1086 \\ nop
10831087 \\1:
10841088 \\ sw $ra, 128($t4)
10851089 \\ .set pop
......@@ -1164,6 +1168,7 @@ const Or1k = extern struct {
11641168 \\ l.sw 120(r15), r30
11651169 \\ l.sw 124(r15), r31
11661170 \\ l.jal 1f
1171 \\ l.nop
11671172 \\1:
11681173 \\ l.sw 128(r15), r9
11691174 :
......@@ -1512,7 +1517,7 @@ const S390x = extern struct {
15121517
15131518/// This is an `extern struct` so that inline assembly in `current` can use field offsets.
15141519const Sparc = extern struct {
1515 g: [8]Gpr,
1520 g: [8]Gpr align(8), // Align to make `std` safe on 32-bit.
15161521 o: [8]Gpr,
15171522 l: [8]Gpr,
15181523 i: [8]Gpr,
......@@ -1525,61 +1530,63 @@ const Sparc = extern struct {
15251530
15261531 var ctx: Sparc = undefined;
15271532 asm volatile (if (Gpr == u64)
1528 \\ stx %g0, [%l0 + 0]
1529 \\ stx %g1, [%l0 + 8]
1530 \\ stx %g2, [%l0 + 16]
1531 \\ stx %g3, [%l0 + 24]
1532 \\ stx %g4, [%l0 + 32]
1533 \\ stx %g5, [%l0 + 40]
1534 \\ stx %g6, [%l0 + 48]
1535 \\ stx %g7, [%l0 + 56]
1536 \\ stx %o0, [%l0 + 64]
1537 \\ stx %o1, [%l0 + 72]
1538 \\ stx %o2, [%l0 + 80]
1539 \\ stx %o3, [%l0 + 88]
1540 \\ stx %o4, [%l0 + 96]
1541 \\ stx %o5, [%l0 + 104]
1542 \\ stx %o6, [%l0 + 112]
1543 \\ stx %o7, [%l0 + 120]
1544 \\ stx %l0, [%l0 + 128]
1545 \\ stx %l1, [%l0 + 136]
1546 \\ stx %l2, [%l0 + 144]
1547 \\ stx %l3, [%l0 + 152]
1548 \\ stx %l4, [%l0 + 160]
1549 \\ stx %l5, [%l0 + 168]
1550 \\ stx %l6, [%l0 + 176]
1551 \\ stx %l7, [%l0 + 184]
1552 \\ stx %i0, [%l0 + 192]
1553 \\ stx %i1, [%l0 + 200]
1554 \\ stx %i2, [%l0 + 208]
1555 \\ stx %i3, [%l0 + 216]
1556 \\ stx %i4, [%l0 + 224]
1557 \\ stx %i5, [%l0 + 232]
1558 \\ stx %i6, [%l0 + 240]
1559 \\ stx %i7, [%l0 + 248]
1533 \\ stx %%g0, [%%l0 + 0]
1534 \\ stx %%g1, [%%l0 + 8]
1535 \\ stx %%g2, [%%l0 + 16]
1536 \\ stx %%g3, [%%l0 + 24]
1537 \\ stx %%g4, [%%l0 + 32]
1538 \\ stx %%g5, [%%l0 + 40]
1539 \\ stx %%g6, [%%l0 + 48]
1540 \\ stx %%g7, [%%l0 + 56]
1541 \\ stx %%o0, [%%l0 + 64]
1542 \\ stx %%o1, [%%l0 + 72]
1543 \\ stx %%o2, [%%l0 + 80]
1544 \\ stx %%o3, [%%l0 + 88]
1545 \\ stx %%o4, [%%l0 + 96]
1546 \\ stx %%o5, [%%l0 + 104]
1547 \\ stx %%o6, [%%l0 + 112]
1548 \\ stx %%o7, [%%l0 + 120]
1549 \\ stx %%l0, [%%l0 + 128]
1550 \\ stx %%l1, [%%l0 + 136]
1551 \\ stx %%l2, [%%l0 + 144]
1552 \\ stx %%l3, [%%l0 + 152]
1553 \\ stx %%l4, [%%l0 + 160]
1554 \\ stx %%l5, [%%l0 + 168]
1555 \\ stx %%l6, [%%l0 + 176]
1556 \\ stx %%l7, [%%l0 + 184]
1557 \\ stx %%i0, [%%l0 + 192]
1558 \\ stx %%i1, [%%l0 + 200]
1559 \\ stx %%i2, [%%l0 + 208]
1560 \\ stx %%i3, [%%l0 + 216]
1561 \\ stx %%i4, [%%l0 + 224]
1562 \\ stx %%i5, [%%l0 + 232]
1563 \\ stx %%i6, [%%l0 + 240]
1564 \\ stx %%i7, [%%l0 + 248]
15601565 \\ call 1f
1566 \\ nop
15611567 \\1:
1562 \\ stx %o7, [%l0 + 256]
1568 \\ stx %%o7, [%%l0 + 256]
15631569 else
1564 \\ std %g0, [%l0 + 0]
1565 \\ std %g2, [%l0 + 8]
1566 \\ std %g4, [%l0 + 16]
1567 \\ std %g6, [%l0 + 24]
1568 \\ std %o0, [%l0 + 32]
1569 \\ std %o2, [%l0 + 40]
1570 \\ std %o4, [%l0 + 48]
1571 \\ std %o6, [%l0 + 56]
1572 \\ std %l0, [%l0 + 64]
1573 \\ std %l2, [%l0 + 72]
1574 \\ std %l4, [%l0 + 80]
1575 \\ std %l6, [%l0 + 88]
1576 \\ std %i0, [%l0 + 96]
1577 \\ std %i2, [%l0 + 104]
1578 \\ std %i4, [%l0 + 112]
1579 \\ std %i6, [%l0 + 120]
1570 \\ std %%g0, [%%l0 + 0]
1571 \\ std %%g2, [%%l0 + 8]
1572 \\ std %%g4, [%%l0 + 16]
1573 \\ std %%g6, [%%l0 + 24]
1574 \\ std %%o0, [%%l0 + 32]
1575 \\ std %%o2, [%%l0 + 40]
1576 \\ std %%o4, [%%l0 + 48]
1577 \\ std %%o6, [%%l0 + 56]
1578 \\ std %%l0, [%%l0 + 64]
1579 \\ std %%l2, [%%l0 + 72]
1580 \\ std %%l4, [%%l0 + 80]
1581 \\ std %%l6, [%%l0 + 88]
1582 \\ std %%i0, [%%l0 + 96]
1583 \\ std %%i2, [%%l0 + 104]
1584 \\ std %%i4, [%%l0 + 112]
1585 \\ std %%i6, [%%l0 + 120]
15801586 \\ call 1f
1587 \\ nop
15811588 \\1:
1582 \\ st %o7, [%l0 + 128]
1589 \\ st %%o7, [%%l0 + 128]
15831590 :
15841591 : [ctx] "{l0}" (&ctx),
15851592 : .{ .o7 = true, .memory = true });
......@@ -1608,7 +1615,11 @@ const Sparc = extern struct {
16081615 8...15 => return @ptrCast(&ctx.o[register_num - 8]),
16091616 16...23 => return @ptrCast(&ctx.l[register_num - 16]),
16101617 24...31 => return @ptrCast(&ctx.i[register_num - 24]),
1611 32 => return @ptrCast(&ctx.pc),
1618 65 => return @ptrCast(&ctx.pc),
1619
1620 32...63 => return error.UnsupportedRegister, // F0-F31
1621 64 => return error.UnsupportedRegister, // Y
1622 72...87 => return error.UnsupportedRegister, // D0-D15
16121623
16131624 else => return error.InvalidRegister,
16141625 }
......@@ -1689,9 +1700,8 @@ const Ve = extern struct {
16891700 \\ st %%s61, 488(, %%s8)
16901701 \\ st %%s62, 496(, %%s8)
16911702 \\ st %%s63, 504(, %%s8)
1692 \\ br.l 1f
1693 \\1:
1694 \\ st %%lr, 512(, %%s8)
1703 \\ sic %%s10
1704 \\ st %%s10, 512(, %%s8)
16951705 :
16961706 : [ctx] "{s8}" (&ctx),
16971707 : .{ .s10 = true, .memory = true });
......@@ -1758,7 +1768,7 @@ const X86_16 = struct {
17581768 switch (register_num) {
17591769 4 => return @ptrCast(ctx.regs.getPtr(.sp)),
17601770 5 => return @ptrCast(ctx.regs.getPtr(.bp)),
1761 6 => return @ptrCast(ctx.regs.getPtr(.ip)),
1771 8 => return @ptrCast(ctx.regs.getPtr(.ip)),
17621772 41 => return @ptrCast(ctx.regs.getPtr(.cs)),
17631773 42 => return @ptrCast(ctx.regs.getPtr(.ss)),
17641774 else => return error.InvalidRegister,
lib/std/os/linux/aarch64.zig+27-34
......@@ -116,55 +116,48 @@ pub fn clone() callconv(.naked) u64 {
116116 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117117 // x8, x0, x1, x2, x3, x4
118118 asm volatile (
119 \\ // align stack and save func,arg
120 \\ and x1,x1,#-16
121 \\ stp x0,x3,[x1,#-16]!
119 \\ // align stack and save func,arg
120 \\ and x1,x1,#-16
121 \\ stp x0,x3,[x1,#-16]!
122122 \\
123 \\ // syscall
124 \\ uxtw x0,w2
125 \\ mov x2,x4
126 \\ mov x3,x5
127 \\ mov x4,x6
128 \\ mov x8,#220 // SYS_clone
129 \\ svc #0
123 \\ // syscall
124 \\ uxtw x0,w2
125 \\ mov x2,x4
126 \\ mov x3,x5
127 \\ mov x4,x6
128 \\ mov x8,#220 // SYS_clone
129 \\ svc #0
130130 \\
131 \\ cbz x0,1f
132 \\ // parent
133 \\ ret
131 \\ cbz x0,1f
132 \\ // parent
133 \\ ret
134134 \\
135 \\ // child
135 \\ // child
136136 \\1:
137137 );
138138 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
139 \\ .cfi_undefined lr
139 \\ .cfi_undefined lr
140140 );
141141 asm volatile (
142 \\ mov fp, 0
143 \\ mov lr, 0
142 \\ mov fp, 0
143 \\ mov lr, 0
144144 \\
145 \\ ldp x1,x0,[sp],#16
146 \\ blr x1
147 \\ mov x8,#93 // SYS_exit
148 \\ svc #0
145 \\ ldp x1,x0,[sp],#16
146 \\ blr x1
147 \\ mov x8,#93 // SYS_exit
148 \\ svc #0
149149 );
150150}
151151
152152pub const restore = restore_rt;
153153
154154pub fn restore_rt() callconv(.naked) noreturn {
155 switch (builtin.zig_backend) {
156 .stage2_c => asm volatile (
157 \\ mov w8, %[number]
158 \\ svc #0
159 :
160 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
161 ),
162 else => asm volatile (
163 \\ svc #0
164 :
165 : [number] "{x8}" (@backingInt(SYS.rt_sigreturn)),
166 ),
167 }
155 asm volatile (
156 \\ mov w8, %[number]
157 \\ svc #0
158 :
159 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
160 );
168161}
169162
170163pub const VDSO = struct {
lib/std/os/linux/alpha.zig+8-8
......@@ -295,8 +295,8 @@ pub fn clone() callconv(.naked) u64 {
295295 // a0 = $16, a1 = $17, a2 = $18, a3 = $19,
296296 // a4 = $20, a5 = $21, sp = $30, v0 = $0
297297 \\ # Save function pointer and argument pointer on new thread stack
298 \\ ldi $1, -8
299 \\ and $17, $17, $1
298 \\ ldi $1, -16
299 \\ and $17, $1, $17
300300 \\ lda $17, -16($17)
301301 \\ stq $16, 0($17)
302302 \\ stq $19, 8($17)
......@@ -323,16 +323,16 @@ pub fn clone() callconv(.naked) u64 {
323323 \\ .cfi_undefined $26
324324 );
325325 asm volatile (
326 // v0 = $0, t9 = $23, a0 = $16, ra = $26, sp = $30, fp = $15
326 // v0 = $0, a0 = $16, ra = $26, sp = $30, fp = $15, pv = $27
327327 \\ mov 0, $15
328328 \\
329 \\ ldq $23, 0($30)
329 \\ ldq $27, 0($30)
330330 \\ ldq $16, 8($30)
331331 \\ lda $30, 16($30)
332 \\ jsr $26, ($23)
332 \\ jsr $26, ($27)
333333 \\
334334 \\ mov $0, $16
335 \\ ldi $0, 1 # SYS_EXIT
335 \\ ldi $0, 1 # SYS_exit
336336 \\ callsys
337337 );
338338}
......@@ -341,7 +341,7 @@ pub fn restore() noreturn {
341341 asm volatile (
342342 // v0 = $0, a0 = $16, sp = $30
343343 \\ mov $30, $16
344 \\ ldi $0, 103 # SIGRETURN
344 \\ ldi $0, 103 # SYS_sigreturn
345345 \\ callsys
346346 );
347347}
......@@ -350,7 +350,7 @@ pub fn restore_rt() noreturn {
350350 asm volatile (
351351 // v0 = $0, a0 = $16, sp = $30
352352 \\ mov $30, $16
353 \\ ldi $0, 351 # RT_SIGRETURN
353 \\ ldi $0, 351 # SYS_rt_sigreturn
354354 \\ callsys
355355 );
356356}
lib/std/os/linux/arc.zig+29-36
......@@ -116,56 +116,49 @@ pub fn clone() callconv(.naked) u32 {
116116 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117117 // r8 r0, r1, r2, r3, r4
118118 asm volatile (
119 \\ // Align stack pointer
120 \\ and r1, r1, -16
121 \\ mov r10, r0
122 \\ mov r11, r3
123 \\ // Setup the arguments
124 \\ mov r0, r2
125 \\ mov r2, r4
126 \\ mov r3, r5
127 \\ mov r4, r6
128 \\ mov r8, 220 // SYS_clone
129 \\ trap_s 0
130 \\ cmp r0, 0
131 \\ beq 1f
132 \\ j [blink]
133 \\ // Child
134 \\ 1:
119 \\ // Align stack pointer
120 \\ and r1, r1, -16
121 \\ mov r10, r0
122 \\ mov r11, r3
123 \\ // Setup the arguments
124 \\ mov r0, r2
125 \\ mov r2, r4
126 \\ mov r3, r5
127 \\ mov r4, r6
128 \\ mov r8, 220 // SYS_clone
129 \\ trap_s 0
130 \\ cmp r0, 0
131 \\ beq 1f
132 \\ j [blink]
133 \\ // Child
134 \\1:
135135 );
136136 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
137137 \\ .cfi_undefined blink
138138 );
139139
140140 asm volatile (
141 \\ mov fp, 0
142 \\ mov blink, 0
141 \\ mov fp, 0
142 \\ mov blink, 0
143143 \\
144 \\ mov r0, r11
145 \\ jl [r10]
144 \\ mov r0, r11
145 \\ jl [r10]
146146 \\
147 \\ // Exit
148 \\ mov r8, 93 // SYS_exit
149 \\ trap_s 0
147 \\ // Exit
148 \\ mov r8, 93 // SYS_exit
149 \\ trap_s 0
150150 );
151151}
152152
153153pub const restore = restore_rt;
154154
155155pub fn restore_rt() callconv(.naked) noreturn {
156 switch (builtin.zig_backend) {
157 .stage2_c => asm volatile (
158 \\ mov r8, %[number]
159 \\ trap_s 0
160 :
161 : [number] "I" (@backingInt(SYS.rt_sigreturn)),
162 ),
163 else => asm volatile (
164 \\ trap_s 0
165 :
166 : [number] "{r8}" (@backingInt(SYS.rt_sigreturn)),
167 ),
168 }
156 asm volatile (
157 \\ mov r8, %[number]
158 \\ trap_s 0
159 :
160 : [number] "I" (@backingInt(SYS.rt_sigreturn)),
161 );
169162}
170163
171164pub const time_t = i64;
lib/std/os/linux/arm.zig+37-49
......@@ -116,65 +116,53 @@ pub fn clone() callconv(.naked) u32 {
116116 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117117 // r7 r0, r1, r2, r3, r4
118118 asm volatile (
119 \\ stmfd sp!,{r4,r5,r6,r7}
120 \\ mov r7,#120 // SYS_clone
121 \\ mov r6,r3
122 \\ mov r5,r0
123 \\ mov r0,r2
124 \\ and r1,r1,#-16
125 \\ ldr r2,[sp,#16]
126 \\ ldr r3,[sp,#20]
127 \\ ldr r4,[sp,#24]
128 \\ svc 0
129 \\ tst r0,r0
130 \\ beq 1f
131 \\ ldmfd sp!,{r4,r5,r6,r7}
132 \\ bx lr
119 \\ stmfd sp!,{r4,r5,r6,r7}
120 \\ mov r7,#120 // SYS_clone
121 \\ mov r6,r3
122 \\ mov r5,r0
123 \\ mov r0,r2
124 \\ and r1,r1,#-16
125 \\ ldr r2,[sp,#16]
126 \\ ldr r3,[sp,#20]
127 \\ ldr r4,[sp,#24]
128 \\ svc 0
129 \\ tst r0,r0
130 \\ beq 1f
131 \\ ldmfd sp!,{r4,r5,r6,r7}
132 \\ bx lr
133133 \\
134 \\ // https://github.com/llvm/llvm-project/issues/115891
135 \\1: mov r7, #0
136 \\ mov r11, #0
137 \\ mov lr, #0
134 \\ // https://github.com/llvm/llvm-project/issues/115891
135 \\1:
136 \\ mov r7, #0
137 \\ mov r11, #0
138 \\ mov lr, #0
138139 \\
139 \\ mov r0,r6
140 \\ bl 3f
141 \\ mov r7,#1 // SYS_exit
142 \\ svc 0
140 \\ mov r0,r6
141 \\ bl 3f
142 \\ mov r7,#1 // SYS_exit
143 \\ svc 0
143144 \\
144 \\3: bx r5
145 \\3:
146 \\ bx r5
145147 );
146148}
147149
148150pub fn restore() callconv(.naked) noreturn {
149 switch (builtin.zig_backend) {
150 .stage2_c => asm volatile (
151 \\ mov r7, %[number]
152 \\ svc #0
153 :
154 : [number] "I" (@backingInt(SYS.sigreturn)),
155 ),
156 else => asm volatile (
157 \\ svc #0
158 :
159 : [number] "{r7}" (@backingInt(SYS.sigreturn)),
160 ),
161 }
151 asm volatile (
152 \\ mov r7, %[number]
153 \\ svc #0
154 :
155 : [number] "I" (@backingInt(SYS.sigreturn)),
156 );
162157}
163158
164159pub fn restore_rt() callconv(.naked) noreturn {
165 switch (builtin.zig_backend) {
166 .stage2_c => asm volatile (
167 \\ mov r7, %[number]
168 \\ svc #0
169 :
170 : [number] "I" (@backingInt(SYS.rt_sigreturn)),
171 ),
172 else => asm volatile (
173 \\ svc #0
174 :
175 : [number] "{r7}" (@backingInt(SYS.rt_sigreturn)),
176 ),
177 }
160 asm volatile (
161 \\ mov r7, %[number]
162 \\ svc #0
163 :
164 : [number] "I" (@backingInt(SYS.rt_sigreturn)),
165 );
178166}
179167
180168pub const VDSO = struct {
lib/std/os/linux/csky.zig+3-3
......@@ -113,14 +113,14 @@ pub fn clone() callconv(.naked) u32 {
113113 // __clone(func, stack, flags, arg, ptid, tls, ctid)
114114 // r0, r1, r2, r3, +0, +4, +8
115115 //
116 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117 // r7 r0, r1, r2, r3, r4
116 // syscall(SYS_clone, flags, stack, ptid, ctid, tls)
117 // r7 r0, r1, r2, r3, r4
118118 asm volatile (
119119 \\ // Preserve callee-saved registers.
120120 \\ mov t0, r4
121121 \\ mov t1, r7
122122 \\
123 \\ andi r1, r1, -8
123 \\ andni r1, r1, 7
124124 \\
125125 \\ subi r1, 8
126126 \\ stw r0, (r1, 0)
lib/std/os/linux/mips.zig-10
......@@ -10,7 +10,6 @@ pub fn syscall0(
1010 return asm volatile (
1111 \\ syscall
1212 \\ beq $a3, $zero, 1f
13 \\ blez $v0, 1f
1413 \\ subu $v0, $zero, $v0
1514 \\1:
1615 : [ret] "={$2}" (-> u32),
......@@ -25,7 +24,6 @@ pub fn syscall1(
2524 return asm volatile (
2625 \\ syscall
2726 \\ beq $a3, $zero, 1f
28 \\ blez $v0, 1f
2927 \\ subu $v0, $zero, $v0
3028 \\1:
3129 : [ret] "={$2}" (-> u32),
......@@ -42,7 +40,6 @@ pub fn syscall2(
4240 return asm volatile (
4341 \\ syscall
4442 \\ beq $a3, $zero, 1f
45 \\ blez $v0, 1f
4643 \\ subu $v0, $zero, $v0
4744 \\1:
4845 : [ret] "={$2}" (-> u32),
......@@ -61,7 +58,6 @@ pub fn syscall3(
6158 return asm volatile (
6259 \\ syscall
6360 \\ beq $a3, $zero, 1f
64 \\ blez $v0, 1f
6561 \\ subu $v0, $zero, $v0
6662 \\1:
6763 : [ret] "={$2}" (-> u32),
......@@ -82,7 +78,6 @@ pub fn syscall4(
8278 return asm volatile (
8379 \\ syscall
8480 \\ beq $a3, $zero, 1f
85 \\ blez $v0, 1f
8681 \\ subu $v0, $zero, $v0
8782 \\1:
8883 : [ret] "={$2}" (-> u32),
......@@ -111,7 +106,6 @@ pub fn syscall5(
111106 \\ syscall
112107 \\ addu $sp, $sp, 24
113108 \\ beq $a3, $zero, 1f
114 \\ blez $v0, 1f
115109 \\ subu $v0, $zero, $v0
116110 \\1:
117111 : [ret] "={$2}" (-> u32),
......@@ -140,7 +134,6 @@ pub fn syscall6(
140134 \\ syscall
141135 \\ addu $sp, $sp, 24
142136 \\ beq $a3, $zero, 1f
143 \\ blez $v0, 1f
144137 \\ subu $v0, $zero, $v0
145138 \\1:
146139 : [ret] "={$2}" (-> u32),
......@@ -172,7 +165,6 @@ pub fn syscall7(
172165 \\ syscall
173166 \\ addu $sp, $sp, 32
174167 \\ beq $a3, $zero, 1f
175 \\ blez $v0, 1f
176168 \\ subu $v0, $zero, $v0
177169 \\1:
178170 : [ret] "={$2}" (-> u32),
......@@ -193,7 +185,6 @@ pub fn syscall_pipe(
193185 return asm volatile (
194186 \\ syscall
195187 \\ beq $a3, $zero, 1f
196 \\ blez $v0, 2f
197188 \\ subu $v0, $zero, $v0
198189 \\ b 2f
199190 \\1:
......@@ -229,7 +220,6 @@ pub fn clone() callconv(.naked) u32 {
229220 \\ li $v0, 4120 # SYS_clone
230221 \\ syscall
231222 \\ beq $a3, $zero, 1f
232 \\ blez $v0, 2f
233223 \\ subu $v0, $zero, $v0
234224 \\ b 2f
235225 \\1:
lib/std/os/linux/mips64.zig-9
......@@ -10,7 +10,6 @@ pub fn syscall0(
1010 return asm volatile (
1111 \\ syscall
1212 \\ beq $a3, $zero, 1f
13 \\ blez $v0, 1f
1413 \\ dsubu $v0, $zero, $v0
1514 \\1:
1615 : [ret] "={$2}" (-> u64),
......@@ -25,7 +24,6 @@ pub fn syscall1(
2524 return asm volatile (
2625 \\ syscall
2726 \\ beq $a3, $zero, 1f
28 \\ blez $v0, 1f
2927 \\ dsubu $v0, $zero, $v0
3028 \\1:
3129 : [ret] "={$2}" (-> u64),
......@@ -42,7 +40,6 @@ pub fn syscall2(
4240 return asm volatile (
4341 \\ syscall
4442 \\ beq $a3, $zero, 1f
45 \\ blez $v0, 1f
4643 \\ dsubu $v0, $zero, $v0
4744 \\1:
4845 : [ret] "={$2}" (-> u64),
......@@ -61,7 +58,6 @@ pub fn syscall3(
6158 return asm volatile (
6259 \\ syscall
6360 \\ beq $a3, $zero, 1f
64 \\ blez $v0, 1f
6561 \\ dsubu $v0, $zero, $v0
6662 \\1:
6763 : [ret] "={$2}" (-> u64),
......@@ -82,7 +78,6 @@ pub fn syscall4(
8278 return asm volatile (
8379 \\ syscall
8480 \\ beq $a3, $zero, 1f
85 \\ blez $v0, 1f
8681 \\ dsubu $v0, $zero, $v0
8782 \\1:
8883 : [ret] "={$2}" (-> u64),
......@@ -105,7 +100,6 @@ pub fn syscall5(
105100 return asm volatile (
106101 \\ syscall
107102 \\ beq $a3, $zero, 1f
108 \\ blez $v0, 1f
109103 \\ dsubu $v0, $zero, $v0
110104 \\1:
111105 : [ret] "={$2}" (-> u64),
......@@ -130,7 +124,6 @@ pub fn syscall6(
130124 return asm volatile (
131125 \\ syscall
132126 \\ beq $a3, $zero, 1f
133 \\ blez $v0, 1f
134127 \\ dsubu $v0, $zero, $v0
135128 \\1:
136129 : [ret] "={$2}" (-> u64),
......@@ -150,7 +143,6 @@ pub fn syscall_pipe(
150143 return asm volatile (
151144 \\ syscall
152145 \\ beq $a3, $zero, 1f
153 \\ blez $v0, 2f
154146 \\ dsubu $v0, $zero, $v0
155147 \\ b 2f
156148 \\1:
......@@ -184,7 +176,6 @@ pub fn clone() callconv(.naked) u64 {
184176 \\ li $v0, 5055 # SYS_clone
185177 \\ syscall
186178 \\ beq $a3, $zero, 1f
187 \\ blez $v0, 2f
188179 \\ dsubu $v0, $zero, $v0
189180 \\ b 2f
190181 \\1:
lib/std/os/linux/mipsn32.zig-10
......@@ -10,7 +10,6 @@ pub fn syscall0(
1010 return asm volatile (
1111 \\ syscall
1212 \\ beq $a3, $zero, 1f
13 \\ blez $v0, 1f
1413 \\ subu $v0, $zero, $v0
1514 \\1:
1615 : [ret] "={$2}" (-> u32),
......@@ -25,7 +24,6 @@ pub fn syscall1(
2524 return asm volatile (
2625 \\ syscall
2726 \\ beq $a3, $zero, 1f
28 \\ blez $v0, 1f
2927 \\ subu $v0, $zero, $v0
3028 \\1:
3129 : [ret] "={$2}" (-> u32),
......@@ -42,7 +40,6 @@ pub fn syscall2(
4240 return asm volatile (
4341 \\ syscall
4442 \\ beq $a3, $zero, 1f
45 \\ blez $v0, 1f
4643 \\ subu $v0, $zero, $v0
4744 \\1:
4845 : [ret] "={$2}" (-> u32),
......@@ -61,7 +58,6 @@ pub fn syscall3(
6158 return asm volatile (
6259 \\ syscall
6360 \\ beq $a3, $zero, 1f
64 \\ blez $v0, 1f
6561 \\ subu $v0, $zero, $v0
6662 \\1:
6763 : [ret] "={$2}" (-> u32),
......@@ -82,7 +78,6 @@ pub fn syscall4(
8278 return asm volatile (
8379 \\ syscall
8480 \\ beq $a3, $zero, 1f
85 \\ blez $v0, 1f
8681 \\ subu $v0, $zero, $v0
8782 \\1:
8883 : [ret] "={$2}" (-> u32),
......@@ -105,7 +100,6 @@ pub fn syscall5(
105100 return asm volatile (
106101 \\ syscall
107102 \\ beq $a3, $zero, 1f
108 \\ blez $v0, 1f
109103 \\ subu $v0, $zero, $v0
110104 \\1:
111105 : [ret] "={$2}" (-> u32),
......@@ -130,7 +124,6 @@ pub fn syscall6(
130124 return asm volatile (
131125 \\ syscall
132126 \\ beq $a3, $zero, 1f
133 \\ blez $v0, 1f
134127 \\ subu $v0, $zero, $v0
135128 \\1:
136129 : [ret] "={$2}" (-> u32),
......@@ -150,7 +143,6 @@ pub fn syscall_pipe(
150143 return asm volatile (
151144 \\ syscall
152145 \\ beq $a3, $zero, 1f
153 \\ blez $v0, 2f
154146 \\ subu $v0, $zero, $v0
155147 \\ b 2f
156148 \\1:
......@@ -171,7 +163,6 @@ pub fn syscall_lseek(
171163 return asm volatile (
172164 \\ syscall
173165 \\ beq $a3, $zero, 1f
174 \\ blez $v0, 1f
175166 \\ dsubu $v0, $zero, $v0
176167 \\1:
177168 : [ret] "={$2}" (-> u64),
......@@ -203,7 +194,6 @@ pub fn clone() callconv(.naked) u32 {
203194 \\ li $v0, 6055 # SYS_clone
204195 \\ syscall
205196 \\ beq $a3, $zero, 1f
206 \\ blez $v0, 2f
207197 \\ subu $v0, $zero, $v0
208198 \\ b 2f
209199 \\1:
lib/std/os/linux/or1k.zig+5-1
......@@ -124,7 +124,8 @@ pub fn clone() callconv(.naked) u32 {
124124 // r11 r3, r4, r5, r6, r7
125125 asm volatile (
126126 \\ # Save function pointer and argument pointer on new thread stack
127 \\ l.andi r4, r4, -4
127 \\ l.addi r13, r0, -4
128 \\ l.and r4, r4, r13
128129 \\ l.addi r4, r4, -8
129130 \\ l.sw 0(r4), r3
130131 \\ l.sw 4(r4), r6
......@@ -138,7 +139,9 @@ pub fn clone() callconv(.naked) u32 {
138139 \\ l.sys 1
139140 \\ l.sfeqi r11, 0
140141 \\ l.bf 1f
142 \\ l.nop
141143 \\ l.jr r9
144 \\ l.nop
142145 \\1:
143146 );
144147 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
......@@ -151,6 +154,7 @@ pub fn clone() callconv(.naked) u32 {
151154 \\ l.lwz r11, 0(r1)
152155 \\ l.lwz r3, 4(r1)
153156 \\ l.jalr r11
157 \\ l.nop
154158 \\
155159 \\ l.ori r3, r11, 0
156160 \\ l.ori r11, r0, 93 # SYS_exit
lib/std/os/linux/powerpc.zig+25-38
......@@ -16,7 +16,7 @@ pub fn syscall0(
1616 \\ sc
1717 \\ bns+ 1f
1818 \\ neg 3, 3
19 \\ 1:
19 \\1:
2020 : [ret] "={r3}" (-> u32),
2121 [r0_out] "={r0}" (r0_out),
2222 : [number] "{r0}" (@backingInt(number)),
......@@ -33,7 +33,7 @@ pub fn syscall1(
3333 \\ sc
3434 \\ bns+ 1f
3535 \\ neg 3, 3
36 \\ 1:
36 \\1:
3737 : [ret] "={r3}" (-> u32),
3838 [r0_out] "={r0}" (r0_out),
3939 : [number] "{r0}" (@backingInt(number)),
......@@ -53,7 +53,7 @@ pub fn syscall2(
5353 \\ sc
5454 \\ bns+ 1f
5555 \\ neg 3, 3
56 \\ 1:
56 \\1:
5757 : [ret] "={r3}" (-> u32),
5858 [r0_out] "={r0}" (r0_out),
5959 [r4_out] "={r4}" (r4_out),
......@@ -77,7 +77,7 @@ pub fn syscall3(
7777 \\ sc
7878 \\ bns+ 1f
7979 \\ neg 3, 3
80 \\ 1:
80 \\1:
8181 : [ret] "={r3}" (-> u32),
8282 [r0_out] "={r0}" (r0_out),
8383 [r4_out] "={r4}" (r4_out),
......@@ -105,7 +105,7 @@ pub fn syscall4(
105105 \\ sc
106106 \\ bns+ 1f
107107 \\ neg 3, 3
108 \\ 1:
108 \\1:
109109 : [ret] "={r3}" (-> u32),
110110 [r0_out] "={r0}" (r0_out),
111111 [r4_out] "={r4}" (r4_out),
......@@ -137,7 +137,7 @@ pub fn syscall5(
137137 \\ sc
138138 \\ bns+ 1f
139139 \\ neg 3, 3
140 \\ 1:
140 \\1:
141141 : [ret] "={r3}" (-> u32),
142142 [r0_out] "={r0}" (r0_out),
143143 [r4_out] "={r4}" (r4_out),
......@@ -173,7 +173,7 @@ pub fn syscall6(
173173 \\ sc
174174 \\ bns+ 1f
175175 \\ neg 3, 3
176 \\ 1:
176 \\1:
177177 : [ret] "={r3}" (-> u32),
178178 [r0_out] "={r0}" (r0_out),
179179 [r4_out] "={r4}" (r4_out),
......@@ -200,8 +200,9 @@ pub fn clone() callconv(.naked) u32 {
200200 asm volatile (
201201 \\ # store non-volatile regs r29, r30 on stack in order to put our
202202 \\ # start func and its arg there
203 \\ stwu 29, -16(1)
204 \\ stw 30, 4(1)
203 \\ stwu 1, -16(1)
204 \\ stw 29, 8(1)
205 \\ stw 30, 12(1)
205206 \\
206207 \\ # save r3 (func) into r29, and r6(arg) into r30
207208 \\ mr 29, 3
......@@ -234,8 +235,8 @@ pub fn clone() callconv(.naked) u32 {
234235 \\
235236 \\ # if not 0, restore stack and return
236237 \\ beq cr7, 2f
237 \\ lwz 29, 0(1)
238 \\ lwz 30, 4(1)
238 \\ lwz 29, 8(1)
239 \\ lwz 30, 12(1)
239240 \\ addi 1, 1, 16
240241 \\ blr
241242 \\
......@@ -247,7 +248,7 @@ pub fn clone() callconv(.naked) u32 {
247248 );
248249 asm volatile (
249250 \\ li 31, 0
250 \\ mtlr 0
251 \\ mtlr 31
251252 \\
252253 \\ #call funcptr: move arg (d) into r3
253254 \\ mr 3, 30
......@@ -262,35 +263,21 @@ pub fn clone() callconv(.naked) u32 {
262263}
263264
264265pub fn restore() callconv(.naked) noreturn {
265 switch (builtin.zig_backend) {
266 .stage2_c => asm volatile (
267 \\ li 0, %[number]
268 \\ sc
269 :
270 : [number] "i" (@backingInt(SYS.sigreturn)),
271 ),
272 else => asm volatile (
273 \\ sc
274 :
275 : [number] "{r0}" (@backingInt(SYS.sigreturn)),
276 ),
277 }
266 asm volatile (
267 \\ li 0, %[number]
268 \\ sc
269 :
270 : [number] "i" (@backingInt(SYS.sigreturn)),
271 );
278272}
279273
280274pub fn restore_rt() callconv(.naked) noreturn {
281 switch (builtin.zig_backend) {
282 .stage2_c => asm volatile (
283 \\ li 0, %[number]
284 \\ sc
285 :
286 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
287 ),
288 else => asm volatile (
289 \\ sc
290 :
291 : [number] "{r0}" (@backingInt(SYS.rt_sigreturn)),
292 ),
293 }
275 asm volatile (
276 \\ li 0, %[number]
277 \\ sc
278 :
279 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
280 );
294281}
295282
296283pub const VDSO = struct {
lib/std/os/linux/powerpc64.zig+52-66
......@@ -16,7 +16,7 @@ pub fn syscall0(
1616 \\ sc
1717 \\ bns+ 1f
1818 \\ neg 3, 3
19 \\ 1:
19 \\1:
2020 : [ret] "={r3}" (-> u64),
2121 [r0_out] "={r0}" (r0_out),
2222 : [number] "{r0}" (@backingInt(number)),
......@@ -33,7 +33,7 @@ pub fn syscall1(
3333 \\ sc
3434 \\ bns+ 1f
3535 \\ neg 3, 3
36 \\ 1:
36 \\1:
3737 : [ret] "={r3}" (-> u64),
3838 [r0_out] "={r0}" (r0_out),
3939 : [number] "{r0}" (@backingInt(number)),
......@@ -53,7 +53,7 @@ pub fn syscall2(
5353 \\ sc
5454 \\ bns+ 1f
5555 \\ neg 3, 3
56 \\ 1:
56 \\1:
5757 : [ret] "={r3}" (-> u64),
5858 [r0_out] "={r0}" (r0_out),
5959 [r4_out] "={r4}" (r4_out),
......@@ -77,7 +77,7 @@ pub fn syscall3(
7777 \\ sc
7878 \\ bns+ 1f
7979 \\ neg 3, 3
80 \\ 1:
80 \\1:
8181 : [ret] "={r3}" (-> u64),
8282 [r0_out] "={r0}" (r0_out),
8383 [r4_out] "={r4}" (r4_out),
......@@ -105,7 +105,7 @@ pub fn syscall4(
105105 \\ sc
106106 \\ bns+ 1f
107107 \\ neg 3, 3
108 \\ 1:
108 \\1:
109109 : [ret] "={r3}" (-> u64),
110110 [r0_out] "={r0}" (r0_out),
111111 [r4_out] "={r4}" (r4_out),
......@@ -137,7 +137,7 @@ pub fn syscall5(
137137 \\ sc
138138 \\ bns+ 1f
139139 \\ neg 3, 3
140 \\ 1:
140 \\1:
141141 : [ret] "={r3}" (-> u64),
142142 [r0_out] "={r0}" (r0_out),
143143 [r4_out] "={r4}" (r4_out),
......@@ -173,7 +173,7 @@ pub fn syscall6(
173173 \\ sc
174174 \\ bns+ 1f
175175 \\ neg 3, 3
176 \\ 1:
176 \\1:
177177 : [ret] "={r3}" (-> u64),
178178 [r0_out] "={r0}" (r0_out),
179179 [r4_out] "={r4}" (r4_out),
......@@ -198,84 +198,70 @@ pub fn clone() callconv(.naked) u64 {
198198 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
199199 // 0 3, 4, 5, 6, 7
200200 asm volatile (
201 \\ # create initial stack frame for new thread
202 \\ clrrdi 4, 4, 4
203 \\ li 0, 0
204 \\ stdu 0,-32(4)
201 \\ # create initial stack frame for new thread
202 \\ clrrdi 4, 4, 4
203 \\ li 0, 0
204 \\ stdu 0,-32(4)
205205 \\
206 \\ # save fn and arg to child stack
207 \\ std 3, 8(4)
208 \\ std 6, 16(4)
206 \\ # save fn and arg to child stack
207 \\ std 3, 8(4)
208 \\ std 6, 16(4)
209209 \\
210 \\ # shuffle args into correct registers and call SYS_clone
211 \\ mr 3, 5
212 \\ #mr 4, 4
213 \\ mr 5, 7
214 \\ mr 6, 8
215 \\ mr 7, 9
216 \\ li 0, 120 # SYS_clone = 120
217 \\ sc
210 \\ # shuffle args into correct registers and call SYS_clone
211 \\ mr 3, 5
212 \\ #mr 4, 4
213 \\ mr 5, 7
214 \\ mr 6, 8
215 \\ mr 7, 9
216 \\ li 0, 120 # SYS_clone = 120
217 \\ sc
218218 \\
219 \\ # if error, negate return (errno)
220 \\ bns+ 1f
221 \\ neg 3, 3
219 \\ # if error, negate return (errno)
220 \\ bns+ 1f
221 \\ neg 3, 3
222222 \\
223223 \\1:
224 \\ # if we're the parent, return
225 \\ cmpwi cr7, 3, 0
226 \\ bnelr cr7
224 \\ # if we're the parent, return
225 \\ cmpwi cr7, 3, 0
226 \\ bnelr cr7
227227 \\
228 \\ # we're the child
228 \\ # we're the child
229229 );
230230 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
231 \\ .cfi_undefined lr
231 \\ .cfi_undefined lr
232232 );
233233 asm volatile (
234 \\ li 31, 0
235 \\ mtlr 0
234 \\ li 31, 0
235 \\ mtlr 31
236236 \\
237 \\ # call fn(arg)
238 \\ ld 3, 16(1)
239 \\ ld 12, 8(1)
240 \\ mtctr 12
241 \\ bctrl
237 \\ # call fn(arg)
238 \\ ld 3, 16(1)
239 \\ ld 12, 8(1)
240 \\ mtctr 12
241 \\ bctrl
242242 \\
243 \\ # call SYS_exit. exit code is already in r3 from fn return value
244 \\ li 0, 1 # SYS_exit = 1
245 \\ sc
243 \\ # call SYS_exit. exit code is already in r3 from fn return value
244 \\ li 0, 1 # SYS_exit = 1
245 \\ sc
246246 );
247247}
248248
249249pub fn restore() callconv(.naked) noreturn {
250 switch (builtin.zig_backend) {
251 .stage2_c => asm volatile (
252 \\ li 0, %[number]
253 \\ sc
254 :
255 : [number] "i" (@backingInt(SYS.sigreturn)),
256 ),
257 else => asm volatile (
258 \\ sc
259 :
260 : [number] "{r0}" (@backingInt(SYS.sigreturn)),
261 ),
262 }
250 asm volatile (
251 \\ li 0, %[number]
252 \\ sc
253 :
254 : [number] "i" (@backingInt(SYS.sigreturn)),
255 );
263256}
264257
265258pub fn restore_rt() callconv(.naked) noreturn {
266 switch (builtin.zig_backend) {
267 .stage2_c => asm volatile (
268 \\ li 0, %[number]
269 \\ sc
270 :
271 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
272 ),
273 else => asm volatile (
274 \\ sc
275 :
276 : [number] "{r0}" (@backingInt(SYS.rt_sigreturn)),
277 ),
278 }
259 asm volatile (
260 \\ li 0, %[number]
261 \\ sc
262 :
263 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
264 );
279265}
280266
281267pub const VDSO = struct {
lib/std/os/linux/riscv32.zig+25-24
......@@ -116,40 +116,41 @@ pub fn clone() callconv(.naked) u32 {
116116 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117117 // a7 a0, a1, a2, a3, a4
118118 asm volatile (
119 \\ # Save func and arg to stack
120 \\ addi a1, a1, -8
121 \\ sw a0, 0(a1)
122 \\ sw a3, 4(a1)
119 \\ andi a1, a1, -16
120 \\ # Save func and arg to stack
121 \\ addi a1, a1, -16
122 \\ sw a0, 0(a1)
123 \\ sw a3, 4(a1)
123124 \\
124 \\ # Call SYS_clone
125 \\ mv a0, a2
126 \\ mv a2, a4
127 \\ mv a3, a5
128 \\ mv a4, a6
129 \\ li a7, 220 # SYS_clone
130 \\ ecall
125 \\ # Call SYS_clone
126 \\ mv a0, a2
127 \\ mv a2, a4
128 \\ mv a3, a5
129 \\ mv a4, a6
130 \\ li a7, 220 # SYS_clone
131 \\ ecall
131132 \\
132 \\ beqz a0, 1f
133 \\ # Parent
134 \\ ret
133 \\ beqz a0, 1f
134 \\ # Parent
135 \\ ret
135136 \\
136 \\ # Child
137 \\ # Child
137138 \\1:
138139 );
139140 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
140 \\ .cfi_undefined ra
141 \\ .cfi_undefined ra
141142 );
142143 asm volatile (
143 \\ mv fp, zero
144 \\ mv ra, zero
144 \\ mv fp, zero
145 \\ mv ra, zero
145146 \\
146 \\ lw a1, 0(sp)
147 \\ lw a0, 4(sp)
148 \\ jalr a1
147 \\ lw a1, 0(sp)
148 \\ lw a0, 4(sp)
149 \\ jalr a1
149150 \\
150 \\ # Exit
151 \\ li a7, 93 # SYS_exit
152 \\ ecall
151 \\ # Exit
152 \\ li a7, 93 # SYS_exit
153 \\ ecall
153154 );
154155}
155156
lib/std/os/linux/riscv64.zig+25-24
......@@ -116,40 +116,41 @@ pub fn clone() callconv(.naked) u64 {
116116 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
117117 // a7 a0, a1, a2, a3, a4
118118 asm volatile (
119 \\ # Save func and arg to stack
120 \\ addi a1, a1, -16
121 \\ sd a0, 0(a1)
122 \\ sd a3, 8(a1)
119 \\ andi a1, a1, -16
120 \\ # Save func and arg to stack
121 \\ addi a1, a1, -16
122 \\ sd a0, 0(a1)
123 \\ sd a3, 8(a1)
123124 \\
124 \\ # Call SYS_clone
125 \\ mv a0, a2
126 \\ mv a2, a4
127 \\ mv a3, a5
128 \\ mv a4, a6
129 \\ li a7, 220 # SYS_clone
130 \\ ecall
125 \\ # Call SYS_clone
126 \\ mv a0, a2
127 \\ mv a2, a4
128 \\ mv a3, a5
129 \\ mv a4, a6
130 \\ li a7, 220 # SYS_clone
131 \\ ecall
131132 \\
132 \\ beqz a0, 1f
133 \\ # Parent
134 \\ ret
133 \\ beqz a0, 1f
134 \\ # Parent
135 \\ ret
135136 \\
136 \\ # Child
137 \\ # Child
137138 \\1:
138139 );
139140 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
140 \\ .cfi_undefined ra
141 \\ .cfi_undefined ra
141142 );
142143 asm volatile (
143 \\ mv fp, zero
144 \\ mv ra, zero
144 \\ mv fp, zero
145 \\ mv ra, zero
145146 \\
146 \\ ld a1, 0(sp)
147 \\ ld a0, 8(sp)
148 \\ jalr a1
147 \\ ld a1, 0(sp)
148 \\ ld a0, 8(sp)
149 \\ jalr a1
149150 \\
150 \\ # Exit
151 \\ li a7, 93 # SYS_exit
152 \\ ecall
151 \\ # Exit
152 \\ li a7, 93 # SYS_exit
153 \\ ecall
153154 );
154155}
155156
lib/std/os/linux/s390x.zig+57-72
......@@ -111,98 +111,83 @@ pub fn syscall6(
111111
112112pub fn clone() callconv(.naked) u64 {
113113 asm volatile (
114 \\# int clone(
115 \\# fn, a = r2
116 \\# stack, b = r3
117 \\# flags, c = r4
118 \\# arg, d = r5
119 \\# ptid, e = r6
120 \\# tls, f = *(r15+160)
121 \\# ctid) g = *(r15+168)
122 \\#
123 \\# pseudo C code:
124 \\# tid = syscall(SYS_clone,b,c,e,g,f);
125 \\# if (!tid) syscall(SYS_exit, a(d));
126 \\# return tid;
114 \\ # int clone(
115 \\ # fn, a = r2
116 \\ # stack, b = r3
117 \\ # flags, c = r4
118 \\ # arg, d = r5
119 \\ # ptid, e = r6
120 \\ # tls, f = *(r15+160)
121 \\ # ctid) g = *(r15+168)
122 \\ #
123 \\ # pseudo C code:
124 \\ # tid = syscall(SYS_clone,b,c,e,g,f);
125 \\ # if (!tid) syscall(SYS_exit, a(d));
126 \\ # return tid;
127127 \\
128 \\# preserve call-saved register used as syscall arg
129 \\stg %%r6, 48(%%r15)
128 \\ # preserve call-saved register used as syscall arg
129 \\ stg %%r6, 48(%%r15)
130130 \\
131 \\# create initial stack frame for new thread
132 \\nill %%r3, 0xfff8
133 \\aghi %%r3, -160
134 \\lghi %%r0, 0
135 \\stg %%r0, 0(%%r3)
131 \\ # create initial stack frame for new thread
132 \\ nill %%r3, 0xfff8
133 \\ aghi %%r3, -160
134 \\ lghi %%r0, 0
135 \\ stg %%r0, 0(%%r3)
136136 \\
137 \\# save fn and arg to child stack
138 \\stg %%r2, 8(%%r3)
139 \\stg %%r5, 16(%%r3)
137 \\ # save fn and arg to child stack
138 \\ stg %%r2, 8(%%r3)
139 \\ stg %%r5, 16(%%r3)
140140 \\
141 \\# shuffle args into correct registers and call SYS_clone
142 \\lgr %%r2, %%r3
143 \\lgr %%r3, %%r4
144 \\lgr %%r4, %%r6
145 \\lg %%r5, 168(%%r15)
146 \\lg %%r6, 160(%%r15)
147 \\svc 120
141 \\ # shuffle args into correct registers and call SYS_clone
142 \\ lgr %%r2, %%r3
143 \\ lgr %%r3, %%r4
144 \\ lgr %%r4, %%r6
145 \\ lg %%r5, 168(%%r15)
146 \\ lg %%r6, 160(%%r15)
147 \\ svc 120
148148 \\
149 \\# restore call-saved register
150 \\lg %%r6, 48(%%r15)
149 \\ # restore call-saved register
150 \\ lg %%r6, 48(%%r15)
151151 \\
152 \\# if error or if we're the parent, return
153 \\ltgr %%r2, %%r2
154 \\bnzr %%r14
152 \\ # if error or if we're the parent, return
153 \\ ltgr %%r2, %%r2
154 \\ bnzr %%r14
155155 \\
156 \\# we're the child
156 \\ # we're the child
157157 );
158158 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
159 \\.cfi_undefined %%r14
159 \\ .cfi_undefined %%r14
160160 );
161161 asm volatile (
162 \\lghi %%r11, 0
163 \\lghi %%r14, 0
162 \\ lghi %%r11, 0
163 \\ lghi %%r14, 0
164164 \\
165 \\# call fn(arg)
166 \\lg %%r1, 8(%%r15)
167 \\lg %%r2, 16(%%r15)
168 \\basr %%r14, %%r1
169 \\
170 \\# call SYS_exit. exit code is already in r2 from fn return value
171 \\svc 1
165 \\ # call fn(arg)
166 \\ lg %%r1, 8(%%r15)
167 \\ lg %%r2, 16(%%r15)
168 \\ basr %%r14, %%r1
172169 \\
170 \\ # call SYS_exit. exit code is already in r2 from fn return value
171 \\ svc 1
173172 );
174173}
175174
176175pub fn restore() callconv(.naked) noreturn {
177 switch (builtin.zig_backend) {
178 .stage2_c => asm volatile (
179 \\lghi %%r1, %[number]
180 \\svc 0
181 :
182 : [number] "K" (@backingInt(SYS.sigreturn)),
183 ),
184 else => asm volatile (
185 \\svc 0
186 :
187 : [number] "{r1}" (@backingInt(SYS.sigreturn)),
188 ),
189 }
176 asm volatile (
177 \\ lghi %%r1, %[number]
178 \\ svc 0
179 :
180 : [number] "K" (@backingInt(SYS.sigreturn)),
181 );
190182}
191183
192184pub fn restore_rt() callconv(.naked) noreturn {
193 switch (builtin.zig_backend) {
194 .stage2_c => asm volatile (
195 \\lghi %%r1, %[number]
196 \\svc 0
197 :
198 : [number] "K" (@backingInt(SYS.rt_sigreturn)),
199 ),
200 else => asm volatile (
201 \\svc 0
202 :
203 : [number] "{r1}" (@backingInt(SYS.rt_sigreturn)),
204 ),
205 }
185 asm volatile (
186 \\ lghi %%r1, %[number]
187 \\ svc 0
188 :
189 : [number] "K" (@backingInt(SYS.rt_sigreturn)),
190 );
206191}
207192
208193pub const time_t = i64;
lib/std/os/linux/sh.zig+2-2
......@@ -167,8 +167,8 @@ pub fn clone() callconv(.naked) u32 {
167167 \\ mov #120, r3 ! SYS_clone
168168 \\ mov r6, r4
169169 \\ mov.l @r15, r6
170 \\ mov.l @(r15, 8), r7
171 \\ mov.l @(r15, 4), r0
170 \\ mov.l @(8, r15), r7
171 \\ mov.l @(4, r15), r0
172172 \\ trapa #31
173173 \\ or r0, r0
174174 \\ or r0, r0
lib/std/os/linux/sparc.zig+2-2
......@@ -214,11 +214,11 @@ pub fn clone() callconv(.naked) u32 {
214214 \\
215215 \\ # Align, and add some extra space for the initial frame
216216 \\ and %%i1, -8, %%i1
217 \\ sub %%i1, 96 + 2047, %%o1
217 \\ sub %%i1, 96, %%o1
218218 \\
219219 \\ mov %%i4, %%o2
220220 \\ mov %%i5, %%o3
221 \\ ld [%%fp + 92 + 2047], %%o4
221 \\ ld [%%fp + 92], %%o4
222222 \\ t 0x10
223223 \\ bcs 1f
224224 \\ nop
lib/std/os/linux/tls.zig+8-8
......@@ -261,10 +261,9 @@ pub fn setThreadPointer(addr: usize) void {
261261 },
262262 .alpha => {
263263 asm volatile (
264 \\ lda $16, 0(%[addr])
265264 \\ wruniq
266265 :
267 : [addr] "r" (addr),
266 : [addr] "{$16}" (addr),
268267 );
269268 },
270269 .arc, .arceb => {
......@@ -282,7 +281,7 @@ pub fn setThreadPointer(addr: usize) void {
282281 assert(rc == 0);
283282 },
284283 .m68k => {
285 const rc = linux.syscall1(.set_thread_area, addr);
284 const rc = @call(.always_inline, linux.syscall1, .{ .set_thread_area, addr });
286285 assert(rc == 0);
287286 },
288287 .hexagon => {
......@@ -295,9 +294,10 @@ pub fn setThreadPointer(addr: usize) void {
295294 .hppa => {
296295 asm volatile (
297296 \\ ble 0xe0(%%sr2, %%r0)
297 \\ nop
298298 :
299 : [addr] "={r26}" (addr),
300 : .{ .r29 = true });
299 : [addr] "{r26}" (addr),
300 : .{ .r31 = true });
301301 },
302302 .loongarch32, .loongarch64 => {
303303 asm volatile (
......@@ -357,7 +357,7 @@ pub fn setThreadPointer(addr: usize) void {
357357 },
358358 .sh, .sheb => {
359359 asm volatile (
360 \\ ldc gbr, %[addr]
360 \\ ldc %[addr], gbr
361361 :
362362 : [addr] "r" (addr),
363363 );
......@@ -417,7 +417,7 @@ pub fn getThreadPointer() usize {
417417 \\ move %[ret], $tp
418418 : [ret] "=r" (-> usize),
419419 ),
420 .m68k => linux.syscall1(.get_thread_area),
420 .m68k => linux.syscall0(.get_thread_area),
421421 .mips, .mipsel, .mips64, .mips64el => asm (
422422 \\ rdhwr %[ret], $29
423423 : [ret] "=r" (-> usize),
......@@ -449,7 +449,7 @@ pub fn getThreadPointer() usize {
449449 : [ret] "=r" (-> usize),
450450 ),
451451 .sh, .sheb => asm (
452 \\ stc %[ret], gbr
452 \\ stc gbr, %[ret]
453453 : [ret] "=r" (-> usize),
454454 ),
455455 .sparc, .sparc64 => asm (
lib/std/os/linux/x32.zig+27-35
......@@ -125,54 +125,46 @@ pub fn syscall_lseek(
125125
126126pub fn clone() callconv(.naked) u32 {
127127 asm volatile (
128 \\ movl $0x40000038,%%eax // SYS_clone
129 \\ mov %%rdi,%%r11
130 \\ mov %%rdx,%%rdi
131 \\ mov %%r8,%%rdx
132 \\ mov %%r9,%%r8
133 \\ mov 8(%%rsp),%%r10d
134 \\ mov %%r11,%%r9
135 \\ and $-16,%%rsi
136 \\ sub $8,%%rsi
137 \\ mov %%rcx,(%%rsi)
138 \\ syscall
139 \\ test %%eax,%%eax
140 \\ jz 1f
141 \\ ret
128 \\ movl $0x40000038,%%eax // SYS_clone
129 \\ mov %%rdi,%%r11
130 \\ mov %%rdx,%%rdi
131 \\ mov %%r8,%%rdx
132 \\ mov %%r9,%%r8
133 \\ mov 8(%%rsp),%%r10d
134 \\ mov %%r11,%%r9
135 \\ and $-16,%%rsi
136 \\ sub $8,%%rsi
137 \\ mov %%rcx,(%%rsi)
138 \\ syscall
139 \\ test %%eax,%%eax
140 \\ jz 1f
141 \\ ret
142142 \\
143143 \\1:
144144 );
145145 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
146 \\ .cfi_undefined %%rip
146 \\ .cfi_undefined %%rip
147147 );
148148 asm volatile (
149 \\ xor %%ebp,%%ebp
150 \\
151 \\ pop %%rdi
152 \\ call *%%r9
153 \\ mov %%eax,%%edi
154 \\ movl $0x4000003c,%%eax // SYS_exit
155 \\ syscall
149 \\ xor %%ebp,%%ebp
156150 \\
151 \\ pop %%rdi
152 \\ call *%%r9
153 \\ mov %%eax,%%edi
154 \\ movl $0x4000003c,%%eax // SYS_exit
155 \\ syscall
157156 );
158157}
159158
160159pub const restore = restore_rt;
161160
162161pub fn restore_rt() callconv(.naked) noreturn {
163 switch (builtin.zig_backend) {
164 .stage2_c => asm volatile (
165 \\ movl %[number], %%eax
166 \\ syscall
167 :
168 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
169 ),
170 else => asm volatile (
171 \\ syscall
172 :
173 : [number] "{rax}" (@backingInt(SYS.rt_sigreturn)),
174 ),
175 }
162 asm volatile (
163 \\ movl %[number], %%eax
164 \\ syscall
165 :
166 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
167 );
176168}
177169
178170pub const time_t = i64;
lib/std/os/linux/x86.zig+46-61
......@@ -142,81 +142,66 @@ pub fn clone() callconv(.naked) u32 {
142142 // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
143143 // eax, ebx, ecx, edx, esi, edi
144144 asm volatile (
145 \\ pushl %%ebp
146 \\ movl %%esp,%%ebp
147 \\ pushl %%ebx
148 \\ pushl %%esi
149 \\ pushl %%edi
150 \\ // Setup the arguments
151 \\ movl 16(%%ebp),%%ebx
152 \\ movl 12(%%ebp),%%ecx
153 \\ andl $-16,%%ecx
154 \\ subl $20,%%ecx
155 \\ movl 20(%%ebp),%%eax
156 \\ movl %%eax,4(%%ecx)
157 \\ movl 8(%%ebp),%%eax
158 \\ movl %%eax,0(%%ecx)
159 \\ movl 24(%%ebp),%%edx
160 \\ movl 28(%%ebp),%%esi
161 \\ movl 32(%%ebp),%%edi
162 \\ movl $120,%%eax // SYS_clone
163 \\ int $128
164 \\ testl %%eax,%%eax
165 \\ jz 1f
166 \\ popl %%edi
167 \\ popl %%esi
168 \\ popl %%ebx
169 \\ popl %%ebp
170 \\ retl
145 \\ pushl %%ebp
146 \\ movl %%esp,%%ebp
147 \\ pushl %%ebx
148 \\ pushl %%esi
149 \\ pushl %%edi
150 \\ // Setup the arguments
151 \\ movl 16(%%ebp),%%ebx
152 \\ movl 12(%%ebp),%%ecx
153 \\ andl $-16,%%ecx
154 \\ subl $20,%%ecx
155 \\ movl 20(%%ebp),%%eax
156 \\ movl %%eax,4(%%ecx)
157 \\ movl 8(%%ebp),%%eax
158 \\ movl %%eax,0(%%ecx)
159 \\ movl 24(%%ebp),%%edx
160 \\ movl 28(%%ebp),%%esi
161 \\ movl 32(%%ebp),%%edi
162 \\ movl $120,%%eax // SYS_clone
163 \\ int $128
164 \\ testl %%eax,%%eax
165 \\ jz 1f
166 \\ popl %%edi
167 \\ popl %%esi
168 \\ popl %%ebx
169 \\ popl %%ebp
170 \\ retl
171171 \\
172172 \\1:
173173 );
174174 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
175 \\ .cfi_undefined %%eip
175 \\ .cfi_undefined %%eip
176176 );
177177 asm volatile (
178 \\ xorl %%ebp,%%ebp
178 \\ xorl %%ebp,%%ebp
179179 \\
180 \\ popl %%eax
181 \\ calll *%%eax
182 \\ movl %%eax,%%ebx
183 \\ movl $1,%%eax // SYS_exit
184 \\ int $128
180 \\ popl %%eax
181 \\ calll *%%eax
182 \\ movl %%eax,%%ebx
183 \\ movl $1,%%eax // SYS_exit
184 \\ int $128
185185 );
186186}
187187
188188pub fn restore() callconv(.naked) noreturn {
189 switch (builtin.zig_backend) {
190 .stage2_c => asm volatile (
191 \\ addl $4, %%esp
192 \\ movl %[number], %%eax
193 \\ int $0x80
194 :
195 : [number] "i" (@backingInt(SYS.sigreturn)),
196 ),
197 else => asm volatile (
198 \\ addl $4, %%esp
199 \\ int $0x80
200 :
201 : [number] "{eax}" (@backingInt(SYS.sigreturn)),
202 ),
203 }
189 asm volatile (
190 \\ addl $4, %%esp
191 \\ movl %[number], %%eax
192 \\ int $0x80
193 :
194 : [number] "i" (@backingInt(SYS.sigreturn)),
195 );
204196}
205197
206198pub fn restore_rt() callconv(.naked) noreturn {
207 switch (builtin.zig_backend) {
208 .stage2_c => asm volatile (
209 \\ movl %[number], %%eax
210 \\ int $0x80
211 :
212 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
213 ),
214 else => asm volatile (
215 \\ int $0x80
216 :
217 : [number] "{eax}" (@backingInt(SYS.rt_sigreturn)),
218 ),
219 }
199 asm volatile (
200 \\ movl %[number], %%eax
201 \\ int $0x80
202 :
203 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
204 );
220205}
221206
222207pub const VDSO = struct {
lib/std/os/linux/x86_64.zig+27-35
......@@ -111,54 +111,46 @@ pub fn syscall6(
111111
112112pub fn clone() callconv(.naked) u64 {
113113 asm volatile (
114 \\ movl $56,%%eax // SYS_clone
115 \\ movq %%rdi,%%r11
116 \\ movq %%rdx,%%rdi
117 \\ movq %%r8,%%rdx
118 \\ movq %%r9,%%r8
119 \\ movq 8(%%rsp),%%r10
120 \\ movq %%r11,%%r9
121 \\ andq $-16,%%rsi
122 \\ subq $8,%%rsi
123 \\ movq %%rcx,(%%rsi)
124 \\ syscall
125 \\ testq %%rax,%%rax
126 \\ jz 1f
127 \\ retq
114 \\ movl $56,%%eax // SYS_clone
115 \\ movq %%rdi,%%r11
116 \\ movq %%rdx,%%rdi
117 \\ movq %%r8,%%rdx
118 \\ movq %%r9,%%r8
119 \\ movq 8(%%rsp),%%r10
120 \\ movq %%r11,%%r9
121 \\ andq $-16,%%rsi
122 \\ subq $8,%%rsi
123 \\ movq %%rcx,(%%rsi)
124 \\ syscall
125 \\ testq %%rax,%%rax
126 \\ jz 1f
127 \\ retq
128128 \\
129129 \\1:
130130 );
131131 if (builtin.unwind_tables != .none or !builtin.strip_debug_info) asm volatile (
132 \\ .cfi_undefined %%rip
132 \\ .cfi_undefined %%rip
133133 );
134134 asm volatile (
135 \\ xorl %%ebp,%%ebp
136 \\
137 \\ popq %%rdi
138 \\ callq *%%r9
139 \\ movl %%eax,%%edi
140 \\ movl $60,%%eax // SYS_exit
141 \\ syscall
135 \\ xorl %%ebp,%%ebp
142136 \\
137 \\ popq %%rdi
138 \\ callq *%%r9
139 \\ movl %%eax,%%edi
140 \\ movl $60,%%eax // SYS_exit
141 \\ syscall
143142 );
144143}
145144
146145pub const restore = restore_rt;
147146
148147pub fn restore_rt() callconv(.naked) noreturn {
149 switch (builtin.zig_backend) {
150 .stage2_c => asm volatile (
151 \\ movl %[number], %%eax
152 \\ syscall
153 :
154 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
155 ),
156 else => asm volatile (
157 \\ syscall
158 :
159 : [number] "{rax}" (@backingInt(SYS.rt_sigreturn)),
160 ),
161 }
148 asm volatile (
149 \\ movl %[number], %%eax
150 \\ syscall
151 :
152 : [number] "i" (@backingInt(SYS.rt_sigreturn)),
153 );
162154}
163155
164156pub const time_t = i64;
lib/std/os/linux/xtensa.zig+6-13
......@@ -173,19 +173,12 @@ pub fn clone() callconv(.naked) u32 {
173173pub const restore = restore_rt;
174174
175175pub fn restore_rt() callconv(.naked) noreturn {
176 switch (builtin.zig_backend) {
177 .stage2_c => asm volatile (
178 \\ movi a2, %[number]
179 \\ syscall
180 :
181 : [number] "I" (@backingInt(SYS.rt_sigreturn)),
182 ),
183 else => asm volatile (
184 \\ syscall
185 :
186 : [number] "{a2}" (@backingInt(SYS.rt_sigreturn)),
187 ),
188 }
176 asm volatile (
177 \\ movi a2, %[number]
178 \\ syscall
179 :
180 : [number] "I" (@backingInt(SYS.rt_sigreturn)),
181 );
189182}
190183
191184pub const VDSO = void;
lib/std/pie.zig+42-21
......@@ -83,7 +83,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
8383 \\ add %[ret], pc
8484 \\ b 2f
8585 \\1:
86 \\ .word _DYNAMIC-1b
86 \\ .word _DYNAMIC - 1b
8787 \\2:
8888 : [ret] "=r" (-> [*]const elf.Dyn),
8989 ),
......@@ -97,20 +97,29 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
9797 ),
9898 // The compiler is not required to load the GP register, so do it ourselves.
9999 .alpha => asm volatile (
100 \\ .weak _DYNAMIC
101 \\ .hidden _DYNAMIC
100102 \\ br $29, 1f
101103 \\1:
102104 \\ ldgp $29, 0($29)
103 \\ ldq %[ret], -0x8000($29)
105 \\ ldah %[ret], _DYNAMIC($29) !gprelhigh
106 \\ lda %[ret], _DYNAMIC(%[ret]) !gprellow
104107 : [ret] "=r" (-> [*]const elf.Dyn),
105108 :
106 : .{ .r26 = true, .r29 = true }),
107 // The CSKY ABI requires the gb register to point to the GOT. Additionally, the first
108 // entry in the GOT is defined to hold the address of _DYNAMIC.
109 : .{ .r29 = true }),
109110 .csky => asm volatile (
110 \\ mov %[ret], gb
111 \\ ldw %[ret], %[ret]
111 \\ .weak _DYNAMIC
112 \\ .hidden _DYNAMIC
113 \\ grs %[ret], 1f
114 \\ br 2f
115 \\1:
116 \\ .long _DYNAMIC - 1b
117 \\2:
118 \\ ldw r12, (%[ret], 0)
119 \\ addu %[ret], %[ret], r12
112120 : [ret] "=r" (-> [*]const elf.Dyn),
113 ),
121 :
122 : .{ .r12 = true }),
114123 .hexagon => asm volatile (
115124 \\ .weak _DYNAMIC
116125 \\ .hidden _DYNAMIC
......@@ -143,12 +152,20 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
143152 \\ .hidden _DYNAMIC
144153 \\ lea _DYNAMIC - . - 8, %[ret]
145154 \\ lea (%[ret], %%pc), %[ret]
146 : [ret] "=r" (-> [*]const elf.Dyn),
155 : [ret] "=a" (-> [*]const elf.Dyn),
147156 ),
148157 .microblaze, .microblazeel => asm volatile (
149 \\ lwi %[ret], r20, 0
158 \\ .weak _DYNAMIC
159 \\ .hidden _DYNAMIC
160 \\ mfs %[ret], rpc
161 \\ bri 1f
162 \\ .word _DYNAMIC - . + 8
163 \\1:
164 \\ lwi r18, %[ret], 8
165 \\ add %[ret], %[ret], r18
150166 : [ret] "=r" (-> [*]const elf.Dyn),
151 ),
167 :
168 : .{ .r18 = true }),
152169 .mips, .mipsel => asm volatile (
153170 \\ .weak _DYNAMIC
154171 \\ .hidden _DYNAMIC
......@@ -190,6 +207,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
190207 \\ .weak _DYNAMIC
191208 \\ .hidden _DYNAMIC
192209 \\ l.jal 1f
210 \\ l.nop
193211 \\ .word _DYNAMIC - .
194212 \\1:
195213 \\ l.lwz %[ret], 0(r9)
......@@ -212,11 +230,13 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
212230 .powerpc64, .powerpc64le => asm volatile (
213231 \\ .weak _DYNAMIC
214232 \\ .hidden _DYNAMIC
233 \\ .balign 8
215234 \\ bl 1f
235 \\ nop
216236 \\ .quad _DYNAMIC - .
217237 \\1:
218238 \\ mflr %[ret]
219 \\ ld 4, 0(%[ret])
239 \\ ld 4, 4(%[ret])
220240 \\ add %[ret], 4, %[ret]
221241 : [ret] "=r" (-> [*]const elf.Dyn),
222242 :
......@@ -245,24 +265,25 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
245265 \\ mov.l 1f, %[ret]
246266 \\ add r0, %[ret]
247267 \\ bra 2f
248 \\1:
268 \\ nop
249269 \\ .balign 4
250 \\ .long DYNAMIC - .
270 \\1:
271 \\ .long _DYNAMIC - .
251272 \\2:
252273 : [ret] "=r" (-> [*]const elf.Dyn),
253274 :
254275 : .{ .r0 = true }),
255 // The compiler does not necessarily have any obligation to load the `l7` register (pointing
256 // to the GOT), so do it ourselves just in case.
257276 .sparc, .sparc64 => asm volatile (
258 \\ sethi %%hi(_GLOBAL_OFFSET_TABLE_ - 4), %%l7
277 \\ .weak _DYNAMIC
278 \\ .hidden _DYNAMIC
279 \\ sethi %%pc22(_DYNAMIC - 4), %[ret]
259280 \\ call 1f
260 \\ add %%l7, %%lo(_GLOBAL_OFFSET_TABLE_ + 4), %%l7
281 \\ add %[ret], %%pc10(_DYNAMIC + 4), %[ret]
261282 \\1:
262 \\ add %%l7, %%o7, %[ret]
283 \\ add %[ret], %%o7, %[ret]
263284 : [ret] "=r" (-> [*]const elf.Dyn),
264285 :
265 : .{ .l7 = true }),
286 : .{ .o7 = true }),
266287 .xtensa, .xtensaeb => asm volatile (
267288 \\ .weak _DYNAMIC
268289 \\ .hidden _DYNAMIC
......@@ -274,7 +295,7 @@ inline fn getDynamicSymbol() [*]const elf.Dyn {
274295 \\ .balign 4
275296 \\ .word _DYNAMIC - .
276297 \\1:
277 \\ add a0, a0, 1
298 \\ addi a0, a0, 1
278299 \\ l32i a8, a0, 0
279300 \\ add %[ret], a0, a8
280301 : [ret] "=a" (-> [*]const elf.Dyn),
lib/std/start.zig+26-20
......@@ -247,7 +247,7 @@ fn _start() callconv(.naked) noreturn {
247247 \\ mov $30, $16
248248 \\ ldi $1, -16
249249 \\ and $30, $30, $1
250 \\ jsr $26, %[posixCallMainAndExit]
250 \\ br $31, %[posixCallMainAndExit]
251251 ,
252252 .arc, .arceb =>
253253 // ARC v1 and v2 had a very low stack alignment requirement of 4; v3 increased it to 16.
......@@ -276,14 +276,16 @@ fn _start() callconv(.naked) noreturn {
276276 // `_DYNAMIC` as well.
277277 // r8 = FP
278278 \\ grs t0, 1f
279 \\ 1:
279 \\1:
280280 \\ lrw gb, 1b@GOTPC
281281 \\ addu gb, t0
282282 \\ movi r8, 0
283283 \\ movi lr, 0
284284 \\ mov a0, sp
285 \\ andi sp, sp, -8
286 \\ jmpi %[posixCallMainAndExit]
285 \\ andni sp, sp, 7
286 \\ lrw t1, %[posixCallMainAndExit]@GOTOFF
287 \\ addu t1, gb
288 \\ jmp t1
287289 ,
288290 .hexagon =>
289291 // r29 = SP, r30 = FP, r31 = LR
......@@ -293,7 +295,7 @@ fn _start() callconv(.naked) noreturn {
293295 \\ r29 = and(r29, #-8)
294296 \\ memw(r29 + #-8) = r29
295297 \\ r29 = add(r29, #-8)
296 \\ call %[posixCallMainAndExit]
298 \\ jump %[posixCallMainAndExit]
297299 ,
298300 .kvx =>
299301 \\ make $fp = 0
......@@ -324,15 +326,17 @@ fn _start() callconv(.naked) noreturn {
324326 \\ l.ori r2, r0, 0
325327 \\ l.ori r9, r0, 0
326328 \\ l.ori r3, r1, 0
327 \\ l.andi r1, r1, -4
328 \\ l.jal %[posixCallMainAndExit]
329 \\ l.addi r13, r0, -4
330 \\ l.and r1, r1, r13
331 \\ l.j %[posixCallMainAndExit]
332 \\ l.nop
329333 ,
330334 .riscv32, .riscv32be, .riscv64, .riscv64be =>
331335 \\ li fp, 0
332336 \\ li ra, 0
333337 \\ mv a0, sp
334338 \\ andi sp, sp, -16
335 \\ tail %[posixCallMainAndExit]@plt
339 \\ tail %[posixCallMainAndExit]
336340 ,
337341 .m68k =>
338342 // Note that the - 8 is needed because pc in the jsr instruction points into the middle
......@@ -354,7 +358,7 @@ fn _start() callconv(.naked) noreturn {
354358 \\ or %%r1, %%r0, %%r0
355359 \\ or %%r2, %%r31, %%r0
356360 \\ clr %%r31, %%r31, 4<0>
357 \\ br.n %[posixCallMainAndExit]
361 \\ br %[posixCallMainAndExit]
358362 ,
359363 .microblaze, .microblazeel =>
360364 // r1 = SP, r15 = LR, r19 = FP, r20 = GP
......@@ -364,7 +368,7 @@ fn _start() callconv(.naked) noreturn {
364368 \\ addi r20, r20, _GLOBAL_OFFSET_TABLE_ + 8
365369 \\ ori r5, r1, 0
366370 \\ andi r1, r1, -4
367 \\ brlid r15, %[posixCallMainAndExit]
371 \\ bri %[posixCallMainAndExit]
368372 ,
369373 .mips, .mipsel =>
370374 \\ move $fp, $zero
......@@ -383,7 +387,7 @@ fn _start() callconv(.naked) noreturn {
383387 \\ move $a0, $sp
384388 \\ and $sp, -8
385389 \\ subu $sp, $sp, 16
386 \\ jalr $t9
390 \\ jr $t9
387391 ,
388392 .mips64, .mips64el => switch (builtin.abi) {
389393 .gnuabin32, .muslabin32, .abin32 =>
......@@ -399,9 +403,9 @@ fn _start() callconv(.naked) noreturn {
399403 \\ addu $t9, $t9, $gp
400404 \\ move $ra, $zero
401405 \\ move $a0, $sp
402 \\ and $sp, -8
406 \\ and $sp, -16
403407 \\ subu $sp, $sp, 16
404 \\ jalr $t9
408 \\ jr $t9
405409 ,
406410 else =>
407411 \\ move $fp, $zero
......@@ -422,7 +426,7 @@ fn _start() callconv(.naked) noreturn {
422426 \\ move $a0, $sp
423427 \\ and $sp, -16
424428 \\ dsubu $sp, $sp, 16
425 \\ jalr $t9
429 \\ jr $t9
426430 ,
427431 },
428432 .powerpc, .powerpcle =>
......@@ -434,7 +438,7 @@ fn _start() callconv(.naked) noreturn {
434438 \\ stwu 1, -16(1)
435439 \\ stw 0, 0(1)
436440 \\ li 31, 0
437 \\ mtlr 0
441 \\ mtlr 31
438442 \\ b %[posixCallMainAndExit]
439443 ,
440444 .powerpc64, .powerpc64le =>
......@@ -447,7 +451,7 @@ fn _start() callconv(.naked) noreturn {
447451 \\ li 0, 0
448452 \\ stdu 0, -32(1)
449453 \\ li 31, 0
450 \\ mtlr 0
454 \\ mtlr 31
451455 \\ b %[posixCallMainAndExit]
452456 \\ nop
453457 ,
......@@ -472,12 +476,14 @@ fn _start() callconv(.naked) noreturn {
472476 \\ mov r15, r4
473477 \\ mov #-4, r0
474478 \\ and r0, r15
479 \\ mova 2f, r0
475480 \\ mov.l 2f, r1
476 \\1:
477 \\ bsrf r1
478 \\2:
481 \\ add r0, r1
482 \\ jmp @r1
483 \\ nop
479484 \\ .balign 4
480 \\ .long %[posixCallMainAndExit]@PCREL - (1b + 4 - .)
485 \\1:
486 \\ .long %[posixCallMainAndExit] - .
481487 ,
482488 .sparc =>
483489 // argc is stored after a register window (16 registers * 4 bytes).