authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-17 10:37:23+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-17 14:57:36+01:00
loge292f33de75fa00863a855161d6df9f6884df841
treef187fe5f8f865e5db5f658387e2be1ec4bb4acc9
parent44135ea84e562ae67a5eeced99566be58bffc6fc

stage2 aarch64: add basic genSetStack


1 files changed, 63 insertions(+), 0 deletions(-)

src/codegen.zig+63
...@@ -2758,6 +2758,69 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2758,6 +2758,69 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2758 return self.genSetStack(src, ty, stack_offset, MCValue{ .register = reg });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 else => return self.fail(src, "TODO implement getSetStack for {}", .{self.target.cpu.arch}),2824 else => return self.fail(src, "TODO implement getSetStack for {}", .{self.target.cpu.arch}),
2762 }2825 }
2763 }2826 }