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