diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-01-03 19:51:38 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-03 19:51:38 -0800 |
| commit | 53a0b7997d1ee51f1c93cb44e6ee967e244b0c7d (patch) | |
| tree | 49bf490307029821e76e9561f2312e92592c1197 /src/codegen.zig | |
| parent | c8e44d82bd4dcd8f6beeb771027d38a576674364 (diff) | |
| parent | 807dc56fd6c9af2603e3db9c1160b0a72fc703c0 (diff) | |
| download | zig-53a0b7997d1ee51f1c93cb44e6ee967e244b0c7d.tar.gz zig-53a0b7997d1ee51f1c93cb44e6ee967e244b0c7d.zip | |
Merge pull request #7681 from kubkon/stage2-aarch64-fn-args
stage2: basic fn args for aarch64
Diffstat (limited to 'src/codegen.zig')
| -rw-r--r-- | src/codegen.zig | 67 |
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}), } |
