diff --git a/lib/std/os/plan9.zig b/lib/std/os/plan9.zig index dbf33894cb..99e25709b1 100644 --- a/lib/std/os/plan9.zig +++ b/lib/std/os/plan9.zig @@ -64,6 +64,28 @@ pub fn pwrite(fd: usize, buf: [*]const u8, count: usize, offset: usize) usize { return syscall_bits.syscall4(.PWRITE, fd, @ptrToInt(buf), count, offset); } -pub fn exits(status: ?[*:0]const u8) void { - syscall_bits.syscall1(.EXITS, if (status) |s| @ptrToInt(s) else 0); +pub fn open(path: [*:0]const u8, omode: OpenMode) usize { + return syscall_bits.syscall2(.OPEN, @ptrToInt(path), @enumToInt(omode)); } + +pub fn create(path: [*:0]const u8, omode: OpenMode, perms: usize) usize { + return syscall_bits.syscall3(.CREATE, @ptrToInt(path), @enumToInt(omode), perms); +} + +pub fn exits(status: ?[*:0]const u8) void { + _ = syscall_bits.syscall1(.EXITS, if (status) |s| @ptrToInt(s) else 0); +} + +pub fn close(fd: usize) usize { + return syscall_bits.syscall1(.CLOSE, fd); +} +pub const OpenMode = enum(usize) { + OREAD = 0, //* open for read + OWRITE = 1, //* write + ORDWR = 2, //* read and write + OEXEC = 3, //* execute, == read but check execute permission + OTRUNC = 16, //* or'ed in (except for exec), truncate file first + OCEXEC = 32, //* or'ed in (per file descriptor), close on exec + ORCLOSE = 64, //* or'ed in, remove on close + OEXCL = 0x1000, //* or'ed in, exclusive create +}; diff --git a/lib/std/os/plan9/x86_64.zig b/lib/std/os/plan9/x86_64.zig index 652c18edb8..83d0d35307 100644 --- a/lib/std/os/plan9/x86_64.zig +++ b/lib/std/os/plan9/x86_64.zig @@ -1,7 +1,54 @@ const plan9 = @import("../plan9.zig"); -// TODO get ret from inline asm // TODO better inline asm +pub fn syscall1(sys: plan9.SYS, arg0: usize) usize { + return asm volatile ( + \\push %%r8 + \\push $0 + \\syscall + \\pop %%r11 + \\pop %%r11 + : [ret] "={rax}" (-> usize), + : [syscall_number] "{rbp}" (@enumToInt(sys)), + [arg0] "{r8}" (arg0), + : "rcx", "rax", "rbp", "r11", "memory" + ); +} +pub fn syscall2(sys: plan9.SYS, arg0: usize, arg1: usize) usize { + return asm volatile ( + \\push %%r9 + \\push %%r8 + \\push $0 + \\syscall + \\pop %%r11 + \\pop %%r11 + \\pop %%r11 + : [ret] "={rax}" (-> usize), + : [arg0] "{r8}" (arg0), + [arg1] "{r9}" (arg1), + [syscall_number] "{rbp}" (@enumToInt(sys)), + : "rcx", "rax", "rbp", "r11", "memory" + ); +} +pub fn syscall3(sys: plan9.SYS, arg0: usize, arg1: usize, arg2: usize) usize { + return asm volatile ( + \\push %%r10 + \\push %%r9 + \\push %%r8 + \\push $0 + \\syscall + \\pop %%r11 + \\pop %%r11 + \\pop %%r11 + \\pop %%r11 + : [ret] "={rax}" (-> usize), + : [arg0] "{r8}" (arg0), + [arg1] "{r9}" (arg1), + [arg2] "{r10}" (arg2), + [syscall_number] "{rbp}" (@enumToInt(sys)), + : "rcx", "rax", "rbp", "r11", "memory" + ); +} pub fn syscall4(sys: plan9.SYS, arg0: usize, arg1: usize, arg2: usize, arg3: usize) usize { return asm volatile ( \\push %%r11 @@ -16,26 +63,11 @@ pub fn syscall4(sys: plan9.SYS, arg0: usize, arg1: usize, arg2: usize, arg3: usi \\pop %%r11 \\pop %%r11 : [ret] "={rax}" (-> usize), - // : : [arg0] "{r8}" (arg0), [arg1] "{r9}" (arg1), [arg2] "{r10}" (arg2), [arg2] "{r11}" (arg3), [syscall_number] "{rbp}" (@enumToInt(sys)), - : "rcx", "rbp", "r11", "memory" - ); -} -pub fn syscall1(sys: plan9.SYS, arg0: usize) void { - _ = sys; - asm volatile ( - \\push %%r8 - \\push $0 - \\syscall - \\pop %%r11 - \\pop %%r11 - : - : [syscall_number] "{rbp}" (@enumToInt(sys)), - [arg0] "{r8}" (arg0), - : "rcx", "rbp", "r11", "memory" + : "rcx", "rax", "rbp", "r11", "memory" ); }