aboutsummaryrefslogtreecommitdiff
path: root/lib/std/os/linux/mips64.zig
diff options
context:
space:
mode:
authorAlex Rønne Petersen <alex@alexrp.com>2024-08-13 01:09:52 +0200
committerGitHub <noreply@github.com>2024-08-12 16:09:52 -0700
commitb00f586c3d55ea3a1a81410534acef2fee9fa827 (patch)
tree7d13cc32e39ba56338595c8ec5aaabb2697ae413 /lib/std/os/linux/mips64.zig
parentd6f997259487fc01b1aa6d24bdc7b960c4aaec46 (diff)
downloadzig-b00f586c3d55ea3a1a81410534acef2fee9fa827.tar.gz
zig-b00f586c3d55ea3a1a81410534acef2fee9fa827.zip
`std.os.linux`: Add clone() implementation for mips64. (#21038)
Only for n64; no handling for n32 yet. Also remove pointless comment about o32 in mips64 code.
Diffstat (limited to 'lib/std/os/linux/mips64.zig')
-rw-r--r--lib/std/os/linux/mips64.zig45
1 files changed, 38 insertions, 7 deletions
diff --git a/lib/std/os/linux/mips64.zig b/lib/std/os/linux/mips64.zig
index 5089ba6fd3..579d41ca75 100644
--- a/lib/std/os/linux/mips64.zig
+++ b/lib/std/os/linux/mips64.zig
@@ -118,9 +118,6 @@ pub fn syscall5(number: SYS, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
);
}
-// NOTE: The o32 calling convention requires the callee to reserve 16 bytes for
-// the first four arguments even though they're passed in $a0-$a3.
-
pub fn syscall6(
number: SYS,
arg1: usize,
@@ -175,10 +172,44 @@ pub fn syscall7(
);
}
-const CloneFn = *const fn (arg: usize) callconv(.C) u8;
-
-/// This matches the libc clone function.
-pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize;
+pub fn clone() callconv(.Naked) usize {
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
+ // 3, 4, 5, 6, 7, 8, 9
+ //
+ // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+ // 2 4, 5, 6, 7, 8
+ asm volatile (
+ \\ # Save function pointer and argument pointer on new thread stack
+ \\ and $5, $5, -16
+ \\ dsubu $5, $5, 16
+ \\ sd $4, 0($5)
+ \\ sd $7, 8($5)
+ \\ # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
+ \\ move $4, $6
+ \\ move $6, $8
+ \\ move $7, $9
+ \\ move $8, $10
+ \\ li $2, 5055 # SYS_clone
+ \\ syscall
+ \\ beq $7, $0, 1f
+ \\ nop
+ \\ jr $ra
+ \\ dsubu $2, $0, $2
+ \\1:
+ \\ beq $2, $0, 1f
+ \\ nop
+ \\ jr $ra
+ \\ nop
+ \\1:
+ \\ ld $25, 0($sp)
+ \\ ld $4, 8($sp)
+ \\ jalr $25
+ \\ nop
+ \\ move $4, $2
+ \\ li $2, 5058 # SYS_exit
+ \\ syscall
+ );
+}
pub fn restore() callconv(.Naked) noreturn {
asm volatile (