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:
committed by
Andrew Kelley
parent
b521510cd4
commit
91c3206b45
@@ -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", .{});
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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", .{});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user