| ... | ... | @@ -641,20 +641,33 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 641 | 641 | const cc = self.fn_type.fnCallingConvention(); |
| 642 | 642 | if (cc != .Naked) { |
| 643 | 643 | // TODO Finish function prologue and epilogue for aarch64. |
| 644 | | // Reserve the stack for local variables, etc. |
| 645 | 644 | |
| 646 | 645 | // stp fp, lr, [sp, #-16]! |
| 646 | // mov fp, sp |
| 647 | // sub sp, sp, #reloc |
| 647 | 648 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.stp( |
| 648 | 649 | .x29, |
| 649 | 650 | .x30, |
| 650 | 651 | Register.sp, |
| 651 | 652 | Instruction.LoadStorePairOffset.pre_index(-16), |
| 652 | 653 | ).toU32()); |
| 654 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.add(.x29, .xzr, 0, false).toU32()); |
| 655 | const backpatch_reloc = self.code.items.len; |
| 656 | try self.code.resize(backpatch_reloc + 4); |
| 653 | 657 | |
| 654 | 658 | try self.dbgSetPrologueEnd(); |
| 655 | 659 | |
| 656 | 660 | try self.genBody(self.mod_fn.body); |
| 657 | 661 | |
| 662 | // Backpatch stack offset |
| 663 | const stack_end = self.max_end_stack; |
| 664 | const aligned_stack_end = mem.alignForward(stack_end, self.stack_align); |
| 665 | if (math.cast(u12, aligned_stack_end)) |size| { |
| 666 | writeInt(u32, self.code.items[backpatch_reloc..][0..4], Instruction.sub(.xzr, .xzr, size, false).toU32()); |
| 667 | } else |_| { |
| 668 | return self.failSymbol("TODO AArch64: allow larger stacks", .{}); |
| 669 | } |
| 670 | |
| 658 | 671 | try self.dbgSetEpilogueBegin(); |
| 659 | 672 | |
| 660 | 673 | // exitlude jumps |
| ... | ... | @@ -690,6 +703,8 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 690 | 703 | Register.sp, |
| 691 | 704 | Instruction.LoadStorePairOffset.post_index(16), |
| 692 | 705 | ).toU32()); |
| 706 | // add sp, sp, #stack_size |
| 707 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.add(.xzr, .xzr, @intCast(u12, aligned_stack_end), false).toU32()); |
| 693 | 708 | // ret lr |
| 694 | 709 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.ret(null).toU32()); |
| 695 | 710 | } else { |
| ... | ... | @@ -2685,9 +2700,9 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2685 | 2700 | |
| 2686 | 2701 | switch (abi_size) { |
| 2687 | 2702 | 1, 4 => { |
| 2688 | | const offset = if (adj_off <= math.maxInt(u12)) blk: { |
| 2689 | | break :blk Instruction.Offset.imm(@intCast(u12, adj_off)); |
| 2690 | | } else Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }), 0); |
| 2703 | const offset = if (math.cast(u12, adj_off)) |imm| blk: { |
| 2704 | break :blk Instruction.Offset.imm(imm); |
| 2705 | } else |_| Instruction.Offset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off }), 0); |
| 2691 | 2706 | const str = switch (abi_size) { |
| 2692 | 2707 | 1 => Instruction.strb, |
| 2693 | 2708 | 4 => Instruction.str, |
| ... | ... | @@ -2848,12 +2863,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2848 | 2863 | |
| 2849 | 2864 | switch (abi_size) { |
| 2850 | 2865 | 4, 8 => { |
| 2851 | | const offset = if (adj_off <= math.maxInt(u12)) blk: { |
| 2852 | | break :blk Instruction.LoadStoreOffset.imm(@intCast(u12, adj_off)); |
| 2853 | | } else Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off })); |
| 2854 | | const rn: Register = switch (abi_size) { |
| 2855 | | 4 => .w29, |
| 2856 | | 8 => .x29, |
| 2866 | const offset = if (math.cast(i9, adj_off)) |imm| |
| 2867 | Instruction.LoadStoreOffset.imm_post_index(-imm) |
| 2868 | else |_| |
| 2869 | Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off })); |
| 2870 | const rn: Register = switch (arch) { |
| 2871 | .aarch64, .aarch64_be => .x29, |
| 2872 | .aarch64_32 => .w29, |
| 2857 | 2873 | else => unreachable, |
| 2858 | 2874 | }; |
| 2859 | 2875 | |