aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/codegen.zig67
1 files changed, 66 insertions, 1 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 58be73a31c..cd6ea15737 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -2837,7 +2837,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.movk(reg, @intCast(u16, x >> 48), 48).toU32());
}
},
- .register => return self.fail(src, "TODO implement genSetReg for aarch64 {}", .{mcv}),
+ .register => |src_reg| {
+ // If the registers are the same, nothing to do.
+ if (src_reg.id() == reg.id())
+ return;
+
+ // mov reg, src_reg
+ writeInt(u32, try self.code.addManyAsArray(4), Instruction.orr(
+ reg,
+ .xzr,
+ src_reg,
+ Instruction.Shift.none,
+ ).toU32());
+ },
.memory => |addr| {
if (self.bin_file.options.pie) {
// 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 {
else => return self.fail(src, "TODO implement function parameters for {} on arm", .{cc}),
}
},
+ .aarch64 => {
+ switch (cc) {
+ .Naked => {
+ assert(result.args.len == 0);
+ result.return_value = .{ .unreach = {} };
+ result.stack_byte_count = 0;
+ result.stack_align = 1;
+ return result;
+ },
+ .Unspecified, .C => {
+ // ARM64 Procedure Call Standard
+ var ncrn: usize = 0; // Next Core Register Number
+ var nsaa: u32 = 0; // Next stacked argument address
+
+ for (param_types) |ty, i| {
+ // We round up NCRN only for non-Apple platforms which allow the 16-byte aligned
+ // values to spread across odd-numbered registers.
+ if (ty.abiAlignment(self.target.*) == 16 and !self.target.isDarwin()) {
+ // Round up NCRN to the next even number
+ ncrn += ncrn % 2;
+ }
+
+ const param_size = @intCast(u32, ty.abiSize(self.target.*));
+ if (std.math.divCeil(u32, param_size, 8) catch unreachable <= 8 - ncrn) {
+ if (param_size <= 8) {
+ result.args[i] = .{ .register = c_abi_int_param_regs[ncrn] };
+ ncrn += 1;
+ } else {
+ return self.fail(src, "TODO MCValues with multiple registers", .{});
+ }
+ } else if (ncrn < 8 and nsaa == 0) {
+ return self.fail(src, "TODO MCValues split between registers and stack", .{});
+ } else {
+ ncrn = 8;
+ // TODO Apple allows the arguments on the stack to be non-8-byte aligned provided
+ // that the entire stack space consumed by the arguments is 8-byte aligned.
+ if (ty.abiAlignment(self.target.*) == 8) {
+ if (nsaa % 8 != 0) {
+ nsaa += 8 - (nsaa % 8);
+ }
+ }
+
+ result.args[i] = .{ .stack_offset = nsaa };
+ nsaa += param_size;
+ }
+ }
+
+ result.stack_byte_count = nsaa;
+ result.stack_align = 16;
+ },
+ else => return self.fail(src, "TODO implement function parameters for {} on aarch64", .{cc}),
+ }
+ },
else => if (param_types.len != 0)
return self.fail(src, "TODO implement codegen parameters for {}", .{self.target.cpu.arch}),
}