Commit 3ac097a5 by Anthony Green

Enable build with microsoft compiler

From-SVN: r162935
parent fc28e435
...@@ -49,6 +49,29 @@ ...@@ -49,6 +49,29 @@
* src/arm/sysv.S (__ARM_ARCH__): Define for processor * src/arm/sysv.S (__ARM_ARCH__): Define for processor
__ARM_ARCH_7EM__. __ARM_ARCH_7EM__.
2010-01-15 Anthony Green <green@redhat.com>
* README: Add notes on building with Microsoft Visual C++.
2010-01-15 Daniel Witte <dwitte@mozilla.com>
* msvcc.sh: New file.
* src/x86/win32.S: Port assembly routines to MSVC and #ifdef.
* src/x86/ffi.c: Tweak function declaration and remove excess
parens.
* include/ffi.h.in: Add __declspec(align(8)) to typedef struct
ffi_closure.
* src/x86/ffi.c: Merge ffi_call_SYSV and ffi_call_STDCALL into new
function ffi_call_win32 on X86_WIN32.
* src/x86/win32.S (ffi_call_SYSV): Rename to ffi_call_win32.
(ffi_call_STDCALL): Remove.
* src/prep_cif.c (ffi_prep_cif): Move stack space allocation code
to ffi_prep_cif_machdep for x86.
* src/x86/ffi.c (ffi_prep_cif_machdep): To here.
2010-01-15 Oliver Kiddle <okiddle@yahoo.co.uk> 2010-01-15 Oliver Kiddle <okiddle@yahoo.co.uk>
* src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for * src/x86/ffitarget.h (ffi_abi): Check for __i386 and __amd64 for
......
...@@ -110,6 +110,14 @@ will add some extra code which will suppress certain warnings when you ...@@ -110,6 +110,14 @@ will add some extra code which will suppress certain warnings when you
are using Purify with libffi. Only use this switch when using are using Purify with libffi. Only use this switch when using
Purify, as it will slow down the library. Purify, as it will slow down the library.
It's also possible to build libffi on Windows platforms with
Microsoft's Visual C++ compiler. In this case, use the msvcc.sh
wrapper script during configuration like so:
path/to/configure --enable-shared --enable-static \
CC=path/to/msvcc.sh LD=link \
CPP=\"cl -nologo -EP\"
Configure has many other options. Use "configure --help" to see them all. Configure has many other options. Use "configure --help" to see them all.
Once configure has finished, type "make". Note that you must be using Once configure has finished, type "make". Note that you must be using
...@@ -126,6 +134,12 @@ History ...@@ -126,6 +134,12 @@ History
See the ChangeLog files for details. See the ChangeLog files for details.
3.0.10 ???-??-??
Fix the N64 build on mips-sgi-irix6.5.
Testsuite fixes for Tru64 Unix.
Enable builds with Microsoft's compiler.
Enable x86 builds with Sun's compiler.
3.0.9 Dec-31-09 3.0.9 Dec-31-09
Add AVR32 and win64 ports. Add ARM softfp support. Add AVR32 and win64 ports. Add ARM softfp support.
Many fixes for AIX, Solaris, HP-UX, *BSD. Many fixes for AIX, Solaris, HP-UX, *BSD.
......
...@@ -251,6 +251,9 @@ size_t ffi_java_raw_size (ffi_cif *cif); ...@@ -251,6 +251,9 @@ size_t ffi_java_raw_size (ffi_cif *cif);
#if FFI_CLOSURES #if FFI_CLOSURES
#ifdef _MSC_VER
__declspec(align(8))
#endif
typedef struct { typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE]; char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif; ffi_cif *cif;
......
...@@ -109,16 +109,13 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ...@@ -109,16 +109,13 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
/* Perform a sanity check on the return type */ /* Perform a sanity check on the return type */
FFI_ASSERT_VALID_TYPE(cif->rtype); FFI_ASSERT_VALID_TYPE(cif->rtype);
/* x86-64 and s390 stack space allocation is handled in prep_machdep. */ /* x86, x86-64 and s390 stack space allocation is handled in prep_machdep. */
#if !defined M68K && !defined __x86_64__ && !defined S390 && !defined PA #if !defined M68K && !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
/* Make space for the return structure pointer */ /* Make space for the return structure pointer */
if (cif->rtype->type == FFI_TYPE_STRUCT if (cif->rtype->type == FFI_TYPE_STRUCT
#ifdef SPARC #ifdef SPARC
&& (cif->abi != FFI_V9 || cif->rtype->size > 32) && (cif->abi != FFI_V9 || cif->rtype->size > 32)
#endif #endif
#ifdef X86_DARWIN
&& (cif->rtype->size > 8)
#endif
) )
bytes = STACK_ARG_SIZE(sizeof(void*)); bytes = STACK_ARG_SIZE(sizeof(void*));
#endif #endif
...@@ -134,7 +131,7 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ...@@ -134,7 +131,7 @@ ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
check after the initialization. */ check after the initialization. */
FFI_ASSERT_VALID_TYPE(*ptr); FFI_ASSERT_VALID_TYPE(*ptr);
#if !defined __x86_64__ && !defined S390 && !defined PA #if !defined __i386__ && !defined __x86_64__ && !defined S390 && !defined PA
#ifdef SPARC #ifdef SPARC
if (((*ptr)->type == FFI_TYPE_STRUCT if (((*ptr)->type == FFI_TYPE_STRUCT
&& ((*ptr)->size > 16 || cif->abi != FFI_V9)) && ((*ptr)->size > 16 || cif->abi != FFI_V9))
......
...@@ -148,13 +148,13 @@ void ffi_prep_args(char *stack, extended_cif *ecif) ...@@ -148,13 +148,13 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
/* Perform machine dependent cif processing */ /* Perform machine dependent cif processing */
ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{ {
unsigned int i;
ffi_type **ptr;
/* Set the return type flag */ /* Set the return type flag */
switch (cif->rtype->type) switch (cif->rtype->type)
{ {
case FFI_TYPE_VOID: case FFI_TYPE_VOID:
#ifdef X86
case FFI_TYPE_STRUCT:
#endif
#if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64) #if defined(X86) || defined (X86_WIN32) || defined(X86_FREEBSD) || defined(X86_DARWIN) || defined(X86_WIN64)
case FFI_TYPE_UINT8: case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
...@@ -165,7 +165,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -165,7 +165,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
#endif #endif
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
...@@ -184,8 +183,8 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -184,8 +183,8 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = FFI_TYPE_SINT64; cif->flags = FFI_TYPE_SINT64;
break; break;
#ifndef X86
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
#ifndef X86
if (cif->rtype->size == 1) if (cif->rtype->size == 1)
{ {
cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */ cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
...@@ -207,15 +206,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -207,15 +206,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = FFI_TYPE_SINT64; /* same as int64 type */ cif->flags = FFI_TYPE_SINT64; /* same as int64 type */
} }
else else
#endif
{ {
cif->flags = FFI_TYPE_STRUCT; cif->flags = FFI_TYPE_STRUCT;
#ifdef X86_WIN64
// allocate space for return value pointer // allocate space for return value pointer
cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG); cif->bytes += ALIGN(sizeof(void*), FFI_SIZEOF_ARG);
#endif
} }
break; break;
#endif
default: default:
#ifdef X86_WIN64 #ifdef X86_WIN64
...@@ -229,41 +226,36 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ...@@ -229,41 +226,36 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
break; break;
} }
#ifdef X86_DARWIN for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
cif->bytes = (cif->bytes + 15) & ~0xF; {
#endif if (((*ptr)->alignment - 1) & cif->bytes)
cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
}
#ifdef X86_WIN64 #ifdef X86_WIN64
{
unsigned int i;
ffi_type **ptr;
for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++)
{
if (((*ptr)->alignment - 1) & cif->bytes)
cif->bytes = ALIGN(cif->bytes, (*ptr)->alignment);
cif->bytes += ALIGN((*ptr)->size, FFI_SIZEOF_ARG);
}
}
// ensure space for storing four registers // ensure space for storing four registers
cif->bytes += 4 * sizeof(ffi_arg); cif->bytes += 4 * sizeof(ffi_arg);
#endif #endif
#ifdef X86_DARWIN
cif->bytes = (cif->bytes + 15) & ~0xF;
#endif
return FFI_OK; return FFI_OK;
} }
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
#ifdef X86_WIN32
extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
#endif /* X86_WIN32 */
#ifdef X86_WIN64 #ifdef X86_WIN64
extern int extern int
ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *, ffi_call_win64(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void)); unsigned, unsigned, unsigned *, void (*fn)(void));
#elif defined(X86_WIN32)
extern void
ffi_call_win32(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
#else
extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
unsigned, unsigned, unsigned *, void (*fn)(void));
#endif #endif
void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
...@@ -321,18 +313,18 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ...@@ -321,18 +313,18 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
cif->flags, ecif.rvalue, fn); cif->flags, ecif.rvalue, fn);
} }
break; break;
#elif defined(X86_WIN32)
case FFI_SYSV:
case FFI_STDCALL:
ffi_call_win32(ffi_prep_args, &ecif, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
#else #else
case FFI_SYSV: case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
fn); fn);
break; break;
#ifdef X86_WIN32 #endif
case FFI_STDCALL:
ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
#endif /* X86_WIN32 */
#endif /* X86_WIN64 */
default: default:
FFI_ASSERT(0); FFI_ASSERT(0);
break; break;
...@@ -342,6 +334,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) ...@@ -342,6 +334,8 @@ void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
/** private members **/ /** private members **/
/* The following __attribute__((regparm(1))) decorations will have no effect
on MSVC - standard cdecl convention applies. */
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif); void** args, ffi_cif* cif);
void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *) void FFI_HIDDEN ffi_closure_SYSV (ffi_closure *)
...@@ -390,11 +384,8 @@ ffi_closure_win64_inner (ffi_closure *closure, void *args) { ...@@ -390,11 +384,8 @@ ffi_closure_win64_inner (ffi_closure *closure, void *args) {
} }
#else #else
unsigned int FFI_HIDDEN unsigned int FFI_HIDDEN __attribute__ ((regparm(1)))
ffi_closure_SYSV_inner (closure, respp, args) ffi_closure_SYSV_inner (ffi_closure *closure, void **respp, void *args)
ffi_closure *closure;
void **respp;
void *args;
{ {
/* our various things... */ /* our various things... */
ffi_cif *cif; ffi_cif *cif;
...@@ -505,7 +496,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, ...@@ -505,7 +496,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
/* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \ #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \ unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __ctx = (unsigned int)(CTX); \
unsigned int __dis = __fun - (__ctx + 10); \ unsigned int __dis = __fun - (__ctx + 10); \
...@@ -513,10 +504,10 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, ...@@ -513,10 +504,10 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
*(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \
*(unsigned char *) &__tramp[5] = 0xe9; \ *(unsigned char *) &__tramp[5] = 0xe9; \
*(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \
}) }
#define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \ #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \ unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __ctx = (unsigned int)(CTX); \
unsigned int __dis = __fun - (__ctx + 10); \ unsigned int __dis = __fun - (__ctx + 10); \
...@@ -527,7 +518,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, ...@@ -527,7 +518,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
*(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \ *(unsigned int*) &__tramp[6] = __dis; /* call __fun */ \
*(unsigned char *) &__tramp[10] = 0xc2; \ *(unsigned char *) &__tramp[10] = 0xc2; \
*(unsigned short*) &__tramp[11] = __size; /* ret __size */ \ *(unsigned short*) &__tramp[11] = __size; /* ret __size */ \
}) }
/* the cif must already be prep'ed */ /* the cif must already be prep'ed */
...@@ -627,16 +618,6 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif) ...@@ -627,16 +618,6 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif)
* libffi-1.20, this is not the case.) * libffi-1.20, this is not the case.)
*/ */
extern void
ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
unsigned, unsigned *, void (*fn)(void));
#ifdef X86_WIN32
extern void
ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
unsigned, unsigned *, void (*fn)(void));
#endif /* X86_WIN32 */
void void
ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
{ {
...@@ -660,16 +641,18 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue) ...@@ -660,16 +641,18 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *fake_avalue)
switch (cif->abi) switch (cif->abi)
{ {
#ifdef X86_WIN32
case FFI_SYSV:
case FFI_STDCALL:
ffi_call_win32(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
#else
case FFI_SYSV: case FFI_SYSV:
ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
ecif.rvalue, fn); ecif.rvalue, fn);
break; break;
#ifdef X86_WIN32 #endif
case FFI_STDCALL:
ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
ecif.rvalue, fn);
break;
#endif /* X86_WIN32 */
default: default:
FFI_ASSERT(0); FFI_ASSERT(0);
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment