| ... | ... | @@ -2730,13 +2730,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2730 | 2730 | // For MachO, the binary, with the exception of object files, has to be a PIE. |
| 2731 | 2731 | // Therefore we cannot load an absolute address. |
| 2732 | 2732 | // Instead, we need to make use of PC-relative addressing. |
| 2733 | | // TODO This needs to be optimised in the stack usage (perhaps use a shadow stack |
| 2734 | | // like described here: |
| 2735 | | // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/using-the-stack-in-aarch64-implementing-push-and-pop) |
| 2736 | | // TODO As far as branching is concerned, instead of saving the return address |
| 2737 | | // in a register, I'm thinking here of immitating x86_64, and having the address |
| 2738 | | // passed on the stack. |
| 2739 | 2733 | if (reg.id() == 0) { // x0 is special-cased |
| 2734 | // TODO This needs to be optimised in the stack usage (perhaps use a shadow stack |
| 2735 | // like described here: |
| 2736 | // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/using-the-stack-in-aarch64-implementing-push-and-pop) |
| 2740 | 2737 | // str x28, [sp, #-16] |
| 2741 | 2738 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x28, Register.sp, .{ |
| 2742 | 2739 | .offset = Instruction.Offset.imm_pre_index(-16), |
| ... | ... | @@ -2755,21 +2752,25 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2755 | 2752 | // b [label] |
| 2756 | 2753 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32()); |
| 2757 | 2754 | // mov r, x0 |
| 2758 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(reg, .x0, Instruction.RegisterShift.none()).toU32()); |
| 2755 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr( |
| 2756 | reg, |
| 2757 | .x0, |
| 2758 | Instruction.RegisterShift.none(), |
| 2759 | ).toU32()); |
| 2759 | 2760 | // ldr x28, [sp], #16 |
| 2760 | 2761 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{ |
| 2761 | 2762 | .rn = Register.sp, |
| 2762 | 2763 | .offset = Instruction.Offset.imm_post_index(16), |
| 2763 | 2764 | }).toU32()); |
| 2764 | 2765 | } else { |
| 2765 | | // str x28, [sp, #-16] |
| 2766 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x28, Register.sp, .{ |
| 2767 | | .offset = Instruction.Offset.imm_pre_index(-16), |
| 2768 | | }).toU32()); |
| 2769 | | // str x0, [sp, #-16] |
| 2770 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x0, Register.sp, .{ |
| 2771 | | .offset = Instruction.Offset.imm_pre_index(-16), |
| 2772 | | }).toU32()); |
| 2766 | // stp x0, x28, [sp, #-16] |
| 2767 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.stp( |
| 2768 | .x0, |
| 2769 | .x28, |
| 2770 | Register.sp, |
| 2771 | -2, |
| 2772 | .SignedOffset, |
| 2773 | ).toU32()); |
| 2773 | 2774 | // adr x28, #8 |
| 2774 | 2775 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32()); |
| 2775 | 2776 | if (self.bin_file.cast(link.File.MachO)) |macho_file| { |
| ... | ... | @@ -2784,17 +2785,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2784 | 2785 | // b [label] |
| 2785 | 2786 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32()); |
| 2786 | 2787 | // mov r, x0 |
| 2787 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(reg, .x0, Instruction.RegisterShift.none()).toU32()); |
| 2788 | | // ldr x0, [sp], #16 |
| 2789 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x0, .{ |
| 2790 | | .rn = Register.sp, |
| 2791 | | .offset = Instruction.Offset.imm_post_index(16), |
| 2792 | | }).toU32()); |
| 2793 | | // ldr x28, [sp], #16 |
| 2794 | | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{ |
| 2795 | | .rn = Register.sp, |
| 2796 | | .offset = Instruction.Offset.imm_post_index(16), |
| 2797 | | }).toU32()); |
| 2788 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr( |
| 2789 | reg, |
| 2790 | .x0, |
| 2791 | Instruction.RegisterShift.none(), |
| 2792 | ).toU32()); |
| 2793 | // ldp x0, x28, [sp, #16] |
| 2794 | mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldp( |
| 2795 | .x0, |
| 2796 | .x28, |
| 2797 | Register.sp, |
| 2798 | 2, |
| 2799 | .SignedOffset, |
| 2800 | ).toU32()); |
| 2798 | 2801 | } |
| 2799 | 2802 | } else { |
| 2800 | 2803 | // The value is in memory at a hard-coded address. |