Commit c94974ca by Bo Thorsen Committed by Bo Thorsen

[multiple changes]

2002-07-16  Bo Thorsen  <bo@suse.de>

	* src/x86/ffi64.c: New file that adds x86-64 support.
	* src/x86/unix64.S: New file that handles argument setup for
	x86-64.
	* src/x86/sysv.S: Don't use this on x86-64.
	* src/x86/ffi.c: Don't use this on x86-64.
	Remove unused vars.
	* src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation
	for x86-64.
	* src/ffitest.c (struct6): New test that tests a special case in
	the x86-64 ABI.
	(struct7): Likewise.
	(struct8): Likewise.
	(struct9): Likewise.
	(closure_test_fn): Silence warning about this when it's not used.
	(main): Add the new tests.
	(main): Fix a couple of wrong casts and silence some compiler warnings.
	* include/ffi.h.in: Add x86-64 ABI definition.
	* fficonfig.h.in: Regenerate.
	* Makefile.am: Add x86-64 support.
	* configure.in: Likewise.
	* Makefile.in: Regenerate.
	* configure: Likewise.

2002-06-24  Bo Thorsen  <bo@suse.de>

	* src/types.c: Merge settings for similar architectures.
	Add x86-64 sizes and alignments.

2002-06-23  Bo Thorsen  <bo@suse.de>

	* src/arm/ffi.c (ffi_prep_args): Remove unused vars.
	* src/sparc/ffi.c (ffi_prep_args_v8): Likewise.
	* src/mips/ffi.c (ffi_prep_args): Likewise.
	* src/m68k/ffi.c (ffi_prep_args): Likewise.

