mirror of
https://github.com/ziglang/zig.git
synced 2026-01-03 20:13:21 +00:00
commit
19e5663869
@ -33,6 +33,7 @@ pub const netbsd = std.c;
|
||||
pub const openbsd = std.c;
|
||||
pub const solaris = std.c;
|
||||
pub const linux = @import("os/linux.zig");
|
||||
pub const plan9 = @import("os/plan9.zig");
|
||||
pub const uefi = @import("os/uefi.zig");
|
||||
pub const wasi = @import("os/wasi.zig");
|
||||
pub const windows = @import("os/windows.zig");
|
||||
|
||||
91
lib/std/os/plan9.zig
Normal file
91
lib/std/os/plan9.zig
Normal file
@ -0,0 +1,91 @@
|
||||
const std = @import("../std.zig");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub const syscall_bits = switch (builtin.stage2_arch) {
|
||||
.x86_64 => @import("plan9/x86_64.zig"),
|
||||
else => @compileError("more plan9 syscall implementations (needs more inline asm in stage2"),
|
||||
};
|
||||
pub const SYS = enum(usize) {
|
||||
SYSR1 = 0,
|
||||
_ERRSTR = 1,
|
||||
BIND = 2,
|
||||
CHDIR = 3,
|
||||
CLOSE = 4,
|
||||
DUP = 5,
|
||||
ALARM = 6,
|
||||
EXEC = 7,
|
||||
EXITS = 8,
|
||||
_FSESSION = 9,
|
||||
FAUTH = 10,
|
||||
_FSTAT = 11,
|
||||
SEGBRK = 12,
|
||||
_MOUNT = 13,
|
||||
OPEN = 14,
|
||||
_READ = 15,
|
||||
OSEEK = 16,
|
||||
SLEEP = 17,
|
||||
_STAT = 18,
|
||||
RFORK = 19,
|
||||
_WRITE = 20,
|
||||
PIPE = 21,
|
||||
CREATE = 22,
|
||||
FD2PATH = 23,
|
||||
BRK_ = 24,
|
||||
REMOVE = 25,
|
||||
_WSTAT = 26,
|
||||
_FWSTAT = 27,
|
||||
NOTIFY = 28,
|
||||
NOTED = 29,
|
||||
SEGATTACH = 30,
|
||||
SEGDETACH = 31,
|
||||
SEGFREE = 32,
|
||||
SEGFLUSH = 33,
|
||||
RENDEZVOUS = 34,
|
||||
UNMOUNT = 35,
|
||||
_WAIT = 36,
|
||||
SEMACQUIRE = 37,
|
||||
SEMRELEASE = 38,
|
||||
SEEK = 39,
|
||||
FVERSION = 40,
|
||||
ERRSTR = 41,
|
||||
STAT = 42,
|
||||
FSTAT = 43,
|
||||
WSTAT = 44,
|
||||
FWSTAT = 45,
|
||||
MOUNT = 46,
|
||||
AWAIT = 47,
|
||||
PREAD = 50,
|
||||
PWRITE = 51,
|
||||
TSEMACQUIRE = 52,
|
||||
_NSEC = 53,
|
||||
};
|
||||
|
||||
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 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
|
||||
};
|
||||
73
lib/std/os/plan9/x86_64.zig
Normal file
73
lib/std/os/plan9/x86_64.zig
Normal file
@ -0,0 +1,73 @@
|
||||
const plan9 = @import("../plan9.zig");
|
||||
// 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
|
||||
\\push %%r10
|
||||
\\push %%r9
|
||||
\\push %%r8
|
||||
\\push $0
|
||||
\\syscall
|
||||
\\pop %%r11
|
||||
\\pop %%r11
|
||||
\\pop %%r11
|
||||
\\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", "rax", "rbp", "r11", "memory"
|
||||
);
|
||||
}
|
||||
@ -9002,6 +9002,9 @@ fn zirIsNonNullPtr(
|
||||
const inst_data = sema.code.instructions.items(.data)[inst].un_node;
|
||||
const src = inst_data.src();
|
||||
const ptr = sema.resolveInst(inst_data.operand);
|
||||
if ((try sema.resolveMaybeUndefVal(block, src, ptr)) == null) {
|
||||
return block.addUnOp(.is_non_null_ptr, ptr);
|
||||
}
|
||||
const loaded = try sema.analyzeLoad(block, src, ptr, src);
|
||||
return sema.analyzeIsNull(block, src, loaded, true);
|
||||
}
|
||||
|
||||
@ -1836,10 +1836,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index) !void {
|
||||
try self.register_manager.getReg(reg, null);
|
||||
try self.genSetReg(arg_ty, reg, arg_mcv);
|
||||
},
|
||||
.stack_offset => {
|
||||
.stack_offset => |off| {
|
||||
// Here we need to emit instructions like this:
|
||||
// mov qword ptr [rsp + stack_offset], x
|
||||
return self.fail("TODO implement calling with parameters in memory", .{});
|
||||
try self.genSetStack(arg_ty, off, arg_mcv);
|
||||
},
|
||||
.ptr_stack_offset => {
|
||||
return self.fail("TODO implement calling with MCValue.ptr_stack_offset arg", .{});
|
||||
@ -1997,9 +1997,10 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void {
|
||||
fn airRetLoad(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const un_op = self.air.instructions.items(.data)[inst].un_op;
|
||||
const ptr = try self.resolveInst(un_op);
|
||||
_ = ptr;
|
||||
return self.fail("TODO implement airRetLoad for {}", .{self.target.cpu.arch});
|
||||
//return self.finishAir(inst, .dead, .{ un_op, .none, .none });
|
||||
// we can reuse self.ret_mcv because it just gets returned
|
||||
try self.load(self.ret_mcv, ptr, self.air.typeOf(un_op));
|
||||
try self.ret(self.ret_mcv);
|
||||
return self.finishAir(inst, .dead, .{ un_op, .none, .none });
|
||||
}
|
||||
|
||||
fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void {
|
||||
@ -2497,8 +2498,7 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
|
||||
const clobbers_len = @truncate(u5, extended.small >> 10);
|
||||
_ = clobbers_len; // TODO honor these
|
||||
const is_volatile = @truncate(u1, extended.small >> 15) != 0;
|
||||
const outputs = @bitCast([]const Air.Inst.Ref, self.air.extra[air_extra.end..][0..outputs_len]);
|
||||
const args = @bitCast([]const Air.Inst.Ref, self.air.extra[air_extra.end + outputs.len ..][0..args_len]);
|
||||
const args = @bitCast([]const Air.Inst.Ref, self.air.extra[air_extra.end..][0..args_len]);
|
||||
|
||||
if (outputs_len > 1) {
|
||||
return self.fail("TODO implement codegen for asm with more than 1 output", .{});
|
||||
@ -2601,16 +2601,12 @@ fn airAsm(self: *Self, inst: Air.Inst.Index) !void {
|
||||
break :result MCValue{ .none = {} };
|
||||
}
|
||||
};
|
||||
if (outputs.len + args.len <= Liveness.bpi - 1) {
|
||||
if (args.len <= Liveness.bpi - 1) {
|
||||
var buf = [1]Air.Inst.Ref{.none} ** (Liveness.bpi - 1);
|
||||
std.mem.copy(Air.Inst.Ref, &buf, outputs);
|
||||
std.mem.copy(Air.Inst.Ref, buf[outputs.len..], args);
|
||||
std.mem.copy(Air.Inst.Ref, &buf, args);
|
||||
return self.finishAir(inst, result, buf);
|
||||
}
|
||||
var bt = try self.iterateBigTomb(inst, outputs.len + args.len);
|
||||
for (outputs) |output| {
|
||||
bt.feed(output);
|
||||
}
|
||||
var bt = try self.iterateBigTomb(inst, args.len);
|
||||
for (args) |arg| {
|
||||
bt.feed(arg);
|
||||
}
|
||||
@ -3310,7 +3306,7 @@ fn resolveCallingConventionValues(self: *Self, fn_ty: Type) !CallMCValues {
|
||||
const param_size = @intCast(u32, ty.abiSize(self.target.*));
|
||||
const pass_in_reg = switch (ty.zigTypeTag()) {
|
||||
.Bool => true,
|
||||
.Int => param_size <= 8,
|
||||
.Int, .Enum => param_size <= 8,
|
||||
.Pointer => ty.ptrSize() != .Slice,
|
||||
.Optional => ty.isPtrLikeOptional(),
|
||||
else => false,
|
||||
|
||||
@ -43,6 +43,13 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\ : "rcx", "rbp", "r11", "memory"
|
||||
\\ );
|
||||
\\}
|
||||
, "");
|
||||
, "Hello World\n");
|
||||
case.addCompareOutput(
|
||||
\\const std = @import("std");
|
||||
\\pub fn main() void {
|
||||
\\ const str = "Hello World!\n";
|
||||
\\ _ = std.os.plan9.pwrite(1, str, str.len, 0);
|
||||
\\}
|
||||
, "Hello World\n");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user