Commit 97067642 by Andreas Tobler

Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD.

2005-07-19  Andreas Tobler  <a.tobler@schweiz.ch>

	* Makefile.am (nodist_libffi_la_SOURCES): Add POWERPC_FREEBSD.
	* Makefile.in: Regenerate.
	* include/Makefile.in: Likewise.
	* testsuite/Makefile.in: Likewise.
	* configure.ac: Add POWERPC_FREEBSD rules.
	* configure: Regenerate.
	* src/powerpc/ffitarget.h: Add POWERPC_FREEBSD rules.
	(FFI_SYSV_TYPE_SMALL_STRUCT): Define.
	* src/powerpc/ffi.c: Add flags to handle small structure returns
	in ffi_call_SYSV.
	(ffi_prep_cif_machdep): Handle small structures for SYSV 4 ABI.
	Aka FFI_SYSV.
	(ffi_closure_helper_SYSV): Likewise.
	* src/powerpc/ppc_closure.S: Add return types for small structures.
	* src/powerpc/sysv.S: Add bits to handle small structures for
	final SYSV 4 ABI

From-SVN: r102174
parent af62f6f9
......@@ -117,6 +117,9 @@ endif
if POWERPC_DARWIN
nodist_libffi_la_SOURCES += src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
endif
if POWERPC_FREEBSD
nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
endif
if ARM
nodist_libffi_la_SOURCES += src/arm/sysv.S src/arm/ffi.c
endif
......
......@@ -51,14 +51,15 @@ target_triplet = @target@
@POWERPC_TRUE@am__append_10 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
@POWERPC_AIX_TRUE@am__append_11 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
@POWERPC_DARWIN_TRUE@am__append_12 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
@ARM_TRUE@am__append_13 = src/arm/sysv.S src/arm/ffi.c
@LIBFFI_CRIS_TRUE@am__append_14 = src/cris/sysv.S src/cris/ffi.c
@FRV_TRUE@am__append_15 = src/frv/eabi.S src/frv/ffi.c
@S390_TRUE@am__append_16 = src/s390/sysv.S src/s390/ffi.c
@X86_64_TRUE@am__append_17 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
@SH_TRUE@am__append_18 = src/sh/sysv.S src/sh/ffi.c
@SH64_TRUE@am__append_19 = src/sh64/sysv.S src/sh64/ffi.c
@PA_TRUE@am__append_20 = src/pa/linux.S src/pa/ffi.c
@POWERPC_FREEBSD_TRUE@am__append_13 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
@ARM_TRUE@am__append_14 = src/arm/sysv.S src/arm/ffi.c
@LIBFFI_CRIS_TRUE@am__append_15 = src/cris/sysv.S src/cris/ffi.c
@FRV_TRUE@am__append_16 = src/frv/eabi.S src/frv/ffi.c
@S390_TRUE@am__append_17 = src/s390/sysv.S src/s390/ffi.c
@X86_64_TRUE@am__append_18 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
@SH_TRUE@am__append_19 = src/sh/sysv.S src/sh/ffi.c
@SH64_TRUE@am__append_20 = src/sh64/sysv.S src/sh64/ffi.c
@PA_TRUE@am__append_21 = src/pa/linux.S src/pa/ffi.c
DIST_COMMON = README $(am__configure_deps) $(srcdir)/../compile \
$(srcdir)/../config.guess $(srcdir)/../config.sub \
$(srcdir)/../depcomp $(srcdir)/../install-sh \
......@@ -111,36 +112,40 @@ am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
@POWERPC_DARWIN_TRUE@am__objects_12 = src/powerpc/ffi_darwin.lo \
@POWERPC_DARWIN_TRUE@ src/powerpc/darwin.lo \
@POWERPC_DARWIN_TRUE@ src/powerpc/darwin_closure.lo
@ARM_TRUE@am__objects_13 = src/arm/sysv.lo src/arm/ffi.lo
@LIBFFI_CRIS_TRUE@am__objects_14 = src/cris/sysv.lo src/cris/ffi.lo
@FRV_TRUE@am__objects_15 = src/frv/eabi.lo src/frv/ffi.lo
@S390_TRUE@am__objects_16 = src/s390/sysv.lo src/s390/ffi.lo
@X86_64_TRUE@am__objects_17 = src/x86/ffi64.lo src/x86/unix64.lo \
@POWERPC_FREEBSD_TRUE@am__objects_13 = src/powerpc/ffi.lo \
@POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \
@POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo
@ARM_TRUE@am__objects_14 = src/arm/sysv.lo src/arm/ffi.lo
@LIBFFI_CRIS_TRUE@am__objects_15 = src/cris/sysv.lo src/cris/ffi.lo
@FRV_TRUE@am__objects_16 = src/frv/eabi.lo src/frv/ffi.lo
@S390_TRUE@am__objects_17 = src/s390/sysv.lo src/s390/ffi.lo
@X86_64_TRUE@am__objects_18 = src/x86/ffi64.lo src/x86/unix64.lo \
@X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo
@SH_TRUE@am__objects_18 = src/sh/sysv.lo src/sh/ffi.lo
@SH64_TRUE@am__objects_19 = src/sh64/sysv.lo src/sh64/ffi.lo
@PA_TRUE@am__objects_20 = src/pa/linux.lo src/pa/ffi.lo
@SH_TRUE@am__objects_19 = src/sh/sysv.lo src/sh/ffi.lo
@SH64_TRUE@am__objects_20 = src/sh64/sysv.lo src/sh64/ffi.lo
@PA_TRUE@am__objects_21 = src/pa/linux.lo src/pa/ffi.lo
nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \
$(am__objects_9) $(am__objects_10) $(am__objects_11) \
$(am__objects_12) $(am__objects_13) $(am__objects_14) \
$(am__objects_15) $(am__objects_16) $(am__objects_17) \
$(am__objects_18) $(am__objects_19) $(am__objects_20)
$(am__objects_18) $(am__objects_19) $(am__objects_20) \
$(am__objects_21)
libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
$(nodist_libffi_la_OBJECTS)
libffi_convenience_la_LIBADD =
am__objects_21 = src/debug.lo src/prep_cif.lo src/types.lo \
am__objects_22 = src/debug.lo src/prep_cif.lo src/types.lo \
src/raw_api.lo src/java_raw_api.lo
am_libffi_convenience_la_OBJECTS = $(am__objects_21)
am__objects_22 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
am_libffi_convenience_la_OBJECTS = $(am__objects_22)
am__objects_23 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11) $(am__objects_12) \
$(am__objects_13) $(am__objects_14) $(am__objects_15) \
$(am__objects_16) $(am__objects_17) $(am__objects_18) \
$(am__objects_19) $(am__objects_20)
nodist_libffi_convenience_la_OBJECTS = $(am__objects_22)
$(am__objects_19) $(am__objects_20) $(am__objects_21)
nodist_libffi_convenience_la_OBJECTS = $(am__objects_23)
libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
$(nodist_libffi_convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
......@@ -259,6 +264,8 @@ POWERPC_AIX_TRUE = @POWERPC_AIX_TRUE@
POWERPC_DARWIN_FALSE = @POWERPC_DARWIN_FALSE@
POWERPC_DARWIN_TRUE = @POWERPC_DARWIN_TRUE@
POWERPC_FALSE = @POWERPC_FALSE@
POWERPC_FREEBSD_FALSE = @POWERPC_FREEBSD_FALSE@
POWERPC_FREEBSD_TRUE = @POWERPC_FREEBSD_TRUE@
POWERPC_TRUE = @POWERPC_TRUE@
RANLIB = @RANLIB@
S390_FALSE = @S390_FALSE@
......@@ -404,7 +411,8 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
$(am__append_9) $(am__append_10) $(am__append_11) \
$(am__append_12) $(am__append_13) $(am__append_14) \
$(am__append_15) $(am__append_16) $(am__append_17) \
$(am__append_18) $(am__append_19) $(am__append_20)
$(am__append_18) $(am__append_19) $(am__append_20) \
$(am__append_21)
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions
......
......@@ -310,7 +310,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS CCAS CCASFLAGS LN_S RANLIB ac_ct_RANLIB LIBTOOL MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS MIPS_IRIX_TRUE MIPS_IRIX_FALSE MIPS_LINUX_TRUE MIPS_LINUX_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_WIN32_TRUE X86_WIN32_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE IA64_FALSE M32R_TRUE M32R_FALSE M68K_TRUE M68K_FALSE POWERPC_TRUE POWERPC_FALSE POWERPC_AIX_TRUE POWERPC_AIX_FALSE POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE ARM_TRUE ARM_FALSE LIBFFI_CRIS_TRUE LIBFFI_CRIS_FALSE FRV_TRUE FRV_FALSE S390_TRUE S390_FALSE X86_64_TRUE X86_64_FALSE SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE PA_TRUE PA_FALSE ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR toolexecdir toolexeclibdir LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS multi_basedir build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CFLAGS CCAS CCASFLAGS LN_S RANLIB ac_ct_RANLIB LIBTOOL MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT CPP CPPFLAGS EGREP TESTSUBDIR_TRUE TESTSUBDIR_FALSE AM_RUNTESTFLAGS MIPS_IRIX_TRUE MIPS_IRIX_FALSE MIPS_LINUX_TRUE MIPS_LINUX_FALSE SPARC_TRUE SPARC_FALSE X86_TRUE X86_FALSE X86_WIN32_TRUE X86_WIN32_FALSE ALPHA_TRUE ALPHA_FALSE IA64_TRUE IA64_FALSE M32R_TRUE M32R_FALSE M68K_TRUE M68K_FALSE POWERPC_TRUE POWERPC_FALSE POWERPC_AIX_TRUE POWERPC_AIX_FALSE POWERPC_DARWIN_TRUE POWERPC_DARWIN_FALSE POWERPC_FREEBSD_TRUE POWERPC_FREEBSD_FALSE ARM_TRUE ARM_FALSE LIBFFI_CRIS_TRUE LIBFFI_CRIS_FALSE FRV_TRUE FRV_FALSE S390_TRUE S390_FALSE X86_64_TRUE X86_64_FALSE SH_TRUE SH_FALSE SH64_TRUE SH64_FALSE PA_TRUE PA_FALSE ALLOCA HAVE_LONG_DOUBLE TARGET TARGETDIR toolexecdir toolexeclibdir LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
......@@ -5403,6 +5403,7 @@ powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;;
powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;;
powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;;
powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;;
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
......@@ -5548,6 +5549,16 @@ fi
if test x$TARGET = xPOWERPC_FREEBSD; then
POWERPC_FREEBSD_TRUE=
POWERPC_FREEBSD_FALSE='#'
else
POWERPC_FREEBSD_TRUE='#'
POWERPC_FREEBSD_FALSE=
fi
if test x$TARGET = xARM; then
ARM_TRUE=
ARM_FALSE='#'
......@@ -7799,6 +7810,13 @@ echo "$as_me: error: conditional \"POWERPC_DARWIN\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${POWERPC_FREEBSD_TRUE}" && test -z "${POWERPC_FREEBSD_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"POWERPC_FREEBSD\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
echo "$as_me: error: conditional \"POWERPC_FREEBSD\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${ARM_TRUE}" && test -z "${ARM_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"ARM\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
......@@ -8498,6 +8516,8 @@ s,@POWERPC_AIX_TRUE@,$POWERPC_AIX_TRUE,;t t
s,@POWERPC_AIX_FALSE@,$POWERPC_AIX_FALSE,;t t
s,@POWERPC_DARWIN_TRUE@,$POWERPC_DARWIN_TRUE,;t t
s,@POWERPC_DARWIN_FALSE@,$POWERPC_DARWIN_FALSE,;t t
s,@POWERPC_FREEBSD_TRUE@,$POWERPC_FREEBSD_TRUE,;t t
s,@POWERPC_FREEBSD_FALSE@,$POWERPC_FREEBSD_FALSE,;t t
s,@ARM_TRUE@,$ARM_TRUE,;t t
s,@ARM_FALSE@,$ARM_FALSE,;t t
s,@LIBFFI_CRIS_TRUE@,$LIBFFI_CRIS_TRUE,;t t
......
......@@ -68,6 +68,7 @@ powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;;
powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;;
powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;;
powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;;
powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;;
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;;
......@@ -101,6 +102,7 @@ AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
AM_CONDITIONAL(POWERPC_FREEBSD, test x$TARGET = xPOWERPC_FREEBSD)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
AM_CONDITIONAL(LIBFFI_CRIS, test x$TARGET = xLIBFFI_CRIS)
AM_CONDITIONAL(FRV, test x$TARGET = xFRV)
......
......@@ -137,6 +137,8 @@ POWERPC_AIX_TRUE = @POWERPC_AIX_TRUE@
POWERPC_DARWIN_FALSE = @POWERPC_DARWIN_FALSE@
POWERPC_DARWIN_TRUE = @POWERPC_DARWIN_TRUE@
POWERPC_FALSE = @POWERPC_FALSE@
POWERPC_FREEBSD_FALSE = @POWERPC_FREEBSD_FALSE@
POWERPC_FREEBSD_TRUE = @POWERPC_FREEBSD_TRUE@
POWERPC_TRUE = @POWERPC_TRUE@
RANLIB = @RANLIB@
S390_FALSE = @S390_FALSE@
......
......@@ -41,6 +41,7 @@ extern void hidden ffi_closure_LINUX64(void);
enum {
/* The assembly depends on these exact flags. */
FLAG_RETURNS_SMST = 1 << (31-31), /* Used for FFI_SYSV small structs. */
FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */
FLAG_RETURNS_FP = 1 << (31-29),
FLAG_RETURNS_64BITS = 1 << (31-28),
......@@ -462,6 +463,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
unsigned flags = 0;
unsigned struct_copy_size = 0;
unsigned type = cif->rtype->type;
unsigned size = cif->rtype->size;
if (cif->abi != FFI_LINUX64)
{
......@@ -518,15 +520,30 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
break;
case FFI_TYPE_STRUCT:
if (cif->abi != FFI_GCC_SYSV && cif->abi != FFI_LINUX64)
if (cif->abi == FFI_SYSV)
{
if (cif->rtype->size <= 4)
break;
else if (cif->rtype->size <= 8)
{
flags |= FLAG_RETURNS_64BITS;
/* The final SYSV ABI says that structures smaller or equal 8 bytes
are returned in r3/r4. The FFI_GCC_SYSV ABI instead returns them
in memory. */
/* Treat structs with size <= 8 bytes. */
if (size <= 8) {
flags |= FLAG_RETURNS_SMST;
/* These structs are returned in r3. We pack the type and the
precalculated shift value (needed in the sysv.S) into flags.
The same applies for the structs returned in r3/r4. */
if (size <= 4) {
flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 1 )
| (8 * (4 - size) << 4);
break;
}
/* These structs are returned in r3 and r4. See above. */
if (size <= 8) {
flags |= 1 << (31 - FFI_SYSV_TYPE_SMALL_STRUCT - 2 )
| (8 * (8 - size) << 4);
break;
}
}
}
/* else fall through. */
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
......@@ -573,7 +590,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* 'long long' arguments are passed as two words, but
either both words must fit in registers or both go
on the stack. If they go on the stack, they must
be 8-byte-aligned.
be 8-byte-aligned.
Also, only certain register pairs can be used for
passing long long int -- specifically (r3,r4), (r5,r6),
......@@ -770,7 +787,7 @@ ffi_prep_closure (ffi_closure* closure,
#else
unsigned int *tramp;
FFI_ASSERT (cif->abi == FFI_GCC_SYSV);
FFI_ASSERT (cif->abi == FFI_GCC_SYSV || cif->abi == FFI_SYSV);
tramp = (unsigned int *) &closure->tramp[0];
tramp[0] = 0x7c0802a6; /* mflr r0 */
......@@ -829,20 +846,27 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
long ng; /* number of general registers already used */
ffi_cif * cif;
double temp;
unsigned size;
cif = closure->cif;
avalue = alloca(cif->nargs * sizeof(void *));
size = cif->rtype->size;
nf = 0;
ng = 0;
/* Copy the caller's structure return value address so that the closure
returns the data directly to the caller. */
returns the data directly to the caller.
For FFI_SYSV the result is passed in r3/r4 if the struct size is less
or equal 8 bytes. */
if (cif->rtype->type == FFI_TYPE_STRUCT)
{
rvalue = (void *) *pgr;
ng++;
pgr++;
if (!((cif->abi == FFI_SYSV) && (size <= 8))) {
rvalue = (void *) *pgr;
ng++;
pgr++;
}
}
i = 0;
......@@ -986,7 +1010,12 @@ ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue,
(closure->fun) (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_SYSV how to perform return type promotions. */
/* Tell ffi_closure_SYSV how to perform return type promotions.
Because the FFI_SYSV ABI returns the structures <= 8 bytes in r3/r4
we have to tell ffi_closure_SYSV how to treat them. */
if (cif->abi == FFI_SYSV && cif->rtype->type == FFI_TYPE_STRUCT
&& size <= 8)
return FFI_SYSV_TYPE_SMALL_STRUCT + size;
return cif->rtype->type;
}
......
......@@ -62,6 +62,13 @@ typedef enum ffi_abi {
FFI_DEFAULT_ABI = FFI_DARWIN,
#endif
#ifdef POWERPC_FREEBSD
FFI_SYSV,
FFI_GCC_SYSV,
FFI_LINUX64,
FFI_DEFAULT_ABI = FFI_SYSV,
#endif
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
} ffi_abi;
#endif
......@@ -71,6 +78,9 @@ typedef enum ffi_abi {
#define FFI_CLOSURES 1
#define FFI_NATIVE_RAW_API 0
/* Needed for FFI_SYSV small structure returns. */
#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST)
#if defined(POWERPC64) || defined(POWERPC_AIX)
#define FFI_TRAMPOLINE_SIZE 24
#else /* POWERPC || POWERPC_AIX */
......
......@@ -63,9 +63,22 @@ ENTRY(ffi_closure_SYSV)
# so use it to look up in a table
# so we know how to deal with each type
# Extract the size of the return type for small structures.
# Then calculate (4 - size) and multiply the result by 8.
# This gives the value needed for the shift operation below.
# This part is only needed for FFI_SYSV and small structures.
addi %r5,%r3,-(FFI_SYSV_TYPE_SMALL_STRUCT)
cmpwi cr0,%r5,4
ble cr0,.Lnext
addi %r5,%r5,-4
.Lnext:
addi %r5,%r5,-4
neg %r5,%r5
slwi %r5,%r5,3
# look up the proper starting point in table
# by using return type as offset
addi %r5,%r1,112 # get pointer to results area
addi %r6,%r1,112 # get pointer to results area
bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR
mflr %r4 # move to r4
slwi %r3,%r3,4 # now multiply return type by 16
......@@ -94,85 +107,85 @@ ENTRY(ffi_closure_SYSV)
# case FFI_TYPE_INT
.Lret_type1:
lwz %r3,0(%r5)
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_FLOAT
.Lret_type2:
lfs %f1,0(%r5)
lfs %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_DOUBLE
.Lret_type3:
lfd %f1,0(%r5)
lfd %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_LONGDOUBLE
.Lret_type4:
lfd %f1,0(%r5)
lfd %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT8
.Lret_type5:
lbz %r3,3(%r5)
lbz %r3,3(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT8
.Lret_type6:
lbz %r3,3(%r5)
lbz %r3,3(%r6)
extsb %r3,%r3
b .Lfinish
nop
# case FFI_TYPE_UINT16
.Lret_type7:
lhz %r3,2(%r5)
lhz %r3,2(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT16
.Lret_type8:
lha %r3,2(%r5)
lha %r3,2(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT32
.Lret_type9:
lwz %r3,0(%r5)
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT32
.Lret_type10:
lwz %r3,0(%r5)
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT64
.Lret_type11:
lwz %r3,0(%r5)
lwz %r4,4(%r5)
lwz %r3,0(%r6)
lwz %r4,4(%r6)
b .Lfinish
nop
# case FFI_TYPE_SINT64
.Lret_type12:
lwz %r3,0(%r5)
lwz %r4,4(%r5)
lwz %r3,0(%r6)
lwz %r4,4(%r6)
b .Lfinish
nop
......@@ -185,10 +198,75 @@ ENTRY(ffi_closure_SYSV)
# case FFI_TYPE_POINTER
.Lret_type14:
lwz %r3,0(%r5)
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# The return types below are only used when the ABI type is FFI_SYSV.
# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
.Lret_type15:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
.Lret_type16:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
.Lret_type17:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
.Lret_type18:
# this one handles the structs from above too.
lwz %r3,0(%r6)
srw %r3,%r3,%r5
b .Lfinish
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
.Lret_type19:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
.Lret_type20:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
.Lret_type21:
# fall through.
nop
nop
nop
nop
# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
.Lret_type22:
# this one handles the above unhandled structs.
lwz %r3,0(%r6)
lwz %r4,4(%r6)
bl __lshrdi3 # libgcc function to shift r3/r4, shift value in r5.
b .Lfinish
# case done
.Lfinish:
......
......@@ -99,6 +99,7 @@ ENTRY(ffi_call_SYSV)
/* Now, deal with the return value. */
mtcrf 0x01,%r31
bt- 31,L(small_struct_return_value)
bt- 30,L(done_return_value)
bt- 29,L(fp_return_value)
stw %r3,0(%r30)
......@@ -124,6 +125,27 @@ L(fp_return_value):
L(float_return_value):
stfs %f1,0(%r30)
b L(done_return_value)
L(small_struct_return_value):
mtcrf 0x10,%r31 /* cr3 */
bt- 15,L(smst_one_register)
mtcrf 0x08,%r31 /* cr4 */
bt- 16,L(smst_two_register)
b L(done_return_value)
L(smst_one_register):
rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
slw %r3,%r3,%r5
stw %r3,0(%r30)
b L(done_return_value)
L(smst_two_register):
rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
bl __ashldi3 /* libgcc function to shift r3/r4,
shift value in r5. */
stw %r3,0(%r30)
stw %r4,4(%r30)
b L(done_return_value)
.LFE1:
END(ffi_call_SYSV)
......
......@@ -123,6 +123,8 @@ POWERPC_AIX_TRUE = @POWERPC_AIX_TRUE@
POWERPC_DARWIN_FALSE = @POWERPC_DARWIN_FALSE@
POWERPC_DARWIN_TRUE = @POWERPC_DARWIN_TRUE@
POWERPC_FALSE = @POWERPC_FALSE@
POWERPC_FREEBSD_FALSE = @POWERPC_FREEBSD_FALSE@
POWERPC_FREEBSD_TRUE = @POWERPC_FREEBSD_TRUE@
POWERPC_TRUE = @POWERPC_TRUE@
RANLIB = @RANLIB@
S390_FALSE = @S390_FALSE@
......
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