aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-11-20 17:40:17 -0800
committerGitHub <noreply@github.com>2020-11-20 17:40:17 -0800
commitbf0cc32aa64002299361a30c5e4b701e99da5dea (patch)
tree3f91cea946e06c9be54d471beed9127064ecf80a /lib/std
parent8cf319d2064c6ef4d2bd9757104561014224a731 (diff)
parent2193bbfd938ef562abdf1c9f1aced9acb24009bd (diff)
downloadzig-bf0cc32aa64002299361a30c5e4b701e99da5dea.tar.gz
zig-bf0cc32aa64002299361a30c5e4b701e99da5dea.zip
Merge pull request #7165 from LemonBoy/ppc64final
Make the PPC64 port usable
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/os/linux.zig2
-rw-r--r--lib/std/special/c.zig89
-rw-r--r--lib/std/target.zig4
3 files changed, 54 insertions, 41 deletions
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index d0bc80c645..5299c995a0 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -1098,6 +1098,8 @@ pub fn lstat(pathname: [*:0]const u8, statbuf: *kernel_stat) usize {
pub fn fstatat(dirfd: i32, path: [*:0]const u8, stat_buf: *kernel_stat, flags: u32) usize {
if (@hasField(SYS, "fstatat64")) {
return syscall4(.fstatat64, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
+ } else if (@hasField(SYS, "newfstatat")) {
+ return syscall4(.newfstatat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
} else {
return syscall4(.fstatat, @bitCast(usize, @as(isize, dirfd)), @ptrToInt(path), @ptrToInt(stat_buf), flags);
}
diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig
index 55548e399e..449b70d6b0 100644
--- a/lib/std/special/c.zig
+++ b/lib/std/special/c.zig
@@ -386,6 +386,11 @@ fn clone() callconv(.Naked) void {
);
},
.arm => {
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
+ // r0, r1, r2, r3, +0, +4, +8
+
+ // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+ // r7 r0, r1, r2, r3, r4
asm volatile (
\\ stmfd sp!,{r4,r5,r6,r7}
\\ mov r7,#120
@@ -445,6 +450,11 @@ fn clone() callconv(.Naked) void {
);
},
.mips, .mipsel => {
+ // __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, -8
@@ -465,12 +475,14 @@ fn clone() callconv(.Naked) void {
\\ addu $sp, $sp, 16
\\ jr $ra
\\ subu $2, $0, $2
- \\1: beq $2, $0, 1f
+ \\1:
+ \\ beq $2, $0, 1f
\\ nop
\\ addu $sp, $sp, 16
\\ jr $ra
\\ nop
- \\1: lw $25, 0($sp)
+ \\1:
+ \\ lw $25, 0($sp)
\\ lw $4, 4($sp)
\\ jalr $25
\\ nop
@@ -480,51 +492,48 @@ fn clone() callconv(.Naked) void {
);
},
.powerpc64, .powerpc64le => {
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
+ // 3, 4, 5, 6, 7, 8, 9
+
+ // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+ // 0 3, 4, 5, 6, 7
asm volatile (
- \\ # store non-volatile regs r30, r31 on stack in order to put our
- \\ # start func and its arg there
- \\ stwu 30, -16(1)
- \\ stw 31, 4(1)
- \\ # save r3 (func) into r30, and r6(arg) into r31
- \\ mr 30, 3
- \\ mr 31, 6
\\ # create initial stack frame for new thread
- \\ clrrwi 4, 4, 4
- \\ li 0, 0
- \\ stwu 0, -16(4)
- \\ #move c into first arg
- \\ mr 3, 5
- \\ mr 5, 7
- \\ mr 6, 8
- \\ mr 7, 9
- \\ # move syscall number into r0
- \\ li 0, 120
+ \\ clrrdi 4, 4, 4
+ \\ li 0, 0
+ \\ stdu 0,-32(4)
+ \\
+ \\ # save fn and arg to child stack
+ \\ std 3, 8(4)
+ \\ std 6, 16(4)
+ \\
+ \\ # shuffle args into correct registers and call SYS_clone
+ \\ mr 3, 5
+ \\ #mr 4, 4
+ \\ mr 5, 7
+ \\ mr 6, 8
+ \\ mr 7, 9
+ \\ li 0, 120 # SYS_clone = 120
\\ sc
- \\ # check for syscall error
- \\ bns+ 1f # jump to label 1 if no summary overflow.
- \\ #else
- \\ neg 3, 3 #negate the result (errno)
+ \\
+ \\ # if error, negate return (errno)
+ \\ bns+ 1f
+ \\ neg 3, 3
+ \\
\\1:
- \\ # compare sc result with 0
+ \\ # if we're the parent, return
\\ cmpwi cr7, 3, 0
- \\ # if not 0, jump to end
- \\ bne cr7, 2f
- \\ #else: we're the child
- \\ #call funcptr: move arg (d) into r3
- \\ mr 3, 31
- \\ #move r30 (funcptr) into CTR reg
- \\ mtctr 30
- \\ # call CTR reg
+ \\ bnelr cr7
+ \\
+ \\ # we're the child. call fn(arg)
+ \\ ld 3, 16(1)
+ \\ ld 12, 8(1)
+ \\ mtctr 12
\\ bctrl
- \\ # mov SYS_exit into r0 (the exit param is already in r3)
- \\ li 0, 1
+ \\
+ \\ # call SYS_exit. exit code is already in r3 from fn return value
+ \\ li 0, 1 # SYS_exit = 1
\\ sc
- \\2:
- \\ # restore stack
- \\ lwz 30, 0(1)
- \\ lwz 31, 4(1)
- \\ addi 1, 1, 16
- \\ blr
);
},
.sparcv9 => {
diff --git a/lib/std/target.zig b/lib/std/target.zig
index 56390fbce3..9a006a95fa 100644
--- a/lib/std/target.zig
+++ b/lib/std/target.zig
@@ -1123,7 +1123,9 @@ pub const Target = struct {
.mips, .mipsel => &mips.cpu.mips32,
.mips64, .mips64el => &mips.cpu.mips64,
.msp430 => &msp430.cpu.generic,
- .powerpc, .powerpc64, .powerpc64le => &powerpc.cpu.generic,
+ .powerpc => &powerpc.cpu.ppc32,
+ .powerpc64 => &powerpc.cpu.ppc64,
+ .powerpc64le => &powerpc.cpu.ppc64le,
.amdgcn => &amdgpu.cpu.generic,
.riscv32 => &riscv.cpu.generic_rv32,
.riscv64 => &riscv.cpu.generic_rv64,