aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-11-29 10:33:43 -0800
committerGitHub <noreply@github.com>2020-11-29 10:33:43 -0800
commite701ac1a51e6f1d39b698b9b258c349b902dd848 (patch)
tree5260c0b1787f3aac72858164f7e50c81e40fb025 /lib/std
parent89ee4b86210dd3292f39e8ab405834a11865833c (diff)
parentf10bff9ffb452eaf22af8dd85412653ac8bd1081 (diff)
downloadzig-e701ac1a51e6f1d39b698b9b258c349b902dd848.tar.gz
zig-e701ac1a51e6f1d39b698b9b258c349b902dd848.zip
Merge pull request #7237 from koachan/sparc64-longdouble_fork
Add "long double" mapping and implement fork() on Linux/sparc64
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/os/linux.zig4
-rw-r--r--lib/std/os/linux/sparc64.zig23
2 files changed, 26 insertions, 1 deletions
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index 56e9d45a08..dbb9225aa2 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -112,7 +112,9 @@ pub fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:
}
pub fn fork() usize {
- if (@hasField(SYS, "fork")) {
+ if (comptime builtin.arch.isSPARC()) {
+ return syscall_fork();
+ } else if (@hasField(SYS, "fork")) {
return syscall0(.fork);
} else {
return syscall2(.clone, SIGCHLD, 0);
diff --git a/lib/std/os/linux/sparc64.zig b/lib/std/os/linux/sparc64.zig
index eefa4d60fd..902940071e 100644
--- a/lib/std/os/linux/sparc64.zig
+++ b/lib/std/os/linux/sparc64.zig
@@ -21,6 +21,29 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
);
}
+pub fn syscall_fork() usize {
+ // Linux/sparc64 fork() returns two values in %o0 and %o1:
+ // - On the parent's side, %o0 is the child's PID and %o1 is 0.
+ // - On the child's side, %o0 is the parent's PID and %o1 is 1.
+ // We need to clear the child's %o0 so that the return values
+ // conform to the libc convention.
+ return asm volatile (
+ \\ t 0x6d
+ \\ bcc,pt %%xcc, 1f
+ \\ nop
+ \\ ba 2f
+ \\ neg %%o0
+ \\ 1:
+ \\ # Clear the child's %%o0
+ \\ dec %%o1
+ \\ and %%o1, %%o0, %%o0
+ \\ 2:
+ : [ret] "={o0}" (-> usize)
+ : [number] "{g1}" (@enumToInt(SYS.fork))
+ : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
+ );
+}
+
pub fn syscall0(number: SYS) usize {
return asm volatile (
\\ t 0x6d