From-SVN: r55571
parent ad28cff7
2002-07-16 Bo Thorsen <bo@suse.de>
* src/x86/ffi64.c: New file that adds x86-64 support.
* src/x86/unix64.S: New file that handles argument setup for
x86-64.
* src/x86/sysv.S: Don't use this on x86-64.
* src/x86/ffi.c: Don't use this on x86-64.
Remove unused vars.
* src/prep_cif.c (ffi_prep_cif): Don't do stack size calculation
for x86-64.
* src/ffitest.c (struct6): New test that tests a special case in
the x86-64 ABI.
(struct7): Likewise.
(struct8): Likewise.
(struct9): Likewise.
(closure_test_fn): Silence warning about this when it's not used.
(main): Add the new tests.
(main): Fix a couple of wrong casts and silence some compiler warnings.
* include/ffi.h.in: Add x86-64 ABI definition.
* fficonfig.h.in: Regenerate.
* Makefile.am: Add x86-64 support.
* configure.in: Likewise.
* Makefile.in: Regenerate.
* configure: Likewise.
2002-06-24 Bo Thorsen <bo@suse.de>
* src/types.c: Merge settings for similar architectures.
Add x86-64 sizes and alignments.
2002-06-23 Bo Thorsen <bo@suse.de>
* src/arm/ffi.c (ffi_prep_args): Remove unused vars.
* src/sparc/ffi.c (ffi_prep_args_v8): Likewise.
* src/mips/ffi.c (ffi_prep_args): Likewise.
* src/m68k/ffi.c (ffi_prep_args): Likewise.
2002-07-18 H.J. Lu (hjl@gnu.org)
* Makefile.am (TARGET_SRC_MIPS_LINUX): New.
......@@ -15,11 +52,6 @@
* src/s390/sysv.S: Save/restore %r6. Add DWARF-2 unwind info.
2002-05-28 Bo Thorsen <bo@suse.de>
* src/x86/ffi.c (ffi_prep_incoming_args_SYSV): Remove
the same unused avn var from this one too.
2002-05-27 Roger Sayle <roger@eyesopen.com>
* src/x86/ffi.c (ffi_prep_args): Remove reference to avn.
......
......@@ -8,6 +8,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
src/mips/n32.s src/mips/o32.S src/mips/o32.s \
src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \
src/x86/ffi64.c src/x86/unix64.S \
src/alpha/ffi.c src/alpha/osf.S \
src/m68k/ffi.c src/m68k/sysv.S \
src/powerpc/ffi.c src/powerpc/sysv.S \
......@@ -106,6 +107,7 @@ TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/
TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
TARGET_SRC_S390 = src/s390/sysv.S src/s390/ffi.c
TARGET_SRC_X86_64 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
##libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c $(TARGET_SRC_@TARGET@)
## Work around automake deficiency
......@@ -167,6 +169,10 @@ if S390
libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
endif
if X86_64
libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
libffi_convenience_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
endif
AM_CFLAGS = -fexceptions
......
......@@ -89,6 +89,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 src/mips/ffi.c src/mips/n32.S \
src/mips/n32.s src/mips/o32.S src/mips/o32.s \
src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \
src/x86/ffi64.c src/x86/unix64.S \
src/alpha/ffi.c src/alpha/osf.S \
src/m68k/ffi.c src/m68k/sysv.S \
src/powerpc/ffi.c src/powerpc/sysv.S \
......@@ -177,6 +178,7 @@ TARGET_SRC_POWERPC_AIX = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/
TARGET_SRC_POWERPC_DARWIN = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
TARGET_SRC_ARM = src/arm/sysv.S src/arm/ffi.c
TARGET_SRC_S390 = src/s390/sysv.S src/s390/ffi.c
TARGET_SRC_X86_64 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c
......@@ -195,6 +197,7 @@ libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
@POWERPC_DARWIN_TRUE@libffi_la_SOURCES = @POWERPC_DARWIN_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
@ARM_TRUE@libffi_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
@S390_TRUE@libffi_la_SOURCES = @S390_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
@X86_64_TRUE@libffi_la_SOURCES = @X86_64_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
@MIPS_GCC_TRUE@libffi_convenience_la_SOURCES = @MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC)
@MIPS_LINUX_TRUE@libffi_convenience_la_SOURCES = @MIPS_LINUX_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_LINUX)
@MIPS_SGI_TRUE@libffi_convenience_la_SOURCES = @MIPS_SGI_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI)
......@@ -209,6 +212,7 @@ libffi_la_common_SOURCES = src/debug.c src/prep_cif.c src/types.c \
@POWERPC_DARWIN_TRUE@libffi_convenience_la_SOURCES = @POWERPC_DARWIN_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC_DARWIN)
@ARM_TRUE@libffi_convenience_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM)
@S390_TRUE@libffi_convenience_la_SOURCES = @S390_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_S390)
@X86_64_TRUE@libffi_convenience_la_SOURCES = @X86_64_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86_64)
AM_CFLAGS = -fexceptions
......@@ -304,6 +308,9 @@ libffi_la_LIBADD =
@S390_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo \
@S390_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
@S390_TRUE@src/s390/sysv.lo src/s390/ffi.lo
@X86_64_TRUE@libffi_convenience_la_OBJECTS = src/debug.lo src/prep_cif.lo \
@X86_64_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
@X86_64_TRUE@src/x86/ffi.lo src/x86/sysv.lo src/x86/unix64.lo src/x86/ffi64.lo
@X86_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
@X86_TRUE@src/raw_api.lo src/java_raw_api.lo src/x86/ffi.lo \
@X86_TRUE@src/x86/sysv.lo
......@@ -323,6 +330,9 @@ libffi_la_LIBADD =
@M68K_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo \
@M68K_TRUE@src/types.lo src/raw_api.lo src/java_raw_api.lo \
@M68K_TRUE@src/m68k/ffi.lo src/m68k/sysv.lo
@X86_64_TRUE@libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
@X86_64_TRUE@src/raw_api.lo src/java_raw_api.lo src/x86/ffi.lo \
@X86_64_TRUE@src/x86/sysv.lo src/x86/unix64.lo src/x86/ffi64.lo
noinst_PROGRAMS = ffitest$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
......
......@@ -70,6 +70,7 @@ powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;;
x86_64-*-linux*) TARGET=X86_64; TARGETDIR=x86;;
esac
if test $TARGETDIR = unknown; then
......@@ -90,6 +91,7 @@ AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
AM_CONDITIONAL(S390, test x$TARGET = xS390)
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
if test x$TARGET = xMIPS_LINUX; then
TARGET=MIPS
......
......@@ -189,10 +189,15 @@ typedef enum ffi_abi {
#endif
#endif
/* ---- Intel x86 ---------------- */
#ifdef X86
/* ---- Intel x86 and AMD x86-64 - */
#if defined(X86) || defined(X86_64)
FFI_SYSV,
FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */
#ifdef X86
FFI_DEFAULT_ABI = FFI_SYSV,
#else
FFI_DEFAULT_ABI = FFI_UNIX64,
#endif
#endif
/* ---- Intel x86 Win32 ---------- */
......
......@@ -36,13 +36,10 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
/*@=exportheader@*/
{
register unsigned int i;
register int tmp;
register unsigned int avn;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
tmp = 0;
argp = stack;
if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) {
......@@ -50,11 +47,10 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
argp += 4;
}
avn = ecif->cif->nargs;
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
(i != 0) && (avn != 0);
(i != 0);
i--, p_arg++)
{
size_t z;
......@@ -64,9 +60,6 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
argp = (char *) ALIGN(argp, (*p_arg)->alignment);
}
if (avn != 0)
{
avn--;
z = (*p_arg)->size;
if (z < sizeof(int))
{
......@@ -107,7 +100,6 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
}
p_argv++;
argp += z;
}
}
return;
......
......@@ -153,6 +153,33 @@ typedef struct
char c2;
} test_structure_5;
typedef struct
{
float f;
double d;
} test_structure_6;
typedef struct
{
float f1;
float f2;
double d;
} test_structure_7;
typedef struct
{
float f1;
float f2;
float f3;
float f4;
} test_structure_8;
typedef struct
{
float f;
int i;
} test_structure_9;
static test_structure_1 struct1(test_structure_1 ts)
{
/*@-type@*/
......@@ -194,15 +221,52 @@ static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2)
return ts1;
}
static test_structure_6 struct6 (test_structure_6 ts)
{
ts.f += 1;
ts.d += 1;
return ts;
}
static test_structure_7 struct7 (test_structure_7 ts)
{
ts.f1 += 1;
ts.f2 += 1;
ts.d += 1;
return ts;
}
static test_structure_8 struct8 (test_structure_8 ts)
{
ts.f1 += 1;
ts.f2 += 1;
ts.f3 += 1;
ts.f4 += 1;
return ts;
}
static test_structure_9 struct9 (test_structure_9 ts)
{
ts.f += 1;
ts.i += 1;
return ts;
}
/* Take an int and a float argument, together with int userdata, and */
/* return the sum. */
static void closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
#if FFI_CLOSURES
static void
closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata)
{
*(int*)resp =
*(int *)args[0] + (int)(*(float *)args[1]) + (int)(long)userdata;
*(int*)resp = *(int*)args[0] + (int)(*(float*)args[1]) + (int)(long)userdata;
}
typedef int (*closure_test_type)(int, float);
#endif
int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
{
......@@ -230,11 +294,19 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
ffi_type ts3_type;
ffi_type ts4_type;
ffi_type ts5_type;
ffi_type ts6_type;
ffi_type ts7_type;
ffi_type ts8_type;
ffi_type ts9_type;
ffi_type *ts1_type_elements[4];
ffi_type *ts2_type_elements[3];
ffi_type *ts3_type_elements[2];
ffi_type *ts4_type_elements[4];
ffi_type *ts5_type_elements[3];
ffi_type *ts6_type_elements[3];
ffi_type *ts7_type_elements[4];
ffi_type *ts8_type_elements[5];
ffi_type *ts9_type_elements[3];
ts1_type.size = 0;
ts1_type.alignment = 0;
......@@ -256,12 +328,32 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
ts5_type.alignment = 0;
ts5_type.type = FFI_TYPE_STRUCT;
ts6_type.size = 0;
ts6_type.alignment = 0;
ts6_type.type = FFI_TYPE_STRUCT;
ts7_type.size = 0;
ts7_type.alignment = 0;
ts7_type.type = FFI_TYPE_STRUCT;
ts8_type.size = 0;
ts8_type.alignment = 0;
ts8_type.type = FFI_TYPE_STRUCT;
ts9_type.size = 0;
ts9_type.alignment = 0;
ts9_type.type = FFI_TYPE_STRUCT;
/*@-immediatetrans@*/
ts1_type.elements = ts1_type_elements;
ts2_type.elements = ts2_type_elements;
ts3_type.elements = ts3_type_elements;
ts4_type.elements = ts4_type_elements;
ts5_type.elements = ts5_type_elements;
ts6_type.elements = ts6_type_elements;
ts7_type.elements = ts7_type_elements;
ts8_type.elements = ts8_type_elements;
ts9_type.elements = ts9_type_elements;
/*@=immediatetrans@*/
ts1_type_elements[0] = &ffi_type_uchar;
......@@ -285,6 +377,25 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
ts5_type_elements[1] = &ffi_type_schar;
ts5_type_elements[2] = NULL;
ts6_type_elements[0] = &ffi_type_float;
ts6_type_elements[1] = &ffi_type_double;
ts6_type_elements[2] = NULL;
ts7_type_elements[0] = &ffi_type_float;
ts7_type_elements[1] = &ffi_type_float;
ts7_type_elements[2] = &ffi_type_double;
ts7_type_elements[3] = NULL;
ts8_type_elements[0] = &ffi_type_float;
ts8_type_elements[1] = &ffi_type_float;
ts8_type_elements[2] = &ffi_type_float;
ts8_type_elements[3] = &ffi_type_float;
ts8_type_elements[4] = NULL;
ts9_type_elements[0] = &ffi_type_float;
ts9_type_elements[1] = &ffi_type_sint;
ts9_type_elements[2] = NULL;
ul = 0;
/* return value tests */
......@@ -326,7 +437,7 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
{
ul++;
ffi_call(&cif, FFI_FN(return_sc), &rint, values);
CHECK(rint == (int) sc);
CHECK(rint == (ffi_arg) sc);
}
args[0] = &ffi_type_uchar;
......@@ -413,7 +524,7 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
ffi_call(&cif, FFI_FN(floating), &rint, values);
printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2));
printf ("%d vs %d\n", (int)rint, floating (si1, f, d, ld, si2));
CHECK(rint == floating(si1, f, d, ld, si2));
......@@ -483,7 +594,7 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
&ffi_type_float, args) == FFI_OK);
/*@-usedef@*/
ff = many(fa[0], fa[1],
ff = many (fa[0], fa[1],
fa[2], fa[3],
fa[4], fa[5],
fa[6], fa[7],
......@@ -532,7 +643,8 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
{
ul++;
ffi_call(&cif, FFI_FN(promotion), &rint, values);
CHECK(rint == (int) sc + (int) ss + (int) uc + (int) us);
CHECK((int)rint == (signed char) sc + (signed short) ss +
(unsigned char) uc + (unsigned short) us);
}
printf("%lu promotion tests run\n", ul);
}
......@@ -579,8 +691,7 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
values[0] = &ts2_arg;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ts2_type, args) == FFI_OK);
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts2_type, args) == FFI_OK);
ts2_arg.d1 = 5.55;
ts2_arg.d2 = 6.66;
......@@ -647,8 +758,7 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
values[0] = &ts4_arg;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1,
&ts4_type, args) == FFI_OK);
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts4_type, args) == FFI_OK);
ts4_arg.ui1 = 2;
ts4_arg.ui2 = 3;
......@@ -678,8 +788,7 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
values[1] = &ts5_arg2;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2,
&ts5_type, args) == FFI_OK);
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, &ts5_type, args) == FFI_OK);
ts5_arg1.c1 = 2;
ts5_arg1.c2 = 6;
......@@ -697,6 +806,150 @@ int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[])
free (ts5_result);
}
/* struct tests */
{
test_structure_6 ts6_arg;
/* This is a hack to get a properly aligned result buffer */
test_structure_6 *ts6_result =
(test_structure_6 *) malloc (sizeof(test_structure_6));
args[0] = &ts6_type;
values[0] = &ts6_arg;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts6_type, args) == FFI_OK);
ts6_arg.f = 5.55f;
ts6_arg.d = 6.66;
printf ("%g\n", ts6_arg.f);
printf ("%g\n", ts6_arg.d);
ffi_call(&cif, FFI_FN(struct6), ts6_result, values);
printf ("%g\n", ts6_result->f);
printf ("%g\n", ts6_result->d);
CHECK(ts6_result->f == 5.55f + 1);
CHECK(ts6_result->d == 6.66 + 1);
printf("structure test 6 ok!\n");
free (ts6_result);
}
/* struct tests */
{
test_structure_7 ts7_arg;
/* This is a hack to get a properly aligned result buffer */
test_structure_7 *ts7_result =
(test_structure_7 *) malloc (sizeof(test_structure_7));
args[0] = &ts7_type;
values[0] = &ts7_arg;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts7_type, args) == FFI_OK);
ts7_arg.f1 = 5.55f;
ts7_arg.f2 = 55.5f;
ts7_arg.d = 6.66;
printf ("%g\n", ts7_arg.f1);
printf ("%g\n", ts7_arg.f2);
printf ("%g\n", ts7_arg.d);
ffi_call(&cif, FFI_FN(struct7), ts7_result, values);
printf ("%g\n", ts7_result->f1);
printf ("%g\n", ts7_result->f2);
printf ("%g\n", ts7_result->d);
CHECK(ts7_result->f1 == 5.55f + 1);
CHECK(ts7_result->f2 == 55.5f + 1);
CHECK(ts7_result->d == 6.66 + 1);
printf("structure test 7 ok!\n");
free (ts7_result);
}
/* struct tests */
{
test_structure_8 ts8_arg;
/* This is a hack to get a properly aligned result buffer */
test_structure_8 *ts8_result =
(test_structure_8 *) malloc (sizeof(test_structure_8));
args[0] = &ts8_type;
values[0] = &ts8_arg;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts8_type, args) == FFI_OK);
ts8_arg.f1 = 5.55f;
ts8_arg.f2 = 55.5f;
ts8_arg.f3 = -5.55f;
ts8_arg.f4 = -55.5f;
printf ("%g\n", ts8_arg.f1);
printf ("%g\n", ts8_arg.f2);
printf ("%g\n", ts8_arg.f3);
printf ("%g\n", ts8_arg.f4);
ffi_call(&cif, FFI_FN(struct8), ts8_result, values);
printf ("%g\n", ts8_result->f1);
printf ("%g\n", ts8_result->f2);
printf ("%g\n", ts8_result->f3);
printf ("%g\n", ts8_result->f4);
CHECK(ts8_result->f1 == 5.55f + 1);
CHECK(ts8_result->f2 == 55.5f + 1);
CHECK(ts8_result->f3 == -5.55f + 1);
CHECK(ts8_result->f4 == -55.5f + 1);
printf("structure test 8 ok!\n");
free (ts8_result);
}
/* struct tests */
{
test_structure_9 ts9_arg;
/* This is a hack to get a properly aligned result buffer */
test_structure_9 *ts9_result =
(test_structure_9 *) malloc (sizeof(test_structure_9));
args[0] = &ts9_type;
values[0] = &ts9_arg;
/* Initialize the cif */
CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ts9_type, args) == FFI_OK);
ts9_arg.f = 5.55f;
ts9_arg.i = 5;
printf ("%g\n", ts9_arg.f);
printf ("%d\n", ts9_arg.i);
ffi_call(&cif, FFI_FN(struct9), ts9_result, values);
printf ("%g\n", ts9_result->f);
printf ("%d\n", ts9_result->i);
CHECK(ts9_result->f == 5.55f + 1);
CHECK(ts9_result->i == 5 + 1);
printf("structure test 9 ok!\n");
free (ts9_result);
}
#else
printf("Structure passing doesn't work on Win32.\n");
#endif /* X86_WIN32 */
......
......@@ -16,14 +16,11 @@ static void *
ffi_prep_args (void *stack, extended_cif *ecif)
{
unsigned int i;
int tmp;
unsigned int avn;
void **p_argv;
char *argp;
ffi_type **p_arg;
void *struct_value_ptr;
tmp = 0;
argp = stack;
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
......@@ -32,11 +29,10 @@ ffi_prep_args (void *stack, extended_cif *ecif)
else
struct_value_ptr = NULL;
avn = ecif->cif->nargs;
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
i != 0 && avn != 0;
i != 0;
i--, p_arg++)
{
size_t z;
......@@ -45,9 +41,6 @@ ffi_prep_args (void *stack, extended_cif *ecif)
if (((*p_arg)->alignment - 1) & (unsigned) argp)
argp = (char *) ALIGN (argp, (*p_arg)->alignment);
if (avn != 0)
{
avn--;
z = (*p_arg)->size;
if (z < sizeof (int))
{
......@@ -82,7 +75,6 @@ ffi_prep_args (void *stack, extended_cif *ecif)
memcpy (argp, *p_argv, z);
p_argv++;
argp += z;
}
}
return struct_value_ptr;
......
......@@ -51,7 +51,6 @@ static void ffi_prep_args(char *stack,
int flags)
{
register int i;
register int avn;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
......@@ -81,12 +80,9 @@ static void ffi_prep_args(char *stack,
FIX_ARGP;
}
avn = ecif->cif->nargs;
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
i && avn;
i--, p_arg++)
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
{
size_t z;
......@@ -102,9 +98,6 @@ static void ffi_prep_args(char *stack,
#define OFFSET sizeof(int)
#endif
if (avn)
{
avn--;
z = (*p_arg)->size;
if (z < sizeof(SLOT_TYPE_UNSIGNED))
{
......@@ -180,7 +173,6 @@ static void ffi_prep_args(char *stack,
p_argv++;
argp += z;
FIX_ARGP;
}
}
return;
......
......@@ -103,7 +103,9 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
/* Perform a sanity check on the return type */
FFI_ASSERT(ffi_type_test(cif->rtype));
#ifndef M68K
/* x86-64 and s390 stack space allocation is handled in prep_machdep.
TODO: Disable this for s390 too? */
#if !defined M68K && !defined __x86_64__
/* Make space for the return structure pointer */
if (cif->rtype->type == FFI_TYPE_STRUCT
#ifdef SPARC
......@@ -122,6 +124,8 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK))
return FFI_BAD_TYPEDEF;
/* TODO: Disable this calculation for s390 too? */
#ifndef __x86_64__
#ifdef SPARC
if (((*ptr)->type == FFI_TYPE_STRUCT
&& ((*ptr)->size > 16 || cif->abi != FFI_V9))
......@@ -137,6 +141,7 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
bytes += STACK_ARG_SIZE((*ptr)->size);
}
#endif
}
cif->bytes = bytes;
......
......@@ -34,14 +34,10 @@
void ffi_prep_args_v8(char *stack, extended_cif *ecif)
{
int i;
int tmp;
int avn;
void **p_argv;
char *argp;
ffi_type **p_arg;
tmp = 0;
/* Skip 16 words for the window save area */
argp = stack + 16*sizeof(int);
......@@ -66,18 +62,12 @@ void ffi_prep_args_v8(char *stack, extended_cif *ecif)
((int*)argp)[5] = 0;
#endif
avn = ecif->cif->nargs;
p_argv = ecif->avalue;
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types;
i && avn;
i--, p_arg++)
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
{
size_t z;
if (avn)
{
avn--;
if ((*p_arg)->type == FFI_TYPE_STRUCT
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|| (*p_arg)->type == FFI_TYPE_LONGDOUBLE
......@@ -122,7 +112,6 @@ void ffi_prep_args_v8(char *stack, extended_cif *ecif)
}
p_argv++;
argp += z;
}
}
return;
......
......@@ -42,7 +42,7 @@ FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32);
FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32);
FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT);
#if defined ALPHA || defined SPARC64
#if defined ALPHA || defined SPARC64 || defined X86_64
FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER);
......@@ -52,22 +52,7 @@ FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER);
#endif
#ifdef X86
FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
#elif defined X86_WIN32
FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
#elif defined ARM
FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
#elif defined M68K
#if defined X86 || defined X86_WIN32 || defined ARM || defined M68K
FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64);
FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64);
......@@ -80,12 +65,7 @@ FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64);
#endif
#ifdef X86
FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
#elif defined X86_WIN32
#if defined X86 || defined X86_WIN32 || defined M68K
FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
......@@ -95,25 +75,20 @@ FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE);
#elif defined M68K
FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE);
FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE);
#elif defined SPARC
FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
#ifdef SPARC64
FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
#else
FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE);
#endif
#elif defined X86_64
FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE);
#else
FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE);
......
......@@ -23,6 +23,8 @@
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef __x86_64__
#include <ffi.h>
#include <ffi_common.h>
......@@ -491,3 +493,5 @@ ffi_raw_call(/*@dependent@*/ ffi_cif *cif,
}
#endif
#endif /* __x86_64__ */
/* -----------------------------------------------------------------------
sysv.S - Copyright (c) 1996, 1998, 2001 Cygnus Solutions
sysv.S - Copyright (c) 1996, 1998, 2001, 2002 Cygnus Solutions
X86 Foreign Function Interface
......@@ -23,6 +23,8 @@
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifndef __x86_64__
#define LIBFFI_ASM
#include <ffi.h>
......@@ -163,3 +165,5 @@ __FRAME_BEGIN__:
.align 4
.LEFDE1:
.set .LLFDE1,.LEFDE1-.LSFDE1
#endif /* ifndef __x86_64__ */
/* -----------------------------------------------------------------------
unix64.S - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
x86-64 Foreign Function Interface
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */
#ifdef __x86_64__
#define LIBFFI_ASM
#include <ffi.h>
.section .rodata
.LC0:
.string "asm in progress %lld\n"
.LC1:
.string "asm in progress\n"
.text
.align 2
.globl ffi_call_UNIX64
.type ffi_call_UNIX64,@function
ffi_call_UNIX64:
.LFB1:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
/* Save all arguments */
subq $48, %rsp
.LCFI2:
movq %rdi, -8(%rbp) /* ffi_prep_args */
movq %rsi, -16(%rbp) /* ffi_fill_return_value */
movq %rdx, -24(%rbp) /* ecif */
movq %rcx, -32(%rbp) /* cif->bytes */
movq %r8, -40(%rbp) /* ecif.rvalue */
movq %r9, -48(%rbp) /* fn */
/* Make room for all of the new args and the register args */
addl $176, %ecx
.LCFI3:
subq %rcx, %rsp
.LCFI4:
/* Setup the call to ffi_prep_args. */
movq %rdi, %rax /* &ffi_prep_args */
movq %rsp, %rdi /* stackLayout */
movq %rdx, %rsi /* ecif */
call *%rax /* ffi_prep_args(stackLayout, ecif);*/
/* ffi_prep_args have put all the register contents into the */
/* stackLayout struct. Now put the register values in place. */
movq (%rsp), %rdi
movq 8(%rsp), %rsi
movq 16(%rsp), %rdx
movq 24(%rsp), %rcx
movq 32(%rsp), %r8
movq 40(%rsp), %r9
movaps 48(%rsp), %xmm0
movaps 64(%rsp), %xmm1
movaps 80(%rsp), %xmm2
movaps 96(%rsp), %xmm3
movaps 112(%rsp), %xmm4
movaps 128(%rsp), %xmm5
movaps 144(%rsp), %xmm6
movaps 160(%rsp), %xmm7
/* Remove space for stackLayout so stack arguments are placed
correctly for the call. */
.LCFI5:
addq $176, %rsp
.LCFI6:
/* Call the user function. */
call *-48(%rbp)
/* Make stack space for the return_value struct. */
subq $64, %rsp
/* Fill in all potential return values to this struct. */
movq %rax, (%rsp)
movq %rdx, 8(%rsp)
movaps %xmm0, 16(%rsp)
movaps %xmm1, 32(%rsp)
fstpt 48(%rsp)
/* Now call ffi_fill_return_value. */
movq %rsp, %rdi /* struct return_value */
movq -24(%rbp), %rsi /* ecif */
movq -16(%rbp), %rax /* &ffi_fill_return_value */
call *%rax /* call it */
/* And the work is done. */
leave
ret
.LFE1:
.ffi_call_UNIX64_end:
.size ffi_call_UNIX64,.ffi_call_UNIX64_end-ffi_call_UNIX64
.text
.align 2
.globl float2sse
.type float2sse,@function
float2sse:
/* Save the contents of this sse-float in a pointer. */
movaps %xmm0, (%rdi)
ret
.align 2
.globl floatfloat2sse
.type floatfloat2sse,@function
floatfloat2sse:
/* Save the contents of these two sse-floats in a pointer. */
movq (%rdi), %xmm0
movaps %xmm0, (%rsi)
ret
.align 2
.globl double2sse
.type double2sse,@function
double2sse:
/* Save the contents of this sse-double in a pointer. */
movaps %xmm0, (%rdi)
ret
.align 2
.globl sse2float
.type sse2float,@function
sse2float:
/* Save the contents of this sse-float in a pointer. */
movaps (%rdi), %xmm0
ret
.align 2
.globl sse2double
.type sse2double,@function
sse2double:
/* Save the contents of this pointer in a sse-double. */
movaps (%rdi), %xmm0
ret
.align 2
.globl sse2floatfloat
.type sse2floatfloat,@function
sse2floatfloat:
/* Save the contents of this pointer in two sse-floats. */
movaps (%rdi), %xmm0
movq %xmm0, (%rsi)
ret
#endif /* __x86_64__ */
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