| ... | ... | @@ -2758,6 +2758,69 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2758 | 2758 | return self.genSetStack(src, ty, stack_offset, MCValue{ .register = reg }); |
| 2759 | 2759 | }, |
| 2760 | 2760 | }, |
| 2761 | .aarch64, .aarch64_be, .aarch64_32 => switch (mcv) { |
| 2762 | .dead => unreachable, |
| 2763 | .ptr_stack_offset => unreachable, |
| 2764 | .ptr_embedded_in_code => unreachable, |
| 2765 | .unreach, .none => return, // Nothing to do. |
| 2766 | .undef => { |
| 2767 | if (!self.wantSafety()) |
| 2768 | return; // The already existing value will do just fine. |
| 2769 | // TODO Upgrade this to a memset call when we have that available. |
| 2770 | switch (ty.abiSize(self.target.*)) { |
| 2771 | 1 => return self.genSetStack(src, ty, stack_offset, .{ .immediate = 0xaa }), |
| 2772 | 2 => return self.genSetStack(src, ty, stack_offset, .{ .immediate = 0xaaaa }), |
| 2773 | 4 => return self.genSetStack(src, ty, stack_offset, .{ .immediate = 0xaaaaaaaa }), |
| 2774 | 8 => return self.genSetStack(src, ty, stack_offset, .{ .immediate = 0xaaaaaaaaaaaaaaaa }), |
| 2775 | else => return self.fail(src, "TODO implement memset", .{}), |
| 2776 | } |
| 2777 | }, |
| 2778 | .compare_flags_unsigned => |op| { |
| 2779 | return self.fail(src, "TODO implement set stack variable with compare flags value (unsigned)", .{}); |
| 2780 | }, |
| 2781 | .compare_flags_signed => |op| { |
| 2782 | return self.fail(src, "TODO implement set stack variable with compare flags value (signed)", .{}); |
| 2783 | }, |
| 2784 | .immediate => { |
| 2785 | const reg = try self.copyToTmpRegister(src, mcv); |
| 2786 | return self.genSetStack(src, ty, stack_offset, MCValue{ .register = reg }); |
| 2787 | }, |
| 2788 | .embedded_in_code => |code_offset| { |
| 2789 | return self.fail(src, "TODO implement set stack variable from embedded_in_code", .{}); |
| 2790 | }, |
| 2791 | .register => |reg| { |
| 2792 | const abi_size = ty.abiSize(self.target.*); |
| 2793 | const adj_off = stack_offset + abi_size; |
| 2794 | |
| 2795 | switch (abi_size) { |
| 2796 | 4, 8 => { |
| 2797 | const offset = if (adj_off <= math.maxInt(u12)) blk: { |
| 2798 | break :blk Instruction.LoadStoreOffset.imm(@intCast(u12, adj_off)); |
| 2799 | } else Instruction.LoadStoreOffset.reg(try self.copyToTmpRegister(src, MCValue{ .immediate = adj_off })); |
| 2800 | const rn: Register = switch (abi_size) { |
| 2801 | 4 => .w29, |
| 2802 | 8 => .x29, |
| 2803 | else => unreachable, |
| 2804 | }; |
| 2805 | |
| 2806 | writeInt(u32, try self.code.addManyAsArray(4), Instruction.str(reg, rn, .{ |
| 2807 | .offset = offset, |
| 2808 | }).toU32()); |
| 2809 | }, |
| 2810 | else => return self.fail(src, "TODO implement storing other types abi_size={}", .{abi_size}), |
| 2811 | } |
| 2812 | }, |
| 2813 | .memory => |vaddr| { |
| 2814 | return self.fail(src, "TODO implement set stack variable from memory vaddr", .{}); |
| 2815 | }, |
| 2816 | .stack_offset => |off| { |
| 2817 | if (stack_offset == off) |
| 2818 | return; // Copy stack variable to itself; nothing to do. |
| 2819 | |
| 2820 | const reg = try self.copyToTmpRegister(src, mcv); |
| 2821 | return self.genSetStack(src, ty, stack_offset, MCValue{ .register = reg }); |
| 2822 | }, |
| 2823 | }, |
| 2761 | 2824 | else => return self.fail(src, "TODO implement getSetStack for {}", .{self.target.cpu.arch}), |
| 2762 | 2825 | } |
| 2763 | 2826 | } |