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 {
28372837 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 48), 48).toU32());
28382838 }
28392839 },
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 },
28412853 .memory => |addr| {
28422854 if (self.bin_file.options.pie) {
28432855 // 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 {
34753487 else => return self.fail(src, "TODO implement function parameters for {} on arm", .{cc}),
34763488 }
34773489 },
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 },
34783543 else => if (param_types.len != 0)
34793544 return self.fail(src, "TODO implement codegen parameters for {}", .{self.target.cpu.arch}),
34803545 }
src/link/MachO.zig+1-1
......@@ -298,7 +298,7 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
298298 self.base.file = file;
299299
300300 // 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});
302302 defer allocator.free(d_sym_path);
303303 var d_sym_bundle = try options.emit.?.directory.handle.makeOpenPath(d_sym_path, .{});
304304 defer d_sym_bundle.close();
test/stage2/aarch64.zig+44
......@@ -155,4 +155,48 @@ pub fn addCases(ctx: *TestContext) !void {
155155 "Hello, World!\n",
156156 );
157157 }
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 }
158202}