Commit 26116211ec

Koakuma <koachan@protonmail.com>
2022-05-14 17:43:46
stage2: sparc64: Implement inline memcpy for genSetStack
1 parent 7822426
Changed files (1)
src
arch
sparc64
src/arch/sparc64/CodeGen.zig
@@ -2375,7 +2375,47 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
                 return self.fail("TODO larger stack offsets", .{});
             return self.genStore(reg, .sp, i13, simm13, abi_size);
         },
-        .memory, .stack_offset => return self.fail("TODO implement memcpy", .{}),
+        .memory, .stack_offset => {
+            switch (mcv) {
+                .stack_offset => |off| {
+                    if (stack_offset == off)
+                        return; // Copy stack variable to itself; nothing to do.
+                },
+                else => {},
+            }
+
+            if (abi_size <= 8) {
+                const reg = try self.copyToTmpRegister(ty, mcv);
+                return self.genSetStack(ty, stack_offset, MCValue{ .register = reg });
+            } else {
+                var ptr_ty_payload: Type.Payload.ElemType = .{
+                    .base = .{ .tag = .single_mut_pointer },
+                    .data = ty,
+                };
+                const ptr_ty = Type.initPayload(&ptr_ty_payload.base);
+
+                const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null });
+                const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs);
+                defer for (regs_locks) |reg| {
+                    self.register_manager.unlockReg(reg);
+                };
+
+                const src_reg = regs[0];
+                const dst_reg = regs[1];
+                const len_reg = regs[2];
+                const tmp_reg = regs[3];
+
+                switch (mcv) {
+                    .stack_offset => |off| try self.genSetReg(ptr_ty, src_reg, .{ .ptr_stack_offset = off }),
+                    .memory => |addr| try self.genSetReg(Type.usize, src_reg, .{ .immediate = addr }),
+                    else => unreachable,
+                }
+
+                try self.genSetReg(ptr_ty, dst_reg, .{ .ptr_stack_offset = stack_offset });
+                try self.genSetReg(Type.usize, len_reg, .{ .immediate = abi_size });
+                try self.genInlineMemcpy(src_reg, dst_reg, len_reg, tmp_reg);
+            }
+        },
     }
 }