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 {...@@ -2393,6 +2393,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
2393 },2393 },
2394 .Int => {2394 .Int => {
2395 const info = typed_value.ty.intInfo(self.target.*);2395 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 }
2396 if (info.bits > ptr_bits or info.signedness == .signed) {2399 if (info.bits > ptr_bits or info.signedness == .signed) {
2397 return self.fail("TODO const int bigger than ptr and signed int", .{});2400 return self.fail("TODO const int bigger than ptr and signed int", .{});
2398 }2401 }
src/arch/aarch64/bits.zig+13-3
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");
2const DW = std.dwarf;3const DW = std.dwarf;
3const assert = std.debug.assert;4const assert = std.debug.assert;
4const testing = std.testing;5const testing = std.testing;
...@@ -58,10 +59,19 @@ pub const Register = enum(u6) {...@@ -58,10 +59,19 @@ pub const Register = enum(u6) {
5859
59// zig fmt: on60// zig fmt: on
6061
61pub const callee_preserved_regs = [_]Register{62const callee_preserved_regs_impl = if (builtin.os.tag.isDarwin()) struct {
62 .x19, .x20, .x21, .x22, .x23,63 pub const callee_preserved_regs = [_]Register{
63 .x24, .x25, .x26, .x27, .x28,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 };
64};73};
74pub const callee_preserved_regs = callee_preserved_regs_impl.callee_preserved_regs;
6575
66pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };76pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
67pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };77pub 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 {...@@ -3178,6 +3178,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
3178 },3178 },
3179 .Int => {3179 .Int => {
3180 const info = typed_value.ty.intInfo(self.target.*);3180 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 }
3181 if (info.bits > ptr_bits or info.signedness == .signed) {3184 if (info.bits > ptr_bits or info.signedness == .signed) {
3182 return self.fail("TODO const int bigger than ptr and signed int", .{});3185 return self.fail("TODO const int bigger than ptr and signed int", .{});
3183 }3186 }
src/link/MachO.zig+1
...@@ -3285,6 +3285,7 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64...@@ -3285,6 +3285,7 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
3285 .seg = self.data_const_segment_cmd_index.?,3285 .seg = self.data_const_segment_cmd_index.?,
3286 .sect = self.got_section_index.?,3286 .sect = self.got_section_index.?,
3287 }).? + 1);3287 }).? + 1);
3288 got_atom.dirty = true;
3288 }3289 }
32893290
3290 symbol.n_value = vaddr;3291 symbol.n_value = vaddr;
test/stage2/darwin.zig+20-12
...@@ -45,18 +45,32 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -45,18 +45,32 @@ pub fn addCases(ctx: *TestContext) !void {
45 "Hello, World!\n",45 "Hello, World!\n",
46 );46 );
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
48 // Print it 4 times and force growth and realloc.65 // Print it 4 times and force growth and realloc.
49 case.addCompareOutput(66 case.addCompareOutput(
50 \\extern fn write(usize, usize, usize) usize;67 \\extern fn write(usize, usize, usize) usize;
51 \\extern fn exit(usize) noreturn;
52 \\68 \\
53 \\pub export fn main() noreturn {69 \\pub fn main() void {
54 \\ print();70 \\ print();
55 \\ print();71 \\ print();
56 \\ print();72 \\ print();
57 \\ print();73 \\ print();
58 \\
59 \\ exit(0);
60 \\}74 \\}
61 \\75 \\
62 \\fn print() void {76 \\fn print() void {
...@@ -75,12 +89,9 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -75,12 +89,9 @@ pub fn addCases(ctx: *TestContext) !void {
75 // Print it once, and change the message.89 // Print it once, and change the message.
76 case.addCompareOutput(90 case.addCompareOutput(
77 \\extern fn write(usize, usize, usize) usize;91 \\extern fn write(usize, usize, usize) usize;
78 \\extern fn exit(usize) noreturn;
79 \\92 \\
80 \\pub export fn main() noreturn {93 \\pub fn main() void {
81 \\ print();94 \\ print();
82 \\
83 \\ exit(0);
84 \\}95 \\}
85 \\96 \\
86 \\fn print() void {97 \\fn print() void {
...@@ -95,13 +106,10 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -95,13 +106,10 @@ pub fn addCases(ctx: *TestContext) !void {
95 // Now we print it twice.106 // Now we print it twice.
96 case.addCompareOutput(107 case.addCompareOutput(
97 \\extern fn write(usize, usize, usize) usize;108 \\extern fn write(usize, usize, usize) usize;
98 \\extern fn exit(usize) noreturn;
99 \\109 \\
100 \\pub export fn main() noreturn {110 \\pub fn main() void {
101 \\ print();111 \\ print();
102 \\ print();112 \\ print();
103 \\
104 \\ exit(0);
105 \\}113 \\}
106 \\114 \\
107 \\fn print() void {115 \\fn print() void {