authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-10-11 18:10:12-04:00
committergravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-11-09 07:08:23-05:00
log09992f8acc2432080409c3c3b32cab52bc8a3d91
treeab4d563bb7c7c2232f50cc3a349a2107b6d5857f
parent4d75382452abd5e50e6f8ca9c82b67fbe0983456

add initial plan9 support to std


5 files changed, 124 insertions(+), 15 deletions(-)

lib/std/os.zig+1
...@@ -33,6 +33,7 @@ pub const netbsd = std.c;...@@ -33,6 +33,7 @@ pub const netbsd = std.c;
33pub const openbsd = std.c;33pub const openbsd = std.c;
34pub const solaris = std.c;34pub const solaris = std.c;
35pub const linux = @import("os/linux.zig");35pub const linux = @import("os/linux.zig");
36pub const plan9 = @import("os/plan9.zig");
36pub const uefi = @import("os/uefi.zig");37pub const uefi = @import("os/uefi.zig");
37pub const wasi = @import("os/wasi.zig");38pub const wasi = @import("os/wasi.zig");
38pub const windows = @import("os/windows.zig");39pub const windows = @import("os/windows.zig");
lib/std/os/plan9.zig created+69
...@@ -0,0 +1,69 @@
1const std = @import("../std.zig");
2const builtin = @import("builtin");
3
4pub const syscall_bits = switch (builtin.stage2_arch) {
5 .x86_64 => @import("plan9/x86_64.zig"),
6 else => @compileError("more plan9 syscall implementations (needs more inline asm in stage2"),
7};
8pub const SYS = enum(usize) {
9 SYSR1 = 0,
10 _ERRSTR = 1,
11 BIND = 2,
12 CHDIR = 3,
13 CLOSE = 4,
14 DUP = 5,
15 ALARM = 6,
16 EXEC = 7,
17 EXITS = 8,
18 _FSESSION = 9,
19 FAUTH = 10,
20 _FSTAT = 11,
21 SEGBRK = 12,
22 _MOUNT = 13,
23 OPEN = 14,
24 _READ = 15,
25 OSEEK = 16,
26 SLEEP = 17,
27 _STAT = 18,
28 RFORK = 19,
29 _WRITE = 20,
30 PIPE = 21,
31 CREATE = 22,
32 FD2PATH = 23,
33 BRK_ = 24,
34 REMOVE = 25,
35 _WSTAT = 26,
36 _FWSTAT = 27,
37 NOTIFY = 28,
38 NOTED = 29,
39 SEGATTACH = 30,
40 SEGDETACH = 31,
41 SEGFREE = 32,
42 SEGFLUSH = 33,
43 RENDEZVOUS = 34,
44 UNMOUNT = 35,
45 _WAIT = 36,
46 SEMACQUIRE = 37,
47 SEMRELEASE = 38,
48 SEEK = 39,
49 FVERSION = 40,
50 ERRSTR = 41,
51 STAT = 42,
52 FSTAT = 43,
53 WSTAT = 44,
54 FWSTAT = 45,
55 MOUNT = 46,
56 AWAIT = 47,
57 PREAD = 50,
58 PWRITE = 51,
59 TSEMACQUIRE = 52,
60 _NSEC = 53,
61};
62
63pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) void {
64 syscall_bits.syscall4(.PWRITE, fd, @ptrToInt(buf), count, offset);
65}
66
67pub fn exits(status: ?[*:0]const u8) void {
68 syscall_bits.syscall1(.EXITS, if (status) |s| @ptrToInt(s) else 0);
69}
lib/std/os/plan9/x86_64.zig created+40
...@@ -0,0 +1,40 @@
1const plan9 = @import("../plan9.zig");
2// TODO get ret from inline asm
3// TODO better inline asm
4
5pub fn syscall4(sys: plan9.SYS, arg0: usize, arg1: usize, arg2: usize, arg3: usize) void {
6 asm volatile (
7 \\push %%r11
8 \\push %%r10
9 \\push %%r9
10 \\push %%r8
11 \\push $0
12 \\syscall
13 \\pop %%r11
14 \\pop %%r11
15 \\pop %%r11
16 \\pop %%r11
17 \\pop %%r11
18 :
19 : [arg0] "{r8}" (arg0),
20 [arg1] "{r9}" (arg1),
21 [arg2] "{r10}" (arg2),
22 [arg2] "{r11}" (arg3),
23 [syscall_number] "{rbp}" (@enumToInt(sys)),
24 : "rcx", "rbp", "r11", "memory"
25 );
26}
27pub fn syscall1(sys: plan9.SYS, arg0: usize) void {
28 _ = sys;
29 asm volatile (
30 \\push %%r8
31 \\push $0
32 \\syscall
33 \\pop %%r11
34 \\pop %%r11
35 :
36 : [syscall_number] "{rbp}" (@enumToInt(sys)),
37 [arg0] "{r8}" (arg0),
38 : "rcx", "rbp", "r11", "memory"
39 );
40}
src/Sema.zig+3
...@@ -8919,6 +8919,9 @@ fn zirIsNonNullPtr(...@@ -8919,6 +8919,9 @@ fn zirIsNonNullPtr(
8919 const inst_data = sema.code.instructions.items(.data)[inst].un_node;8919 const inst_data = sema.code.instructions.items(.data)[inst].un_node;
8920 const src = inst_data.src();8920 const src = inst_data.src();
8921 const ptr = sema.resolveInst(inst_data.operand);8921 const ptr = sema.resolveInst(inst_data.operand);
8922 if ((try sema.resolveMaybeUndefVal(block, src, ptr)) == null) {
8923 return block.addUnOp(.is_non_null_ptr, ptr);
8924 }
8922 const loaded = try sema.analyzeLoad(block, src, ptr, src);8925 const loaded = try sema.analyzeLoad(block, src, ptr, src);
8923 return sema.analyzeIsNull(block, src, loaded, true);8926 return sema.analyzeIsNull(block, src, loaded, true);
8924}8927}
src/arch/x86_64/CodeGen.zig+11-15
...@@ -1826,10 +1826,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {...@@ -1826,10 +1826,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
1826 try self.register_manager.getReg(reg, null);1826 try self.register_manager.getReg(reg, null);
1827 try self.genSetReg(arg_ty, reg, arg_mcv);1827 try self.genSetReg(arg_ty, reg, arg_mcv);
1828 },1828 },
1829 .stack_offset => {1829 .stack_offset => |off| {
1830 // Here we need to emit instructions like this:1830 // Here we need to emit instructions like this:
1831 // mov qword ptr [rsp + stack_offset], x1831 // mov qword ptr [rsp + stack_offset], x
1832 return self.fail("TODO implement calling with parameters in memory", .{});1832 try self.genSetStack(arg_ty, off, arg_mcv);
1833 },1833 },
1834 .ptr_stack_offset => {1834 .ptr_stack_offset => {
1835 return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{});1835 return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{});
...@@ -1987,9 +1987,10 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {...@@ -1987,9 +1987,10 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
1987fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {1987fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
1988 const un_op = self.air.instructions.items(.data)[inst].un_op;1988 const un_op = self.air.instructions.items(.data)[inst].un_op;
1989 const ptr = try self.resolveInst(un_op);1989 const ptr = try self.resolveInst(un_op);
1990 _ = ptr;1990 // we can reuse self.ret_mcv because it just gets returned
1991 return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch});1991 try self.load(self.ret_mcv, ptr, self.air.typeOf(un_op));
1992 //return self.finishAir(inst, .dead, .{ un_op, .none, .none });1992 try self.ret(self.ret_mcv);
1993 return self.finishAir(inst, .dead, .{ un_op, .none, .none });
1993}1994}
19941995
1995fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {1996fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
...@@ -2487,8 +2488,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -2487,8 +2488,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
2487 const clobbers_len = @truncate(u5, extended.small >> 10);2488 const clobbers_len = @truncate(u5, extended.small >> 10);
2488 _ = clobbers_len; // TODO honor these2489 _ = clobbers_len; // TODO honor these
2489 const is_volatile = @truncate(u1, extended.small >> 15) != 0;2490 const is_volatile = @truncate(u1, extended.small >> 15) != 0;
2490 const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[air_extra.end..][0..outputs_len]);2491 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[air_extra.end..][0..args_len]);
2491 const args = @bitCast([]const Air.Inst.Ref, self.air.extra[air_extra.end + outputs.len ..][0..args_len]);
24922492
2493 if (outputs_len > 1) {2493 if (outputs_len > 1) {
2494 return self.fail("TODO implement codegen for asm with more than 1 output", .{});2494 return self.fail("TODO implement codegen for asm with more than 1 output", .{});
...@@ -2591,16 +2591,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {...@@ -2591,16 +2591,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
2591 break :result MCValue{ .none = {} };2591 break :result MCValue{ .none = {} };
2592 }2592 }
2593 };2593 };
2594 if (outputs.len + args.len <= Liveness.bpi - 1) {2594 if (args.len <= Liveness.bpi - 1) {
2595 var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1);2595 var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1);
2596 std.mem.copy(Air.Inst.Ref, &buf, outputs);2596 std.mem.copy(Air.Inst.Ref, &buf, args);
2597 std.mem.copy(Air.Inst.Ref, buf[outputs.len..], args);
2598 return self.finishAir(inst, result, buf);2597 return self.finishAir(inst, result, buf);
2599 }2598 }
2600 var bt = try self.iterateBigTomb(inst, outputs.len + args.len);2599 var bt = try self.iterateBigTomb(inst, args.len);
2601 for (outputs) |output| {
2602 bt.feed(output);
2603 }
2604 for (args) |arg| {2600 for (args) |arg| {
2605 bt.feed(arg);2601 bt.feed(arg);
2606 }2602 }
...@@ -3297,7 +3293,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {...@@ -3297,7 +3293,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
3297 const param_size = @intCast(u32, ty.abiSize(self.target.*));3293 const param_size = @intCast(u32, ty.abiSize(self.target.*));
3298 const pass_in_reg = switch (ty.zigTypeTag()) {3294 const pass_in_reg = switch (ty.zigTypeTag()) {
3299 .Bool => true,3295 .Bool => true,
3300 .Int => param_size <= 8,3296 .Int, .Enum => param_size <= 8,
3301 .Pointer => ty.ptrSize() != .Slice,3297 .Pointer => ty.ptrSize() != .Slice,
3302 .Optional => ty.isPtrLikeOptional(),3298 .Optional => ty.isPtrLikeOptional(),
3303 else => false,3299 else => false,