Commit 09992f8acc
Changed files (5)
lib
std
os
plan9
src
arch
x86_64
lib/std/os/plan9/x86_64.zig
@@ -0,0 +1,40 @@
+const plan9 = @import("../plan9.zig");
+// TODO get ret from inline asm
+// TODO better inline asm
+
+pub fn syscall4(sys: plan9.SYS, arg0: usize, arg1: usize, arg2: usize, arg3: usize) void {
+ asm volatile (
+ \\push %%r11
+ \\push %%r10
+ \\push %%r9
+ \\push %%r8
+ \\push $0
+ \\syscall
+ \\pop %%r11
+ \\pop %%r11
+ \\pop %%r11
+ \\pop %%r11
+ \\pop %%r11
+ :
+ : [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"
+ );
+}
lib/std/os/plan9.zig
@@ -0,0 +1,69 @@
+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) void {
+ 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);
+}
lib/std/os.zig
@@ -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");
src/arch/x86_64/CodeGen.zig
@@ -1826,10 +1826,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", .{});
@@ -1987,9 +1987,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 {
@@ -2487,8 +2488,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", .{});
@@ -2591,16 +2591,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);
}
@@ -3297,7 +3293,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,
src/Sema.zig
@@ -8919,6 +8919,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);
}