From aeb9ed82dc9fca947375bb0e5908075e4619b14a Mon Sep 17 00:00:00 2001
From: TheLastRar <TheLastRar@users.noreply.github.com>
Date: Sat, 11 Jan 2025 23:17:40 +0000
Subject: [PATCH] x86emitter: Backup and restore non-volatile SSE registers

XMM6-XMM15 are non-volatile on Windows
---
 common/emitter/x86emitter.cpp | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/common/emitter/x86emitter.cpp b/common/emitter/x86emitter.cpp
index 157d25e4b41f2..ae0547441b852 100644
--- a/common/emitter/x86emitter.cpp
+++ b/common/emitter/x86emitter.cpp
@@ -1224,22 +1224,35 @@ const xRegister32
 #ifdef _WIN32
 		xPUSH(rdi);
 		xPUSH(rsi);
-		xSUB(rsp, 32); // Windows calling convention specifies additional space for the callee to spill registers
-		m_offset += 48;
-#endif
+		m_offset += 16;
 
+		// Align for movaps, in addition to any following instructions
 		stackAlign(m_offset, true);
+
+		xSUB(rsp, 16 * 10);
+		for (u32 i = 6; i < 16; i++)
+			xMOVAPS(ptr128[rsp + (i - 6) * 16], xRegisterSSE(i));
+		xSUB(rsp, 32); // Windows calling convention specifies additional space for the callee to spill registers
+#else
+		// Align for any following instructions
+		stackAlign(m_offset, true);
+#endif
 	}
 
 	xScopedStackFrame::~xScopedStackFrame()
 	{
-		stackAlign(m_offset, false);
-
 		// Restore the register context
 #ifdef _WIN32
 		xADD(rsp, 32);
+		for (u32 i = 6; i < 16; i++)
+			xMOVAPS(xRegisterSSE::GetInstance(i), ptr[rsp + (i - 6) * 16]);
+		xADD(rsp, 16 * 10);
+
+		stackAlign(m_offset, false);
 		xPOP(rsi);
 		xPOP(rdi);
+#else
+		stackAlign(m_offset, false);
 #endif
 		xPOP(r15);
 		xPOP(r14);