| ... | ... | @@ -2837,7 +2837,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2837 | 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 | 2853 | .memory => |addr| { |
| 2842 | 2854 | if (self.bin_file.options.pie) { |
| 2843 | 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 | 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 | 3543 | else => if (param_types.len != 0) |
| 3479 | 3544 | return self.fail(src, "TODO implement codegen parameters for {}", .{self.target.cpu.arch}), |
| 3480 | 3545 | } |