authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-03 19:51:38-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-01-03 19:51:38-08:00
log53a0b7997d1ee51f1c93cb44e6ee967e244b0c7d
tree49bf490307029821e76e9561f2312e92592c1197
parentc8e44d82bd4dcd8f6beeb771027d38a576674364
parent807dc56fd6c9af2603e3db9c1160b0a72fc703c0
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #7681 from kubkon/stage2-aarch64-fn-args

stage2: basic fn args for aarch64

3 files changed, 111 insertions(+), 2 deletions(-)

src/codegen.zig+66-1
...@@ -2837,7 +2837,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2837,7 +2837,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2837 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 48), 48).toU32());2837 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 48), 48).toU32());
2838 }2838 }
2839 },2839 },
2840 .register => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),2840 .register => |src_reg| {
2841 // If the registers are the same, nothing to do.
2842 if (src_reg.id() == reg.id())
2843 return;
2844
2845 // mov reg, src_reg
2846 writeInt(u32, try self.code.addManyAsArray(4), Instruction.orr(
2847 reg,
2848 .xzr,
2849 src_reg,
2850 Instruction.Shift.none,
2851 ).toU32());
2852 },
2841 .memory => |addr| {2853 .memory => |addr| {
2842 if (self.bin_file.options.pie) {2854 if (self.bin_file.options.pie) {
2843 // For MachO, the binary, with the exception of object files, has to be a PIE.2855 // For MachO, the binary, with the exception of object files, has to be a PIE.
...@@ -3475,6 +3487,59 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3475,6 +3487,59 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3475 else => return self.fail(src, "TODO implement function parameters for {} on arm", .{cc}),3487 else => return self.fail(src, "TODO implement function parameters for {} on arm", .{cc}),
3476 }3488 }
3477 },3489 },
3490 .aarch64 => {
3491 switch (cc) {
3492 .Naked => {
3493 assert(result.args.len == 0);
3494 result.return_value = .{ .unreach = {} };
3495 result.stack_byte_count = 0;
3496 result.stack_align = 1;
3497 return result;
3498 },
3499 .Unspecified, .C => {
3500 // ARM64 Procedure Call Standard
3501 var ncrn: usize = 0; // Next Core Register Number
3502 var nsaa: u32 = 0; // Next stacked argument address
3503
3504 for (param_types) |ty, i| {
3505 // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned
3506 // values to spread across odd-numbered registers.
3507 if (ty.abiAlignment(self.target.*) == 16 and !self.target.isDarwin()) {
3508 // Round up NCRN to the next even number
3509 ncrn += ncrn % 2;
3510 }
3511
3512 const param_size = @intCast(u32, ty.abiSize(self.target.*));
3513 if (std.math.divCeil(u32, param_size, 8) catch unreachable <= 8 - ncrn) {
3514 if (param_size <= 8) {
3515 result.args[i] = .{ .register = c_abi_int_param_regs[ncrn] };
3516 ncrn += 1;
3517 } else {
3518 return self.fail(src, "TODO MCValues with multiple registers", .{});
3519 }
3520 } else if (ncrn < 8 and nsaa == 0) {
3521 return self.fail(src, "TODO MCValues split between registers and stack", .{});
3522 } else {
3523 ncrn = 8;
3524 // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided
3525 // that the entire stack space consumed by the arguments is 8-byte aligned.
3526 if (ty.abiAlignment(self.target.*) == 8) {
3527 if (nsaa % 8 != 0) {
3528 nsaa += 8 - (nsaa % 8);
3529 }
3530 }
3531
3532 result.args[i] = .{ .stack_offset = nsaa };
3533 nsaa += param_size;
3534 }
3535 }
3536
3537 result.stack_byte_count = nsaa;
3538 result.stack_align = 16;
3539 },
3540 else => return self.fail(src, "TODO implement function parameters for {} on aarch64", .{cc}),
3541 }
3542 },
3478 else => if (param_types.len != 0)3543 else => if (param_types.len != 0)
3479 return self.fail(src, "TODO implement codegen parameters for {}", .{self.target.cpu.arch}),3544 return self.fail(src, "TODO implement codegen parameters for {}", .{self.target.cpu.arch}),
3480 }3545 }
src/link/MachO.zig+1-1
...@@ -298,7 +298,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio...@@ -298,7 +298,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
298 self.base.file = file;298 self.base.file = file;
299299
300 // Create dSYM bundle.300 // Create dSYM bundle.
301 const d_sym_path = try fmt.allocPrint(allocator, "{}.dSYM/Contents/Resources/DWARF/", .{sub_path});301 const d_sym_path = try fmt.allocPrint(allocator, "{s}.dSYM/Contents/Resources/DWARF/", .{sub_path});
302 defer allocator.free(d_sym_path);302 defer allocator.free(d_sym_path);
303 var d_sym_bundle = try options.emit.?.directory.handle.makeOpenPath(d_sym_path, .{});303 var d_sym_bundle = try options.emit.?.directory.handle.makeOpenPath(d_sym_path, .{});
304 defer d_sym_bundle.close();304 defer d_sym_bundle.close();
test/stage2/aarch64.zig+44
...@@ -155,4 +155,48 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -155,4 +155,48 @@ pub fn addCases(ctx: *TestContext) !void {
155 "Hello, World!\n",155 "Hello, World!\n",
156 );156 );
157 }157 }
158
159 {
160 var case = ctx.exe("exit fn taking argument", macos_aarch64);
161
162 case.addCompareOutput(
163 \\export fn _start() noreturn {
164 \\ exit(0);
165 \\}
166 \\
167 \\fn exit(ret: usize) noreturn {
168 \\ asm volatile ("svc #0x80"
169 \\ :
170 \\ : [number] "{x16}" (1),
171 \\ [arg1] "{x0}" (ret)
172 \\ : "memory"
173 \\ );
174 \\ unreachable;
175 \\}
176 ,
177 "",
178 );
179 }
180
181 {
182 var case = ctx.exe("exit fn taking argument", linux_aarch64);
183
184 case.addCompareOutput(
185 \\export fn _start() noreturn {
186 \\ exit(0);
187 \\}
188 \\
189 \\fn exit(ret: usize) noreturn {
190 \\ asm volatile ("svc #0"
191 \\ :
192 \\ : [number] "{x8}" (93),
193 \\ [arg1] "{x0}" (ret)
194 \\ : "memory", "cc"
195 \\ );
196 \\ unreachable;
197 \\}
198 ,
199 "",
200 );
201 }
158}202}