[commit] r2454 - Maintain 16-byte stack alignment in win32 SSE2 regime on Alien callbacks.

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[commit] r2454 - Maintain 16-byte stack alignment in win32 SSE2 regime on Alien callbacks.

commits-3
 
Author: eliot
Date: 2011-07-12 10:34:46 -0700 (Tue, 12 Jul 2011)
New Revision: 2454

Modified:
   trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.c
Log:
Maintain 16-byte stack alignment in win32 SSE2 regime on Alien callbacks.


Modified: trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.c
===================================================================
--- trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.c 2011-07-11 20:55:34 UTC (rev 2453)
+++ trunk/platforms/Cross/plugins/IA32ABI/ia32abicc.c 2011-07-12 17:34:46 UTC (rev 2454)
@@ -30,6 +30,7 @@
 #include <stdio.h> /* for fprintf(stderr,...) */
 
 #include "vmCallback.h"
+#include "sqAssert.h"
 #include "sqMemoryAccess.h"
 #include "sqVirtualMachine.h"
 #include "ia32abi.h"
@@ -64,6 +65,12 @@
 # define STACK_ALIGN_BYTES 16
 #elif __linux__ && __i386__
 # define STACK_ALIGN_BYTES 16
+#elif defined(WIN32) && __SSE2__
+/* using sse2 instructions requires 16-byte stack alignment but on win32 there's
+ * no guarantee that libraries preserve alignment so compensate on callback.
+ */
+# define STACK_ALIGN_HACK
+# define STACK_ALIGN_BYTES 16
 #endif
 
 #if !defined(setsp)
@@ -165,7 +172,8 @@
  * requirement on platforms using SSE2 such as Mac OS X, and harmless elsewhere.
  *
  * This function's roles are to use setjmp/longjmp to save the call point
- * and return to it, and to return any of the various values from the callback.
+ * and return to it, to correct C stack pointer alignment if necessary (see
+ * STACK_ALIGN_HACK), and to return any of the various values from the callback.
  *
  * Looking forward to support for x86-64, which typically has 6 register
  * arguments, the function would take 8 arguments, the 6 register args as
@@ -185,6 +193,23 @@
  return -1;
  }
 
+#if defined(STACK_ALIGN_HACK)
+  { void *sp = getsp();
+    int offset = (unsigned long)sp & (STACK_ALIGN_BYTES - 1);
+ if (offset) {
+#if _MSC_VER
+ _asm sub esp, dword ptr offset;
+#elif __GNUC__
+ asm("sub %0,%%esp" : : "m"(offset));
+#else
+# error need to subtract offset from esp
+#endif
+ sp = getsp();
+ assert(!((unsigned long)sp & (STACK_ALIGN_BYTES - 1)));
+ }
+  }
+#endif
+
  if (!(returnType = setjmp(vmcc.trampoline))) {
  previousCallbackContext = getRMCC();
  setRMCC(&vmcc);