Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

powerpc64le-linux-gnu #24

Open
pingiun opened this issue Apr 14, 2020 · 6 comments
Open

powerpc64le-linux-gnu #24

pingiun opened this issue Apr 14, 2020 · 6 comments

Comments

@pingiun
Copy link
Contributor

pingiun commented Apr 14, 2020

On a debian powerpc64le virtual machine, Zig release 0.6.0:

Scanning dependencies of target zig0
[ 98%] Building CXX object CMakeFiles/zig0.dir/src/main.cpp.o
[ 98%] Building CXX object CMakeFiles/zig0.dir/src/stage2.cpp.o
[ 99%] Linking CXX executable zig0
[ 99%] Built target zig0
Scanning dependencies of target zig_build_libstage2
./lib/std/fs/file.zig:30:24: error: container 'std.os' has no member called 'mode_t'
    pub const Mode = os.mode_t;
                       ^
./lib/std/fs.zig:1343:19: note: referenced here
        mode: File.Mode = File.default_mode,
                  ^
./lib/std/io/buffered_atomic_file.zig:29:40: note: referenced here
        self.atomic_file = try fs.cwd().atomicFile(dest_path, .{});
                                       ^
./src-self-hosted/stage2.zig:373:21: note: referenced here
        const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
                    ^
./lib/std/time.zig:146:23: error: container 'std.os' has no member called 'timespec'
            var ts: os.timespec = undefined;
                      ^
./lib/std/fs/file.zig:208:18: error: container 'std.os' has no member called 'ino_t'
        inode: os.ino_t,
                 ^
