PATCH: assembler _invoke

Marcus Meissner marcus at jet.franken.de
Thu Jan 5 03:08:41 CST 2006


On Wed, Jan 04, 2006 at 09:14:18PM -0800, Dan Kegel wrote:
> This would definitely be better handled in assembly...

Here is the first try. It leaves the old version for non-intel
and non-gcc compilers.

Ciao, Marcus

Index: typelib.c
===================================================================
RCS file: /home/wine/wine/dlls/oleaut32/typelib.c,v
retrieving revision 1.200
diff -u -r1.200 typelib.c
--- typelib.c	3 Jan 2006 12:42:34 -0000	1.200
+++ typelib.c	5 Jan 2006 09:07:25 -0000
@@ -4843,7 +4843,33 @@
 
     switch (callconv) {
     case CC_STDCALL:
+#if defined(__i386__) && defined(__GNUC__)
 
+        __asm__(
+            /* store all stuff into registers now, since we modify the stack */
+            "       mov %1, %%ecx\n"	
+            "       mov %2, %%edx\n"
+            "       mov %3, %%esi\n"
+            "       test %%ecx, %%ecx\n"
+            "       jz 1f\n" /* no args, nothing to push */
+            /*
+             * Arguments are pushed from right to left.
+             * We use intel memory move operations.
+             */
+            "       std\n"  		/* direction: backward */
+            "2:     lodsl\n" 		/* moves *esi -> eax, esi-= 4 */
+            "       pushl %%eax\n"
+            "       dec %%ecx\n"
+            "       jnz 2b\n"
+            "1:     cld\n"		/* direction: forward (default) */
+            "       call *%%edx\n"
+            "       mov %%eax, %0\n"
+        :   "=g" (res)
+        :   "g" (nrargs), "g" (func), "g" (args + (nrargs-1))
+        :   "memory", "cc", "ax", "si", "cx", "dx"
+        );
+	break;
+#else
 	switch (nrargs) {
 	case 0:
 		res = func();
@@ -4905,6 +4931,7 @@
 		break;
 	}
 	break;
+#endif
     default:
 	FIXME("unsupported calling convention %d\n",callconv);
 	res = -1;



More information about the wine-patches mailing list