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.
This commit is contained in:
Jakub Konka
2021-11-09 16:56:36 +01:00
committed by Andrew Kelley
parent b521510cd4
commit 91c3206b45
5 changed files with 40 additions and 15 deletions

View File

@@ -2393,6 +2393,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
},
.Int => {
const info = typed_value.ty.intInfo(self.target.*);
if (info.bits <= ptr_bits and info.signedness == .signed) {
return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };
}
if (info.bits > ptr_bits or info.signedness == .signed) {
return self.fail("TODO const int bigger than ptr and signed int", .{});
}

View File

@@ -1,4 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
const DW = std.dwarf;
const assert = std.debug.assert;
const testing = std.testing;
@@ -58,10 +59,19 @@ pub const Register = enum(u6) {
// zig fmt: on
pub const callee_preserved_regs = [_]Register{
.x19, .x20, .x21, .x22, .x23,
.x24, .x25, .x26, .x27, .x28,
const callee_preserved_regs_impl = if (builtin.os.tag.isDarwin()) struct {
pub const callee_preserved_regs = [_]Register{
.x20, .x21, .x22, .x23,
.x24, .x25, .x26, .x27,
.x28,
};
} else struct {
pub const callee_preserved_regs = [_]Register{
.x19, .x20, .x21, .x22, .x23,
.x24, .x25, .x26, .x27, .x28,
};
};
pub const callee_preserved_regs = callee_preserved_regs_impl.callee_preserved_regs;
pub const c_abi_int_param_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };
pub const c_abi_int_return_regs = [_]Register{ .x0, .x1, .x2, .x3, .x4, .x5, .x6, .x7 };

View File

@@ -3178,6 +3178,9 @@ fn genTypedValue(self: *Self, typed_value: TypedValue) InnerError!MCValue {
},
.Int => {
const info = typed_value.ty.intInfo(self.target.*);
if (info.bits <= ptr_bits and info.signedness == .signed) {
return MCValue{ .immediate = @bitCast(u64, typed_value.val.toSignedInt()) };
}
if (info.bits > ptr_bits or info.signedness == .signed) {
return self.fail("TODO const int bigger than ptr and signed int", .{});
}

View File

@@ -3285,6 +3285,7 @@ fn placeDecl(self: *MachO, decl: *Module.Decl, code_len: usize) !*macho.nlist_64
.seg = self.data_const_segment_cmd_index.?,
.sect = self.got_section_index.?,
}).? + 1);
got_atom.dirty = true;
}
symbol.n_value = vaddr;

View File

@@ -45,18 +45,32 @@ pub fn addCases(ctx: *TestContext) !void {
"Hello, World!\n",
);
// Now using start.zig without an explicit extern exit fn
case.addCompareOutput(
\\extern fn write(usize, usize, usize) usize;
\\
\\pub fn main() void {
\\ print();
\\}
\\
\\fn print() void {
\\ const msg = @ptrToInt("Hello, World!\n");
\\ const len = 14;
\\ _ = write(1, msg, len);
\\}
,
"Hello, World!\n",
);
// Print it 4 times and force growth and realloc.
case.addCompareOutput(
\\extern fn write(usize, usize, usize) usize;
\\extern fn exit(usize) noreturn;
\\
\\pub export fn main() noreturn {
\\pub fn main() void {
\\ print();
\\ print();
\\ print();
\\ print();
\\
\\ exit(0);
\\}
\\
\\fn print() void {
@@ -75,12 +89,9 @@ pub fn addCases(ctx: *TestContext) !void {
// Print it once, and change the message.
case.addCompareOutput(
\\extern fn write(usize, usize, usize) usize;
\\extern fn exit(usize) noreturn;
\\
\\pub export fn main() noreturn {
\\pub fn main() void {
\\ print();
\\
\\ exit(0);
\\}
\\
\\fn print() void {
@@ -95,13 +106,10 @@ pub fn addCases(ctx: *TestContext) !void {
// Now we print it twice.
case.addCompareOutput(
\\extern fn write(usize, usize, usize) usize;
\\extern fn exit(usize) noreturn;
\\
\\pub export fn main() noreturn {
\\pub fn main() void {
\\ print();
\\ print();
\\
\\ exit(0);
\\}
\\
\\fn print() void {