is really "__asm" needed for current FFI support?

Andreas Raab andreas.raab at gmx.de
Mon Oct 25 19:14:18 UTC 2004


Hi,

Yes, the code is absolutely required as in: I do not know how you would 
achieve what you need to do there -calling a C function using the 
appropriate platform ABI- outside of assembler.

Cheers,
  - Andreas

----- Original Message ----- 
From: "Alejandro F. Reimondo" <aleReimondo at smalltalking.net>
To: "The general-purpose Squeak developers list" 
<squeak-dev at lists.squeakfoundation.org>
Cc: "Andreas Raab" <raab at isgnw.cs.Uni-Magdeburg.DE>
Sent: Monday, October 25, 2004 5:44 AM
Subject: is really "__asm" needed for current FFI support?


> 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