is really "__asm" needed for current FFI support?
Alejandro F. Reimondo
aleReimondo at smalltalking.net
Mon Oct 25 12:44:29 UTC 2004
Hi Andreas, all,
I have found the current implementation of FFI a little complex,
but I think that it is related with some perfomance needs.
Trying to make a build under WinCE I have found that currently
a piece of assembler code must be implemented for
each platform&processor...
Please confirm me if it is really required, or if someone knows
any standard C code to put for ffiCallAddress:
implementation (or any higher level function).
I think that it will be hard for me to port the asm code to my
winCE host processor (ARM4). I can try to make the effort,
but think that we will really need a 100% standard C level
compatibility for FFI (as we have in very first versions).
The current assembler code implemented for win32 platform
follows this email.
Thanks for your time!
Ale.
/***************************************************************************
**/
/***************************************************************************
**/
int oldSP;
int oldBP;
int newSP;
int newBP;
/* ffiCallAddress:
Perform the actual function call. */
int ffiCallAddress(int fn)
{
#if 0
{
FILE *f = fopen("ffi.log","at");
fprintf(f, "%x",fn);
fflush(f);
fclose(f);
}
#endif
#ifdef _MSC_VER
__asm {
push ebx
mov ebx, fn
push ecx
push edx
push edi
push esi
push ebp
/* mark the frame */
mov ebp, esp
/* alloca() ffiStackIndex size bytes */
mov ecx, ffiArgIndex
shl ecx, 2
sub esp, ecx
/* copy stack */
mov edi, esp
lea esi, ffiArgs
shr ecx, 2
cld
rep movsd
/* go calling */
call ebx
/* restore frame */
mov esp, ebp
/* store the return values */
mov intReturnValue, eax
mov intReturnValue2, edx
fstp floatReturnValue
/* restore register values */
pop ebp
pop esi
pop edi
pop edx
pop ecx
pop ebx
/* done */
}
#endif
#ifdef __GNUC__
asm("
movl %%ebp, _oldBP
movl %%esp, _oldSP
pushl %%ebx;
pushl %%ecx;
pushl %%edx;
pushl %%edi;
pushl %%esi;
pushl %%ebp;
/* mark the frame */
movl %%esp, %%ebp
/* alloca() ffiStackIndex size bytes */
movl _ffiArgIndex, %%ecx;
shll $2, %%ecx;
subl %%ecx, %%esp
/* copy stack */
movl %%esp, %%edi;
leal _ffiArgs, %%esi;
shrl $2, %%ecx;
cld;
rep movsl;
/* go calling */
call *%%ebx
/* restore frame */
movl %%ebp, %%esp
/* store the return values */
movl %%eax, _intReturnValue
movl %%edx, _intReturnValue2
fstpl _floatReturnValue
/* restore register values */
popl %%ebp
popl %%esi
popl %%edi
popl %%edx
popl %%ecx
popl %%ebx
movl %%ebp, _newBP
movl %%esp, _newSP
": /* no outputs */ : "ebx" (fn) : "eax" /* clobbered registers */);
/* done */
#endif
#if 0
{
FILE *f = fopen("ffi.log","at");
fprintf(f, "...ok\n");
if(oldBP != newBP || oldSP != newSP) {
fprintf(f,"oldSP=%x, oldBP=%x\nnewSP=%x, newBP=%x\n",oldSP,
oldBP,newSP,newBP);
}
fprintf(f,"SP=%x, BP=%x\n",newSP,newBP);
fflush(f);
fclose(f);
}
#endif
return intReturnValue;
}
int ffiCallAddressOfWithPointerReturn(int fn, int callType)
{
return ffiCallAddress(fn);
}
int ffiCallAddressOfWithStructReturn(int fn, int callType, int* structSpec,
int specSize)
{
return ffiCallAddress(fn);
}
int ffiCallAddressOfWithReturnType(int fn, int callType, int typeSpec)
{
return ffiCallAddress(fn);
}
More information about the Squeak-dev
mailing list
|