Skip to content

Commit 53a0b79

Browse files
authored
Merge pull request #7681 from kubkon/stage2-aarch64-fn-args
stage2: basic fn args for aarch64
2 parents c8e44d8 + 807dc56 commit 53a0b79

File tree

3 files changed

+111
-2
lines changed

3 files changed

+111
-2
lines changed

src/codegen.zig

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

0 commit comments

Comments
 (0)