authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-11-09 16:56:36+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-11-10 11:33:24-05:00
log91c3206b45074821749f52043937bf6ed6d9a105
tree5d6d674d146e4189bc22865bed42dea0f9ada320
parentb521510cd4e68407226dd95c9e87cc97ca5a0796

macho: use start.zig for macOS entrypoint

This effectively allows us to compile ```zig pub fn main() void {} ``` which then calls into `std.start`. Changes required to make this happen: * handle signed int to immediate in x86_64 and aarch64 codegen * ensure that on arm64 macOS, `.x19` is a caller-preserved register - I'm not sure about that one at all and would like to brainstorm it with anyone interested and especially Joachim. * finally, fix a bug in the linker - mark new got entry as dirty upon atom growth.

5 files changed, 40 insertions(+), 15 deletions(-)

src/arch/aarch64/CodeGen.zig+3
......@@ -2393,6 +2393,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
23932393 },
23942394 .Int => {
23952395 const info = typed_value.ty.intInfo(self.target.*);
2396 if (info.bits <= ptr_bits and info.signedness == .signed) {
2397 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };
2398 }
23962399 if (info.bits > ptr_bits or info.signedness == .signed) {
23972400 return self.fail("TODO const int bigger than ptr and signed int", .{});
23982401 }
src/arch/aarch64/bits.zig+13-3
......@@ -1,4 +1,5 @@
11const std = @import("std");
2const builtin = @import("builtin");
23const DW = std.dwarf;
34const assert = std.debug.assert;
45const testing = std.testing;
......@@ -58,10 +59,19 @@ pub const Register = enum(u6) {
5859
5960// zig fmt: on
6061
61pub const callee_preserved_regs = [_]Register{
62 .x19, .x20, .x21, .x22, .x23,
63 .x24, .x25, .x26, .x27, .x28,
62const callee_preserved_regs_impl = if (builtin.os.tag.isDarwin()) struct {
63 pub const callee_preserved_regs = [_]Register{
64 .x20, .x21, .x22, .x23,
65 .x24, .x25, .x26, .x27,
66 .x28,
67 };
68} else struct {
69 pub const callee_preserved_regs = [_]Register{
70 .x19, .x20, .x21, .x22, .x23,
71 .x24, .x25, .x26, .x27, .x28,
72 };
6473};
74pub const callee_preserved_regs = callee_preserved_regs_impl.callee_preserved_regs;
6575
6676pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
6777pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
src/arch/x86_64/CodeGen.zig+3
......@@ -3178,6 +3178,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
31783178 },
31793179 .Int => {
31803180 const info = typed_value.ty.intInfo(self.target.*);
3181 if (info.bits <= ptr_bits and info.signedness == .signed) {
3182 return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };
3183 }
31813184 if (info.bits > ptr_bits or info.signedness == .signed) {
31823185 return self.fail("TODO const int bigger than ptr and signed int", .{});
31833186 }
src/link/MachO.zig+1
......@@ -3285,6 +3285,7 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
32853285 .seg = self.data_const_segment_cmd_index.?,
32863286 .sect = self.got_section_index.?,
32873287 }).? + 1);
3288 got_atom.dirty = true;
32883289 }
32893290
32903291 symbol.n_value = vaddr;
test/stage2/darwin.zig+20-12
......@@ -45,18 +45,32 @@ pub fn addCases(ctx: *TestContext) !void {
4545 "Hello, World!\n",
4646 );
4747
48 // Now using start.zig without an explicit extern exit fn
49 case.addCompareOutput(
50 \\extern fn write(usize, usize, usize) usize;
51 \\
52 \\pub fn main() void {
53 \\ print();
54 \\}
55 \\
56 \\fn print() void {
57 \\ const msg = @ptrToInt("Hello, World!\n");
58 \\ const len = 14;
59 \\ _ = write(1, msg, len);
60 \\}
61 ,
62 "Hello, World!\n",
63 );
64
4865 // Print it 4 times and force growth and realloc.
4966 case.addCompareOutput(
5067 \\extern fn write(usize, usize, usize) usize;
51 \\extern fn exit(usize) noreturn;
5268 \\
53 \\pub export fn main() noreturn {
69 \\pub fn main() void {
5470 \\ print();
5571 \\ print();
5672 \\ print();
5773 \\ print();
58 \\
59 \\ exit(0);
6074 \\}
6175 \\
6276 \\fn print() void {
......@@ -75,12 +89,9 @@ pub fn addCases(ctx: *TestContext) !void {
7589 // Print it once, and change the message.
7690 case.addCompareOutput(
7791 \\extern fn write(usize, usize, usize) usize;
78 \\extern fn exit(usize) noreturn;
7992 \\
80 \\pub export fn main() noreturn {
93 \\pub fn main() void {
8194 \\ print();
82 \\
83 \\ exit(0);
8495 \\}
8596 \\
8697 \\fn print() void {
......@@ -95,13 +106,10 @@ pub fn addCases(ctx: *TestContext) !void {
95106 // Now we print it twice.
96107 case.addCompareOutput(
97108 \\extern fn write(usize, usize, usize) usize;
98 \\extern fn exit(usize) noreturn;
99109 \\
100 \\pub export fn main() noreturn {
110 \\pub fn main() void {
101111 \\ print();
102112 \\ print();
103 \\
104 \\ exit(0);
105113 \\}
106114 \\
107115 \\fn print() void {