| author | |
| committer | |
| log | 09992f8acc2432080409c3c3b32cab52bc8a3d91 |
| tree | ab4d563bb7c7c2232f50cc3a349a2107b6d5857f |
| parent | 4d75382452abd5e50e6f8ca9c82b67fbe0983456 |
5 files changed, 124 insertions(+), 15 deletions(-)
lib/std/os.zig+1| ... | ... | @@ -33,6 +33,7 @@ pub const netbsd = std.c; |
| 33 | 33 | pub const openbsd = std.c; |
| 34 | 34 | pub const solaris = std.c; |
| 35 | 35 | pub const linux = @import("os/linux.zig"); |
| 36 | pub const plan9 = @import("os/plan9.zig"); | |
| 36 | 37 | pub const uefi = @import("os/uefi.zig"); |
| 37 | 38 | pub const wasi = @import("os/wasi.zig"); |
| 38 | 39 | pub const windows = @import("os/windows.zig"); |
lib/std/os/plan9.zig created+69| ... | ... | @@ -0,0 +1,69 @@ |
| 1 | const std = @import("../std.zig"); | |
| 2 | const builtin = @import("builtin"); | |
| 3 | ||
| 4 | pub 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 | }; | |
| 8 | pub 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 | ||
| 63 | pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) void { | |
| 64 | syscall_bits.syscall4(.PWRITE, fd, @ptrToInt(buf), count, offset); | |
| 65 | } | |
| 66 | ||
| 67 | pub 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 @@ |
| 1 | const plan9 = @import("../plan9.zig"); | |
| 2 | // TODO get ret from inline asm | |
| 3 | // TODO better inline asm | |
| 4 | ||
| 5 | pub 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 | } | |
| 27 | pub 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 | 8919 | const inst_data = sema.code.instructions.items(.data)[inst].un_node; |
| 8920 | 8920 | const src = inst_data.src(); |
| 8921 | 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 | 8925 | const loaded = try sema.analyzeLoad(block, src, ptr, src); |
| 8923 | 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 | 1826 | try self.register_manager.getReg(reg, null); |
| 1827 | 1827 | try self.genSetReg(arg_ty, reg, arg_mcv); |
| 1828 | 1828 | }, |
| 1829 | .stack_offset => { | |
| 1829 | .stack_offset => |off| { | |
| 1830 | 1830 | // Here we need to emit instructions like this: |
| 1831 | 1831 | // 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 | 1834 | .ptr_stack_offset => { |
| 1835 | 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 | 1987 | fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void { |
| 1988 | 1988 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 1989 | 1989 | const ptr = try self.resolveInst(un_op); |
| 1990 | _ = ptr; | |
| 1991 | return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch}); | |
| 1992 | //return self.finishAir(inst, .dead, .{ un_op, .none, .none }); | |
| 1990 | // we can reuse self.ret_mcv because it just gets returned | |
| 1991 | try self.load(self.ret_mcv, ptr, self.air.typeOf(un_op)); | |
| 1992 | try self.ret(self.ret_mcv); | |
| 1993 | return self.finishAir(inst, .dead, .{ un_op, .none, .none }); | |
| 1993 | 1994 | } |
| 1994 | 1995 | |
| 1995 | 1996 | fn 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 | 2488 | const clobbers_len = @truncate(u5, extended.small >> 10); |
| 2488 | 2489 | _ = clobbers_len; // TODO honor these |
| 2489 | 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 + outputs.len ..][0..args_len]); | |
| 2491 | const args = @bitCast([]const Air.Inst.Ref, self.air.extra[air_extra.end..][0..args_len]); | |
| 2492 | 2492 | |
| 2493 | 2493 | if (outputs_len > 1) { |
| 2494 | 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 | 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 | 2595 | var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1); |
| 2596 | std.mem.copy(Air.Inst.Ref, &buf, outputs); | |
| 2597 | std.mem.copy(Air.Inst.Ref, buf[outputs.len..], args); | |
| 2596 | std.mem.copy(Air.Inst.Ref, &buf, args); | |
| 2598 | 2597 | return self.finishAir(inst, result, buf); |
| 2599 | 2598 | } |
| 2600 | var bt = try self.iterateBigTomb(inst, outputs.len + args.len); | |
| 2601 | for (outputs) |output| { | |
| 2602 | bt.feed(output); | |
| 2603 | } | |
| 2599 | var bt = try self.iterateBigTomb(inst, args.len); | |
| 2604 | 2600 | for (args) |arg| { |
| 2605 | 2601 | bt.feed(arg); |
| 2606 | 2602 | } |
| ... | ... | @@ -3297,7 +3293,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues { |
| 3297 | 3293 | const param_size = @intCast(u32, ty.abiSize(self.target.*)); |
| 3298 | 3294 | const pass_in_reg = switch (ty.zigTypeTag()) { |
| 3299 | 3295 | .Bool => true, |
| 3300 | .Int => param_size <= 8, | |
| 3296 | .Int, .Enum => param_size <= 8, | |
| 3301 | 3297 | .Pointer => ty.ptrSize() != .Slice, |
| 3302 | 3298 | .Optional => ty.isPtrLikeOptional(), |
| 3303 | 3299 | else => false, |