./lib/std/fs/file.zig:226:38: note: referenced here
    pub fn stat(self: File) StatError!Stat {
                                     ^
./lib/std/fs/file.zig:186:25: note: referenced here
        return (try self.stat()).size;
                        ^
./lib/std/event/loop.zig:1244:25: error: container 'std.os' has no member called 'mode_t'
                mode: os.mode_t,
                        ^
./lib/std/event/loop.zig:1182:13: note: while checking this field
            open: Open,
            ^
./lib/std/event/loop.zig:1165:9: note: while checking this field
        msg: Msg,
        ^
./lib/std/linked_list.zig:200:13: note: while checking this field
            data: T,
            ^
./lib/std/atomic/queue.zig:12:9: note: while checking this field
        head: ?*Node,
        ^
./lib/std/event/loop.zig:1160:9: note: while checking this field
        fs_queue: std.atomic.Queue(Request),
        ^
./lib/std/event/loop.zig:16:5: note: while checking this field
    os_data: OsData,
    ^
./lib/std/event/loop.zig:96:25: note: referenced here
    pub const instance: ?*Loop = if (@hasDecl(root, "event_loop")) root.event_loop else default_instance;
                        ^
./lib/std/os.zig:614:41: note: referenced here
            EAGAIN => if (std.event.Loop.instance) |loop| {
                                        ^
./lib/std/fs.zig:609:54: error: container 'std.os' has no member called 'O_CLOEXEC'
        const os_flags = lock_flag | O_LARGEFILE | os.O_CLOEXEC | if (flags.write and flags.read)
                                                     ^
./lib/std/fs.zig:835:53: error: container 'std.os' has no member called 'O_DIRECTORY'
            return self.openDirFlagsZ(sub_path_c, os.O_DIRECTORY | os.O_RDONLY | os.O_CLOEXEC | O_PATH);
                                                    ^
./lib/std/reset_event.zig:252:26: error: container 'std.os.linux' has no member called 'timespec'
            var ts: linux.timespec = undefined;
                         ^
./lib/std/os/linux.zig:138:12: error: use of undeclared identifier 'syscall3'
    return syscall3(
           ^
./lib/std/time.zig:183:19: error: container 'std.os' has no member called 'timespec'
        var ts: os.timespec = undefined;
                  ^
./lib/std/os.zig:912:74: error: use of undeclared identifier 'mode_t'
pub fn openatZ(dir_fd: fd_t, file_path: [*:0]const u8, flags: u32, mode: mode_t) OpenError!fd_t {
                                                                         ^
./lib/std/fs.zig:857:15: note: referenced here
            os.openatZ(self.fd, sub_path_c, flags, 0);
              ^
make[2]: *** [CMakeFiles/zig_build_libstage2.dir/build.make:57: CMakeFiles/zig_build_libstage2] Error 1
make[1]: *** [CMakeFiles/Makefile2:304: CMakeFiles/zig_build_libstage2.dir/all] Error 2
make: *** [Makefile:130: all] Error 2

Behavior tests:

jelle@summit:~/zig-bootstrap-0.6.0/zig$ ./zig0 test test/stage1/behavior.zig
./test/stage1/behavior/bugs/920.zig:23:21: error: division by zero
    tables.x[0] = v / f(r);
                    ^
./test/stage1/behavior/bugs/920.zig:54:27: note: called from here
    break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case);
                          ^
./test/stage1/behavior/bugs/920.zig:52:25: note: called from here
const NormalDist = blk: {
                        ^
./test/stage1/behavior/bugs/920.zig:54:27: note: referenced here
    break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case);
                          ^
./test/stage1/behavior/bugs/920.zig:63:48: note: referenced here
        std.testing.expect(NormalDist1.f[i] == NormalDist.f[i]);
                                               ^
./test/stage1/behavior/cast.zig:283:12: error: integer value '18446744073709551615' cannot be stored in type 'u8'
    expect(@floatToInt(I, f) == i);
           ^
./test/stage1/behavior/cast.zig:273:21: note: called from here
    expectFloatToInt(f16, 255.1, u8, 255);
                    ^
./test/stage1/behavior/cast.zig:265:29: note: called from here
    comptime testFloatToInts();
                            ^
./test/stage1/behavior/cast.zig:263:20: note: called from here
test "@floatToInt" {
                   ^
./test/stage1/behavior/cast.zig:273:21: note: referenced here
    expectFloatToInt(f16, 255.1, u8, 255);
                    ^
./test/stage1/behavior/cast.zig:265:29: note: referenced here
    comptime testFloatToInts();
                            ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/floatop.zig:23:15: note: called from here
        expect(math.approxEq(f32, @sqrt(b), 1.0488088481701516, epsilon));
              ^
./test/stage1/behavior/floatop.zig:10:22: note: called from here
    comptime testSqrt();
                     ^
./test/stage1/behavior/floatop.zig:9:14: note: called from here
test "@sqrt" {
             ^
./test/stage1/behavior/floatop.zig:23:15: note: referenced here
        expect(math.approxEq(f32, @sqrt(b), 1.0488088481701516, epsilon));
              ^
./test/stage1/behavior/floatop.zig:10:22: note: referenced here
    comptime testSqrt();
                     ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/floatop.zig:151:15: note: called from here
        expect(math.approxEq(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
              ^
./test/stage1/behavior/floatop.zig:129:21: note: called from here
    comptime testExp();
                    ^
./test/stage1/behavior/floatop.zig:128:13: note: called from here
test "@exp" {
            ^
./test/stage1/behavior/floatop.zig:151:15: note: referenced here
        expect(math.approxEq(f32, @exp(@as(f32, 1.1)), result[0], epsilon));
              ^
./test/stage1/behavior/floatop.zig:129:21: note: referenced here
    comptime testExp();
                    ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/floatop.zig:181:15: note: called from here
        expect(math.approxEq(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
              ^
./test/stage1/behavior/floatop.zig:159:22: note: called from here
    comptime testExp2();
                     ^
./test/stage1/behavior/floatop.zig:158:14: note: called from here
test "@exp2" {
             ^
./test/stage1/behavior/floatop.zig:181:15: note: referenced here
        expect(math.approxEq(f32, @exp2(@as(f32, 1.1)), result[0], epsilon));
              ^
./test/stage1/behavior/floatop.zig:159:22: note: referenced here
    comptime testExp2();
                     ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/floatop.zig:200:15: note: called from here
        expect(math.approxEq(f16, @log(a), 1, epsilon));
              ^
./test/stage1/behavior/floatop.zig:191:21: note: called from here
    comptime testLog();
                    ^
./test/stage1/behavior/floatop.zig:188:13: note: called from here
test "@log" {
            ^
./test/stage1/behavior/floatop.zig:200:15: note: referenced here
        expect(math.approxEq(f16, @log(a), 1, epsilon));
              ^
./test/stage1/behavior/floatop.zig:191:21: note: referenced here
    comptime testLog();
                    ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/floatop.zig:326:15: note: called from here
        expect(@floor(a) == 2);
              ^
./test/stage1/behavior/floatop.zig:317:23: note: called from here
    comptime testFloor();
                      ^
./test/stage1/behavior/floatop.zig:316:15: note: called from here
test "@floor" {
              ^
./test/stage1/behavior/floatop.zig:326:15: note: referenced here
        expect(@floor(a) == 2);
              ^
./test/stage1/behavior/floatop.zig:317:23: note: referenced here
    comptime testFloor();
                      ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/floatop.zig:356:15: note: called from here
        expect(@ceil(a) == 3);
              ^
./test/stage1/behavior/floatop.zig:347:22: note: called from here
    comptime testCeil();
                     ^
./test/stage1/behavior/floatop.zig:346:14: note: called from here
test "@ceil" {
             ^
./test/stage1/behavior/floatop.zig:356:15: note: referenced here
        expect(@ceil(a) == 3);
              ^
./test/stage1/behavior/floatop.zig:347:22: note: referenced here
    comptime testCeil();
                     ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/floatop.zig:386:15: note: called from here
        expect(@trunc(a) == 2);
              ^
./test/stage1/behavior/floatop.zig:377:23: note: called from here
    comptime testTrunc();
                      ^
./test/stage1/behavior/floatop.zig:376:15: note: called from here
test "@trunc" {
              ^
./test/stage1/behavior/floatop.zig:386:15: note: referenced here
        expect(@trunc(a) == 2);
              ^
./test/stage1/behavior/floatop.zig:377:23: note: referenced here
    comptime testTrunc();
                      ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/floatop.zig:429:19: note: called from here
            expect(x < 2);
                  ^
./test/stage1/behavior/floatop.zig:408:34: note: called from here
    comptime testFloatComparisons();
                                 ^
./test/stage1/behavior/floatop.zig:406:35: note: called from here
test "floating point comparisons" {
                                  ^
./test/stage1/behavior/floatop.zig:429:19: note: referenced here
            expect(x < 2);
                  ^
./test/stage1/behavior/floatop.zig:408:34: note: referenced here
    comptime testFloatComparisons();
                                 ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/math.zig:15:11: note: called from here
    expect(div(f16, 1.0, 2.0) == 0.5);
          ^
./test/stage1/behavior/math.zig:11:26: note: called from here
    comptime testDivision();
                         ^
./test/stage1/behavior/math.zig:9:17: note: called from here
test "division" {
                ^
./test/stage1/behavior/math.zig:15:11: note: referenced here
    expect(div(f16, 1.0, 2.0) == 0.5);
          ^
./test/stage1/behavior/math.zig:11:26: note: referenced here
    comptime testDivision();
                         ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/math.zig:310:20: note: called from here
    comptime expect(0x1.0 == 1.0);
                   ^
./test/stage1/behavior/math.zig:309:34: note: called from here
test "hex float literal parsing" {
                                 ^
./test/stage1/behavior/math.zig:310:20: note: referenced here
    comptime expect(0x1.0 == 1.0);
                   ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/math.zig:335:23: note: called from here
                expect(@bitCast(u128, f) == 0x40042eab345678439abcdefea5678234);
                      ^
./test/stage1/behavior/math.zig:407:25: note: called from here
    comptime S.doTheTest();
                        ^
./test/stage1/behavior/math.zig:320:48: note: called from here
test "quad hex float literal parsing accurate" {
                                               ^
./test/stage1/behavior/math.zig:335:23: note: referenced here
                expect(@bitCast(u128, f) == 0x40042eab345678439abcdefea5678234);
                      ^
./test/stage1/behavior/math.zig:407:25: note: referenced here
    comptime S.doTheTest();
                        ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/math.zig:587:11: note: called from here
    expect(make_f128(1.0) > 0.9);
          ^
./test/stage1/behavior/math.zig:576:23: note: called from here
    comptime test_f128();
                      ^
./test/stage1/behavior/math.zig:574:13: note: called from here
test "f128" {
            ^
./test/stage1/behavior/math.zig:587:11: note: referenced here
    expect(make_f128(1.0) > 0.9);
          ^
./test/stage1/behavior/math.zig:576:23: note: referenced here
    comptime test_f128();
                      ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/math.zig:678:11: note: called from here
    expect(nan1 != nan2);
          ^
./test/stage1/behavior/math.zig:672:26: note: called from here
    comptime testNanEqNan(f128);
                         ^
./test/stage1/behavior/math.zig:664:23: note: called from here
test "NaN comparison" {
                      ^
./test/stage1/behavior/math.zig:678:11: note: referenced here
    expect(nan1 != nan2);
          ^
./test/stage1/behavior/math.zig:672:26: note: referenced here
    comptime testNanEqNan(f128);
                         ^
./lib/std/testing.zig:192:14: error: encountered @panic at compile-time
    if (!ok) @panic("test failure");
             ^
./test/stage1/behavior/muladd.zig:13:15: note: called from here
        expect(@mulAdd(f16, a, b, c) == 20);
              ^
./test/stage1/behavior/muladd.zig:4:24: note: called from here
    comptime testMulAdd();
                       ^
./test/stage1/behavior/muladd.zig:3:16: note: called from here
test "@mulAdd" {
               ^
./test/stage1/behavior/muladd.zig:13:15: note: referenced here
        expect(@mulAdd(f16, a, b, c) == 20);
              ^
./test/stage1/behavior/muladd.zig:4:24: note: referenced here
    comptime testMulAdd();
                       ^
./lib/std/start.zig:119:17: error: unsupported arch
        else => @compileError("unsupported arch"),
                ^
./lib/std/event/loop.zig:1244:25: error: container 'std.os' has no member called 'mode_t'
                mode: os.mode_t,
                        ^
./lib/std/event/loop.zig:1182:13: note: while checking this field
            open: Open,
            ^
./lib/std/event/loop.zig:1165:9: note: while checking this field
        msg: Msg,
        ^
./lib/std/linked_list.zig:200:13: note: while checking this field
            data: T,
            ^
./lib/std/atomic/queue.zig:12:9: note: while checking this field
        head: ?*Node,
        ^
./lib/std/event/loop.zig:1160:9: note: while checking this field
        fs_queue: std.atomic.Queue(Request),
        ^
./lib/std/event/loop.zig:16:5: note: while checking this field
    os_data: OsData,
    ^
./lib/std/event/loop.zig:96:25: note: referenced here
    pub const instance: ?*Loop = if (@hasDecl(root, "event_loop")) root.event_loop else default_instance;
                        ^
./lib/std/os.zig:614:41: note: referenced here
            EAGAIN => if (std.event.Loop.instance) |loop| {
                                        ^
./lib/std/fs/file.zig:208:18: error: container 'std.os' has no member called 'ino_t'
        inode: os.ino_t,
                 ^
./lib/std/fs/file.zig:226:38: note: referenced here
    pub fn stat(self: File) StatError!Stat {
                                     ^
./lib/std/fs/file.zig:186:25: note: referenced here
        return (try self.stat()).size;
                        ^
./lib/std/reset_event.zig:252:26: error: container 'std.os.linux' has no member called 'timespec'
            var ts: linux.timespec = undefined;
                         ^
./lib/std/os/linux.zig:789:60: error: use of undeclared identifier 'restore_rt'
    const restorer_fn = if ((act.flags & SA_SIGINFO) != 0) restore_rt else restore;
                                                           ^
./lib/std/os/linux.zig:390:12: error: use of undeclared identifier 'syscall3'
    return syscall3(.write, @bitCast(usize, @as(isize, fd)), @ptrToInt(buf), count);
           ^
./lib/std/os/linux.zig:781:12: error: use of undeclared identifier 'syscall4'
    return syscall4(.rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG / 8);
           ^
./lib/std/os/linux.zig:777:43: error: use of undeclared identifier 'syscall0'
    return @bitCast(pid_t, @truncate(u32, syscall0(.gettid)));
                                          ^
./lib/std/os/linux.zig:568:12: error: use of undeclared identifier 'syscall2'
    return syscall2(.tkill, @bitCast(usize, @as(isize, tid)), @bitCast(usize, @as(isize, sig)));
           ^
./lib/std/os/linux.zig:555:9: error: use of undeclared identifier 'syscall1'
    _ = syscall1(.exit_group, @bitCast(usize, @as(isize, status)));
        ^
./lib/std/fs.zig:609:54: error: container 'std.os' has no member called 'O_CLOEXEC'
        const os_flags = lock_flag | O_LARGEFILE | os.O_CLOEXEC | if (flags.write and flags.read)
                                                     ^
./lib/std/os/linux.zig:195:19: error: use of undeclared identifier 'SYS'
    if (@hasField(SYS, "mmap2")) {
                  ^
@pingiun pingiun changed the title powerpc64le-linux-glibc powerpc64le-linux-gnu Apr 14, 2020
@andrewrk
Copy link
Member

The good news here is that the next step is the fun part: making the zig standard library support powerpc64le-linux

@wilsonk
Copy link

wilsonk commented Apr 14, 2020

Here is an incomplete diff for ppc64le. I had access to a decent POWER machine for a bit and tried to get this working. I lost access to the machine and my VM is too painfully slow to continue on this. Hopefully someone else can use this as a base. There was still one error when trying to build zig with this patch (and the missing files mentioned below). Zig0 would build and was usable for small examples but it couldn't quite build a full zig.

P.S. I forgot to save the os.zig files to go with this (ie. lib/std/os/linux/powerpc64le.zig and lib/std/os/bits/linux/powerpc64le.zig) but they should be pretty easy to recreate from the musl ppc64le sources.

diff --git a/lib/std/os/bits/linux.zig b/lib/std/os/bits/linux.zig
index a6d010e26..a854552b6 100644
--- a/lib/std/os/bits/linux.zig
+++ b/lib/std/os/bits/linux.zig
@@ -15,6 +15,7 @@ pub usingnamespace switch (builtin.arch) {
     .arm => @import("linux/arm-eabi.zig"),
     .riscv64 => @import("linux/riscv64.zig"),
     .mipsel => @import("linux/mipsel.zig"),
+    .powerpc64le => @import("linux/powerpc64le.zig"),
     else => struct {},
 };
 
@@ -1026,12 +1027,13 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
 
 pub const MINSIGSTKSZ = switch (builtin.arch) {
     .i386, .x86_64, .arm, .mipsel => 2048,
+    .powerpc64le => 4096,
     .aarch64 => 5120,
     else => @compileError("MINSIGSTKSZ not defined for this architecture"),
 };
 pub const SIGSTKSZ = switch (builtin.arch) {
     .i386, .x86_64, .arm, .mipsel => 8192,
-    .aarch64 => 16384,
+    .aarch64, .powerpc64le => 16384,
     else => @compileError("SIGSTKSZ not defined for this architecture"),
 };
 
diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig
index 51649941c..67c4daafd 100644
--- a/lib/std/os/linux.zig
+++ b/lib/std/os/linux.zig
@@ -20,6 +20,7 @@ pub usingnamespace switch (builtin.arch) {
     .arm => @import("linux/arm-eabi.zig"),
     .riscv64 => @import("linux/riscv64.zig"),
     .mipsel => @import("linux/mipsel.zig"),
+    .powerpc64le => @import("linux/powerpc64le.zig"),
     else => struct {},
 };
 pub usingnamespace @import("bits.zig");
diff --git a/lib/std/os/linux/tls.zig b/lib/std/os/linux/tls.zig
index efb1e5fe0..9c13d1282 100644
--- a/lib/std/os/linux/tls.zig
+++ b/lib/std/os/linux/tls.zig
@@ -47,7 +47,7 @@ const TLSVariant = enum {
 };
 
 const tls_variant = switch (builtin.arch) {
-    .arm, .armeb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mipsel => TLSVariant.VariantI,
+    .arm, .armeb, .aarch64, .aarch64_be, .riscv32, .riscv64, .mipsel, .powerpc64le => TLSVariant.Va
riantI,
     .x86_64, .i386 => TLSVariant.VariantII,
     else => @compileError("undefined tls_variant for this architecture"),
 };
@@ -83,12 +83,12 @@ comptime {
 // make the generated code more efficient
 
 const tls_tp_offset = switch (builtin.arch) {
-    .mipsel => 0x7000,
+    .mipsel, .powerpc64le => 0x7000,
     else => 0,
 };
 
 const tls_dtv_offset = switch (builtin.arch) {
-    .mipsel => 0x8000,
+    .mipsel, .powerpc64le => 0x8000,
     .riscv32, .riscv64 => 0x800,
     else => 0,
 };
@@ -167,6 +167,19 @@ pub fn setThreadPointer(addr: usize) void {
             const rc = std.os.linux.syscall1(std.os.linux.SYS_set_thread_area, addr);
             assert(rc == 0);
         },
+        .powerpc64le => {
+            asm volatile (
+// This small snippet doesn't seem to be necessary? Just the last three lines? Not totally sure.
+//            \\ stw 3, -12(1)
+//            \\ addi 3, 1, -12
+//            \\ mr 2,3
+//            \\ mr 13,3
+//            \\ li 3,0
+//            \\ blr
+            \\ mr 13, %[addr]
+            :
+            : [addr] "r" (addr)
+            );
+        },
         else => @compileError("Unsupported architecture"),
     }
 }
diff --git a/lib/std/special/c.zig b/lib/std/special/c.zig
index 0895b1e6f..0c1e55ebc 100644
--- a/lib/std/special/c.zig
+++ b/lib/std/special/c.zig
@@ -391,10 +391,80 @@ nakedcc fn clone() void {
                 \\  syscall
             );
         },
+        .powerpc64le => {
+            asm volatile (
+            \\  clrrdi  4,4,4
+            \\  li      0,0
+            \\  stdu    0,-32(4)
+            \\  std     3,8(4)
+            \\  std     6,16(4)
+            \\  mr      3,5
+            \\  mr      4,4
+            \\  mr      5,7
+            \\  mr      6,8
+            \\  mr      7,9
+            \\  li      0,120
+            \\  sc
+            \\  bns+    1f
+            \\  neg     3,3
+            \\1:
+            \\  cmpwi   cr7,3,0
+            \\  bnelr   cr7
+            \\  ld      3,16(1)
+            \\  ld      12, 8(1)
+            \\  mtctr   12
+            \\  bctrl
+            \\  li      0,1
+            \\  sc
+            );
+        },
         else => @compileError("Implement clone() for this arch."),
     }
 }
 
+// This is the valgrind implementation, which seems a little more
+// robust. I am not totally sure it is compatible with musl however! Test??
+    //            \\  stdu        1,-64(1)
+    //            \\  std         29,40(1)
+    //            \\  std         30,48(1)
+    //            \\  std         31,56(1)
+    //            \\  mr          30,3
+    //            \\  mr          31,6
+    //            \\  rldicr      4,4,0,59
+    //            \\  li          0,0
+    //            \\  stdu        0,-32(4)
+    //            \\  mr          29,4
+    //            \\  li          0,120
+    //            \\  mr          3,5
+    //            \\  mr          5,8
+    //            \\  mr          6,13
+    //            \\  mr          7,7
+    //            \\  mr          8,8
+    //            \\  mr          9,9
+    //            \\  sc
+    //            \\  mfcr        4
+    //            \\  sldi        4,4,32
+    //            \\  sldi        3,3,32
+    //            \\  sldi        3,3,32
+    //            \\  or          3,3,4
+    //            \\  cmpwi       3,0
+    //            \\  bne         1f
+    //            \\  mr          1,29
+    //            \\  ld          30,0(30)
+    //            \\  mtctr       30
+    //            \\  mr          3,31
+    //            \\  bctrl
+    //            \\  li          0,1
+    //            \\  sc
+    //            \\  .long 0
+    //            \\1:
+    //            \\  ld          29,40(1)
+    //            \\  ld          30,48(1)
+    //            \\  ld          31,56(1)
+    //            \\  addi        1,1,64
+    //            \\  blr
+
+
 const math = std.math;
 
 export fn fmodf(x: f32, y: f32) f32 {
diff --git a/lib/std/start.zig b/lib/std/start.zig
index 3c4644994..6a90f91e0 100644
--- a/lib/std/start.zig
+++ b/lib/std/start.zig
@@ -120,6 +120,11 @@ nakedcc fn _start() noreturn {
                 : [argc] "=r" (-> [*]usize)
             );
         },
+        .powerpc64le => {
+            starting_stack_ptr = asm volatile ("mr %[argc], 1"
+                : [argc] "=r" (-> [*]usize)
+            );
+        },
         else => @compileError("unsupported arch"),
     }
     // If LLVM inlines stack variables into _start, they will overwrite
@@ -143,6 +148,10 @@ fn posixCallMainAndExit() noreturn {
     if (builtin.os == builtin.Os.freebsd) {
         @setAlignStack(16);
     }
+    switch (builtin.arch) {
+        .powerpc64le => @setAlignStack(16),
+        else => {},
+    }
     const argc = starting_stack_ptr[0];
     const argv = @ptrCast([*][*:0]u8, starting_stack_ptr + 1);
 
diff --git a/src/os.cpp b/src/os.cpp
index f6a0b4fbd..e652a6787 100644
--- a/src/os.cpp
+++ b/src/os.cpp
@@ -2128,6 +2128,9 @@ const char *possible_ld_names[] = {
     "ld-musl-armhf.so.1",
     "ld-linux.so.3",
     "ld-musl-arm.so.1",
+#elif defined(ZIG_ARCH_PPC64LE)
+    "ld-linux-ppc64le.so.2",
+    "ld-musl-ppc64le.so.1",
 #endif
     NULL,
 };
diff --git a/src/os.hpp b/src/os.hpp
index ac8c55946..833fa45a9 100644
--- a/src/os.hpp
+++ b/src/os.hpp
@@ -39,6 +39,8 @@
 #define ZIG_ARCH_ARM64
 #elif defined(__ARM_EABI__)
 #define ZIG_ARCH_ARM
+#elif defined(__ppc64le__)
+#define ZIG_ARCH_PPC64LE
 #else
 #define ZIG_ARCH_UNKNOWN
 #endif
diff --git a/src/target.cpp b/src/target.cpp
index 82d5467e2..c11d87729 100644
--- a/src/target.cpp
+++ b/src/target.cpp
@@ -1459,6 +1459,10 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
         case ZigLLVM_mipsel:
             return "sp";
 
+        case ZigLLVM_ppc:
+        case ZigLLVM_ppc64:
+            return "r1";
+
         case ZigLLVM_wasm32:
         case ZigLLVM_wasm64:
             return nullptr; // known to be not available
@@ -1497,8 +1501,6 @@ const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch) {
         case ZigLLVM_tce:
         case ZigLLVM_tcele:
         case ZigLLVM_xcore:
-        case ZigLLVM_ppc:
-        case ZigLLVM_ppc64:
             zig_panic("TODO populate this table with stack pointer register name for this CPU archi
tecture");
     }
     zig_unreachable();

@andrewrk
Copy link
Member

Want to take this upstream? Send pull request to ziglang/zig

@wilsonk
Copy link

wilsonk commented Apr 14, 2020

I can, but I wouldn't be able to test the patch with zig 0.6 on ppc hardware, so a PR might not run properly.

@andrewrk
Copy link
Member

andrewrk commented Apr 14, 2020

You can still test cross compiling with this bootstrap repository, it's just that the diff needs to go upstream, since this repository copies zig from there.

@LinuxUserGD
Copy link
Contributor

This is the output when cross-compiling from x86_64-gentoo-linux-musl host:

[ 91%] Built target LLVMAVRCodeGen
[ 92%] Built target LLVMARMCodeGen
[ 96%] Built target LLVMAMDGPUCodeGen
[ 97%] Built target LLVMAArch64CodeGen
[ 97%] Building CXX object lib/ExecutionEngine/Orc/CMakeFiles/LLVMOrcJIT.dir/CompileUtils.cpp.o
zig: warning: argument unused during compilation: '-mred-zone' [-Wunused-command-line-argument]
[ 97%] Building CXX object lib/ExecutionEngine/Orc/CMakeFiles/LLVMOrcJIT.dir/Core.cpp.o
zig: warning: argument unused during compilation: '-mred-zone' [-Wunused-command-line-argument]
[ 97%] Building CXX object lib/ExecutionEngine/Orc/CMakeFiles/LLVMOrcJIT.dir/DebugObjectManagerPlugin.cpp.o
zig: warning: argument unused during compilation: '-mred-zone' [-Wunused-command-line-argument]
[ 97%] Building CXX object lib/ExecutionEngine/Orc/CMakeFiles/LLVMOrcJIT.dir/DebuggerSupportPlugin.cpp.o
zig: warning: argument unused during compilation: '-mred-zone' [-Wunused-command-line-argument]
[ 97%] Linking CXX executable ../../../../../bin/clang-ast-dump
LLD Link... ld.lld: error: undefined symbol: __floatditf
>>> referenced by LockFileManager.cpp
>>>               LockFileManager.cpp.o:(llvm::LockFileManager::waitForUnlock(unsigned int)) in archive ../../../../../lib/libLLVMSupport.a
>>> did you mean: __floattitf
>>> defined in: /home/user/.cache/zig/o/3c99341f972f013c322b509c22aa92b9/libcompiler_rt.a(/home/user/.cache/zig/o/3c99341f972f013c322b509c22aa92b9/compiler_rt.o)
make[2]: *** [tools/clang/lib/Tooling/DumpTool/CMakeFiles/clang-ast-dump.dir/build.make:155: bin/clang-ast-dump] Error 1
make[1]: *** [CMakeFiles/Makefile2:30653: tools/clang/lib/Tooling/DumpTool/CMakeFiles/clang-ast-dump.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
[ 97%] Building CXX object lib/ExecutionEngine/Orc/CMakeFiles/LLVMOrcJIT.dir/DebugUtils.cpp.o
zig: warning: argument unused during compilation: '-mred-zone' [-Wunused-command-line-argument]
[ 97%] Building CXX object lib/ExecutionEngine/Orc/CMakeFiles/LLVMOrcJIT.dir/EPCDynamicLibrarySearchGenerator.cpp.o
zig: warning: argument unused during compilation: '-mred-zone' [-Wunused-command-line-argument]
[ 97%] Building CXX object lib/ExecutionEngine/Orc/CMakeFiles/LLVMOrcJIT.dir/EPCDebugObjectRegistrar.cpp.o
zig: warning: argument unused during compilation: '-mred-zone' [-Wunused-command-line-argument]
[ 97%] Building CXX object lib/ExecutionEngine/Orc/CMakeFiles/LLVMOrcJIT.dir/EPCEHFrameRegistrar.cpp.o

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants