authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-07-10 20:56:30-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-11 01:58:26-04:00
log968d1ecf17c0a0774d43965332d00d4ad39743b9
treeb76eadf8b7d8c27fbff9ed1c48efdd218659854d
parent40764650afd47f2ca2d191ed4d910f680702e014

stage2 plan9: add aarch64 support


4 files changed, 77 insertions(+), 5 deletions(-)

lib/std/start.zig+9
...@@ -135,6 +135,15 @@ fn exit2(code: usize) noreturn {...@@ -135,6 +135,15 @@ fn exit2(code: usize) noreturn {
135 : "rcx", "r11", "memory"135 : "rcx", "r11", "memory"
136 );136 );
137 },137 },
138 // TODO once we get stack setting with assembly on
139 // arm, exit with 0 instead of stack garbage
140 .aarch64 => {
141 asm volatile ("svc #0"
142 :
143 : [exit] "{x0}" (0x08)
144 : "memory", "cc"
145 );
146 },
138 else => @compileError("TODO"),147 else => @compileError("TODO"),
139 },148 },
140 else => @compileError("TODO"),149 else => @compileError("TODO"),
src/codegen.zig+50
...@@ -2607,6 +2607,56 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2607,6 +2607,56 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2607 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});2607 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
2608 }2608 }
2609 },2609 },
2610 .aarch64 => {
2611 for (info.args) |mc_arg, arg_i| {
2612 const arg = inst.args[arg_i];
2613 const arg_mcv = try self.resolveInst(inst.args[arg_i]);
2614
2615 switch (mc_arg) {
2616 .none => continue,
2617 .undef => unreachable,
2618 .immediate => unreachable,
2619 .unreach => unreachable,
2620 .dead => unreachable,
2621 .embedded_in_code => unreachable,
2622 .memory => unreachable,
2623 .compare_flags_signed => unreachable,
2624 .compare_flags_unsigned => unreachable,
2625 .register => |reg| {
2626 try self.register_manager.getReg(reg, null);
2627 try self.genSetReg(arg.src, arg.ty, reg, arg_mcv);
2628 },
2629 .stack_offset => {
2630 return self.fail(inst.base.src, "TODO implement calling with parameters in memory", .{});
2631 },
2632 .ptr_stack_offset => {
2633 return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_stack_offset arg", .{});
2634 },
2635 .ptr_embedded_in_code => {
2636 return self.fail(inst.base.src, "TODO implement calling with MCValue.ptr_embedded_in_code arg", .{});
2637 },
2638 }
2639 }
2640 if (inst.func.value()) |func_value| {
2641 if (func_value.castTag(.function)) |func_payload| {
2642 const ptr_bits = self.target.cpu.arch.ptrBitWidth();
2643 const ptr_bytes: u64 = @divExact(ptr_bits, 8);
2644 const got_addr = p9.bases.data;
2645 const got_index = func_payload.data.owner_decl.link.plan9.got_index.?;
2646 const fn_got_addr = got_addr + got_index * ptr_bytes;
2647
2648 try self.genSetReg(inst.base.src, Type.initTag(.usize), .x30, .{ .memory = fn_got_addr });
2649
2650 writeInt(u32, try self.code.addManyAsArray(4), Instruction.blr(.x30).toU32());
2651 } else if (func_value.castTag(.extern_fn)) |_| {
2652 return self.fail(inst.base.src, "TODO implement calling extern functions", .{});
2653 } else {
2654 return self.fail(inst.base.src, "TODO implement calling bitcasted functions", .{});
2655 }
2656 } else {
2657 return self.fail(inst.base.src, "TODO implement calling runtime known function pointer", .{});
2658 }
2659 },
2610 else => return self.fail(inst.base.src, "TODO implement call on plan9 for {}", .{self.target.cpu.arch}),2660 else => return self.fail(inst.base.src, "TODO implement call on plan9 for {}", .{self.target.cpu.arch}),
2611 }2661 }
2612 } else unreachable;2662 } else unreachable;
src/link/Plan9.zig+7-2
...@@ -78,15 +78,20 @@ pub const DeclBlock = struct {...@@ -78,15 +78,20 @@ pub const DeclBlock = struct {
78pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases {78pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases {
79 return switch (arch) {79 return switch (arch) {
80 .x86_64 => .{80 .x86_64 => .{
81 // 0x28 => 40 == header size81 // header size => 40 => 0x28
82 .text = 0x200028,82 .text = 0x200028,
83 .data = 0x400000,83 .data = 0x400000,
84 },84 },
85 .i386 => .{85 .i386 => .{
86 // 0x20 => 32 == header size86 // header size => 32 => 0x20
87 .text = 0x200020,87 .text = 0x200020,
88 .data = 0x400000,88 .data = 0x400000,
89 },89 },
90 .aarch64 => .{
91 // header size => 40 => 0x28
92 .text = 0x10028,
93 .data = 0x20000,
94 },
90 else => std.debug.panic("find default base address for {}", .{arch}),95 else => std.debug.panic("find default base address for {}", .{arch}),
91 };96 };
92}97}
test/stage2/plan9.zig+11-3
...@@ -2,16 +2,24 @@ const std = @import("std");...@@ -2,16 +2,24 @@ const std = @import("std");
2const TestContext = @import("../../src/test.zig").TestContext;2const TestContext = @import("../../src/test.zig").TestContext;
33
4pub fn addCases(ctx: *TestContext) !void {4pub fn addCases(ctx: *TestContext) !void {
5 const target: std.zig.CrossTarget = .{5 const x64: std.zig.CrossTarget = .{
6 .cpu_arch = .x86_64,6 .cpu_arch = .x86_64,
7 .os_tag = .plan9,7 .os_tag = .plan9,
8 };8 };
9 const aarch64: std.zig.CrossTarget = .{
10 .cpu_arch = .aarch64,
11 .os_tag = .plan9,
12 };
13 {
14 var case = ctx.exe("plan9: exiting correctly x64", x64);
15 case.addCompareOutput("pub fn main() void {}", "");
16 }
9 {17 {
10 var case = ctx.exe("plan9: exiting correctly", target);18 var case = ctx.exe("plan9: exiting correctly arm", aarch64);
11 case.addCompareOutput("pub fn main() void {}", "");19 case.addCompareOutput("pub fn main() void {}", "");
12 }20 }
13 {21 {
14 var case = ctx.exe("plan9: hello world", target);22 var case = ctx.exe("plan9: hello world", x64);
15 case.addCompareOutput(23 case.addCompareOutput(
16 \\pub fn main() void {24 \\pub fn main() void {
17 \\ const str = "Hello World!\n";25 \\ const str = "Hello World!\n";