authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-06-21 13:10:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-08 14:12:08-07:00
log1c2facaf6b670863edf30d7c9d1d47368c4a90cc
treecf080a36769142ab4ebecbda0d9e4336402fad16
parentf1aadfa77b2907f0cf93d03d362ee921b0313224

stage2: include enough inline asm support for more plan9 syscalls

Also make the exit more correct by exiting 0 rather than random stuff on the stack.

2 files changed, 44 insertions(+), 6 deletions(-)

lib/std/start.zig+6-2
...@@ -123,11 +123,15 @@ fn exit2(code: usize) noreturn {...@@ -123,11 +123,15 @@ fn exit2(code: usize) noreturn {
123 },123 },
124 else => @compileError("TODO"),124 else => @compileError("TODO"),
125 },125 },
126 // exits(0)
126 .plan9 => switch (builtin.stage2_arch) {127 .plan9 => switch (builtin.stage2_arch) {
127 .x86_64 => {128 .x86_64 => {
128 asm volatile ("syscall"129 asm volatile (
130 \\push $0
131 \\push $0
132 \\syscall
129 :133 :
130 : [number] "{rbp}" (8)134 : [syscall_number] "{rbp}" (8)
131 : "rcx", "r11", "memory"135 : "rcx", "r11", "memory"
132 );136 );
133 },137 },
src/codegen.zig+38-4
...@@ -3330,10 +3330,44 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3330,10 +3330,44 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3330 try self.genSetReg(inst.base.src, arg.ty, reg, arg_mcv);3330 try self.genSetReg(inst.base.src, arg.ty, reg, arg_mcv);
3331 }3331 }
33323332
3333 if (mem.eql(u8, inst.asm_source, "syscall")) {3333 {
3334 try self.code.appendSlice(&[_]u8{ 0x0f, 0x05 });3334 var iter = std.mem.tokenize(inst.asm_source, "\n\r");
3335 } else if (inst.asm_source.len != 0) {3335 while (iter.next()) |ins| {
3336 return self.fail(inst.base.src, "TODO implement support for more x86 assembly instructions", .{});3336 if (mem.eql(u8, ins, "syscall")) {
3337 try self.code.appendSlice(&[_]u8{ 0x0f, 0x05 });
3338 } else if (mem.indexOf(u8, ins, "push")) |_| {
3339 const arg = ins[4..];
3340 if (mem.indexOf(u8, arg, "$")) |l| {
3341 const n = std.fmt.parseInt(u8, ins[4 + l + 1 ..], 10) catch return self.fail(inst.base.src, "TODO implement more inline asm int parsing", .{});
3342 try self.code.appendSlice(&.{ 0x6a, n });
3343 } else if (mem.indexOf(u8, arg, "%%")) |l| {
3344 const reg_name = ins[4 + l + 2 ..];
3345 const reg = parseRegName(reg_name) orelse
3346 return self.fail(inst.base.src, "unrecognized register: '{s}'", .{reg_name});
3347 const low_id: u8 = reg.low_id();
3348 if (reg.isExtended()) {
3349 try self.code.appendSlice(&.{ 0x41, 0b1010000 | low_id });
3350 } else {
3351 try self.code.append(0b1010000 | low_id);
3352 }
3353 } else return self.fail(inst.base.src, "TODO more push operands", .{});
3354 } else if (mem.indexOf(u8, ins, "pop")) |_| {
3355 const arg = ins[3..];
3356 if (mem.indexOf(u8, arg, "%%")) |l| {
3357 const reg_name = ins[3 + l + 2 ..];
3358 const reg = parseRegName(reg_name) orelse
3359 return self.fail(inst.base.src, "unrecognized register: '{s}'", .{reg_name});
3360 const low_id: u8 = reg.low_id();
3361 if (reg.isExtended()) {
3362 try self.code.appendSlice(&.{ 0x41, 0b1011000 | low_id });
3363 } else {
3364 try self.code.append(0b1011000 | low_id);
3365 }
3366 } else return self.fail(inst.base.src, "TODO more pop operands", .{});
3367 } else {
3368 return self.fail(inst.base.src, "TODO implement support for more x86 assembly instructions", .{});
3369 }
3370 }
3337 }3371 }
33383372
3339 if (inst.output_constraint) |output| {3373 if (inst.output_constraint) |output| {