Latest gcc svn sources

This commit is contained in:
green
2008-01-29 15:15:20 +00:00
parent 2544e45a0b
commit 77175b3f72
141 changed files with 5242 additions and 2218 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,15 @@
## Process this with automake to create Makefile.in ## Process this with automake to create Makefile.in
AUTOMAKE_OPTIONS = foreign subdir-objects AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I ..
SUBDIRS = include testsuite SUBDIRS = include testsuite
EXTRA_DIST = LICENSE ChangeLog.v1 \ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \ src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \ src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \ src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
src/ia64/unix.S \
src/mips/ffi.c src/mips/n32.S src/mips/o32.S \ src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
src/mips/ffitarget.h \ src/mips/ffitarget.h \
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
@@ -24,9 +25,10 @@ EXTRA_DIST = LICENSE ChangeLog.v1 \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \ src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \ src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
src/sparc/ffi.c \ src/sparc/ffi.c \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \ src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \ src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffi.c src/pa/linux.S src/frv/eabi.S src/frv/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h
## ################################################################ ## ################################################################
@@ -77,22 +79,22 @@ toolexeclib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.la noinst_LTLIBRARIES = libffi_convenience.la
libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \ libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c src/raw_api.c src/java_raw_api.c src/closures.c
nodist_libffi_la_SOURCES = nodist_libffi_la_SOURCES =
if MIPS_IRIX if MIPS
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S
endif endif
if MIPS_LINUX
nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S
endif
if X86 if X86
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/sysv.S
endif endif
if X86_WIN32 if X86_WIN32
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/win32.S
endif endif
if X86_DARWIN
nodist_libffi_la_SOURCES += src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
endif
if SPARC if SPARC
nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S nodist_libffi_la_SOURCES += src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
endif endif
@@ -141,9 +143,12 @@ endif
if SH64 if SH64
nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c nodist_libffi_la_SOURCES += src/sh64/sysv.S src/sh64/ffi.c
endif endif
if PA if PA_LINUX
nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c nodist_libffi_la_SOURCES += src/pa/linux.S src/pa/ffi.c
endif endif
if PA_HPUX
nodist_libffi_la_SOURCES += src/pa/hpux32.S src/pa/ffi.c
endif
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
@@ -154,3 +159,9 @@ libffi_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version`
AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src
AM_CCASFLAGS = $(AM_CPPFLAGS) AM_CCASFLAGS = $(AM_CPPFLAGS)
# No install-html or install-pdf support in automake yet
.PHONY: install-html install-pdf
install-html:
install-pdf:

View File

@@ -33,10 +33,10 @@ POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
target_triplet = @target@ target_triplet = @target@
@MIPS_IRIX_TRUE@am__append_1 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S @MIPS_TRUE@am__append_1 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S
@MIPS_LINUX_TRUE@am__append_2 = src/mips/ffi.c src/mips/o32.S @X86_TRUE@am__append_2 = src/x86/ffi.c src/x86/sysv.S
@X86_TRUE@am__append_3 = src/x86/ffi.c src/x86/sysv.S @X86_WIN32_TRUE@am__append_3 = src/x86/ffi.c src/x86/win32.S
@X86_WIN32_TRUE@am__append_4 = src/x86/ffi.c src/x86/win32.S @X86_DARWIN_TRUE@am__append_4 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S
@SPARC_TRUE@am__append_5 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S @SPARC_TRUE@am__append_5 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S
@ALPHA_TRUE@am__append_6 = src/alpha/ffi.c src/alpha/osf.S @ALPHA_TRUE@am__append_6 = src/alpha/ffi.c src/alpha/osf.S
@IA64_TRUE@am__append_7 = src/ia64/ffi.c src/ia64/unix.S @IA64_TRUE@am__append_7 = src/ia64/ffi.c src/ia64/unix.S
@@ -53,7 +53,8 @@ target_triplet = @target@
@X86_64_TRUE@am__append_18 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S @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 @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 @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 @PA_LINUX_TRUE@am__append_21 = src/pa/linux.S src/pa/ffi.c
@PA_HPUX_TRUE@am__append_22 = src/pa/hpux32.S src/pa/ffi.c
subdir = . subdir = .
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/fficonfig.h.in \ $(srcdir)/Makefile.in $(srcdir)/fficonfig.h.in \
@@ -82,12 +83,13 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) $(toolexeclib_LTLIBRARIES)
libffi_la_LIBADD = libffi_la_LIBADD =
am__dirstamp = $(am__leading_dot)dirstamp am__dirstamp = $(am__leading_dot)dirstamp
am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \ am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
src/raw_api.lo src/java_raw_api.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo
@MIPS_IRIX_TRUE@am__objects_1 = src/mips/ffi.lo src/mips/o32.lo \ @MIPS_TRUE@am__objects_1 = src/mips/ffi.lo src/mips/o32.lo \
@MIPS_IRIX_TRUE@ src/mips/n32.lo @MIPS_TRUE@ src/mips/n32.lo
@MIPS_LINUX_TRUE@am__objects_2 = src/mips/ffi.lo src/mips/o32.lo @X86_TRUE@am__objects_2 = src/x86/ffi.lo src/x86/sysv.lo
@X86_TRUE@am__objects_3 = src/x86/ffi.lo src/x86/sysv.lo @X86_WIN32_TRUE@am__objects_3 = src/x86/ffi.lo src/x86/win32.lo
@X86_WIN32_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/win32.lo @X86_DARWIN_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/darwin.lo \
@X86_DARWIN_TRUE@ src/x86/ffi64.lo src/x86/darwin64.lo
@SPARC_TRUE@am__objects_5 = src/sparc/ffi.lo src/sparc/v8.lo \ @SPARC_TRUE@am__objects_5 = src/sparc/ffi.lo src/sparc/v8.lo \
@SPARC_TRUE@ src/sparc/v9.lo @SPARC_TRUE@ src/sparc/v9.lo
@ALPHA_TRUE@am__objects_6 = src/alpha/ffi.lo src/alpha/osf.lo @ALPHA_TRUE@am__objects_6 = src/alpha/ffi.lo src/alpha/osf.lo
@@ -115,7 +117,8 @@ am_libffi_la_OBJECTS = src/debug.lo src/prep_cif.lo src/types.lo \
@X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo @X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo
@SH_TRUE@am__objects_19 = src/sh/sysv.lo src/sh/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 @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 @PA_LINUX_TRUE@am__objects_21 = src/pa/linux.lo src/pa/ffi.lo
@PA_HPUX_TRUE@am__objects_22 = src/pa/hpux32.lo src/pa/ffi.lo
nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_3) $(am__objects_4) $(am__objects_5) \ $(am__objects_3) $(am__objects_4) $(am__objects_5) \
$(am__objects_6) $(am__objects_7) $(am__objects_8) \ $(am__objects_6) $(am__objects_7) $(am__objects_8) \
@@ -123,24 +126,25 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
$(am__objects_12) $(am__objects_13) $(am__objects_14) \ $(am__objects_12) $(am__objects_13) $(am__objects_14) \
$(am__objects_15) $(am__objects_16) $(am__objects_17) \ $(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) $(am__objects_21) $(am__objects_22)
libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \ libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
$(nodist_libffi_la_OBJECTS) $(nodist_libffi_la_OBJECTS)
libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libffi_la_LDFLAGS) $(LDFLAGS) -o $@ $(libffi_la_LDFLAGS) $(LDFLAGS) -o $@
libffi_convenience_la_LIBADD = libffi_convenience_la_LIBADD =
am__objects_22 = src/debug.lo src/prep_cif.lo src/types.lo \ am__objects_23 = src/debug.lo src/prep_cif.lo src/types.lo \
src/raw_api.lo src/java_raw_api.lo src/raw_api.lo src/java_raw_api.lo src/closures.lo
am_libffi_convenience_la_OBJECTS = $(am__objects_22) am_libffi_convenience_la_OBJECTS = $(am__objects_23)
am__objects_23 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ am__objects_24 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
$(am__objects_4) $(am__objects_5) $(am__objects_6) \ $(am__objects_4) $(am__objects_5) $(am__objects_6) \
$(am__objects_7) $(am__objects_8) $(am__objects_9) \ $(am__objects_7) $(am__objects_8) $(am__objects_9) \
$(am__objects_10) $(am__objects_11) $(am__objects_12) \ $(am__objects_10) $(am__objects_11) $(am__objects_12) \
$(am__objects_13) $(am__objects_14) $(am__objects_15) \ $(am__objects_13) $(am__objects_14) $(am__objects_15) \
$(am__objects_16) $(am__objects_17) $(am__objects_18) \ $(am__objects_16) $(am__objects_17) $(am__objects_18) \
$(am__objects_19) $(am__objects_20) $(am__objects_21) $(am__objects_19) $(am__objects_20) $(am__objects_21) \
nodist_libffi_convenience_la_OBJECTS = $(am__objects_23) $(am__objects_22)
nodist_libffi_convenience_la_OBJECTS = $(am__objects_24)
libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \ libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
$(nodist_libffi_convenience_la_OBJECTS) $(nodist_libffi_convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ DEFAULT_INCLUDES = -I.@am__isrc@
@@ -309,12 +313,13 @@ toolexeclibdir = @toolexeclibdir@
top_builddir = @top_builddir@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign subdir-objects AUTOMAKE_OPTIONS = foreign subdir-objects
ACLOCAL_AMFLAGS = -I ..
SUBDIRS = include testsuite SUBDIRS = include testsuite
EXTRA_DIST = LICENSE ChangeLog.v1 \ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host \
src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \ src/alpha/ffi.c src/alpha/osf.S src/alpha/ffitarget.h \
src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \ src/arm/ffi.c src/arm/sysv.S src/arm/ffitarget.h \
src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \ src/cris/ffi.c src/cris/sysv.S src/cris/ffitarget.h \
src/ia64/ffi.c src/ia64/ffitarget.h src/ia64/ia64_flags.h \
src/ia64/unix.S \
src/mips/ffi.c src/mips/n32.S src/mips/o32.S \ src/mips/ffi.c src/mips/n32.S src/mips/o32.S \
src/mips/ffitarget.h \ src/mips/ffitarget.h \
src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \ src/m32r/ffi.c src/m32r/sysv.S src/m32r/ffitarget.h \
@@ -330,9 +335,10 @@ EXTRA_DIST = LICENSE ChangeLog.v1 \
src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \ src/sh64/ffi.c src/sh64/sysv.S src/sh64/ffitarget.h \
src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \ src/sparc/v8.S src/sparc/v9.S src/sparc/ffitarget.h \
src/sparc/ffi.c \ src/sparc/ffi.c \
src/x86/ffi.c src/x86/sysv.S src/x86/win32.S \ src/x86/ffi.c src/x86/sysv.S src/x86/win32.S src/x86/darwin.S \
src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \ src/x86/ffi64.c src/x86/unix64.S src/x86/ffitarget.h \
src/pa/ffi.c src/pa/linux.S src/frv/eabi.S src/frv/ffitarget.h src/pa/ffitarget.h src/pa/ffi.c src/pa/linux.S src/pa/hpux32.S \
src/frv/ffi.c src/frv/eabi.S src/frv/ffitarget.h
# Work around what appears to be a GNU make bug handling MAKEFLAGS # Work around what appears to be a GNU make bug handling MAKEFLAGS
@@ -376,7 +382,7 @@ MAKEOVERRIDES =
toolexeclib_LTLIBRARIES = libffi.la toolexeclib_LTLIBRARIES = libffi.la
noinst_LTLIBRARIES = libffi_convenience.la noinst_LTLIBRARIES = libffi_convenience.la
libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \ libffi_la_SOURCES = src/debug.c src/prep_cif.c src/types.c \
src/raw_api.c src/java_raw_api.c src/raw_api.c src/java_raw_api.c src/closures.c
nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
$(am__append_3) $(am__append_4) $(am__append_5) \ $(am__append_3) $(am__append_4) $(am__append_5) \
@@ -385,7 +391,7 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
$(am__append_12) $(am__append_13) $(am__append_14) \ $(am__append_12) $(am__append_13) $(am__append_14) \
$(am__append_15) $(am__append_16) $(am__append_17) \ $(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) $(am__append_21) $(am__append_22)
libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
AM_CFLAGS = -Wall -g -fexceptions AM_CFLAGS = -Wall -g -fexceptions
@@ -494,6 +500,7 @@ src/prep_cif.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/types.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/types.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/raw_api.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/raw_api.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/java_raw_api.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/java_raw_api.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/closures.lo: src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/mips/$(am__dirstamp): src/mips/$(am__dirstamp):
@$(MKDIR_P) src/mips @$(MKDIR_P) src/mips
@: > src/mips/$(am__dirstamp) @: > src/mips/$(am__dirstamp)
@@ -518,6 +525,12 @@ src/x86/sysv.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/win32.lo: src/x86/$(am__dirstamp) \ src/x86/win32.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/darwin.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/ffi64.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/darwin64.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/sparc/$(am__dirstamp): src/sparc/$(am__dirstamp):
@$(MKDIR_P) src/sparc @$(MKDIR_P) src/sparc
@: > src/sparc/$(am__dirstamp) @: > src/sparc/$(am__dirstamp)
@@ -636,8 +649,6 @@ src/s390/sysv.lo: src/s390/$(am__dirstamp) \
src/s390/$(DEPDIR)/$(am__dirstamp) src/s390/$(DEPDIR)/$(am__dirstamp)
src/s390/ffi.lo: src/s390/$(am__dirstamp) \ src/s390/ffi.lo: src/s390/$(am__dirstamp) \
src/s390/$(DEPDIR)/$(am__dirstamp) src/s390/$(DEPDIR)/$(am__dirstamp)
src/x86/ffi64.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp)
src/x86/unix64.lo: src/x86/$(am__dirstamp) \ src/x86/unix64.lo: src/x86/$(am__dirstamp) \
src/x86/$(DEPDIR)/$(am__dirstamp) src/x86/$(DEPDIR)/$(am__dirstamp)
src/sh/$(am__dirstamp): src/sh/$(am__dirstamp):
@@ -668,6 +679,8 @@ src/pa/$(DEPDIR)/$(am__dirstamp):
src/pa/linux.lo: src/pa/$(am__dirstamp) \ src/pa/linux.lo: src/pa/$(am__dirstamp) \
src/pa/$(DEPDIR)/$(am__dirstamp) src/pa/$(DEPDIR)/$(am__dirstamp)
src/pa/ffi.lo: src/pa/$(am__dirstamp) src/pa/$(DEPDIR)/$(am__dirstamp) src/pa/ffi.lo: src/pa/$(am__dirstamp) src/pa/$(DEPDIR)/$(am__dirstamp)
src/pa/hpux32.lo: src/pa/$(am__dirstamp) \
src/pa/$(DEPDIR)/$(am__dirstamp)
libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES) libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES)
$(libffi_la_LINK) -rpath $(toolexeclibdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS) $(libffi_la_LINK) -rpath $(toolexeclibdir) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS)
libffi_convenience.la: $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_DEPENDENCIES) libffi_convenience.la: $(libffi_convenience_la_OBJECTS) $(libffi_convenience_la_DEPENDENCIES)
@@ -683,6 +696,8 @@ mostlyclean-compile:
-rm -f src/arm/ffi.lo -rm -f src/arm/ffi.lo
-rm -f src/arm/sysv.$(OBJEXT) -rm -f src/arm/sysv.$(OBJEXT)
-rm -f src/arm/sysv.lo -rm -f src/arm/sysv.lo
-rm -f src/closures.$(OBJEXT)
-rm -f src/closures.lo
-rm -f src/cris/ffi.$(OBJEXT) -rm -f src/cris/ffi.$(OBJEXT)
-rm -f src/cris/ffi.lo -rm -f src/cris/ffi.lo
-rm -f src/cris/sysv.$(OBJEXT) -rm -f src/cris/sysv.$(OBJEXT)
@@ -715,6 +730,8 @@ mostlyclean-compile:
-rm -f src/mips/o32.lo -rm -f src/mips/o32.lo
-rm -f src/pa/ffi.$(OBJEXT) -rm -f src/pa/ffi.$(OBJEXT)
-rm -f src/pa/ffi.lo -rm -f src/pa/ffi.lo
-rm -f src/pa/hpux32.$(OBJEXT)
-rm -f src/pa/hpux32.lo
-rm -f src/pa/linux.$(OBJEXT) -rm -f src/pa/linux.$(OBJEXT)
-rm -f src/pa/linux.lo -rm -f src/pa/linux.lo
-rm -f src/powerpc/aix.$(OBJEXT) -rm -f src/powerpc/aix.$(OBJEXT)
@@ -761,6 +778,10 @@ mostlyclean-compile:
-rm -f src/sparc/v9.lo -rm -f src/sparc/v9.lo
-rm -f src/types.$(OBJEXT) -rm -f src/types.$(OBJEXT)
-rm -f src/types.lo -rm -f src/types.lo
-rm -f src/x86/darwin.$(OBJEXT)
-rm -f src/x86/darwin.lo
-rm -f src/x86/darwin64.$(OBJEXT)
-rm -f src/x86/darwin64.lo
-rm -f src/x86/ffi.$(OBJEXT) -rm -f src/x86/ffi.$(OBJEXT)
-rm -f src/x86/ffi.lo -rm -f src/x86/ffi.lo
-rm -f src/x86/ffi64.$(OBJEXT) -rm -f src/x86/ffi64.$(OBJEXT)
@@ -775,6 +796,7 @@ mostlyclean-compile:
distclean-compile: distclean-compile:
-rm -f *.tab.c -rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/closures.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/debug.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/debug.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/java_raw_api.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/java_raw_api.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/prep_cif.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/prep_cif.Plo@am__quote@
@@ -798,6 +820,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/n32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/n32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/hpux32.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/linux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/linux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/aix.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/aix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/aix_closure.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/aix_closure.Plo@am__quote@
@@ -818,6 +841,8 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v8.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v8.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v9.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/sparc/$(DEPDIR)/v9.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/darwin64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi64.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/ffi64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/sysv.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@src/x86/$(DEPDIR)/sysv.Plo@am__quote@
@@ -1262,14 +1287,10 @@ install-dvi: install-dvi-recursive
install-exec-am: install-toolexeclibLTLIBRARIES install-exec-am: install-toolexeclibLTLIBRARIES
install-html: install-html-recursive
install-info: install-info-recursive install-info: install-info-recursive
install-man: install-man:
install-pdf: install-pdf-recursive
install-ps: install-ps-recursive install-ps: install-ps-recursive
installcheck-am: installcheck-am:
@@ -1318,6 +1339,11 @@ uninstall-am: uninstall-toolexeclibLTLIBRARIES
pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \ pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
uninstall-toolexeclibLTLIBRARIES uninstall-toolexeclibLTLIBRARIES
# No install-html or install-pdf support in automake yet
.PHONY: install-html install-pdf
install-html:
install-pdf:
# Tell versions [3.59,3.63) of GNU make to not export all variables. # Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:

View File

@@ -212,7 +212,7 @@ Here is a trivial example that calls puts() a few times.
int rc; int rc;
/* Initialize the argument info vectors */ /* Initialize the argument info vectors */
args[0] = &ffi_type_uint; args[0] = &ffi_type_pointer;
values[0] = &s; values[0] = &s;
/* Initialize the cif */ /* Initialize the cif */
@@ -372,15 +372,6 @@ single-precision anyway. This causes one test to fail (the `many
arguments' test). arguments' test).
What's With The Crazy Comments?
===============================
You might notice a number of cryptic comments in the code, delimited
by /*@ and @*/. These are annotations read by the program LCLint, a
tool for statically checking C programs. You can read all about it at
<http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>.
History History
======= =======

401
libffi/configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for libffi 2.1. # Generated by GNU Autoconf 2.61 for libffi 3.0.
# #
# Report bugs to <http://gcc.gnu.org/bugs.html>. # Report bugs to <http://gcc.gnu.org/bugs.html>.
# #
@@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='libffi' PACKAGE_NAME='libffi'
PACKAGE_TARNAME='libffi' PACKAGE_TARNAME='libffi'
PACKAGE_VERSION='2.1' PACKAGE_VERSION='3.0'
PACKAGE_STRING='libffi 2.1' PACKAGE_STRING='libffi 3.0'
PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html' PACKAGE_BUGREPORT='http://gcc.gnu.org/bugs.html'
# Factoring default headers for most tests. # Factoring default headers for most tests.
@@ -885,16 +885,16 @@ MAINT
TESTSUBDIR_TRUE TESTSUBDIR_TRUE
TESTSUBDIR_FALSE TESTSUBDIR_FALSE
AM_RUNTESTFLAGS AM_RUNTESTFLAGS
MIPS_IRIX_TRUE MIPS_TRUE
MIPS_IRIX_FALSE MIPS_FALSE
MIPS_LINUX_TRUE
MIPS_LINUX_FALSE
SPARC_TRUE SPARC_TRUE
SPARC_FALSE SPARC_FALSE
X86_TRUE X86_TRUE
X86_FALSE X86_FALSE
X86_WIN32_TRUE X86_WIN32_TRUE
X86_WIN32_FALSE X86_WIN32_FALSE
X86_DARWIN_TRUE
X86_DARWIN_FALSE
ALPHA_TRUE ALPHA_TRUE
ALPHA_FALSE ALPHA_FALSE
IA64_TRUE IA64_TRUE
@@ -925,8 +925,12 @@ SH_TRUE
SH_FALSE SH_FALSE
SH64_TRUE SH64_TRUE
SH64_FALSE SH64_FALSE
PA_TRUE PA_LINUX_TRUE
PA_FALSE PA_LINUX_FALSE
PA_HPUX_TRUE
PA_HPUX_FALSE
PA64_HPUX_TRUE
PA64_HPUX_FALSE
ALLOCA ALLOCA
HAVE_LONG_DOUBLE HAVE_LONG_DOUBLE
TARGET TARGET
@@ -1453,7 +1457,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures libffi 2.1 to adapt to many kinds of systems. \`configure' configures libffi 3.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1524,7 +1528,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of libffi 2.1:";; short | recursive ) echo "Configuration of libffi 3.0:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1634,7 +1638,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
libffi configure 2.1 libffi configure 3.0
generated by GNU Autoconf 2.61 generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1648,7 +1652,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by libffi $as_me 2.1, which was It was created by libffi $as_me 3.0, which was
generated by GNU Autoconf 2.61. Invocation command line was generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@ $ $0 $@
@@ -2471,7 +2475,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='libffi' PACKAGE='libffi'
VERSION='2.1' VERSION='3.0'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@@ -4684,7 +4688,7 @@ ia64-*-hpux*)
;; ;;
*-*-irix6*) *-*-irix6*)
# Find out which ABI we are using. # Find out which ABI we are using.
echo '#line 4687 "configure"' > conftest.$ac_ext echo '#line 4691 "configure"' > conftest.$ac_ext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
(eval $ac_compile) 2>&5 (eval $ac_compile) 2>&5
ac_status=$? ac_status=$?
@@ -7427,11 +7431,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7430: $lt_compile\"" >&5) (eval echo "\"\$as_me:7434: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:7434: \$? = $ac_status" >&5 echo "$as_me:7438: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -7717,11 +7721,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7720: $lt_compile\"" >&5) (eval echo "\"\$as_me:7724: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:7724: \$? = $ac_status" >&5 echo "$as_me:7728: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -7821,11 +7825,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:7824: $lt_compile\"" >&5) (eval echo "\"\$as_me:7828: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:7828: \$? = $ac_status" >&5 echo "$as_me:7832: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@@ -10172,7 +10176,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 10175 "configure" #line 10179 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@@ -10272,7 +10276,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<EOF cat > conftest.$ac_ext <<EOF
#line 10275 "configure" #line 10279 "configure"
#include "confdefs.h" #include "confdefs.h"
#if HAVE_DLFCN_H #if HAVE_DLFCN_H
@@ -12692,11 +12696,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:12695: $lt_compile\"" >&5) (eval echo "\"\$as_me:12699: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:12699: \$? = $ac_status" >&5 echo "$as_me:12703: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -12796,11 +12800,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:12799: $lt_compile\"" >&5) (eval echo "\"\$as_me:12803: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:12803: \$? = $ac_status" >&5 echo "$as_me:12807: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@@ -14360,11 +14364,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:14363: $lt_compile\"" >&5) (eval echo "\"\$as_me:14367: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:14367: \$? = $ac_status" >&5 echo "$as_me:14371: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -14464,11 +14468,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:14467: $lt_compile\"" >&5) (eval echo "\"\$as_me:14471: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:14471: \$? = $ac_status" >&5 echo "$as_me:14475: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@@ -16653,11 +16657,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16656: $lt_compile\"" >&5) (eval echo "\"\$as_me:16660: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:16660: \$? = $ac_status" >&5 echo "$as_me:16664: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -16943,11 +16947,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:16946: $lt_compile\"" >&5) (eval echo "\"\$as_me:16950: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err) (eval "$lt_compile" 2>conftest.err)
ac_status=$? ac_status=$?
cat conftest.err >&5 cat conftest.err >&5
echo "$as_me:16950: \$? = $ac_status" >&5 echo "$as_me:16954: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output. # So say no if there are warnings other than the usual output.
@@ -17047,11 +17051,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'` -e 's:$: $lt_compiler_flag:'`
(eval echo "\"\$as_me:17050: $lt_compile\"" >&5) (eval echo "\"\$as_me:17054: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err) (eval "$lt_compile" 2>out/conftest.err)
ac_status=$? ac_status=$?
cat out/conftest.err >&5 cat out/conftest.err >&5
echo "$as_me:17054: \$? = $ac_status" >&5 echo "$as_me:17058: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext if (exit $ac_status) && test -s out/conftest2.$ac_objext
then then
# The compiler can only warn and ignore the option if not recognized # The compiler can only warn and ignore the option if not recognized
@@ -20356,48 +20360,108 @@ fi
TARGETDIR="unknown" TARGETDIR="unknown"
case "$host" in case "$host" in
i*86-*-linux*) TARGET=X86; TARGETDIR=x86;; alpha*-*-*)
i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;; TARGET=ALPHA; TARGETDIR=alpha;
i*86-*-solaris2.1[0-9]*) TARGET=X86_64; TARGETDIR=x86;; # Support 128-bit long double, changable via command-line switch.
i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
i*86-*-beos*) TARGET=X86; TARGETDIR=x86;; ;;
i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; arm*-*-*)
i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; TARGET=ARM; TARGETDIR=arm
i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; ;;
i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;;
i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;; cris-*-*)
frv-*-*) TARGET=FRV; TARGETDIR=frv;; TARGET=LIBFFI_CRIS; TARGETDIR=cris
sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;; ;;
sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; frv-*-*)
sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;; TARGET=FRV; TARGETDIR=frv
sparc64-*-linux* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; ;;
alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;;
ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; hppa*-*-linux* | parisc*-*-linux*)
m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;; TARGET=PA_LINUX; TARGETDIR=pa
m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;; ;;
mips64*-*);; hppa*64-*-hpux*)
mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;; TARGET=PA64_HPUX; TARGETDIR=pa
mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;; ;;
powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;; hppa*-*-hpux*)
powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;; TARGET=PA_HPUX; TARGETDIR=pa
powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;; ;;
powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; TARGET=X86_WIN32; TARGETDIR=x86
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; ;;
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; i?86-*-darwin*)
arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; TARGET=X86_DARWIN; TARGETDIR=x86
arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; ;;
cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; i?86-*-solaris2.1[0-9]*)
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; TARGET=X86_64; TARGETDIR=x86
s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;; ;;
x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; i?86-*-*)
sh-*-linux* | sh[34]*-*-linux*) TARGET=SH; TARGETDIR=sh;; TARGET=X86; TARGETDIR=x86
sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; ;;
sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;;
hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;; ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux*)
TARGET=MIPS; TARGETDIR=mips
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc*-*-rtems*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
s390-*-* | s390x-*-*)
TARGET=S390; TARGETDIR=s390
;;
sh-*-* | sh[34]*-*-*)
TARGET=SH; TARGETDIR=sh
;;
sh64-*-* | sh5*-*-*)
TARGET=SH64; TARGETDIR=sh64
;;
sparc*-*-*)
TARGET=SPARC; TARGETDIR=sparc
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac esac
@@ -20408,20 +20472,12 @@ echo "$as_me: error: \"libffi has not been ported to $host.\"" >&2;}
{ (exit 1); exit 1; }; } { (exit 1); exit 1; }; }
fi fi
if test x$TARGET = xMIPS_IRIX; then if test x$TARGET = xMIPS; then
MIPS_IRIX_TRUE= MIPS_TRUE=
MIPS_IRIX_FALSE='#' MIPS_FALSE='#'
else else
MIPS_IRIX_TRUE='#' MIPS_TRUE='#'
MIPS_IRIX_FALSE= MIPS_FALSE=
fi
if test x$TARGET = xMIPS_LINUX; then
MIPS_LINUX_TRUE=
MIPS_LINUX_FALSE='#'
else
MIPS_LINUX_TRUE='#'
MIPS_LINUX_FALSE=
fi fi
if test x$TARGET = xSPARC; then if test x$TARGET = xSPARC; then
@@ -20448,6 +20504,14 @@ else
X86_WIN32_FALSE= X86_WIN32_FALSE=
fi fi
if test x$TARGET = xX86_DARWIN; then
X86_DARWIN_TRUE=
X86_DARWIN_FALSE='#'
else
X86_DARWIN_TRUE='#'
X86_DARWIN_FALSE=
fi
if test x$TARGET = xALPHA; then if test x$TARGET = xALPHA; then
ALPHA_TRUE= ALPHA_TRUE=
ALPHA_FALSE='#' ALPHA_FALSE='#'
@@ -20568,19 +20632,30 @@ else
SH64_FALSE= SH64_FALSE=
fi fi
if test x$TARGET = xPA; then if test x$TARGET = xPA_LINUX; then
PA_TRUE= PA_LINUX_TRUE=
PA_FALSE='#' PA_LINUX_FALSE='#'
else else
PA_TRUE='#' PA_LINUX_TRUE='#'
PA_FALSE= PA_LINUX_FALSE=
fi fi
if test x$TARGET = xPA_HPUX; then
PA_HPUX_TRUE=
PA_HPUX_FALSE='#'
else
PA_HPUX_TRUE='#'
PA_HPUX_FALSE=
fi
if test x$TARGET = xPA64_HPUX; then
PA64_HPUX_TRUE=
PA64_HPUX_FALSE='#'
else
PA64_HPUX_TRUE='#'
PA64_HPUX_FALSE=
fi
case x$TARGET in
xMIPS*) TARGET=MIPS ;;
*) ;;
esac
{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 { echo "$as_me:$LINENO: checking for ANSI C header files" >&5
echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
@@ -22022,6 +22097,7 @@ _ACEOF
# Also AC_SUBST this variable for ffi.h. # Also AC_SUBST this variable for ffi.h.
if test -z "$HAVE_LONG_DOUBLE"; then
HAVE_LONG_DOUBLE=0 HAVE_LONG_DOUBLE=0
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
if test $ac_cv_sizeof_long_double != 0; then if test $ac_cv_sizeof_long_double != 0; then
@@ -22033,6 +22109,7 @@ _ACEOF
fi fi
fi fi
fi
{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5 { echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
@@ -22272,6 +22349,66 @@ presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
esac esac
{ echo "$as_me:$LINENO: checking assembler .cfi pseudo-op support" >&5
echo $ECHO_N "checking assembler .cfi pseudo-op support... $ECHO_C" >&6; }
if test "${libffi_cv_as_cfi_pseudo_op+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
libffi_cv_as_cfi_pseudo_op=unknown
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
asm (".cfi_startproc\n\t.cfi_endproc");
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
libffi_cv_as_cfi_pseudo_op=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
libffi_cv_as_cfi_pseudo_op=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ echo "$as_me:$LINENO: result: $libffi_cv_as_cfi_pseudo_op" >&5
echo "${ECHO_T}$libffi_cv_as_cfi_pseudo_op" >&6; }
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
cat >>confdefs.h <<\_ACEOF
#define HAVE_AS_CFI_PSEUDO_OP 1
_ACEOF
fi
if test x$TARGET = xSPARC; then if test x$TARGET = xSPARC; then
{ echo "$as_me:$LINENO: checking assembler and linker support unaligned pc related relocs" >&5 { echo "$as_me:$LINENO: checking assembler and linker support unaligned pc related relocs" >&5
echo $ECHO_N "checking assembler and linker support unaligned pc related relocs... $ECHO_C" >&6; } echo $ECHO_N "checking assembler and linker support unaligned pc related relocs... $ECHO_C" >&6; }
@@ -22699,17 +22836,10 @@ echo "$as_me: error: conditional \"TESTSUBDIR\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;} Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; } { (exit 1); exit 1; }; }
fi fi
if test -z "${MIPS_IRIX_TRUE}" && test -z "${MIPS_IRIX_FALSE}"; then if test -z "${MIPS_TRUE}" && test -z "${MIPS_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"MIPS_IRIX\" was never defined. { { echo "$as_me:$LINENO: error: conditional \"MIPS\" was never defined.
Usually this means the macro was only invoked conditionally." >&5 Usually this means the macro was only invoked conditionally." >&5
echo "$as_me: error: conditional \"MIPS_IRIX\" was never defined. echo "$as_me: error: conditional \"MIPS\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${MIPS_LINUX_TRUE}" && test -z "${MIPS_LINUX_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"MIPS_LINUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
echo "$as_me: error: conditional \"MIPS_LINUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;} Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; } { (exit 1); exit 1; }; }
fi fi
@@ -22734,6 +22864,13 @@ echo "$as_me: error: conditional \"X86_WIN32\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;} Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; } { (exit 1); exit 1; }; }
fi fi
if test -z "${X86_DARWIN_TRUE}" && test -z "${X86_DARWIN_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"X86_DARWIN\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
echo "$as_me: error: conditional \"X86_DARWIN\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${ALPHA_TRUE}" && test -z "${ALPHA_FALSE}"; then if test -z "${ALPHA_TRUE}" && test -z "${ALPHA_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"ALPHA\" was never defined. { { echo "$as_me:$LINENO: error: conditional \"ALPHA\" was never defined.
Usually this means the macro was only invoked conditionally." >&5 Usually this means the macro was only invoked conditionally." >&5
@@ -22839,10 +22976,24 @@ echo "$as_me: error: conditional \"SH64\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;} Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; } { (exit 1); exit 1; }; }
fi fi
if test -z "${PA_TRUE}" && test -z "${PA_FALSE}"; then if test -z "${PA_LINUX_TRUE}" && test -z "${PA_LINUX_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"PA\" was never defined. { { echo "$as_me:$LINENO: error: conditional \"PA_LINUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&5 Usually this means the macro was only invoked conditionally." >&5
echo "$as_me: error: conditional \"PA\" was never defined. echo "$as_me: error: conditional \"PA_LINUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${PA_HPUX_TRUE}" && test -z "${PA_HPUX_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"PA_HPUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
echo "$as_me: error: conditional \"PA_HPUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; }
fi
if test -z "${PA64_HPUX_TRUE}" && test -z "${PA64_HPUX_FALSE}"; then
{ { echo "$as_me:$LINENO: error: conditional \"PA64_HPUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&5
echo "$as_me: error: conditional \"PA64_HPUX\" was never defined.
Usually this means the macro was only invoked conditionally." >&2;} Usually this means the macro was only invoked conditionally." >&2;}
{ (exit 1); exit 1; }; } { (exit 1); exit 1; }; }
fi fi
@@ -23146,7 +23297,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by libffi $as_me 2.1, which was This file was extended by libffi $as_me 3.0, which was
generated by GNU Autoconf 2.61. Invocation command line was generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -23203,7 +23354,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\ ac_cs_version="\\
libffi config.status 2.1 libffi config.status 3.0
configured by $0, generated by GNU Autoconf 2.61, configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -23548,16 +23699,16 @@ MAINT!$MAINT$ac_delim
TESTSUBDIR_TRUE!$TESTSUBDIR_TRUE$ac_delim TESTSUBDIR_TRUE!$TESTSUBDIR_TRUE$ac_delim
TESTSUBDIR_FALSE!$TESTSUBDIR_FALSE$ac_delim TESTSUBDIR_FALSE!$TESTSUBDIR_FALSE$ac_delim
AM_RUNTESTFLAGS!$AM_RUNTESTFLAGS$ac_delim AM_RUNTESTFLAGS!$AM_RUNTESTFLAGS$ac_delim
MIPS_IRIX_TRUE!$MIPS_IRIX_TRUE$ac_delim MIPS_TRUE!$MIPS_TRUE$ac_delim
MIPS_IRIX_FALSE!$MIPS_IRIX_FALSE$ac_delim MIPS_FALSE!$MIPS_FALSE$ac_delim
MIPS_LINUX_TRUE!$MIPS_LINUX_TRUE$ac_delim
MIPS_LINUX_FALSE!$MIPS_LINUX_FALSE$ac_delim
SPARC_TRUE!$SPARC_TRUE$ac_delim SPARC_TRUE!$SPARC_TRUE$ac_delim
SPARC_FALSE!$SPARC_FALSE$ac_delim SPARC_FALSE!$SPARC_FALSE$ac_delim
X86_TRUE!$X86_TRUE$ac_delim X86_TRUE!$X86_TRUE$ac_delim
X86_FALSE!$X86_FALSE$ac_delim X86_FALSE!$X86_FALSE$ac_delim
X86_WIN32_TRUE!$X86_WIN32_TRUE$ac_delim X86_WIN32_TRUE!$X86_WIN32_TRUE$ac_delim
X86_WIN32_FALSE!$X86_WIN32_FALSE$ac_delim X86_WIN32_FALSE!$X86_WIN32_FALSE$ac_delim
X86_DARWIN_TRUE!$X86_DARWIN_TRUE$ac_delim
X86_DARWIN_FALSE!$X86_DARWIN_FALSE$ac_delim
ALPHA_TRUE!$ALPHA_TRUE$ac_delim ALPHA_TRUE!$ALPHA_TRUE$ac_delim
ALPHA_FALSE!$ALPHA_FALSE$ac_delim ALPHA_FALSE!$ALPHA_FALSE$ac_delim
IA64_TRUE!$IA64_TRUE$ac_delim IA64_TRUE!$IA64_TRUE$ac_delim
@@ -23588,8 +23739,12 @@ SH_TRUE!$SH_TRUE$ac_delim
SH_FALSE!$SH_FALSE$ac_delim SH_FALSE!$SH_FALSE$ac_delim
SH64_TRUE!$SH64_TRUE$ac_delim SH64_TRUE!$SH64_TRUE$ac_delim
SH64_FALSE!$SH64_FALSE$ac_delim SH64_FALSE!$SH64_FALSE$ac_delim
PA_TRUE!$PA_TRUE$ac_delim PA_LINUX_TRUE!$PA_LINUX_TRUE$ac_delim
PA_FALSE!$PA_FALSE$ac_delim PA_LINUX_FALSE!$PA_LINUX_FALSE$ac_delim
PA_HPUX_TRUE!$PA_HPUX_TRUE$ac_delim
PA_HPUX_FALSE!$PA_HPUX_FALSE$ac_delim
PA64_HPUX_TRUE!$PA64_HPUX_TRUE$ac_delim
PA64_HPUX_FALSE!$PA64_HPUX_FALSE$ac_delim
ALLOCA!$ALLOCA$ac_delim ALLOCA!$ALLOCA$ac_delim
HAVE_LONG_DOUBLE!$HAVE_LONG_DOUBLE$ac_delim HAVE_LONG_DOUBLE!$HAVE_LONG_DOUBLE$ac_delim
TARGET!$TARGET$ac_delim TARGET!$TARGET$ac_delim
@@ -23600,7 +23755,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF _ACEOF
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 70; then if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 74; then
break break
elif $ac_last_try; then elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5

View File

@@ -2,7 +2,7 @@ dnl Process this with autoconf to create configure
AC_PREREQ(2.59) AC_PREREQ(2.59)
AC_INIT([libffi], [2.1], [http://gcc.gnu.org/bugs.html]) AC_INIT([libffi], [3.0], [http://gcc.gnu.org/bugs.html])
AC_CONFIG_HEADERS([fficonfig.h]) AC_CONFIG_HEADERS([fficonfig.h])
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
@@ -39,48 +39,108 @@ AM_CONDITIONAL(TESTSUBDIR, test -d $srcdir/testsuite)
TARGETDIR="unknown" TARGETDIR="unknown"
case "$host" in case "$host" in
i*86-*-linux*) TARGET=X86; TARGETDIR=x86;; alpha*-*-*)
i*86-*-gnu*) TARGET=X86; TARGETDIR=x86;; TARGET=ALPHA; TARGETDIR=alpha;
i*86-*-solaris2.1[[0-9]]*) TARGET=X86_64; TARGETDIR=x86;; # Support 128-bit long double, changable via command-line switch.
i*86-*-solaris*) TARGET=X86; TARGETDIR=x86;; HAVE_LONG_DOUBLE='defined(__LONG_DOUBLE_128__)'
i*86-*-beos*) TARGET=X86; TARGETDIR=x86;; ;;
i*86-*-freebsd* | i*86-*-kfreebsd*-gnu) TARGET=X86; TARGETDIR=x86;;
i*86-*-netbsdelf* | i*86-*-knetbsd*-gnu) TARGET=X86; TARGETDIR=x86;; arm*-*-*)
i*86-*-rtems*) TARGET=X86; TARGETDIR=x86;; TARGET=ARM; TARGETDIR=arm
i*86-*-win32*) TARGET=X86_WIN32; TARGETDIR=x86;; ;;
i*86-*-cygwin*) TARGET=X86_WIN32; TARGETDIR=x86;;
i*86-*-mingw*) TARGET=X86_WIN32; TARGETDIR=x86;; cris-*-*)
frv-*-*) TARGET=FRV; TARGETDIR=frv;; TARGET=LIBFFI_CRIS; TARGETDIR=cris
sparc-sun-4*) TARGET=SPARC; TARGETDIR=sparc;; ;;
sparc*-sun-*) TARGET=SPARC; TARGETDIR=sparc;;
sparc-*-linux* | sparc-*-netbsdelf* | sparc-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; frv-*-*)
sparc*-*-rtems*) TARGET=SPARC; TARGETDIR=sparc;; TARGET=FRV; TARGETDIR=frv
sparc64-*-linux* | sparc64-*-netbsd* | sparc64-*-knetbsd*-gnu) TARGET=SPARC; TARGETDIR=sparc;; ;;
alpha*-*-linux* | alpha*-*-osf* | alpha*-*-freebsd* | alpha*-*-kfreebsd*-gnu | alpha*-*-netbsd* | alpha*-*-knetbsd*-gnu) TARGET=ALPHA; TARGETDIR=alpha;;
ia64*-*-*) TARGET=IA64; TARGETDIR=ia64;; hppa*-*-linux* | parisc*-*-linux*)
m32r*-*-linux* ) TARGET=M32R; TARGETDIR=m32r;; TARGET=PA_LINUX; TARGETDIR=pa
m68k-*-linux*) TARGET=M68K; TARGETDIR=m68k;; ;;
mips64*-*);; hppa*64-*-hpux*)
mips-sgi-irix5.* | mips-sgi-irix6.*) TARGET=MIPS_IRIX; TARGETDIR=mips;; TARGET=PA64_HPUX; TARGETDIR=pa
mips*-*-linux*) TARGET=MIPS_LINUX; TARGETDIR=mips;; ;;
powerpc*-*-linux* | powerpc-*-sysv*) TARGET=POWERPC; TARGETDIR=powerpc;; hppa*-*-hpux*)
powerpc-*-beos*) TARGET=POWERPC; TARGETDIR=powerpc;; TARGET=PA_HPUX; TARGETDIR=pa
powerpc-*-darwin*) TARGET=POWERPC_DARWIN; TARGETDIR=powerpc;; ;;
powerpc-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;;
powerpc-*-freebsd*) TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc;; i?86-win32* | i?86-*-cygwin* | i?86-*-mingw*)
powerpc*-*-rtems*) TARGET=POWERPC; TARGETDIR=powerpc;; TARGET=X86_WIN32; TARGETDIR=x86
rs6000-*-aix*) TARGET=POWERPC_AIX; TARGETDIR=powerpc;; ;;
arm*-*-linux-*) TARGET=ARM; TARGETDIR=arm;; i?86-*-darwin*)
arm*-*-netbsdelf* | arm*-*-knetbsd*-gnu) TARGET=ARM; TARGETDIR=arm;; TARGET=X86_DARWIN; TARGETDIR=x86
arm*-*-rtems*) TARGET=ARM; TARGETDIR=arm;; ;;
cris-*-*) TARGET=LIBFFI_CRIS; TARGETDIR=cris;; i?86-*-solaris2.1[[0-9]]*)
s390-*-linux-*) TARGET=S390; TARGETDIR=s390;; TARGET=X86_64; TARGETDIR=x86
s390x-*-linux-*) TARGET=S390; TARGETDIR=s390;; ;;
x86_64-*-linux* | x86_64-*-freebsd* | x86_64-*-kfreebsd*-gnu) TARGET=X86_64; TARGETDIR=x86;; i?86-*-*)
sh-*-linux* | sh[[34]]*-*-linux*) TARGET=SH; TARGETDIR=sh;; TARGET=X86; TARGETDIR=x86
sh-*-rtems*) TARGET=SH; TARGETDIR=sh;; ;;
sh64-*-linux* | sh5*-*-linux*) TARGET=SH64; TARGETDIR=sh64;;
hppa-*-linux* | parisc-*-linux*) TARGET=PA; TARGETDIR=pa;; ia64*-*-*)
TARGET=IA64; TARGETDIR=ia64
;;
m32r*-*-*)
TARGET=M32R; TARGETDIR=m32r
;;
m68k-*-*)
TARGET=M68K; TARGETDIR=m68k
;;
mips-sgi-irix5.* | mips-sgi-irix6.*)
TARGET=MIPS; TARGETDIR=mips
;;
mips*-*-linux*)
TARGET=MIPS; TARGETDIR=mips
;;
powerpc*-*-linux* | powerpc-*-sysv*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-beos*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
powerpc-*-darwin*)
TARGET=POWERPC_DARWIN; TARGETDIR=powerpc
;;
powerpc-*-aix* | rs6000-*-aix*)
TARGET=POWERPC_AIX; TARGETDIR=powerpc
;;
powerpc-*-freebsd*)
TARGET=POWERPC_FREEBSD; TARGETDIR=powerpc
;;
powerpc*-*-rtems*)
TARGET=POWERPC; TARGETDIR=powerpc
;;
s390-*-* | s390x-*-*)
TARGET=S390; TARGETDIR=s390
;;
sh-*-* | sh[[34]]*-*-*)
TARGET=SH; TARGETDIR=sh
;;
sh64-*-* | sh5*-*-*)
TARGET=SH64; TARGETDIR=sh64
;;
sparc*-*-*)
TARGET=SPARC; TARGETDIR=sparc
;;
x86_64-*-darwin*)
TARGET=X86_DARWIN; TARGETDIR=x86
;;
x86_64-*-cygwin* | x86_64-*-mingw*)
;;
x86_64-*-*)
TARGET=X86_64; TARGETDIR=x86
;;
esac esac
AC_SUBST(AM_RUNTESTFLAGS) AC_SUBST(AM_RUNTESTFLAGS)
@@ -89,11 +149,11 @@ if test $TARGETDIR = unknown; then
AC_MSG_ERROR(["libffi has not been ported to $host."]) AC_MSG_ERROR(["libffi has not been ported to $host."])
fi fi
AM_CONDITIONAL(MIPS_IRIX, test x$TARGET = xMIPS_IRIX) AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS)
AM_CONDITIONAL(MIPS_LINUX, test x$TARGET = xMIPS_LINUX)
AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC)
AM_CONDITIONAL(X86, test x$TARGET = xX86) AM_CONDITIONAL(X86, test x$TARGET = xX86)
AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32) AM_CONDITIONAL(X86_WIN32, test x$TARGET = xX86_WIN32)
AM_CONDITIONAL(X86_DARWIN, test x$TARGET = xX86_DARWIN)
AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA) AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
AM_CONDITIONAL(IA64, test x$TARGET = xIA64) AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
AM_CONDITIONAL(M32R, test x$TARGET = xM32R) AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
@@ -109,12 +169,9 @@ AM_CONDITIONAL(S390, test x$TARGET = xS390)
AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64) AM_CONDITIONAL(X86_64, test x$TARGET = xX86_64)
AM_CONDITIONAL(SH, test x$TARGET = xSH) AM_CONDITIONAL(SH, test x$TARGET = xSH)
AM_CONDITIONAL(SH64, test x$TARGET = xSH64) AM_CONDITIONAL(SH64, test x$TARGET = xSH64)
AM_CONDITIONAL(PA, test x$TARGET = xPA) AM_CONDITIONAL(PA_LINUX, test x$TARGET = xPA_LINUX)
AM_CONDITIONAL(PA_HPUX, test x$TARGET = xPA_HPUX)
case x$TARGET in AM_CONDITIONAL(PA64_HPUX, test x$TARGET = xPA64_HPUX)
xMIPS*) TARGET=MIPS ;;
*) ;;
esac
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_FUNCS(memcpy) AC_CHECK_FUNCS(memcpy)
@@ -124,6 +181,7 @@ AC_CHECK_SIZEOF(double)
AC_CHECK_SIZEOF(long double) AC_CHECK_SIZEOF(long double)
# Also AC_SUBST this variable for ffi.h. # Also AC_SUBST this variable for ffi.h.
if test -z "$HAVE_LONG_DOUBLE"; then
HAVE_LONG_DOUBLE=0 HAVE_LONG_DOUBLE=0
if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
if test $ac_cv_sizeof_long_double != 0; then if test $ac_cv_sizeof_long_double != 0; then
@@ -131,10 +189,23 @@ if test $ac_cv_sizeof_double != $ac_cv_sizeof_long_double; then
AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double]) AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the long double type and it is bigger than a double])
fi fi
fi fi
fi
AC_SUBST(HAVE_LONG_DOUBLE) AC_SUBST(HAVE_LONG_DOUBLE)
AC_C_BIGENDIAN AC_C_BIGENDIAN
AC_CACHE_CHECK([assembler .cfi pseudo-op support],
libffi_cv_as_cfi_pseudo_op, [
libffi_cv_as_cfi_pseudo_op=unknown
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
[libffi_cv_as_cfi_pseudo_op=yes],
[libffi_cv_as_cfi_pseudo_op=no])
])
if test "x$libffi_cv_as_cfi_pseudo_op" = xyes; then
AC_DEFINE(HAVE_AS_CFI_PSEUDO_OP, 1,
[Define if your assembler supports .cfi_* directives.])
fi
if test x$TARGET = xSPARC; then if test x$TARGET = xSPARC; then
AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs], AC_CACHE_CHECK([assembler and linker support unaligned pc related relocs],
libffi_cv_as_sparc_ua_pcrel, [ libffi_cv_as_sparc_ua_pcrel, [

View File

@@ -27,6 +27,9 @@
*/ */
#undef HAVE_ALLOCA_H #undef HAVE_ALLOCA_H
/* Define if your assembler supports .cfi_* directives. */
#undef HAVE_AS_CFI_PSEUDO_OP
/* Define if your assembler supports .register. */ /* Define if your assembler supports .register. */
#undef HAVE_AS_REGISTER_PSEUDO_OP #undef HAVE_AS_REGISTER_PSEUDO_OP
@@ -91,6 +94,10 @@
/* Define to 1 if you have the <unistd.h> header file. */ /* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H #undef HAVE_UNISTD_H
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#undef LT_OBJDIR
/* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O #undef NO_MINUS_C_MINUS_O
@@ -112,15 +119,15 @@
/* Define to the version of this package. */ /* Define to the version of this package. */
#undef PACKAGE_VERSION #undef PACKAGE_VERSION
/* The size of `double', as computed by sizeof. */ /* The size of a `double', as computed by sizeof. */
#undef SIZEOF_DOUBLE #undef SIZEOF_DOUBLE
/* The size of `long double', as computed by sizeof. */ /* The size of a `long double', as computed by sizeof. */
#undef SIZEOF_LONG_DOUBLE #undef SIZEOF_LONG_DOUBLE
/* If using the C implementation of alloca, define if you know the /* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be direction of stack growth for your system; otherwise it will be
automatically deduced at runtime. automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */ STACK_DIRECTION = 0 => direction of growth unknown */

View File

@@ -5,12 +5,4 @@ AUTOMAKE_OPTIONS=foreign
DISTCLEANFILES=ffitarget.h DISTCLEANFILES=ffitarget.h
EXTRA_DIST=ffi.h.in ffi_common.h EXTRA_DIST=ffi.h.in ffi_common.h
hackdir=$(includedir) HEADERS = ffi.h ffitarget.h
hack_DATA= ffi.h ffitarget.h
# Where generated headers like ffitarget.h get installed.
# gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
# Uncomment these when libffi is part of the GCC tree.
# toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/libffi
# toollibffi_HEADERS = ffitarget.h

View File

@@ -35,7 +35,7 @@ host_triplet = @host@
target_triplet = @target@ target_triplet = @target@
subdir = include subdir = include
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/ffi.h.in $(srcdir)/ffi.h.in $(toollibffi_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
$(top_srcdir)/configure.ac $(top_srcdir)/configure.ac
@@ -52,9 +52,11 @@ am__vpath_adj = case $$p in \
*) f=$$p;; \ *) f=$$p;; \
esac; esac;
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
am__installdirs = "$(DESTDIR)$(hackdir)" am__installdirs = "$(DESTDIR)$(toollibffidir)"
hackDATA_INSTALL = $(INSTALL_DATA) toollibffiHEADERS_INSTALL = $(INSTALL_HEADER)
DATA = $(hack_DATA) HEADERS = $(toollibffi_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@ ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@ ALLOCA = @ALLOCA@
@@ -180,8 +182,11 @@ top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign AUTOMAKE_OPTIONS = foreign
DISTCLEANFILES = ffitarget.h DISTCLEANFILES = ffitarget.h
EXTRA_DIST = ffi.h.in ffi_common.h EXTRA_DIST = ffi.h.in ffi_common.h
hackdir = $(includedir)
hack_DATA = ffi.h ffitarget.h # Where generated headers like ffitarget.h get installed.
gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include
toollibffi_HEADERS = ffi.h ffitarget.h
all: all-am all: all-am
.SUFFIXES: .SUFFIXES:
@@ -222,29 +227,71 @@ mostlyclean-libtool:
clean-libtool: clean-libtool:
-rm -rf .libs _libs -rm -rf .libs _libs
install-hackDATA: $(hack_DATA) install-toollibffiHEADERS: $(toollibffi_HEADERS)
@$(NORMAL_INSTALL) @$(NORMAL_INSTALL)
test -z "$(hackdir)" || $(MKDIR_P) "$(DESTDIR)$(hackdir)" test -z "$(toollibffidir)" || $(MKDIR_P) "$(DESTDIR)$(toollibffidir)"
@list='$(hack_DATA)'; for p in $$list; do \ @list='$(toollibffi_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f=$(am__strip_dir) \ f=$(am__strip_dir) \
echo " $(hackDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(hackdir)/$$f'"; \ echo " $(toollibffiHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(toollibffidir)/$$f'"; \
$(hackDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(hackdir)/$$f"; \ $(toollibffiHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(toollibffidir)/$$f"; \
done done
uninstall-hackDATA: uninstall-toollibffiHEADERS:
@$(NORMAL_UNINSTALL) @$(NORMAL_UNINSTALL)
@list='$(hack_DATA)'; for p in $$list; do \ @list='$(toollibffi_HEADERS)'; for p in $$list; do \
f=$(am__strip_dir) \ f=$(am__strip_dir) \
echo " rm -f '$(DESTDIR)$(hackdir)/$$f'"; \ echo " rm -f '$(DESTDIR)$(toollibffidir)/$$f'"; \
rm -f "$(DESTDIR)$(hackdir)/$$f"; \ rm -f "$(DESTDIR)$(toollibffidir)/$$f"; \
done done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS tags: TAGS
TAGS:
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS ctags: CTAGS
CTAGS: CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES) distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
@@ -274,9 +321,9 @@ distdir: $(DISTFILES)
done done
check-am: all-am check-am: all-am
check: check-am check: check-am
all-am: Makefile $(DATA) all-am: Makefile $(HEADERS)
installdirs: installdirs:
for dir in "$(DESTDIR)$(hackdir)"; do \ for dir in "$(DESTDIR)$(toollibffidir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done done
install: install-am install: install-am
@@ -310,7 +357,7 @@ clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-am distclean: distclean-am
-rm -f Makefile -rm -f Makefile
distclean-am: clean-am distclean-generic distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-am dvi: dvi-am
@@ -322,7 +369,7 @@ info: info-am
info-am: info-am:
install-data-am: install-hackDATA install-data-am: install-toollibffiHEADERS
install-dvi: install-dvi-am install-dvi: install-dvi-am
@@ -356,28 +403,24 @@ ps: ps-am
ps-am: ps-am:
uninstall-am: uninstall-hackDATA uninstall-am: uninstall-toollibffiHEADERS
.MAKE: install-am install-strip .MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \ .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
distclean distclean-generic distclean-libtool distdir dvi \ clean-libtool ctags distclean distclean-generic \
dvi-am html html-am info info-am install install-am \ distclean-libtool distclean-tags distdir dvi dvi-am html \
install-data install-data-am install-dvi install-dvi-am \ html-am info info-am install install-am install-data \
install-exec install-exec-am install-hackDATA install-html \ install-data-am install-dvi install-dvi-am install-exec \
install-html-am install-info install-info-am install-man \ install-exec-am install-html install-html-am install-info \
install-pdf install-pdf-am install-ps install-ps-am \ install-info-am install-man install-pdf install-pdf-am \
install-strip installcheck installcheck-am installdirs \ install-ps install-ps-am install-strip \
maintainer-clean maintainer-clean-generic mostlyclean \ install-toollibffiHEADERS installcheck installcheck-am \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ installdirs maintainer-clean maintainer-clean-generic \
uninstall uninstall-am uninstall-hackDATA mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
ps ps-am tags uninstall uninstall-am \
uninstall-toollibffiHEADERS
# Where generated headers like ffitarget.h get installed.
# gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
# Uncomment these when libffi is part of the GCC tree.
# toollibffidir := $(libdir)/gcc/$(target_alias)/$(gcc_version)/include/libffi
# toollibffi_HEADERS = ffitarget.h
# Tell versions [3.59,3.63) of GNU make to not export all variables. # Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded. # Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT: .NOEXPORT:

View File

@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------*-C-*- /* -----------------------------------------------------------------*-C-*-
libffi @VERSION@ - Copyright (c) 1996-2003 Red Hat, Inc. libffi @VERSION@ - Copyright (c) 1996-2003, 2007 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@@ -82,6 +82,18 @@ extern "C" {
# endif # endif
#endif #endif
/* The closure code assumes that this works on pointers, i.e. a size_t */
/* can hold a pointer. */
typedef struct _ffi_type
{
size_t size;
unsigned short alignment;
unsigned short type;
struct _ffi_type **elements;
} ffi_type;
#ifndef LIBFFI_HIDE_BASIC_TYPES
#if SCHAR_MAX == 127 #if SCHAR_MAX == 127
# define ffi_type_uchar ffi_type_uint8 # define ffi_type_uchar ffi_type_uint8
# define ffi_type_schar ffi_type_sint8 # define ffi_type_schar ffi_type_sint8
@@ -112,8 +124,6 @@ extern "C" {
#error "int size not supported" #error "int size not supported"
#endif #endif
#define ffi_type_ulong ffi_type_uint64
#define ffi_type_slong ffi_type_sint64
#if LONG_MAX == 2147483647 #if LONG_MAX == 2147483647
# if FFI_LONG_LONG_MAX != 9223372036854775807 # if FFI_LONG_LONG_MAX != 9223372036854775807
#error "no 64-bit data type supported" #error "no 64-bit data type supported"
@@ -122,16 +132,15 @@ extern "C" {
#error "long size not supported" #error "long size not supported"
#endif #endif
/* The closure code assumes that this works on pointers, i.e. a size_t */ #if LONG_MAX == 2147483647
/* can hold a pointer. */ # define ffi_type_ulong ffi_type_uint32
# define ffi_type_slong ffi_type_sint32
typedef struct _ffi_type #elif LONG_MAX == 9223372036854775807
{ # define ffi_type_ulong ffi_type_uint64
size_t size; # define ffi_type_slong ffi_type_sint64
unsigned short alignment; #else
unsigned short type; #error "long size not supported"
/*@null@*/ struct _ffi_type **elements; #endif
} ffi_type;
/* These are defined in types.c */ /* These are defined in types.c */
extern ffi_type ffi_type_void; extern ffi_type ffi_type_void;
@@ -145,9 +154,14 @@ extern ffi_type ffi_type_uint64;
extern ffi_type ffi_type_sint64; extern ffi_type ffi_type_sint64;
extern ffi_type ffi_type_float; extern ffi_type ffi_type_float;
extern ffi_type ffi_type_double; extern ffi_type ffi_type_double;
extern ffi_type ffi_type_longdouble;
extern ffi_type ffi_type_pointer; extern ffi_type ffi_type_pointer;
#if @HAVE_LONG_DOUBLE@
extern ffi_type ffi_type_longdouble;
#else
#define ffi_type_longdouble ffi_type_double
#endif
#endif /* LIBFFI_HIDE_BASIC_TYPES */
typedef enum { typedef enum {
FFI_OK = 0, FFI_OK = 0,
@@ -160,8 +174,8 @@ typedef unsigned FFI_TYPE;
typedef struct { typedef struct {
ffi_abi abi; ffi_abi abi;
unsigned nargs; unsigned nargs;
/*@dependent@*/ ffi_type **arg_types; ffi_type **arg_types;
/*@dependent@*/ ffi_type *rtype; ffi_type *rtype;
unsigned bytes; unsigned bytes;
unsigned flags; unsigned flags;
#ifdef FFI_EXTRA_CIF_FIELDS #ifdef FFI_EXTRA_CIF_FIELDS
@@ -179,6 +193,10 @@ typedef struct {
# endif # endif
#endif #endif
#ifndef FFI_SIZEOF_JAVA_RAW
# define FFI_SIZEOF_JAVA_RAW FFI_SIZEOF_ARG
#endif
typedef union { typedef union {
ffi_sarg sint; ffi_sarg sint;
ffi_arg uint; ffi_arg uint;
@@ -187,10 +205,25 @@ typedef union {
void* ptr; void* ptr;
} ffi_raw; } ffi_raw;
void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, #if FFI_SIZEOF_JAVA_RAW == 4 && FFI_SIZEOF_ARG == 8
/* This is a special case for mips64/n32 ABI (and perhaps others) where
sizeof(void *) is 4 and FFI_SIZEOF_ARG is 8. */
typedef union {
signed int sint;
unsigned int uint;
float flt;
char data[FFI_SIZEOF_JAVA_RAW];
void* ptr;
} ffi_java_raw;
#else
typedef ffi_raw ffi_java_raw;
#endif
void ffi_raw_call (ffi_cif *cif,
void (*fn)(), void (*fn)(),
/*@out@*/ void *rvalue, void *rvalue,
/*@dependent@*/ ffi_raw *avalue); ffi_raw *avalue);
void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw);
void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args);
@@ -200,13 +233,13 @@ size_t ffi_raw_size (ffi_cif *cif);
/* packing, even on 64-bit machines. I.e. on 64-bit machines */ /* packing, even on 64-bit machines. I.e. on 64-bit machines */
/* longs and doubles are followed by an empty 64-bit word. */ /* longs and doubles are followed by an empty 64-bit word. */
void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, void ffi_java_raw_call (ffi_cif *cif,
void (*fn)(), void (*fn)(),
/*@out@*/ void *rvalue, void *rvalue,
/*@dependent@*/ ffi_raw *avalue); ffi_java_raw *avalue);
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); void ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args);
size_t ffi_java_raw_size (ffi_cif *cif); size_t ffi_java_raw_size (ffi_cif *cif);
/* ---- Definitions for closures ----------------------------------------- */ /* ---- Definitions for closures ----------------------------------------- */
@@ -220,12 +253,22 @@ typedef struct {
void *user_data; void *user_data;
} ffi_closure __attribute__((aligned (8))); } ffi_closure __attribute__((aligned (8)));
void *ffi_closure_alloc (size_t size, void **code);
void ffi_closure_free (void *);
ffi_status ffi_status
ffi_prep_closure (ffi_closure*, ffi_prep_closure (ffi_closure*,
ffi_cif *, ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*), void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data); void *user_data);
ffi_status
ffi_prep_closure_loc (ffi_closure*,
ffi_cif *,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void*codeloc);
typedef struct { typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE]; char tramp[FFI_TRAMPOLINE_SIZE];
@@ -247,6 +290,27 @@ typedef struct {
} ffi_raw_closure; } ffi_raw_closure;
typedef struct {
char tramp[FFI_TRAMPOLINE_SIZE];
ffi_cif *cif;
#if !FFI_NATIVE_RAW_API
/* if this is enabled, then a raw closure has the same layout
as a regular closure. We use this to install an intermediate
handler to do the transaltion, void** -> ffi_raw*. */
void (*translate_args)(ffi_cif*,void*,void**,void*);
void *this_closure;
#endif
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*);
void *user_data;
} ffi_java_raw_closure;
ffi_status ffi_status
ffi_prep_raw_closure (ffi_raw_closure*, ffi_prep_raw_closure (ffi_raw_closure*,
ffi_cif *cif, ffi_cif *cif,
@@ -254,25 +318,39 @@ ffi_prep_raw_closure (ffi_raw_closure*,
void *user_data); void *user_data);
ffi_status ffi_status
ffi_prep_java_raw_closure (ffi_raw_closure*, ffi_prep_raw_closure_loc (ffi_raw_closure*,
ffi_cif *cif, ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*), void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data,
void *codeloc);
ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data); void *user_data);
ffi_status
ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data,
void *codeloc);
#endif /* FFI_CLOSURES */ #endif /* FFI_CLOSURES */
/* ---- Public interface definition -------------------------------------- */ /* ---- Public interface definition -------------------------------------- */
ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, ffi_status ffi_prep_cif(ffi_cif *cif,
ffi_abi abi, ffi_abi abi,
unsigned int nargs, unsigned int nargs,
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, ffi_type *rtype,
/*@dependent@*/ ffi_type **atypes); ffi_type **atypes);
void ffi_call(/*@dependent@*/ ffi_cif *cif, void ffi_call(ffi_cif *cif,
void (*fn)(), void (*fn)(),
/*@out@*/ void *rvalue, void *rvalue,
/*@dependent@*/ void **avalue); void **avalue);
/* Useful for eliminating compiler warnings */ /* Useful for eliminating compiler warnings */
#define FFI_FN(f) ((void (*)())f) #define FFI_FN(f) ((void (*)())f)
@@ -310,4 +388,3 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
#endif #endif
#endif #endif

View File

@@ -1,5 +1,6 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi_common.h - Copyright (c) 1996 Red Hat, Inc. ffi_common.h - Copyright (c) 1996 Red Hat, Inc.
Copyright (C) 2007 Free Software Foundation, Inc
Common internal definitions and macros. Only necessary for building Common internal definitions and macros. Only necessary for building
libffi. libffi.
@@ -18,7 +19,9 @@ extern "C" {
this is positioned. */ this is positioned. */
#ifdef __GNUC__ #ifdef __GNUC__
# define alloca __builtin_alloca # define alloca __builtin_alloca
# define MAYBE_UNUSED __attribute__((__unused__))
#else #else
# define MAYBE_UNUSED
# if HAVE_ALLOCA_H # if HAVE_ALLOCA_H
# include <alloca.h> # include <alloca.h>
# else # else
@@ -46,9 +49,9 @@ char *alloca ();
#endif #endif
#ifdef FFI_DEBUG #ifdef FFI_DEBUG
/*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); void ffi_assert(char *expr, char *file, int line);
void ffi_stop_here(void); void ffi_stop_here(void);
void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); void ffi_type_test(ffi_type *a, char *file, int line);
#define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) #define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__))
#define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) #define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l)))
@@ -68,9 +71,9 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif);
/* Extended cif, used in callback from assembly routine */ /* Extended cif, used in callback from assembly routine */
typedef struct typedef struct
{ {
/*@dependent@*/ ffi_cif *cif; ffi_cif *cif;
/*@dependent@*/ void *rvalue; void *rvalue;
/*@dependent@*/ void **avalue; void **avalue;
} extended_cif; } extended_cif;
/* Terse sized type definitions. */ /* Terse sized type definitions. */

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998, 2001 Red Hat, Inc. ffi.c - Copyright (c) 1998, 2001, 2007 Red Hat, Inc.
Alpha Foreign Function Interface Alpha Foreign Function Interface
@@ -25,11 +25,22 @@
#include <ffi.h> #include <ffi.h>
#include <ffi_common.h> #include <ffi_common.h>
#include <stdlib.h> #include <stdlib.h>
extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)()); /* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
extern void ffi_closure_osf(void); all further uses in this file will refer to the 128-bit type. */
#if defined(__LONG_DOUBLE_128__)
# if FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
#else
# undef FFI_TYPE_LONGDOUBLE
# define FFI_TYPE_LONGDOUBLE 4
#endif
extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)())
FFI_HIDDEN;
extern void ffi_closure_osf(void) FFI_HIDDEN;
ffi_status ffi_status
@@ -49,6 +60,11 @@ ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = cif->rtype->type; cif->flags = cif->rtype->type;
break; break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is returned in memory, like a struct. */
cif->flags = FFI_TYPE_STRUCT;
break;
default: default:
cif->flags = FFI_TYPE_INT; cif->flags = FFI_TYPE_INT;
break; break;
@@ -57,6 +73,7 @@ ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
void void
ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
{ {
@@ -64,8 +81,6 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
long i, avn; long i, avn;
ffi_type **arg_types; ffi_type **arg_types;
FFI_ASSERT (cif->abi == FFI_OSF);
/* If the return value is a struct and we don't have a return /* If the return value is a struct and we don't have a return
value address then we need to make one. */ value address then we need to make one. */
if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT) if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT)
@@ -84,6 +99,8 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
while (i < avn) while (i < avn)
{ {
size_t size = (*arg_types)->size;
switch ((*arg_types)->type) switch ((*arg_types)->type)
{ {
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
@@ -129,6 +146,12 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
*(double *) argp = *(double *)(* avalue); *(double *) argp = *(double *)(* avalue);
break; break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is passed by reference. */
*(long double **) argp = (long double *)(* avalue);
size = sizeof (long double *);
break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
memcpy(argp, *avalue, (*arg_types)->size); memcpy(argp, *avalue, (*arg_types)->size);
break; break;
@@ -137,7 +160,7 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
FFI_ASSERT(0); FFI_ASSERT(0);
} }
argp += ALIGN((*arg_types)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; argp += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
i++, arg_types++, avalue++; i++, arg_types++, avalue++;
} }
@@ -146,15 +169,14 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*), void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data) void *user_data,
void *codeloc)
{ {
unsigned int *tramp; unsigned int *tramp;
FFI_ASSERT (cif->abi == FFI_OSF);
tramp = (unsigned int *) &closure->tramp[0]; tramp = (unsigned int *) &closure->tramp[0];
tramp[0] = 0x47fb0401; /* mov $27,$1 */ tramp[0] = 0x47fb0401; /* mov $27,$1 */
tramp[1] = 0xa77b0010; /* ldq $27,16($27) */ tramp[1] = 0xa77b0010; /* ldq $27,16($27) */
@@ -177,7 +199,8 @@ ffi_prep_closure (ffi_closure* closure,
return FFI_OK; return FFI_OK;
} }
int
long FFI_HIDDEN
ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
{ {
ffi_cif *cif; ffi_cif *cif;
@@ -205,6 +228,8 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
/* Grab the addresses of the arguments from the stack frame. */ /* Grab the addresses of the arguments from the stack frame. */
while (i < avn) while (i < avn)
{ {
size_t size = arg_types[i]->size;
switch (arg_types[i]->type) switch (arg_types[i]->type)
{ {
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
@@ -236,16 +261,22 @@ ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp)
avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)]; avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)];
break; break;
case FFI_TYPE_LONGDOUBLE:
/* 128-bit long double is passed by reference. */
avalue[i] = (long double *) argp[argn];
size = sizeof (long double *);
break;
default: default:
FFI_ASSERT(0); abort ();
} }
argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; argn += ALIGN(size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
i++; i++;
} }
/* Invoke the closure. */ /* Invoke the closure. */
(closure->fun) (cif, rvalue, avalue, closure->user_data); closure->fun (cif, rvalue, avalue, closure->user_data);
/* Tell ffi_closure_osf how to perform return type promotions. */ /* Tell ffi_closure_osf how to perform return type promotions. */
return cif->rtype->type; return cif->rtype->type;

View File

@@ -33,8 +33,8 @@ typedef signed long ffi_sarg;
typedef enum ffi_abi { typedef enum ffi_abi {
FFI_FIRST_ABI = 0, FFI_FIRST_ABI = 0,
FFI_OSF, FFI_OSF,
FFI_DEFAULT_ABI = FFI_OSF, FFI_LAST_ABI,
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 FFI_DEFAULT_ABI = FFI_OSF
} ffi_abi; } ffi_abi;
#endif #endif
@@ -45,4 +45,3 @@ typedef enum ffi_abi {
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#endif #endif

View File

@@ -1,10 +1,8 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
osf.S - Copyright (c) 1998, 2001 Red Hat osf.S - Copyright (c) 1998, 2001, 2007 Red Hat
Alpha/OSF Foreign Function Interface Alpha/OSF Foreign Function Interface
$Id: osf.S,v 1.5 2008/01/29 12:28:14 green Exp $
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including ``Software''), to deal in the Software without restriction, including
@@ -42,6 +40,8 @@
.align 3 .align 3
.globl ffi_call_osf .globl ffi_call_osf
.ent ffi_call_osf .ent ffi_call_osf
FFI_HIDDEN(ffi_call_osf)
ffi_call_osf: ffi_call_osf:
.frame $15, 32, $26, 0 .frame $15, 32, $26, 0
.mask 0x4008000, -32 .mask 0x4008000, -32
@@ -129,6 +129,8 @@ $LFE1:
.align 3 .align 3
.globl ffi_closure_osf .globl ffi_closure_osf
.ent ffi_closure_osf .ent ffi_closure_osf
FFI_HIDDEN(ffi_closure_osf)
ffi_closure_osf: ffi_closure_osf:
.frame $30, 16*8, $26, 0 .frame $30, 16*8, $26, 0
.mask 0x4000000, -16*8 .mask 0x4000000, -16*8
@@ -265,7 +267,7 @@ $load_table:
.gprel32 $load_32 # FFI_TYPE_INT .gprel32 $load_32 # FFI_TYPE_INT
.gprel32 $load_float # FFI_TYPE_FLOAT .gprel32 $load_float # FFI_TYPE_FLOAT
.gprel32 $load_double # FFI_TYPE_DOUBLE .gprel32 $load_double # FFI_TYPE_DOUBLE
.gprel32 $load_double # FFI_TYPE_LONGDOUBLE .gprel32 $load_none # FFI_TYPE_LONGDOUBLE
.gprel32 $load_u8 # FFI_TYPE_UINT8 .gprel32 $load_u8 # FFI_TYPE_UINT8
.gprel32 $load_s8 # FFI_TYPE_SINT8 .gprel32 $load_s8 # FFI_TYPE_SINT8
.gprel32 $load_u16 # FFI_TYPE_UINT16 .gprel32 $load_u16 # FFI_TYPE_UINT16

View File

@@ -31,9 +31,7 @@
/* ffi_prep_args is called by the assembly routine once stack space /* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */ has been allocated for the function's arguments */
/*@-exportheader@*/
void ffi_prep_args(char *stack, extended_cif *ecif) void ffi_prep_args(char *stack, extended_cif *ecif)
/*@=exportheader@*/
{ {
register unsigned int i; register unsigned int i;
register void **p_argv; register void **p_argv;
@@ -42,7 +40,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
argp = stack; argp = stack;
if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) { if ( ecif->cif->flags == FFI_TYPE_STRUCT ) {
*(void **) argp = ecif->rvalue; *(void **) argp = ecif->rvalue;
argp += 4; argp += 4;
} }
@@ -60,6 +58,9 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
argp = (char *) ALIGN(argp, (*p_arg)->alignment); argp = (char *) ALIGN(argp, (*p_arg)->alignment);
} }
if ((*p_arg)->type == FFI_TYPE_STRUCT)
argp = (char *) ALIGN(argp, 4);
z = (*p_arg)->size; z = (*p_arg)->size;
if (z < sizeof(int)) if (z < sizeof(int))
{ {
@@ -83,7 +84,7 @@ void ffi_prep_args(char *stack, extended_cif *ecif)
break; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
*(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); memcpy(argp, *p_argv, (*p_arg)->size);
break; break;
default: default:
@@ -117,7 +118,6 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
switch (cif->rtype->type) switch (cif->rtype->type)
{ {
case FFI_TYPE_VOID: case FFI_TYPE_VOID:
case FFI_TYPE_STRUCT:
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
cif->flags = (unsigned) cif->rtype->type; cif->flags = (unsigned) cif->rtype->type;
@@ -128,6 +128,17 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = (unsigned) FFI_TYPE_SINT64; cif->flags = (unsigned) FFI_TYPE_SINT64;
break; break;
case FFI_TYPE_STRUCT:
if (cif->rtype->size <= 4)
/* A Composite Type not larger than 4 bytes is returned in r0. */
cif->flags = (unsigned)FFI_TYPE_INT;
else
/* A Composite Type larger than 4 bytes, or whose size cannot
be determined statically ... is stored in memory at an
address passed [in r0]. */
cif->flags = (unsigned)FFI_TYPE_STRUCT;
break;
default: default:
cif->flags = FFI_TYPE_INT; cif->flags = FFI_TYPE_INT;
break; break;
@@ -136,50 +147,162 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
/*@-declundef@*/ extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
/*@-exportheader@*/ unsigned, unsigned, unsigned *, void (*fn)());
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
void ffi_call(/*@dependent@*/ ffi_cif *cif, void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue)
{ {
extended_cif ecif; extended_cif ecif;
int small_struct = (cif->flags == FFI_TYPE_INT
&& cif->rtype->type == FFI_TYPE_STRUCT);
ecif.cif = cif; ecif.cif = cif;
ecif.avalue = avalue; ecif.avalue = avalue;
unsigned int temp;
/* If the return value is a struct and we don't have a return */ /* If the return value is a struct and we don't have a return */
/* value address then we need to make one */ /* value address then we need to make one */
if ((rvalue == NULL) && if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT)) (cif->flags == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size); ecif.rvalue = alloca(cif->rtype->size);
/*@=sysunrecog@*/
} }
else if (small_struct)
ecif.rvalue = &temp;
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
switch (cif->abi) switch (cif->abi)
{ {
case FFI_SYSV: case FFI_SYSV:
/*@-usedef@*/ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, fn);
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break; break;
default: default:
FFI_ASSERT(0); FFI_ASSERT(0);
break; break;
} }
if (small_struct)
memcpy (rvalue, &temp, cif->rtype->size);
}
/** private members **/
static void ffi_prep_incoming_args_SYSV (char *stack, void **ret,
void** args, ffi_cif* cif);
void ffi_closure_SYSV (ffi_closure *);
/* This function is jumped to by the trampoline */
unsigned int
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure *closure;
void **respp;
void *args;
{
// our various things...
ffi_cif *cif;
void **arg_area;
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void*));
/* this call will initialize ARG_AREA, such that each
* element in that array points to the corresponding
* value on the stack; and if the function returns
* a structure, it will re-set RESP to point to the
* structure return address. */
ffi_prep_incoming_args_SYSV(args, respp, arg_area, cif);
(closure->fun) (cif, *respp, arg_area, closure->user_data);
return cif->flags;
}
/*@-exportheader@*/
static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
void **avalue, ffi_cif *cif)
/*@=exportheader@*/
{
register unsigned int i;
register void **p_argv;
register char *argp;
register ffi_type **p_arg;
argp = stack;
if ( cif->flags == FFI_TYPE_STRUCT ) {
*rvalue = *(void **) argp;
argp += 4;
}
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
size_t alignment = (*p_arg)->alignment;
if (alignment < 4)
alignment = 4;
/* Align if necessary */
if ((alignment - 1) & (unsigned) argp) {
argp = (char *) ALIGN(argp, alignment);
}
z = (*p_arg)->size;
/* because we're little endian, this is what it turns into. */
*p_argv = (void*) argp;
p_argv++;
argp += z;
}
return;
}
/* How to make a trampoline. */
#define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX) \
({ unsigned char *__tramp = (unsigned char*)(TRAMP); \
unsigned int __fun = (unsigned int)(FUN); \
unsigned int __ctx = (unsigned int)(CTX); \
*(unsigned int*) &__tramp[0] = 0xe92d000f; /* stmfd sp!, {r0-r3} */ \
*(unsigned int*) &__tramp[4] = 0xe59f0000; /* ldr r0, [pc] */ \
*(unsigned int*) &__tramp[8] = 0xe59ff000; /* ldr pc, [pc] */ \
*(unsigned int*) &__tramp[12] = __ctx; \
*(unsigned int*) &__tramp[16] = __fun; \
__clear_cache((&__tramp[0]), (&__tramp[19])); \
})
/* the cif must already be prep'ed */
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void *codeloc)
{
FFI_ASSERT (cif->abi == FFI_SYSV);
FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
&ffi_closure_SYSV, \
codeloc);
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
} }

View File

@@ -40,7 +40,8 @@ typedef enum ffi_abi {
/* ---- Definitions for closures ----------------------------------------- */ /* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 0 #define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 20
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#endif #endif

View File

@@ -82,6 +82,14 @@
# define call_reg(x) mov lr, pc ; mov pc, x # define call_reg(x) mov lr, pc ; mov pc, x
#endif #endif
/* Conditionally compile unwinder directives. */
#ifdef __ARM_EABI__
#define UNWIND
#else
#define UNWIND @
#endif
#if defined(__thumb__) && !defined(__THUMB_INTERWORK__) #if defined(__thumb__) && !defined(__THUMB_INTERWORK__)
.macro ARM_FUNC_START name .macro ARM_FUNC_START name
.text .text
@@ -92,6 +100,7 @@
bx pc bx pc
nop nop
.arm .arm
UNWIND .fnstart
/* A hook to tell gdb that we've switched to ARM mode. Also used to call /* A hook to tell gdb that we've switched to ARM mode. Also used to call
directly from other local arm routines. */ directly from other local arm routines. */
_L__\name: _L__\name:
@@ -102,6 +111,7 @@ _L__\name:
.align 0 .align 0
.arm .arm
ENTRY(\name) ENTRY(\name)
UNWIND .fnstart
.endm .endm
#endif #endif
@@ -134,8 +144,11 @@ _L__\name:
ARM_FUNC_START ffi_call_SYSV ARM_FUNC_START ffi_call_SYSV
@ Save registers @ Save registers
stmfd sp!, {r0-r3, fp, lr} stmfd sp!, {r0-r3, fp, lr}
UNWIND .save {r0-r3, fp, lr}
mov fp, sp mov fp, sp
UNWIND .setfp fp, sp
@ Make room for all of the new args. @ Make room for all of the new args.
sub sp, fp, r2 sub sp, fp, r2
@@ -205,5 +218,78 @@ LSYM(Lepilogue):
RETLDM "r0-r3,fp" RETLDM "r0-r3,fp"
.ffi_call_SYSV_end: .ffi_call_SYSV_end:
UNWIND .fnend
.size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV)
/*
unsigned int FFI_HIDDEN
ffi_closure_SYSV_inner (closure, respp, args)
ffi_closure *closure;
void **respp;
void *args;
*/
ARM_FUNC_START ffi_closure_SYSV
UNWIND .pad #16
add ip, sp, #16
stmfd sp!, {ip, lr}
UNWIND .save {r0, lr}
add r2, sp, #8
.pad #16
sub sp, sp, #16
str sp, [sp, #8]
add r1, sp, #8
bl ffi_closure_SYSV_inner
cmp r0, #FFI_TYPE_INT
beq .Lretint
cmp r0, #FFI_TYPE_FLOAT
#ifdef __SOFTFP__
beq .Lretint
#else
beq .Lretfloat
#endif
cmp r0, #FFI_TYPE_DOUBLE
#ifdef __SOFTFP__
beq .Lretlonglong
#else
beq .Lretdouble
#endif
cmp r0, #FFI_TYPE_LONGDOUBLE
#ifdef __SOFTFP__
beq .Lretlonglong
#else
beq .Lretlongdouble
#endif
cmp r0, #FFI_TYPE_SINT64
beq .Lretlonglong
.Lclosure_epilogue:
add sp, sp, #16
ldmfd sp, {sp, pc}
.Lretint:
ldr r0, [sp]
b .Lclosure_epilogue
.Lretlonglong:
ldr r0, [sp]
ldr r1, [sp, #4]
b .Lclosure_epilogue
#ifndef __SOFTFP__
.Lretfloat:
ldfs f0, [sp]
b .Lclosure_epilogue
.Lretdouble:
ldfd f0, [sp]
b .Lclosure_epilogue
.Lretlongdouble:
ldfd f0, [sp]
b .Lclosure_epilogue
#endif
.ffi_closure_SYSV_end:
UNWIND .fnend
.size CNAME(ffi_closure_SYSV),.ffi_closure_SYSV_end-CNAME(ffi_closure_SYSV)

View File

@@ -2,6 +2,7 @@
ffi.c - Copyright (c) 1998 Cygnus Solutions ffi.c - Copyright (c) 1998 Cygnus Solutions
Copyright (c) 2004 Simon Posnjak Copyright (c) 2004 Simon Posnjak
Copyright (c) 2005 Axis Communications AB Copyright (c) 2005 Axis Communications AB
Copyright (C) 2007 Free Software Foundation, Inc.
CRIS Foreign Function Interface CRIS Foreign Function Interface
@@ -360,10 +361,11 @@ ffi_prep_closure_inner (void **params, ffi_closure* closure)
/* API function: Prepare the trampoline. */ /* API function: Prepare the trampoline. */
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif *, void *, void **, void*), void (*fun)(ffi_cif *, void *, void **, void*),
void *user_data) void *user_data,
void *codeloc)
{ {
void *innerfn = ffi_prep_closure_inner; void *innerfn = ffi_prep_closure_inner;
FFI_ASSERT (cif->abi == FFI_SYSV); FFI_ASSERT (cif->abi == FFI_SYSV);
@@ -375,7 +377,7 @@ ffi_prep_closure (ffi_closure* closure,
memcpy (closure->tramp + ffi_cris_trampoline_fn_offset, memcpy (closure->tramp + ffi_cris_trampoline_fn_offset,
&innerfn, sizeof (void *)); &innerfn, sizeof (void *));
memcpy (closure->tramp + ffi_cris_trampoline_closure_offset, memcpy (closure->tramp + ffi_cris_trampoline_closure_offset,
&closure, sizeof (void *)); &codeloc, sizeof (void *));
return FFI_OK; return FFI_OK;
} }

View File

@@ -50,10 +50,9 @@ void ffi_type_test(ffi_type *a, char *file, int line)
{ {
FFI_ASSERT_AT(a != NULL, file, line); FFI_ASSERT_AT(a != NULL, file, line);
/*@-usedef@*/
FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line); FFI_ASSERT_AT(a->type <= FFI_TYPE_LAST, file, line);
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line); FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->size > 0, file, line);
FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line); FFI_ASSERT_AT(a->type == FFI_TYPE_VOID || a->alignment > 0, file, line);
FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line); FFI_ASSERT_AT(a->type != FFI_TYPE_STRUCT || a->elements != NULL, file, line);
/*@=usedef@*/
} }

View File

@@ -3,8 +3,6 @@
FR-V Assembly glue. FR-V Assembly glue.
$Id: eabi.S,v 1.2 2008/01/29 12:28:14 green Exp $
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
``Software''), to deal in the Software without restriction, including ``Software''), to deal in the Software without restriction, including

View File

@@ -1,5 +1,6 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2004 Anthony Green ffi.c - Copyright (c) 2004 Anthony Green
Copyright (C) 2007 Free Software Foundation, Inc.
FR-V Foreign Function Interface FR-V Foreign Function Interface
@@ -243,14 +244,15 @@ void ffi_closure_eabi (unsigned arg1, unsigned arg2, unsigned arg3,
} }
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*), void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data) void *user_data,
void *codeloc)
{ {
unsigned int *tramp = (unsigned int *) &closure->tramp[0]; unsigned int *tramp = (unsigned int *) &closure->tramp[0];
unsigned long fn = (long) ffi_closure_eabi; unsigned long fn = (long) ffi_closure_eabi;
unsigned long cls = (long) closure; unsigned long cls = (long) codeloc;
#ifdef __FRV_FDPIC__ #ifdef __FRV_FDPIC__
register void *got __asm__("gr15"); register void *got __asm__("gr15");
#endif #endif
@@ -259,7 +261,7 @@ ffi_prep_closure (ffi_closure* closure,
fn = (unsigned long) ffi_closure_eabi; fn = (unsigned long) ffi_closure_eabi;
#ifdef __FRV_FDPIC__ #ifdef __FRV_FDPIC__
tramp[0] = &tramp[2]; tramp[0] = &((unsigned int *)codeloc)[2];
tramp[1] = got; tramp[1] = got;
tramp[2] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */ tramp[2] = 0x8cfc0000 + (fn & 0xffff); /* setlos lo(fn), gr6 */
tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */ tramp[3] = 0x8efc0000 + (cls & 0xffff); /* setlos lo(cls), gr7 */
@@ -281,7 +283,8 @@ ffi_prep_closure (ffi_closure* closure,
/* Cache flushing. */ /* Cache flushing. */
for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++) for (i = 0; i < FFI_TRAMPOLINE_SIZE; i++)
__asm__ volatile ("dcf @(%0,%1)\n\tici @(%0,%1)" :: "r" (tramp), "r" (i)); __asm__ volatile ("dcf @(%0,%1)\n\tici @(%2,%1)" :: "r" (tramp), "r" (i),
"r" (codeloc));
return FFI_OK; return FFI_OK;
} }

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Red Hat, Inc. ffi.c - Copyright (c) 1998, 2007 Red Hat, Inc.
Copyright (c) 2000 Hewlett Packard Company Copyright (c) 2000 Hewlett Packard Company
IA64 Foreign Function Interface IA64 Foreign Function Interface
@@ -69,24 +69,19 @@ endian_adjust (void *addr, size_t len)
#endif #endif
} }
/* Store VALUE to ADDR in the current cpu implementation's fp spill format. */ /* Store VALUE to ADDR in the current cpu implementation's fp spill format.
This is a macro instead of a function, so that it works for all 3 floating
point types without type conversions. Type conversion to long double breaks
the denorm support. */
static inline void #define stf_spill(addr, value) \
stf_spill(fpreg *addr, __float80 value)
{
asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value)); asm ("stf.spill %0 = %1%P0" : "=m" (*addr) : "f"(value));
}
/* Load a value from ADDR, which is in the current cpu implementation's /* Load a value from ADDR, which is in the current cpu implementation's
fp spill format. */ fp spill format. As above, this must also be a macro. */
static inline __float80 #define ldf_fill(result, addr) \
ldf_fill(fpreg *addr) asm ("ldf.fill %0 = %1%P1" : "=f"(result) : "m"(*addr));
{
__float80 ret;
asm ("ldf.fill %0 = %1%P1" : "=f"(ret) : "m"(*addr));
return ret;
}
/* Return the size of the C type associated with with TYPE. Which will /* Return the size of the C type associated with with TYPE. Which will
be one of the FFI_IA64_TYPE_HFA_* values. */ be one of the FFI_IA64_TYPE_HFA_* values. */
@@ -110,17 +105,20 @@ hfa_type_size (int type)
/* Load from ADDR a value indicated by TYPE. Which will be one of /* Load from ADDR a value indicated by TYPE. Which will be one of
the FFI_IA64_TYPE_HFA_* values. */ the FFI_IA64_TYPE_HFA_* values. */
static __float80 static void
hfa_type_load (int type, void *addr) hfa_type_load (fpreg *fpaddr, int type, void *addr)
{ {
switch (type) switch (type)
{ {
case FFI_IA64_TYPE_HFA_FLOAT: case FFI_IA64_TYPE_HFA_FLOAT:
return *(float *) addr; stf_spill (fpaddr, *(float *) addr);
return;
case FFI_IA64_TYPE_HFA_DOUBLE: case FFI_IA64_TYPE_HFA_DOUBLE:
return *(double *) addr; stf_spill (fpaddr, *(double *) addr);
return;
case FFI_IA64_TYPE_HFA_LDOUBLE: case FFI_IA64_TYPE_HFA_LDOUBLE:
return *(__float80 *) addr; stf_spill (fpaddr, *(__float80 *) addr);
return;
default: default:
abort (); abort ();
} }
@@ -130,19 +128,31 @@ hfa_type_load (int type, void *addr)
the FFI_IA64_TYPE_HFA_* values. */ the FFI_IA64_TYPE_HFA_* values. */
static void static void
hfa_type_store (int type, void *addr, __float80 value) hfa_type_store (int type, void *addr, fpreg *fpaddr)
{ {
switch (type) switch (type)
{ {
case FFI_IA64_TYPE_HFA_FLOAT: case FFI_IA64_TYPE_HFA_FLOAT:
*(float *) addr = value; {
float result;
ldf_fill (result, fpaddr);
*(float *) addr = result;
break; break;
}
case FFI_IA64_TYPE_HFA_DOUBLE: case FFI_IA64_TYPE_HFA_DOUBLE:
*(double *) addr = value; {
double result;
ldf_fill (result, fpaddr);
*(double *) addr = result;
break; break;
}
case FFI_IA64_TYPE_HFA_LDOUBLE: case FFI_IA64_TYPE_HFA_LDOUBLE:
*(__float80 *) addr = value; {
__float80 result;
ldf_fill (result, fpaddr);
*(__float80 *) addr = result;
break; break;
}
default: default:
abort (); abort ();
} }
@@ -351,8 +361,8 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
&& offset < size && offset < size
&& gp_offset < 8 * 8) && gp_offset < 8 * 8)
{ {
stf_spill (&stack->fp_regs[fpcount], hfa_type_load (&stack->fp_regs[fpcount], hfa_type,
hfa_type_load (hfa_type, avalue[i] + offset)); avalue[i] + offset);
offset += hfa_size; offset += hfa_size;
gp_offset += hfa_size; gp_offset += hfa_size;
fpcount += 1; fpcount += 1;
@@ -390,10 +400,11 @@ ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
extern void ffi_closure_unix (); extern void ffi_closure_unix ();
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*), void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data) void *user_data,
void *codeloc)
{ {
/* The layout of a function descriptor. A C function pointer really /* The layout of a function descriptor. A C function pointer really
points to one of these. */ points to one of these. */
@@ -420,7 +431,7 @@ ffi_prep_closure (ffi_closure* closure,
tramp->code_pointer = fd->code_pointer; tramp->code_pointer = fd->code_pointer;
tramp->real_gp = fd->gp; tramp->real_gp = fd->gp;
tramp->fake_gp = (UINT64)(PTR64)closure; tramp->fake_gp = (UINT64)(PTR64)codeloc;
closure->cif = cif; closure->cif = cif;
closure->user_data = user_data; closure->user_data = user_data;
closure->fun = fun; closure->fun = fun;
@@ -475,9 +486,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
if (gpcount < 8 && fpcount < 8) if (gpcount < 8 && fpcount < 8)
{ {
void *addr = &stack->fp_regs[fpcount++]; fpreg *addr = &stack->fp_regs[fpcount++];
float result;
avalue[i] = addr; avalue[i] = addr;
*(float *)addr = ldf_fill (addr); ldf_fill (result, addr);
*(float *)addr = result;
} }
else else
avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4); avalue[i] = endian_adjust(&stack->gp_regs[gpcount], 4);
@@ -487,9 +500,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
if (gpcount < 8 && fpcount < 8) if (gpcount < 8 && fpcount < 8)
{ {
void *addr = &stack->fp_regs[fpcount++]; fpreg *addr = &stack->fp_regs[fpcount++];
double result;
avalue[i] = addr; avalue[i] = addr;
*(double *)addr = ldf_fill (addr); ldf_fill (result, addr);
*(double *)addr = result;
} }
else else
avalue[i] = &stack->gp_regs[gpcount]; avalue[i] = &stack->gp_regs[gpcount];
@@ -501,9 +516,11 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
gpcount++; gpcount++;
if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8) if (LDBL_MANT_DIG == 64 && gpcount < 8 && fpcount < 8)
{ {
void *addr = &stack->fp_regs[fpcount++]; fpreg *addr = &stack->fp_regs[fpcount++];
__float80 result;
avalue[i] = addr; avalue[i] = addr;
*(__float80 *)addr = ldf_fill (addr); ldf_fill (result, addr);
*(__float80 *)addr = result;
} }
else else
avalue[i] = &stack->gp_regs[gpcount]; avalue[i] = &stack->gp_regs[gpcount];
@@ -534,7 +551,7 @@ ffi_closure_unix_inner (ffi_closure *closure, struct ia64_args *stack,
&& gp_offset < 8 * 8) && gp_offset < 8 * 8)
{ {
hfa_type_store (hfa_type, addr + offset, hfa_type_store (hfa_type, addr + offset,
ldf_fill (&stack->fp_regs[fpcount])); &stack->fp_regs[fpcount]);
offset += hfa_size; offset += hfa_size;
gp_offset += hfa_size; gp_offset += hfa_size;
fpcount += 1; fpcount += 1;

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
java_raw_api.c - Copyright (c) 1999 Red Hat, Inc. java_raw_api.c - Copyright (c) 1999, 2007 Red Hat, Inc.
Cloned from raw_api.c Cloned from raw_api.c
@@ -54,13 +54,13 @@ ffi_java_raw_size (ffi_cif *cif)
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
result += 2 * FFI_SIZEOF_ARG; result += 2 * FFI_SIZEOF_JAVA_RAW;
break; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
/* No structure parameters in Java. */ /* No structure parameters in Java. */
abort(); abort();
default: default:
result += FFI_SIZEOF_ARG; result += FFI_SIZEOF_JAVA_RAW;
} }
} }
@@ -69,7 +69,7 @@ ffi_java_raw_size (ffi_cif *cif)
void void
ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_java_raw *raw, void **args)
{ {
unsigned i; unsigned i;
ffi_type **tp = cif->arg_types; ffi_type **tp = cif->arg_types;
@@ -90,7 +90,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
*args = (void*) ((char*)(raw++) + 2); *args = (void*) ((char*)(raw++) + 2);
break; break;
#if FFI_SIZEOF_ARG == 8 #if FFI_SIZEOF_JAVA_RAW == 8
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
@@ -105,7 +105,8 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
default: default:
*args = raw; *args = raw;
raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; raw +=
ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
} }
} }
@@ -116,7 +117,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
/* then assume little endian */ /* then assume little endian */
for (i = 0; i < cif->nargs; i++, tp++, args++) for (i = 0; i < cif->nargs; i++, tp++, args++)
{ {
#if FFI_SIZEOF_ARG == 8 #if FFI_SIZEOF_JAVA_RAW == 8
switch((*tp)->type) { switch((*tp)->type) {
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
@@ -127,10 +128,11 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
default: default:
*args = (void*) raw++; *args = (void*) raw++;
} }
#else /* FFI_SIZEOF_ARG != 8 */ #else /* FFI_SIZEOF_JAVA_RAW != 8 */
*args = (void*) raw; *args = (void*) raw;
raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); raw +=
#endif /* FFI_SIZEOF_ARG == 8 */ ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
#endif /* FFI_SIZEOF_JAVA_RAW == 8 */
} }
#else #else
@@ -141,7 +143,7 @@ ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args)
} }
void void
ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw)
{ {
unsigned i; unsigned i;
ffi_type **tp = cif->arg_types; ffi_type **tp = cif->arg_types;
@@ -202,7 +204,7 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
(raw++)->flt = *(FLOAT32*) (*args); (raw++)->flt = *(FLOAT32*) (*args);
break; break;
#if FFI_SIZEOF_ARG == 8 #if FFI_SIZEOF_JAVA_RAW == 8
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
@@ -216,11 +218,12 @@ ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
break; break;
default: default:
#if FFI_SIZEOF_ARG == 8 #if FFI_SIZEOF_JAVA_RAW == 8
FFI_ASSERT(0); /* Should have covered all cases */ FFI_ASSERT(0); /* Should have covered all cases */
#else #else
memcpy ((void*) raw->data, (void*)*args, (*tp)->size); memcpy ((void*) raw->data, (void*)*args, (*tp)->size);
raw += ALIGN ((*tp)->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; raw +=
ALIGN ((*tp)->size, sizeof(ffi_java_raw)) / sizeof(ffi_java_raw);
#endif #endif
} }
} }
@@ -244,6 +247,9 @@ ffi_java_rvalue_to_raw (ffi_cif *cif, void *rvalue)
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
case FFI_TYPE_INT: case FFI_TYPE_INT:
#if FFI_SIZEOF_JAVA_RAW == 4
case FFI_TYPE_POINTER:
#endif
*(SINT64 *)rvalue <<= 32; *(SINT64 *)rvalue <<= 32;
break; break;
@@ -269,6 +275,9 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
case FFI_TYPE_INT: case FFI_TYPE_INT:
#if FFI_SIZEOF_JAVA_RAW == 4
case FFI_TYPE_POINTER:
#endif
*(SINT64 *)rvalue >>= 32; *(SINT64 *)rvalue >>= 32;
break; break;
@@ -285,10 +294,8 @@ ffi_java_raw_to_rvalue (ffi_cif *cif, void *rvalue)
* these following couple of functions will handle the translation forth * these following couple of functions will handle the translation forth
* and back automatically. */ * and back automatically. */
void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, void ffi_java_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue,
void (*fn)(), ffi_java_raw *raw)
/*@out@*/ void *rvalue,
/*@dependent@*/ ffi_raw *raw)
{ {
void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
ffi_java_raw_to_ptrarray (cif, raw, avalue); ffi_java_raw_to_ptrarray (cif, raw, avalue);
@@ -302,7 +309,7 @@ static void
ffi_java_translate_args (ffi_cif *cif, void *rvalue, ffi_java_translate_args (ffi_cif *cif, void *rvalue,
void **avalue, void *user_data) void **avalue, void *user_data)
{ {
ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif)); ffi_java_raw *raw = (ffi_java_raw*)alloca (ffi_java_raw_size (cif));
ffi_raw_closure *cl = (ffi_raw_closure*)user_data; ffi_raw_closure *cl = (ffi_raw_closure*)user_data;
ffi_java_ptrarray_to_raw (cif, avalue, raw); ffi_java_ptrarray_to_raw (cif, avalue, raw);
@@ -310,22 +317,20 @@ ffi_java_translate_args (ffi_cif *cif, void *rvalue,
ffi_java_raw_to_rvalue (cif, rvalue); ffi_java_raw_to_rvalue (cif, rvalue);
} }
/* Again, here is the generic version of ffi_prep_raw_closure, which
* will install an intermediate "hub" for translation of arguments from
* the pointer-array format, to the raw format */
ffi_status ffi_status
ffi_prep_java_raw_closure (ffi_raw_closure* cl, ffi_prep_java_raw_closure_loc (ffi_java_raw_closure* cl,
ffi_cif *cif, ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*), void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data) void *user_data,
void *codeloc)
{ {
ffi_status status; ffi_status status;
status = ffi_prep_closure ((ffi_closure*) cl, status = ffi_prep_closure_loc ((ffi_closure*) cl,
cif, cif,
&ffi_java_translate_args, &ffi_java_translate_args,
(void*)cl); codeloc,
codeloc);
if (status == FFI_OK) if (status == FFI_OK)
{ {
cl->fun = fun; cl->fun = fun;
@@ -335,6 +340,19 @@ ffi_prep_java_raw_closure (ffi_raw_closure* cl,
return status; return status;
} }
/* Again, here is the generic version of ffi_prep_raw_closure, which
* will install an intermediate "hub" for translation of arguments from
* the pointer-array format, to the raw format */
ffi_status
ffi_prep_java_raw_closure (ffi_java_raw_closure* cl,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
void *user_data)
{
return ffi_prep_java_raw_closure_loc (cl, cif, fun, user_data, cl);
}
#endif /* FFI_CLOSURES */ #endif /* FFI_CLOSURES */
#endif /* !FFI_NATIVE_RAW_API */ #endif /* !FFI_NATIVE_RAW_API */
#endif /* !FFI_NO_RAW_API */ #endif /* !FFI_NO_RAW_API */

View File

@@ -31,9 +31,7 @@
/* ffi_prep_args is called by the assembly routine once stack /* ffi_prep_args is called by the assembly routine once stack
space has been allocated for the function's arguments. */ space has been allocated for the function's arguments. */
/*@-exportheader@*/
void ffi_prep_args(char *stack, extended_cif *ecif) void ffi_prep_args(char *stack, extended_cif *ecif)
/*@=exportheader@*/
{ {
unsigned int i; unsigned int i;
int tmp; int tmp;
@@ -173,20 +171,10 @@ ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
/*@-declundef@*/ extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
/*@-exportheader@*/ unsigned, unsigned, unsigned *, void (*fn)());
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
void ffi_call(/*@dependent@*/ ffi_cif *cif, void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue)
{ {
extended_cif ecif; extended_cif ecif;
@@ -198,9 +186,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
if ((rvalue == NULL) && if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT)) (cif->rtype->type == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/
ecif.rvalue = alloca (cif->rtype->size); ecif.rvalue = alloca (cif->rtype->size);
/*@=sysunrecog@*/
} }
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
@@ -208,7 +194,6 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi) switch (cif->abi)
{ {
case FFI_SYSV: case FFI_SYSV:
/*@-usedef@*/
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn); cif->flags, ecif.rvalue, fn);
if (cif->rtype->type == FFI_TYPE_STRUCT) if (cif->rtype->type == FFI_TYPE_STRUCT)
@@ -237,7 +222,6 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
} }
} }
} }
/*@=usedef@*/
break; break;
default: default:

View File

@@ -8,11 +8,23 @@
#include <ffi_common.h> #include <ffi_common.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <asm/cachectl.h>
void ffi_call_SYSV (extended_cif *,
unsigned, unsigned,
void *, void (*fn) ());
void *ffi_prep_args (void *stack, extended_cif *ecif);
void ffi_closure_SYSV (ffi_closure *);
void ffi_closure_struct_SYSV (ffi_closure *);
unsigned int ffi_closure_SYSV_inner (ffi_closure *closure,
void *resp, void *args);
/* ffi_prep_args is called by the assembly routine once stack space has /* ffi_prep_args is called by the assembly routine once stack space has
been allocated for the function's arguments. */ been allocated for the function's arguments. */
static void * void *
ffi_prep_args (void *stack, extended_cif *ecif) ffi_prep_args (void *stack, extended_cif *ecif)
{ {
unsigned int i; unsigned int i;
@@ -24,7 +36,7 @@ ffi_prep_args (void *stack, extended_cif *ecif)
argp = stack; argp = stack;
if (ecif->cif->rtype->type == FFI_TYPE_STRUCT if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
&& ecif->cif->rtype->size > 8) && !ecif->cif->flags)
struct_value_ptr = ecif->rvalue; struct_value_ptr = ecif->rvalue;
else else
struct_value_ptr = NULL; struct_value_ptr = NULL;
@@ -37,10 +49,6 @@ ffi_prep_args (void *stack, extended_cif *ecif)
{ {
size_t z; size_t z;
/* Align if necessary. */
if (((*p_arg)->alignment - 1) & (unsigned) argp)
argp = (char *) ALIGN (argp, (*p_arg)->alignment);
z = (*p_arg)->size; z = (*p_arg)->size;
if (z < sizeof (int)) if (z < sizeof (int))
{ {
@@ -72,7 +80,14 @@ ffi_prep_args (void *stack, extended_cif *ecif)
z = sizeof (int); z = sizeof (int);
} }
else else
{
memcpy (argp, *p_argv, z); memcpy (argp, *p_argv, z);
/* Align if necessary. */
if ((sizeof(int) - 1) & z)
z = ALIGN(z, sizeof(int));
}
p_argv++; p_argv++;
argp += z; argp += z;
} }
@@ -86,7 +101,8 @@ ffi_prep_args (void *stack, extended_cif *ecif)
#define CIF_FLAGS_DOUBLE 8 #define CIF_FLAGS_DOUBLE 8
#define CIF_FLAGS_LDOUBLE 16 #define CIF_FLAGS_LDOUBLE 16
#define CIF_FLAGS_POINTER 32 #define CIF_FLAGS_POINTER 32
#define CIF_FLAGS_STRUCT 64 #define CIF_FLAGS_STRUCT1 64
#define CIF_FLAGS_STRUCT2 128
/* Perform machine dependent cif processing */ /* Perform machine dependent cif processing */
ffi_status ffi_status
@@ -100,13 +116,25 @@ ffi_prep_cif_machdep (ffi_cif *cif)
break; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
if (cif->rtype->size > 4 && cif->rtype->size <= 8) switch (cif->rtype->size)
{
case 1:
cif->flags = CIF_FLAGS_STRUCT1;
break;
case 2:
cif->flags = CIF_FLAGS_STRUCT2;
break;
case 4:
cif->flags = CIF_FLAGS_INT;
break;
case 8:
cif->flags = CIF_FLAGS_DINT; cif->flags = CIF_FLAGS_DINT;
else if (cif->rtype->size <= 4) break;
cif->flags = CIF_FLAGS_STRUCT; default:
else
cif->flags = 0; cif->flags = 0;
break; break;
}
break;
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
cif->flags = CIF_FLAGS_FLOAT; cif->flags = CIF_FLAGS_FLOAT;
@@ -137,11 +165,6 @@ ffi_prep_cif_machdep (ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
extern void ffi_call_SYSV (void *(*) (void *, extended_cif *),
extended_cif *,
unsigned, unsigned, unsigned,
void *, void (*fn) ());
void void
ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
{ {
@@ -160,12 +183,10 @@ ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
switch (cif->abi) switch (cif->abi)
{ {
case FFI_SYSV: case FFI_SYSV:
ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes, ffi_call_SYSV (&ecif, cif->bytes, cif->flags,
cif->flags, cif->rtype->size * 8,
ecif.rvalue, fn); ecif.rvalue, fn);
break; break;
@@ -174,3 +195,84 @@ ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue)
break; break;
} }
} }
static void
ffi_prep_incoming_args_SYSV (char *stack, void **avalue, ffi_cif *cif)
{
unsigned int i;
void **p_argv;
char *argp;
ffi_type **p_arg;
argp = stack;
p_argv = avalue;
for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++)
{
size_t z;
z = (*p_arg)->size;
if (z <= 4)
{
*p_argv = (void *) (argp + 4 - z);
z = 4;
}
else
{
*p_argv = (void *) argp;
/* Align if necessary */
if ((sizeof(int) - 1) & z)
z = ALIGN(z, sizeof(int));
}
p_argv++;
argp += z;
}
}
unsigned int
ffi_closure_SYSV_inner (ffi_closure *closure, void *resp, void *args)
{
ffi_cif *cif;
void **arg_area;
cif = closure->cif;
arg_area = (void**) alloca (cif->nargs * sizeof (void *));
ffi_prep_incoming_args_SYSV(args, arg_area, cif);
(closure->fun) (cif, resp, arg_area, closure->user_data);
return cif->flags;
}
ffi_status
ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data,
void *codeloc)
{
FFI_ASSERT (cif->abi == FFI_SYSV);
*(unsigned short *)closure->tramp = 0x207c;
*(void **)(closure->tramp + 2) = codeloc;
*(unsigned short *)(closure->tramp + 6) = 0x4ef9;
if (cif->rtype->type == FFI_TYPE_STRUCT
&& !cif->flags)
*(void **)(closure->tramp + 8) = ffi_closure_struct_SYSV;
else
*(void **)(closure->tramp + 8) = ffi_closure_SYSV;
syscall(SYS_cacheflush, codeloc, FLUSH_SCOPE_LINE,
FLUSH_CACHE_BOTH, FFI_TRAMPOLINE_SIZE);
closure->cif = cif;
closure->user_data = user_data;
closure->fun = fun;
return FFI_OK;
}

View File

@@ -40,7 +40,8 @@ typedef enum ffi_abi {
/* ---- Definitions for closures ----------------------------------------- */ /* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 0 #define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 16
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#endif #endif

View File

@@ -8,40 +8,60 @@
#include <fficonfig.h> #include <fficonfig.h>
#include <ffi.h> #include <ffi.h>
#ifdef HAVE_AS_CFI_PSEUDO_OP
#define CFI_STARTPROC() .cfi_startproc
#define CFI_OFFSET(reg,off) .cfi_offset reg,off
#define CFI_DEF_CFA(reg,off) .cfi_def_cfa reg,off
#define CFI_ENDPROC() .cfi_endproc
#else
#define CFI_STARTPROC()
#define CFI_OFFSET(reg,off)
#define CFI_DEF_CFA(reg,off)
#define CFI_ENDPROC()
#endif
.text .text
.globl ffi_call_SYSV .globl ffi_call_SYSV
.type ffi_call_SYSV,@function .type ffi_call_SYSV,@function
.align 4
ffi_call_SYSV: ffi_call_SYSV:
CFI_STARTPROC()
link %fp,#0 link %fp,#0
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %d2,-(%sp) move.l %d2,-(%sp)
CFI_OFFSET(2,-12)
| Make room for all of the new args. | Make room for all of the new args.
sub.l 16(%fp),%sp sub.l 12(%fp),%sp
| Call ffi_prep_args | Call ffi_prep_args
move.l 12(%fp),-(%sp) move.l 8(%fp),-(%sp)
pea 4(%sp) pea 4(%sp)
move.l 8(%fp),%a0 #if !defined __PIC__
jsr (%a0) jsr ffi_prep_args
#else
bsr.l ffi_prep_args@PLTPC
#endif
addq.l #8,%sp addq.l #8,%sp
| Pass pointer to struct value, if any | Pass pointer to struct value, if any
move.l %a0,%a1 move.l %a0,%a1
| Call the function | Call the function
move.l 32(%fp),%a0 move.l 24(%fp),%a0
jsr (%a0) jsr (%a0)
| Remove the space we pushed for the args | Remove the space we pushed for the args
add.l 16(%fp),%sp add.l 12(%fp),%sp
| Load the pointer to storage for the return value | Load the pointer to storage for the return value
move.l 28(%fp),%a1 move.l 20(%fp),%a1
| Load the return type code | Load the return type code
move.l 20(%fp),%d2 move.l 16(%fp),%d2
| If the return value pointer is NULL, assume no return value. | If the return value pointer is NULL, assume no return value.
tst.l %a1 tst.l %a1
@@ -79,19 +99,111 @@ retlongdouble:
retpointer: retpointer:
btst #5,%d2 btst #5,%d2
jbeq retstruct jbeq retstruct1
move.l %a0,(%a1) move.l %a0,(%a1)
jbra epilogue jbra epilogue
retstruct: retstruct1:
btst #6,%d2 btst #6,%d2
jbeq retstruct2
move.b %d0,(%a1)
jbra epilogue
retstruct2:
btst #7,%d2
jbeq noretval jbeq noretval
move.l 24(%fp),%d2 move.w %d0,(%a1)
bfins %d0,(%a1){#0,%d2}
noretval: noretval:
epilogue: epilogue:
move.l (%sp)+,%d2 move.l (%sp)+,%d2
unlk %a6 unlk %fp
rts rts
CFI_ENDPROC()
.size ffi_call_SYSV,.-ffi_call_SYSV .size ffi_call_SYSV,.-ffi_call_SYSV
.globl ffi_closure_SYSV
.type ffi_closure_SYSV, @function
.align 4
ffi_closure_SYSV:
CFI_STARTPROC()
link %fp,#-12
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %sp,-12(%fp)
pea 8(%fp)
pea -12(%fp)
move.l %a0,-(%sp)
#if !defined __PIC__
jsr ffi_closure_SYSV_inner
#else
bsr.l ffi_closure_SYSV_inner@PLTPC
#endif
lsr.l #1,%d0
jne 1f
jcc .Lcls_epilogue
move.l -12(%fp),%d0
.Lcls_epilogue:
unlk %fp
rts
1:
lea -12(%fp),%a0
lsr.l #2,%d0
jne 1f
jcs .Lcls_ret_float
move.l (%a0)+,%d0
move.l (%a0),%d1
jra .Lcls_epilogue
.Lcls_ret_float:
fmove.s (%a0),%fp0
jra .Lcls_epilogue
1:
lsr.l #2,%d0
jne 1f
jcs .Lcls_ret_ldouble
fmove.d (%a0),%fp0
jra .Lcls_epilogue
.Lcls_ret_ldouble:
fmove.x (%a0),%fp0
jra .Lcls_epilogue
1:
lsr.l #2,%d0
jne .Lcls_ret_struct2
jcs .Lcls_ret_struct1
move.l (%a0),%a0
move.l %a0,%d0
jra .Lcls_epilogue
.Lcls_ret_struct1:
move.b (%a0),%d0
jra .Lcls_epilogue
.Lcls_ret_struct2:
move.w (%a0),%d0
jra .Lcls_epilogue
CFI_ENDPROC()
.size ffi_closure_SYSV,.-ffi_closure_SYSV
.globl ffi_closure_struct_SYSV
.type ffi_closure_struct_SYSV, @function
.align 4
ffi_closure_struct_SYSV:
CFI_STARTPROC()
link %fp,#0
CFI_OFFSET(14,-8)
CFI_DEF_CFA(14,8)
move.l %sp,-12(%fp)
pea 8(%fp)
move.l %a1,-(%sp)
move.l %a0,-(%sp)
#if !defined __PIC__
jsr ffi_closure_SYSV_inner
#else
bsr.l ffi_closure_SYSV_inner@PLTPC
#endif
unlk %fp
rts
CFI_ENDPROC()
.size ffi_closure_struct_SYSV,.-ffi_closure_struct_SYSV

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1996 Red Hat, Inc. ffi.c - Copyright (c) 1996, 2007 Red Hat, Inc.
MIPS Foreign Function Interface MIPS Foreign Function Interface
@@ -27,15 +27,20 @@
#include <ffi_common.h> #include <ffi_common.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/cachectl.h>
#if _MIPS_SIM == _ABIN32 #ifdef FFI_DEBUG
# define FFI_MIPS_STOP_HERE() ffi_stop_here()
#else
# define FFI_MIPS_STOP_HERE() do {} while(0)
#endif
#ifdef FFI_MIPS_N32
#define FIX_ARGP \ #define FIX_ARGP \
FFI_ASSERT(argp <= &stack[bytes]); \ FFI_ASSERT(argp <= &stack[bytes]); \
if (argp == &stack[bytes]) \ if (argp == &stack[bytes]) \
{ \ { \
argp = stack; \ argp = stack; \
ffi_stop_here(); \ FFI_MIPS_STOP_HERE(); \
} }
#else #else
#define FIX_ARGP #define FIX_ARGP
@@ -50,17 +55,17 @@ static void ffi_prep_args(char *stack,
int bytes, int bytes,
int flags) int flags)
{ {
register int i; int i;
register void **p_argv; void **p_argv;
register char *argp; char *argp;
register ffi_type **p_arg; ffi_type **p_arg;
#if _MIPS_SIM == _ABIN32 #ifdef FFI_MIPS_N32
/* If more than 8 double words are used, the remainder go /* If more than 8 double words are used, the remainder go
on the stack. We reorder stuff on the stack here to on the stack. We reorder stuff on the stack here to
support this easily. */ support this easily. */
if (bytes > 8 * FFI_SIZEOF_ARG) if (bytes > 8 * sizeof(ffi_arg))
argp = &stack[bytes - (8 * FFI_SIZEOF_ARG)]; argp = &stack[bytes - (8 * sizeof(ffi_arg))];
else else
argp = stack; argp = stack;
#else #else
@@ -69,7 +74,7 @@ static void ffi_prep_args(char *stack,
memset(stack, 0, bytes); memset(stack, 0, bytes);
#if _MIPS_SIM == _ABIN32 #ifdef FFI_MIPS_N32
if ( ecif->cif->rstruct_flag != 0 ) if ( ecif->cif->rstruct_flag != 0 )
#else #else
if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT )
@@ -85,92 +90,90 @@ static void ffi_prep_args(char *stack,
for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++) for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i; i--, p_arg++)
{ {
size_t z; size_t z;
unsigned short a; unsigned int a;
/* Align if necessary */ /* Align if necessary. */
a = (*p_arg)->alignment; a = (*p_arg)->alignment;
if (a < FFI_SIZEOF_ARG) if (a < sizeof(ffi_arg))
a = FFI_SIZEOF_ARG; a = sizeof(ffi_arg);
if ((a - 1) & (unsigned) argp) { if ((a - 1) & (unsigned long) argp)
{
argp = (char *) ALIGN(argp, a); argp = (char *) ALIGN(argp, a);
FIX_ARGP; FIX_ARGP;
} }
#if _MIPS_SIM == _ABIO32
#define OFFSET 0
#else
#define OFFSET sizeof(int)
#endif
z = (*p_arg)->size; z = (*p_arg)->size;
if (z < sizeof(ffi_arg)) if (z <= sizeof(ffi_arg))
{ {
int type = (*p_arg)->type;
z = sizeof(ffi_arg); z = sizeof(ffi_arg);
switch ((*p_arg)->type) /* The size of a pointer depends on the ABI */
if (type == FFI_TYPE_POINTER)
type =
(ecif->cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
switch (type)
{ {
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
*(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv); *(ffi_arg *)argp = *(SINT8 *)(* p_argv);
break; break;
case FFI_TYPE_UINT8: case FFI_TYPE_UINT8:
*(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv); *(ffi_arg *)argp = *(UINT8 *)(* p_argv);
break; break;
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
*(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv); *(ffi_arg *)argp = *(SINT16 *)(* p_argv);
break; break;
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
*(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv); *(ffi_arg *)argp = *(UINT16 *)(* p_argv);
break; break;
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
*(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv); *(ffi_arg *)argp = *(SINT32 *)(* p_argv);
break; break;
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
case FFI_TYPE_POINTER: *(ffi_arg *)argp = *(UINT32 *)(* p_argv);
*(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv);
break; break;
/* This can only happen with 64bit slots */ /* This can only happen with 64bit slots. */
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
*(float *) argp = *(float *)(* p_argv); *(float *) argp = *(float *)(* p_argv);
break; break;
/* Handle small structures */ /* Handle structures. */
case FFI_TYPE_STRUCT: default:
memcpy(argp, *p_argv, (*p_arg)->size); memcpy(argp, *p_argv, (*p_arg)->size);
break; break;
default:
FFI_ASSERT(0);
} }
} }
else else
{ {
#if _MIPS_SIM == _ABIO32 #ifdef FFI_MIPS_O32
memcpy(argp, *p_argv, z); memcpy(argp, *p_argv, z);
#else #else
{ {
unsigned end = (unsigned) argp+z; unsigned long end = (unsigned long) argp + z;
unsigned cap = (unsigned) stack+bytes; unsigned long cap = (unsigned long) stack + bytes;
/* Check if the data will fit within the register /* Check if the data will fit within the register space.
space. Handle it if it doesn't. */ Handle it if it doesn't. */
if (end <= cap) if (end <= cap)
memcpy(argp, *p_argv, z); memcpy(argp, *p_argv, z);
else else
{ {
unsigned portion = end - cap; unsigned long portion = cap - (unsigned long)argp;
memcpy(argp, *p_argv, portion); memcpy(argp, *p_argv, portion);
argp = stack; argp = stack;
memcpy(argp, z -= portion;
(void*)((unsigned)(*p_argv)+portion), z - portion); memcpy(argp, (void*)((unsigned long)(*p_argv) + portion),
z);
} }
} }
#endif #endif
@@ -179,11 +182,9 @@ static void ffi_prep_args(char *stack,
argp += z; argp += z;
FIX_ARGP; FIX_ARGP;
} }
return;
} }
#if _MIPS_SIM == _ABIN32 #ifdef FFI_MIPS_N32
/* The n32 spec says that if "a chunk consists solely of a double /* The n32 spec says that if "a chunk consists solely of a double
float field (but not a double, which is part of a union), it float field (but not a double, which is part of a union), it
@@ -191,35 +192,41 @@ static void ffi_prep_args(char *stack,
passed in an integer register". This code traverses structure passed in an integer register". This code traverses structure
definitions and generates the appropriate flags. */ definitions and generates the appropriate flags. */
unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift) static unsigned
calc_n32_struct_flags(ffi_type *arg, unsigned *loc, unsigned *arg_reg)
{ {
unsigned flags = 0; unsigned flags = 0;
unsigned index = 0; unsigned index = 0;
ffi_type *e; ffi_type *e;
while (e = arg->elements[index]) while ((e = arg->elements[index]))
{ {
/* Align this object. */
*loc = ALIGN(*loc, e->alignment);
if (e->type == FFI_TYPE_DOUBLE) if (e->type == FFI_TYPE_DOUBLE)
{ {
flags += (FFI_TYPE_DOUBLE << *shift); /* Already aligned to FFI_SIZEOF_ARG. */
*shift += FFI_FLAG_BITS; *arg_reg = *loc / FFI_SIZEOF_ARG;
if (*arg_reg > 7)
break;
flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS));
*loc += e->size;
} }
else if (e->type == FFI_TYPE_STRUCT)
flags += calc_n32_struct_flags(e, shift);
else else
*shift += FFI_FLAG_BITS; *loc += e->size;
index++; index++;
} }
/* Next Argument register at alignment of FFI_SIZEOF_ARG. */
*arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
return flags; return flags;
} }
unsigned calc_n32_return_struct_flags(ffi_type *arg) static unsigned
calc_n32_return_struct_flags(ffi_type *arg)
{ {
unsigned flags = 0; unsigned flags = 0;
unsigned index = 0;
unsigned small = FFI_TYPE_SMALLSTRUCT; unsigned small = FFI_TYPE_SMALLSTRUCT;
ffi_type *e; ffi_type *e;
@@ -238,16 +245,16 @@ unsigned calc_n32_return_struct_flags(ffi_type *arg)
e = arg->elements[0]; e = arg->elements[0];
if (e->type == FFI_TYPE_DOUBLE) if (e->type == FFI_TYPE_DOUBLE)
flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS; flags = FFI_TYPE_DOUBLE;
else if (e->type == FFI_TYPE_FLOAT) else if (e->type == FFI_TYPE_FLOAT)
flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS; flags = FFI_TYPE_FLOAT;
if (flags && (e = arg->elements[1])) if (flags && (e = arg->elements[1]))
{ {
if (e->type == FFI_TYPE_DOUBLE) if (e->type == FFI_TYPE_DOUBLE)
flags += FFI_TYPE_DOUBLE; flags += FFI_TYPE_DOUBLE << FFI_FLAG_BITS;
else if (e->type == FFI_TYPE_FLOAT) else if (e->type == FFI_TYPE_FLOAT)
flags += FFI_TYPE_FLOAT; flags += FFI_TYPE_FLOAT << FFI_FLAG_BITS;
else else
return small; return small;
@@ -272,7 +279,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
{ {
cif->flags = 0; cif->flags = 0;
#if _MIPS_SIM == _ABIO32 #ifdef FFI_MIPS_O32
/* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT /* Set the flags necessary for O32 processing. FFI_O32_SOFT_FLOAT
* does not have special handling for floating point args. * does not have special handling for floating point args.
*/ */
@@ -360,10 +367,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
} }
#endif #endif
#if _MIPS_SIM == _ABIN32 #ifdef FFI_MIPS_N32
/* Set the flags necessary for N32 processing */ /* Set the flags necessary for N32 processing */
{ {
unsigned shift = 0; unsigned arg_reg = 0;
unsigned loc = 0;
unsigned count = (cif->nargs < 8) ? cif->nargs : 8; unsigned count = (cif->nargs < 8) ? cif->nargs : 8;
unsigned index = 0; unsigned index = 0;
@@ -378,7 +386,7 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
/* This means that the structure is being passed as /* This means that the structure is being passed as
a hidden argument */ a hidden argument */
shift = FFI_FLAG_BITS; arg_reg = 1;
count = (cif->nargs < 7) ? cif->nargs : 7; count = (cif->nargs < 7) ? cif->nargs : 7;
cif->rstruct_flag = !0; cif->rstruct_flag = !0;
@@ -389,23 +397,37 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
else else
cif->rstruct_flag = 0; cif->rstruct_flag = 0;
while (count-- > 0) while (count-- > 0 && arg_reg < 8)
{ {
switch ((cif->arg_types)[index]->type) switch ((cif->arg_types)[index]->type)
{ {
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
cif->flags += ((cif->arg_types)[index]->type << shift); cif->flags +=
shift += FFI_FLAG_BITS; ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS));
arg_reg++;
break;
case FFI_TYPE_LONGDOUBLE:
/* Align it. */
arg_reg = ALIGN(arg_reg, 2);
/* Treat it as two adjacent doubles. */
cif->flags +=
(FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
arg_reg++;
cif->flags +=
(FFI_TYPE_DOUBLE << (arg_reg * FFI_FLAG_BITS));
arg_reg++;
break; break;
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
loc = arg_reg * FFI_SIZEOF_ARG;
cif->flags += calc_n32_struct_flags((cif->arg_types)[index], cif->flags += calc_n32_struct_flags((cif->arg_types)[index],
&shift); &loc, &arg_reg);
break; break;
default: default:
shift += FFI_FLAG_BITS; arg_reg++;
break;
} }
index++; index++;
@@ -440,7 +462,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8);
break; break;
case FFI_TYPE_LONGDOUBLE:
/* Long double is returned as if it were a struct containing
two doubles. */
cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8);
cif->flags += (FFI_TYPE_DOUBLE + (FFI_TYPE_DOUBLE << FFI_FLAG_BITS))
<< (4 + (FFI_FLAG_BITS * 8));
break;
default: default:
cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8);
break; break;
@@ -479,7 +507,7 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
switch (cif->abi) switch (cif->abi)
{ {
#if _MIPS_SIM == _ABIO32 #ifdef FFI_MIPS_O32
case FFI_O32: case FFI_O32:
case FFI_O32_SOFT_FLOAT: case FFI_O32_SOFT_FLOAT:
ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, ffi_call_O32(ffi_prep_args, &ecif, cif->bytes,
@@ -487,10 +515,25 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
break; break;
#endif #endif
#if _MIPS_SIM == _ABIN32 #ifdef FFI_MIPS_N32
case FFI_N32: case FFI_N32:
case FFI_N64:
{
int copy_rvalue = 0;
void *rvalue_copy = ecif.rvalue;
if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 16)
{
/* For structures smaller than 16 bytes we clobber memory
in 8 byte increments. Make a copy so we don't clobber
the callers memory outside of the struct bounds. */
rvalue_copy = alloca(16);
copy_rvalue = 1;
}
ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, ffi_call_N32(ffi_prep_args, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn); cif->flags, rvalue_copy, fn);
if (copy_rvalue)
memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size);
}
break; break;
#endif #endif
@@ -500,41 +543,79 @@ void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
} }
} }
#if FFI_CLOSURES /* N32 not implemented yet, FFI_CLOSURES not defined */ #if FFI_CLOSURES
#if defined(FFI_MIPS_O32) #if defined(FFI_MIPS_O32)
extern void ffi_closure_O32(void); extern void ffi_closure_O32(void);
#else
extern void ffi_closure_N32(void);
#endif /* FFI_MIPS_O32 */ #endif /* FFI_MIPS_O32 */
ffi_status ffi_status
ffi_prep_closure (ffi_closure *closure, ffi_prep_closure_loc (ffi_closure *closure,
ffi_cif *cif, ffi_cif *cif,
void (*fun)(ffi_cif*,void*,void**,void*), void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data) void *user_data,
void *codeloc)
{ {
unsigned int *tramp = (unsigned int *) &closure->tramp[0]; unsigned int *tramp = (unsigned int *) &closure->tramp[0];
unsigned int fn; void * fn;
unsigned int ctx = (unsigned int) closure; char *clear_location = (char *) codeloc;
#if defined(FFI_MIPS_O32) #if defined(FFI_MIPS_O32)
FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT); FFI_ASSERT(cif->abi == FFI_O32 || cif->abi == FFI_O32_SOFT_FLOAT);
fn = (unsigned int) ffi_closure_O32; fn = ffi_closure_O32;
#else /* FFI_MIPS_N32 */ #else /* FFI_MIPS_N32 */
FFI_ASSERT(cif->abi == FFI_N32); FFI_ASSERT(cif->abi == FFI_N32 || cif->abi == FFI_N64);
FFI_ASSERT(!"not implemented"); fn = ffi_closure_N32;
#endif /* FFI_MIPS_O32 */ #endif /* FFI_MIPS_O32 */
tramp[0] = 0x3c190000 | (fn >> 16); /* lui $25,high(fn) */ #if defined(FFI_MIPS_O32) || (_MIPS_SIM ==_ABIN32)
tramp[1] = 0x3c080000 | (ctx >> 16); /* lui $8,high(ctx) */ /* lui $25,high(fn) */
tramp[2] = 0x37390000 | (fn & 0xffff); /* ori $25,low(fn) */ tramp[0] = 0x3c190000 | ((unsigned)fn >> 16);
tramp[3] = 0x03200008; /* jr $25 */ /* ori $25,low(fn) */
tramp[4] = 0x35080000 | (ctx & 0xffff); /* ori $8,low(ctx) */ tramp[1] = 0x37390000 | ((unsigned)fn & 0xffff);
/* lui $12,high(codeloc) */
tramp[2] = 0x3c0c0000 | ((unsigned)codeloc >> 16);
/* jr $25 */
tramp[3] = 0x03200008;
/* ori $12,low(codeloc) */
tramp[4] = 0x358c0000 | ((unsigned)codeloc & 0xffff);
#else
/* N64 has a somewhat larger trampoline. */
/* lui $25,high(fn) */
tramp[0] = 0x3c190000 | ((unsigned long)fn >> 48);
/* lui $12,high(codeloc) */
tramp[1] = 0x3c0c0000 | ((unsigned long)codeloc >> 48);
/* ori $25,mid-high(fn) */
tramp[2] = 0x37390000 | (((unsigned long)fn >> 32 ) & 0xffff);
/* ori $12,mid-high(codeloc) */
tramp[3] = 0x358c0000 | (((unsigned long)codeloc >> 32) & 0xffff);
/* dsll $25,$25,16 */
tramp[4] = 0x0019cc38;
/* dsll $12,$12,16 */
tramp[5] = 0x000c6438;
/* ori $25,mid-low(fn) */
tramp[6] = 0x37390000 | (((unsigned long)fn >> 16 ) & 0xffff);
/* ori $12,mid-low(codeloc) */
tramp[7] = 0x358c0000 | (((unsigned long)codeloc >> 16) & 0xffff);
/* dsll $25,$25,16 */
tramp[8] = 0x0019cc38;
/* dsll $12,$12,16 */
tramp[9] = 0x000c6438;
/* ori $25,low(fn) */
tramp[10] = 0x37390000 | ((unsigned long)fn & 0xffff);
/* jr $25 */
tramp[11] = 0x03200008;
/* ori $12,low(codeloc) */
tramp[12] = 0x358c0000 | ((unsigned long)codeloc & 0xffff);
#endif
closure->cif = cif; closure->cif = cif;
closure->fun = fun; closure->fun = fun;
closure->user_data = user_data; closure->user_data = user_data;
/* XXX this is available on Linux, but anything else? */ __builtin___clear_cache(clear_location, clear_location + FFI_TRAMPOLINE_SIZE);
cacheflush (tramp, FFI_TRAMPOLINE_SIZE, ICACHE);
return FFI_OK; return FFI_OK;
} }
@@ -558,23 +639,25 @@ ffi_prep_closure (ffi_closure *closure,
*/ */
int int
ffi_closure_mips_inner_O32 (ffi_closure *closure, ffi_closure_mips_inner_O32 (ffi_closure *closure,
void *rvalue, unsigned long *ar, void *rvalue, ffi_arg *ar,
double *fpr) double *fpr)
{ {
ffi_cif *cif; ffi_cif *cif;
void **avalue; void **avaluep;
ffi_arg *avalue;
ffi_type **arg_types; ffi_type **arg_types;
int i, avn, argn, seen_int; int i, avn, argn, seen_int;
cif = closure->cif; cif = closure->cif;
avalue = alloca (cif->nargs * sizeof (void *)); avalue = alloca (cif->nargs * sizeof (ffi_arg));
avaluep = alloca (cif->nargs * sizeof (ffi_arg));
seen_int = (cif->abi == FFI_O32_SOFT_FLOAT); seen_int = (cif->abi == FFI_O32_SOFT_FLOAT);
argn = 0; argn = 0;
if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT) if ((cif->flags >> (FFI_FLAG_BITS * 2)) == FFI_TYPE_STRUCT)
{ {
rvalue = (void *) ar[0]; rvalue = (void *)(UINT32)ar[0];
argn = 1; argn = 1;
} }
@@ -588,13 +671,43 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
(arg_types[i]->type == FFI_TYPE_FLOAT || (arg_types[i]->type == FFI_TYPE_FLOAT ||
arg_types[i]->type == FFI_TYPE_DOUBLE)) arg_types[i]->type == FFI_TYPE_DOUBLE))
{ {
avalue[i] = ((char *) &fpr[i]); #ifdef __MIPSEB__
if (arg_types[i]->type == FFI_TYPE_FLOAT)
avaluep[i] = ((char *) &fpr[i]) + sizeof (float);
else
#endif
avaluep[i] = (char *) &fpr[i];
} }
else else
{ {
if (arg_types[i]->alignment == 8 && (argn & 0x1)) if (arg_types[i]->alignment == 8 && (argn & 0x1))
argn++; argn++;
avalue[i] = ((char *) &ar[argn]); switch (arg_types[i]->type)
{
case FFI_TYPE_SINT8:
avaluep[i] = &avalue[i];
*(SINT8 *) &avalue[i] = (SINT8) ar[argn];
break;
case FFI_TYPE_UINT8:
avaluep[i] = &avalue[i];
*(UINT8 *) &avalue[i] = (UINT8) ar[argn];
break;
case FFI_TYPE_SINT16:
avaluep[i] = &avalue[i];
*(SINT16 *) &avalue[i] = (SINT16) ar[argn];
break;
case FFI_TYPE_UINT16:
avaluep[i] = &avalue[i];
*(UINT16 *) &avalue[i] = (UINT16) ar[argn];
break;
default:
avaluep[i] = (char *) &ar[argn];
break;
}
seen_int = 1; seen_int = 1;
} }
argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; argn += ALIGN(arg_types[i]->size, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG;
@@ -602,7 +715,7 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
} }
/* Invoke the closure. */ /* Invoke the closure. */
(closure->fun) (cif, rvalue, avalue, closure->user_data); (closure->fun) (cif, rvalue, avaluep, closure->user_data);
if (cif->abi == FFI_O32_SOFT_FLOAT) if (cif->abi == FFI_O32_SOFT_FLOAT)
{ {
@@ -622,4 +735,177 @@ ffi_closure_mips_inner_O32 (ffi_closure *closure,
} }
} }
#if defined(FFI_MIPS_N32)
static void
copy_struct_N32(char *target, unsigned offset, ffi_abi abi, ffi_type *type,
int argn, unsigned arg_offset, ffi_arg *ar,
ffi_arg *fpr)
{
ffi_type **elt_typep = type->elements;
while(*elt_typep)
{
ffi_type *elt_type = *elt_typep;
unsigned o;
char *tp;
char *argp;
char *fpp;
o = ALIGN(offset, elt_type->alignment);
arg_offset += o - offset;
offset = o;
argn += arg_offset / sizeof(ffi_arg);
arg_offset = arg_offset % sizeof(ffi_arg);
argp = (char *)(ar + argn);
fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn);
tp = target + offset;
if (elt_type->type == FFI_TYPE_DOUBLE)
*(double *)tp = *(double *)fpp;
else
memcpy(tp, argp + arg_offset, elt_type->size);
offset += elt_type->size;
arg_offset += elt_type->size;
elt_typep++;
argn += arg_offset / sizeof(ffi_arg);
arg_offset = arg_offset % sizeof(ffi_arg);
}
}
/*
* Decodes the arguments to a function, which will be stored on the
* stack. AR is the pointer to the beginning of the integer
* arguments. FPR is a pointer to the area where floating point
* registers have been saved.
*
* RVALUE is the location where the function return value will be
* stored. CLOSURE is the prepared closure to invoke.
*
* This function should only be called from assembly, which is in
* turn called from a trampoline.
*
* Returns the function return flags.
*
*/
int
ffi_closure_mips_inner_N32 (ffi_closure *closure,
void *rvalue, ffi_arg *ar,
ffi_arg *fpr)
{
ffi_cif *cif;
void **avaluep;
ffi_arg *avalue;
ffi_type **arg_types;
int i, avn, argn;
cif = closure->cif;
avalue = alloca (cif->nargs * sizeof (ffi_arg));
avaluep = alloca (cif->nargs * sizeof (ffi_arg));
argn = 0;
if (cif->rstruct_flag)
{
#if _MIPS_SIM==_ABIN32
rvalue = (void *)(UINT32)ar[0];
#else /* N64 */
rvalue = (void *)ar[0];
#endif
argn = 1;
}
i = 0;
avn = cif->nargs;
arg_types = cif->arg_types;
while (i < avn)
{
if (arg_types[i]->type == FFI_TYPE_FLOAT
|| arg_types[i]->type == FFI_TYPE_DOUBLE)
{
ffi_arg *argp = argn >= 8 ? ar + argn : fpr + argn;
#ifdef __MIPSEB__
if (arg_types[i]->type == FFI_TYPE_FLOAT && argn < 8)
avaluep[i] = ((char *) argp) + sizeof (float);
else
#endif
avaluep[i] = (char *) argp;
}
else
{
unsigned type = arg_types[i]->type;
if (arg_types[i]->alignment > sizeof(ffi_arg))
argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg));
ffi_arg *argp = ar + argn;
/* The size of a pointer depends on the ABI */
if (type == FFI_TYPE_POINTER)
type = (cif->abi == FFI_N64) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32;
switch (type)
{
case FFI_TYPE_SINT8:
avaluep[i] = &avalue[i];
*(SINT8 *) &avalue[i] = (SINT8) *argp;
break;
case FFI_TYPE_UINT8:
avaluep[i] = &avalue[i];
*(UINT8 *) &avalue[i] = (UINT8) *argp;
break;
case FFI_TYPE_SINT16:
avaluep[i] = &avalue[i];
*(SINT16 *) &avalue[i] = (SINT16) *argp;
break;
case FFI_TYPE_UINT16:
avaluep[i] = &avalue[i];
*(UINT16 *) &avalue[i] = (UINT16) *argp;
break;
case FFI_TYPE_SINT32:
avaluep[i] = &avalue[i];
*(SINT32 *) &avalue[i] = (SINT32) *argp;
break;
case FFI_TYPE_UINT32:
avaluep[i] = &avalue[i];
*(UINT32 *) &avalue[i] = (UINT32) *argp;
break;
case FFI_TYPE_STRUCT:
if (argn < 8)
{
/* Allocate space for the struct as at least part of
it was passed in registers. */
avaluep[i] = alloca(arg_types[i]->size);
copy_struct_N32(avaluep[i], 0, cif->abi, arg_types[i],
argn, 0, ar, fpr);
break;
}
/* Else fall through. */
default:
avaluep[i] = (char *) argp;
break;
}
}
argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg);
i++;
}
/* Invoke the closure. */
(closure->fun) (cif, rvalue, avaluep, closure->user_data);
return cif->flags >> (FFI_FLAG_BITS * 8);
}
#endif /* FFI_MIPS_N32 */
#endif /* FFI_CLOSURES */ #endif /* FFI_CLOSURES */

View File

@@ -26,17 +26,13 @@
#ifndef LIBFFI_TARGET_H #ifndef LIBFFI_TARGET_H
#define LIBFFI_TARGET_H #define LIBFFI_TARGET_H
#ifndef LIBFFI_ASM
#include <sgidefs.h>
#endif
#if !defined(_MIPS_SIM) #if !defined(_MIPS_SIM)
-- something is very wrong -- -- something is very wrong --
#else #else
# if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64)) # if (_MIPS_SIM==_ABIN32 && defined(_ABIN32)) || (_MIPS_SIM==_ABI64 && defined(_ABI64))
# define FFI_MIPS_N32 # define FFI_MIPS_N32
# else # else
# if _MIPS_SIM==_ABIO32 && defined(_ABIO32) # if (_MIPS_SIM==_ABIO32 && defined(_ABIO32))
# define FFI_MIPS_O32 # define FFI_MIPS_O32
# else # else
-- this is an unsupported platform -- -- this is an unsupported platform --
@@ -50,6 +46,9 @@
#else #else
/* N32 and N64 frames have 64bit integer args */ /* N32 and N64 frames have 64bit integer args */
# define FFI_SIZEOF_ARG 8 # define FFI_SIZEOF_ARG 8
# if _MIPS_SIM == _ABIN32
# define FFI_SIZEOF_JAVA_RAW 4
# endif
#endif #endif
#define FFI_FLAG_BITS 2 #define FFI_FLAG_BITS 2
@@ -121,6 +120,15 @@
# define ADDU daddu # define ADDU daddu
# define SRL dsrl # define SRL dsrl
# define LI dli # define LI dli
# if (_MIPS_SIM==_ABI64)
# define LA dla
# define EH_FRAME_ALIGN 3
# define FDE_ADDR_BYTES .8byte
# else
# define LA la
# define EH_FRAME_ALIGN 2
# define FDE_ADDR_BYTES .4byte
# endif /* _MIPS_SIM==_ABI64 */
#endif /* !FFI_MIPS_O32 */ #endif /* !FFI_MIPS_O32 */
#else /* !LIBFFI_ASM */ #else /* !LIBFFI_ASM */
#ifdef FFI_MIPS_O32 #ifdef FFI_MIPS_O32
@@ -146,8 +154,12 @@ typedef enum ffi_abi {
#else #else
FFI_DEFAULT_ABI = FFI_O32, FFI_DEFAULT_ABI = FFI_O32,
#endif #endif
#else
# if _MIPS_SIM==_ABI64
FFI_DEFAULT_ABI = FFI_N64,
# else # else
FFI_DEFAULT_ABI = FFI_N32, FFI_DEFAULT_ABI = FFI_N32,
# endif
#endif #endif
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
@@ -162,8 +174,13 @@ typedef enum ffi_abi {
#define FFI_CLOSURES 1 #define FFI_CLOSURES 1
#define FFI_TRAMPOLINE_SIZE 20 #define FFI_TRAMPOLINE_SIZE 20
#else #else
/* N32/N64 not implemented yet. */ /* N32/N64. */
#define FFI_CLOSURES 0 # define FFI_CLOSURES 1
#if _MIPS_SIM==_ABI64
#define FFI_TRAMPOLINE_SIZE 52
#else
#define FFI_TRAMPOLINE_SIZE 20
#endif
#endif /* FFI_MIPS_O32 */ #endif /* FFI_MIPS_O32 */
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0

View File

@@ -45,13 +45,19 @@
.globl ffi_call_N32 .globl ffi_call_N32
.ent ffi_call_N32 .ent ffi_call_N32
ffi_call_N32: ffi_call_N32:
.LFB3:
.frame $fp, SIZEOF_FRAME, ra
.mask 0xc0000000,-FFI_SIZEOF_ARG
.fmask 0x00000000,0
# Prologue # Prologue
SUBU $sp, SIZEOF_FRAME # Frame size SUBU $sp, SIZEOF_FRAME # Frame size
.LCFI0:
REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer
REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address
.LCFI1:
move $fp, $sp move $fp, $sp
.LCFI3:
move t9, callback # callback function pointer move t9, callback # callback function pointer
REG_S bytes, 2*FFI_SIZEOF_ARG($fp) # bytes REG_S bytes, 2*FFI_SIZEOF_ARG($fp) # bytes
REG_S flags, 3*FFI_SIZEOF_ARG($fp) # flags REG_S flags, 3*FFI_SIZEOF_ARG($fp) # flags
@@ -72,14 +78,12 @@ sixteen:
SUBU $sp, $sp, v0 # move the stack pointer to reflect the SUBU $sp, $sp, v0 # move the stack pointer to reflect the
# arg space # arg space
ADDU a0, $sp, 0 # 4 * FFI_SIZEOF_ARG move a0, $sp # 4 * FFI_SIZEOF_ARG
ADDU a3, $fp, 3 * FFI_SIZEOF_ARG ADDU a3, $fp, 3 * FFI_SIZEOF_ARG
# Call ffi_prep_args # Call ffi_prep_args
jal t9 jal t9
# ADDU $sp, $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args
# Copy the stack pointer to t9 # Copy the stack pointer to t9
move t9, $sp move t9, $sp
@@ -90,18 +94,16 @@ sixteen:
REG_L t6, 2*FFI_SIZEOF_ARG($fp) REG_L t6, 2*FFI_SIZEOF_ARG($fp)
# Is it bigger than 8 * FFI_SIZEOF_ARG? # Is it bigger than 8 * FFI_SIZEOF_ARG?
dadd t7, $0, 8 * FFI_SIZEOF_ARG daddiu t8, t6, -(8 * FFI_SIZEOF_ARG)
dsub t8, t6, t7
bltz t8, loadregs bltz t8, loadregs
add t9, t9, t8 ADDU t9, t9, t8
loadregs: loadregs:
REG_L t4, 3*FFI_SIZEOF_ARG($fp) # load the flags word REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6.
add t6, t4, 0 # and copy it into t6
and t4, ((1<<FFI_FLAG_BITS)-1) and t4, t6, ((1<<FFI_FLAG_BITS)-1)
bnez t4, arg1_floatp bnez t4, arg1_floatp
REG_L a0, 0*FFI_SIZEOF_ARG(t9) REG_L a0, 0*FFI_SIZEOF_ARG(t9)
b arg1_next b arg1_next
@@ -113,8 +115,7 @@ arg1_doublep:
l.d $f12, 0*FFI_SIZEOF_ARG(t9) l.d $f12, 0*FFI_SIZEOF_ARG(t9)
arg1_next: arg1_next:
add t4, t6, 0 SRL t4, t6, 1*FFI_FLAG_BITS
SRL t4, 1*FFI_FLAG_BITS
and t4, ((1<<FFI_FLAG_BITS)-1) and t4, ((1<<FFI_FLAG_BITS)-1)
bnez t4, arg2_floatp bnez t4, arg2_floatp
REG_L a1, 1*FFI_SIZEOF_ARG(t9) REG_L a1, 1*FFI_SIZEOF_ARG(t9)
@@ -127,8 +128,7 @@ arg2_doublep:
l.d $f13, 1*FFI_SIZEOF_ARG(t9) l.d $f13, 1*FFI_SIZEOF_ARG(t9)
arg2_next: arg2_next:
add t4, t6, 0 SRL t4, t6, 2*FFI_FLAG_BITS
SRL t4, 2*FFI_FLAG_BITS
and t4, ((1<<FFI_FLAG_BITS)-1) and t4, ((1<<FFI_FLAG_BITS)-1)
bnez t4, arg3_floatp bnez t4, arg3_floatp
REG_L a2, 2*FFI_SIZEOF_ARG(t9) REG_L a2, 2*FFI_SIZEOF_ARG(t9)
@@ -141,8 +141,7 @@ arg3_doublep:
l.d $f14, 2*FFI_SIZEOF_ARG(t9) l.d $f14, 2*FFI_SIZEOF_ARG(t9)
arg3_next: arg3_next:
add t4, t6, 0 SRL t4, t6, 3*FFI_FLAG_BITS
SRL t4, 3*FFI_FLAG_BITS
and t4, ((1<<FFI_FLAG_BITS)-1) and t4, ((1<<FFI_FLAG_BITS)-1)
bnez t4, arg4_floatp bnez t4, arg4_floatp
REG_L a3, 3*FFI_SIZEOF_ARG(t9) REG_L a3, 3*FFI_SIZEOF_ARG(t9)
@@ -155,8 +154,7 @@ arg4_doublep:
l.d $f15, 3*FFI_SIZEOF_ARG(t9) l.d $f15, 3*FFI_SIZEOF_ARG(t9)
arg4_next: arg4_next:
add t4, t6, 0 SRL t4, t6, 4*FFI_FLAG_BITS
SRL t4, 4*FFI_FLAG_BITS
and t4, ((1<<FFI_FLAG_BITS)-1) and t4, ((1<<FFI_FLAG_BITS)-1)
bnez t4, arg5_floatp bnez t4, arg5_floatp
REG_L a4, 4*FFI_SIZEOF_ARG(t9) REG_L a4, 4*FFI_SIZEOF_ARG(t9)
@@ -169,8 +167,7 @@ arg5_doublep:
l.d $f16, 4*FFI_SIZEOF_ARG(t9) l.d $f16, 4*FFI_SIZEOF_ARG(t9)
arg5_next: arg5_next:
add t4, t6, 0 SRL t4, t6, 5*FFI_FLAG_BITS
SRL t4, 5*FFI_FLAG_BITS
and t4, ((1<<FFI_FLAG_BITS)-1) and t4, ((1<<FFI_FLAG_BITS)-1)
bnez t4, arg6_floatp bnez t4, arg6_floatp
REG_L a5, 5*FFI_SIZEOF_ARG(t9) REG_L a5, 5*FFI_SIZEOF_ARG(t9)
@@ -183,8 +180,7 @@ arg6_doublep:
l.d $f17, 5*FFI_SIZEOF_ARG(t9) l.d $f17, 5*FFI_SIZEOF_ARG(t9)
arg6_next: arg6_next:
add t4, t6, 0 SRL t4, t6, 6*FFI_FLAG_BITS
SRL t4, 6*FFI_FLAG_BITS
and t4, ((1<<FFI_FLAG_BITS)-1) and t4, ((1<<FFI_FLAG_BITS)-1)
bnez t4, arg7_floatp bnez t4, arg7_floatp
REG_L a6, 6*FFI_SIZEOF_ARG(t9) REG_L a6, 6*FFI_SIZEOF_ARG(t9)
@@ -197,8 +193,7 @@ arg7_doublep:
l.d $f18, 6*FFI_SIZEOF_ARG(t9) l.d $f18, 6*FFI_SIZEOF_ARG(t9)
arg7_next: arg7_next:
add t4, t6, 0 SRL t4, t6, 7*FFI_FLAG_BITS
SRL t4, 7*FFI_FLAG_BITS
and t4, ((1<<FFI_FLAG_BITS)-1) and t4, ((1<<FFI_FLAG_BITS)-1)
bnez t4, arg8_floatp bnez t4, arg8_floatp
REG_L a7, 7*FFI_SIZEOF_ARG(t9) REG_L a7, 7*FFI_SIZEOF_ARG(t9)
@@ -315,6 +310,224 @@ epilogue:
ADDU $sp, SIZEOF_FRAME # Fix stack pointer ADDU $sp, SIZEOF_FRAME # Fix stack pointer
j ra j ra
.LFE3:
.end ffi_call_N32 .end ffi_call_N32
/* ffi_closure_N32. Expects address of the passed-in ffi_closure in t0
($12). Stores any arguments passed in registers onto the stack,
then calls ffi_closure_mips_inner_N32, which then decodes
them.
Stack layout:
20 - Start of parameters, original sp
19 - Called function a7 save
18 - Called function a6 save
17 - Called function a5 save
16 - Called function a4 save
15 - Called function a3 save
14 - Called function a2 save
13 - Called function a1 save
12 - Called function a0 save
11 - Called function f19
10 - Called function f18
9 - Called function f17
8 - Called function f16
7 - Called function f15
6 - Called function f14
5 - Called function f13
4 - Called function f12
3 - return value high (v1 or $f2)
2 - return value low (v0 or $f0)
1 - ra save
0 - gp save our sp points here
*/
#define SIZEOF_FRAME2 (20 * FFI_SIZEOF_ARG)
#define A7_OFF2 (19 * FFI_SIZEOF_ARG)
#define A6_OFF2 (18 * FFI_SIZEOF_ARG)
#define A5_OFF2 (17 * FFI_SIZEOF_ARG)
#define A4_OFF2 (16 * FFI_SIZEOF_ARG)
#define A3_OFF2 (15 * FFI_SIZEOF_ARG)
#define A2_OFF2 (14 * FFI_SIZEOF_ARG)
#define A1_OFF2 (13 * FFI_SIZEOF_ARG)
#define A0_OFF2 (12 * FFI_SIZEOF_ARG)
#define F19_OFF2 (11 * FFI_SIZEOF_ARG)
#define F18_OFF2 (10 * FFI_SIZEOF_ARG)
#define F17_OFF2 (9 * FFI_SIZEOF_ARG)
#define F16_OFF2 (8 * FFI_SIZEOF_ARG)
#define F15_OFF2 (7 * FFI_SIZEOF_ARG)
#define F14_OFF2 (6 * FFI_SIZEOF_ARG)
#define F13_OFF2 (5 * FFI_SIZEOF_ARG)
#define F12_OFF2 (4 * FFI_SIZEOF_ARG)
#define V1_OFF2 (3 * FFI_SIZEOF_ARG)
#define V0_OFF2 (2 * FFI_SIZEOF_ARG)
#define RA_OFF2 (1 * FFI_SIZEOF_ARG)
#define GP_OFF2 (0 * FFI_SIZEOF_ARG)
.align 2
.globl ffi_closure_N32
.ent ffi_closure_N32
ffi_closure_N32:
.LFB2:
.frame $sp, SIZEOF_FRAME2, ra
.mask 0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)
.fmask 0x00000000,0
SUBU $sp, SIZEOF_FRAME2
.LCFI5:
.cpsetup t9, GP_OFF2, ffi_closure_N32
REG_S ra, RA_OFF2($sp) # Save return address
.LCFI6:
# Store all possible argument registers. If there are more than
# fit in registers, then they were stored on the stack.
REG_S a0, A0_OFF2($sp)
REG_S a1, A1_OFF2($sp)
REG_S a2, A2_OFF2($sp)
REG_S a3, A3_OFF2($sp)
REG_S a4, A4_OFF2($sp)
REG_S a5, A5_OFF2($sp)
REG_S a6, A6_OFF2($sp)
REG_S a7, A7_OFF2($sp)
# Store all possible float/double registers.
s.d $f12, F12_OFF2($sp)
s.d $f13, F13_OFF2($sp)
s.d $f14, F14_OFF2($sp)
s.d $f15, F15_OFF2($sp)
s.d $f16, F16_OFF2($sp)
s.d $f17, F17_OFF2($sp)
s.d $f18, F18_OFF2($sp)
s.d $f19, F19_OFF2($sp)
# Call ffi_closure_mips_inner_N32 to do the real work.
LA t9, ffi_closure_mips_inner_N32
move a0, $12 # Pointer to the ffi_closure
ADDU a1, $sp, V0_OFF2
ADDU a2, $sp, A0_OFF2
ADDU a3, $sp, F12_OFF2
jalr t9
# Return flags are in v0
bne v0, FFI_TYPE_INT, cls_retfloat
REG_L v0, V0_OFF2($sp)
b cls_epilogue
cls_retfloat:
bne v0, FFI_TYPE_FLOAT, cls_retdouble
l.s $f0, V0_OFF2($sp)
b cls_epilogue
cls_retdouble:
bne v0, FFI_TYPE_DOUBLE, cls_retstruct_d
l.d $f0, V0_OFF2($sp)
b cls_epilogue
cls_retstruct_d:
bne v0, FFI_TYPE_STRUCT_D, cls_retstruct_f
l.d $f0, V0_OFF2($sp)
b cls_epilogue
cls_retstruct_f:
bne v0, FFI_TYPE_STRUCT_F, cls_retstruct_d_d
l.s $f0, V0_OFF2($sp)
b cls_epilogue
cls_retstruct_d_d:
bne v0, FFI_TYPE_STRUCT_DD, cls_retstruct_f_f
l.d $f0, V0_OFF2($sp)
l.d $f2, V1_OFF2($sp)
b cls_epilogue
cls_retstruct_f_f:
bne v0, FFI_TYPE_STRUCT_FF, cls_retstruct_d_f
l.s $f0, V0_OFF2($sp)
l.s $f2, V1_OFF2($sp)
b cls_epilogue
cls_retstruct_d_f:
bne v0, FFI_TYPE_STRUCT_DF, cls_retstruct_f_d
l.d $f0, V0_OFF2($sp)
l.s $f2, V1_OFF2($sp)
b cls_epilogue
cls_retstruct_f_d:
bne v0, FFI_TYPE_STRUCT_FD, cls_retstruct_small2
l.s $f0, V0_OFF2($sp)
l.d $f2, V1_OFF2($sp)
b cls_epilogue
cls_retstruct_small2:
REG_L v0, V0_OFF2($sp)
REG_L v1, V1_OFF2($sp)
# Epilogue
cls_epilogue:
REG_L ra, RA_OFF2($sp) # Restore return address
.cpreturn
ADDU $sp, SIZEOF_FRAME2
j ra
.LFE2:
.end ffi_closure_N32
.section .eh_frame,"aw",@progbits
.Lframe1:
.4byte .LECIE1-.LSCIE1 # length
.LSCIE1:
.4byte 0x0 # CIE
.byte 0x1 # Version 1
.ascii "\000" # Augmentation
.uleb128 0x1 # Code alignment 1
.sleb128 -4 # Data alignment -4
.byte 0x1f # Return Address $31
.byte 0xc # DW_CFA_def_cfa
.uleb128 0x1d # in $sp
.uleb128 0x0 # offset 0
.align EH_FRAME_ALIGN
.LECIE1:
.LSFDE1:
.4byte .LEFDE1-.LASFDE1 # length.
.LASFDE1:
.4byte .LASFDE1-.Lframe1 # CIE_pointer.
FDE_ADDR_BYTES .LFB3 # initial_location.
FDE_ADDR_BYTES .LFE3-.LFB3 # address_range.
.byte 0x4 # DW_CFA_advance_loc4
.4byte .LCFI0-.LFB3 # to .LCFI0
.byte 0xe # DW_CFA_def_cfa_offset
.uleb128 SIZEOF_FRAME # adjust stack.by SIZEOF_FRAME
.byte 0x4 # DW_CFA_advance_loc4
.4byte .LCFI1-.LCFI0 # to .LCFI1
.byte 0x9e # DW_CFA_offset of $fp
.uleb128 2*FFI_SIZEOF_ARG/4 #
.byte 0x9f # DW_CFA_offset of ra
.uleb128 1*FFI_SIZEOF_ARG/4 #
.byte 0x4 # DW_CFA_advance_loc4
.4byte .LCFI3-.LCFI1 # to .LCFI3
.byte 0xd # DW_CFA_def_cfa_register
.uleb128 0x1e # in $fp
.align EH_FRAME_ALIGN
.LEFDE1:
.LSFDE3:
.4byte .LEFDE3-.LASFDE3 # length
.LASFDE3:
.4byte .LASFDE3-.Lframe1 # CIE_pointer.
FDE_ADDR_BYTES .LFB2 # initial_location.
FDE_ADDR_BYTES .LFE2-.LFB2 # address_range.
.byte 0x4 # DW_CFA_advance_loc4
.4byte .LCFI5-.LFB2 # to .LCFI5
.byte 0xe # DW_CFA_def_cfa_offset
.uleb128 SIZEOF_FRAME2 # adjust stack.by SIZEOF_FRAME
.byte 0x4 # DW_CFA_advance_loc4
.4byte .LCFI6-.LCFI5 # to .LCFI6
.byte 0x9c # DW_CFA_offset of $gp ($28)
.uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4
.byte 0x9f # DW_CFA_offset of ra ($31)
.uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
.align EH_FRAME_ALIGN
.LEFDE3:
#endif #endif

View File

@@ -36,6 +36,9 @@
#define flags a3 #define flags a3
#define SIZEOF_FRAME (4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG) #define SIZEOF_FRAME (4 * FFI_SIZEOF_ARG + 2 * FFI_SIZEOF_ARG)
#define A3_OFF (SIZEOF_FRAME + 3 * FFI_SIZEOF_ARG)
#define FP_OFF (SIZEOF_FRAME - 2 * FFI_SIZEOF_ARG)
#define RA_OFF (SIZEOF_FRAME - 1 * FFI_SIZEOF_ARG)
.abicalls .abicalls
.text .text
@@ -47,42 +50,36 @@ $LFB0:
# Prologue # Prologue
SUBU $sp, SIZEOF_FRAME # Frame size SUBU $sp, SIZEOF_FRAME # Frame size
$LCFI0: $LCFI0:
REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer REG_S $fp, FP_OFF($sp) # Save frame pointer
$LCFI1: $LCFI1:
REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address REG_S ra, RA_OFF($sp) # Save return address
$LCFI2: $LCFI2:
move $fp, $sp move $fp, $sp
$LCFI3: $LCFI3:
move t9, callback # callback function pointer move t9, callback # callback function pointer
REG_S flags, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG($fp) # flags REG_S flags, A3_OFF($fp) # flags
# Allocate at least 4 words in the argstack # Allocate at least 4 words in the argstack
move v0, bytes
bge bytes, 4 * FFI_SIZEOF_ARG, bigger
LI v0, 4 * FFI_SIZEOF_ARG LI v0, 4 * FFI_SIZEOF_ARG
b sixteen blt bytes, v0, sixteen
bigger: ADDU v0, bytes, 7 # make sure it is aligned
ADDU t0, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned and v0, -8 # to an 8 byte boundry
and v0, t0, -2 * FFI_SIZEOF_ARG # to an 8 byte boundry
sixteen: sixteen:
SUBU $sp, $sp, v0 # move the stack pointer to reflect the SUBU $sp, v0 # move the stack pointer to reflect the
# arg space # arg space
ADDU a0, $sp, 4 * FFI_SIZEOF_ARG ADDU a0, $sp, 4 * FFI_SIZEOF_ARG
ADDU a3, $fp, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG
jalr t9 jalr t9
REG_L t0, SIZEOF_FRAME + 3*FFI_SIZEOF_ARG($fp) # load the flags word REG_L t0, A3_OFF($fp) # load the flags word
add t2, t0, 0 # and copy it into t2 SRL t2, t0, 4 # shift our arg info
and t0, ((1<<4)-1) # mask out the return type and t0, ((1<<4)-1) # mask out the return type
SRL t2, 4 # shift our arg info
ADDU $sp, $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args ADDU $sp, 4 * FFI_SIZEOF_ARG # adjust $sp to new args
bnez t0, pass_d # make it quick for int bnez t0, pass_d # make it quick for int
REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the REG_L a0, 0*FFI_SIZEOF_ARG($sp) # just go ahead and load the
@@ -176,8 +173,8 @@ noretval:
# Epilogue # Epilogue
epilogue: epilogue:
move $sp, $fp move $sp, $fp
REG_L $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer REG_L $fp, FP_OFF($sp) # Restore frame pointer
REG_L ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Restore return address REG_L ra, RA_OFF($sp) # Restore return address
ADDU $sp, SIZEOF_FRAME # Fix stack pointer ADDU $sp, SIZEOF_FRAME # Fix stack pointer
j ra j ra
@@ -186,30 +183,47 @@ $LFE0:
/* ffi_closure_O32. Expects address of the passed-in ffi_closure /* ffi_closure_O32. Expects address of the passed-in ffi_closure
in t0. Stores any arguments passed in registers onto the in t4 ($12). Stores any arguments passed in registers onto the
stack, then calls ffi_closure_mips_inner_O32, which stack, then calls ffi_closure_mips_inner_O32, which
then decodes them. then decodes them.
Stack layout: Stack layout:
14 - Start of parameters, original sp 3 - a3 save
13 - ra save 2 - a2 save
12 - fp save 1 - a1 save
11 - $16 (s0) save 0 - a0 save, original sp
10 - cprestore -1 - ra save
9 - return value high (v1) -2 - fp save
8 - return value low (v0) -3 - $16 (s0) save
7 - f14 (le high, be low) -4 - cprestore
6 - f14 (le low, be high) -5 - return value high (v1)
5 - f12 (le high, be low) -6 - return value low (v0)
4 - f12 (le low, be high) -7 - f14 (le high, be low)
3 - Called function a3 save -8 - f14 (le low, be high)
2 - Called function a2 save -9 - f12 (le high, be low)
1 - Called function a1 save -10 - f12 (le low, be high)
0 - Called function a0 save our sp, fp point here -11 - Called function a3 save
-12 - Called function a2 save
-13 - Called function a1 save
-14 - Called function a0 save, our sp and fp point here
*/ */
#define SIZEOF_FRAME2 (14 * FFI_SIZEOF_ARG) #define SIZEOF_FRAME2 (14 * FFI_SIZEOF_ARG)
#define A3_OFF2 (SIZEOF_FRAME2 + 3 * FFI_SIZEOF_ARG)
#define A2_OFF2 (SIZEOF_FRAME2 + 2 * FFI_SIZEOF_ARG)
#define A1_OFF2 (SIZEOF_FRAME2 + 1 * FFI_SIZEOF_ARG)
#define A0_OFF2 (SIZEOF_FRAME2 + 0 * FFI_SIZEOF_ARG)
#define RA_OFF2 (SIZEOF_FRAME2 - 1 * FFI_SIZEOF_ARG)
#define FP_OFF2 (SIZEOF_FRAME2 - 2 * FFI_SIZEOF_ARG)
#define S0_OFF2 (SIZEOF_FRAME2 - 3 * FFI_SIZEOF_ARG)
#define GP_OFF2 (SIZEOF_FRAME2 - 4 * FFI_SIZEOF_ARG)
#define V1_OFF2 (SIZEOF_FRAME2 - 5 * FFI_SIZEOF_ARG)
#define V0_OFF2 (SIZEOF_FRAME2 - 6 * FFI_SIZEOF_ARG)
#define FA_1_1_OFF2 (SIZEOF_FRAME2 - 7 * FFI_SIZEOF_ARG)
#define FA_1_0_OFF2 (SIZEOF_FRAME2 - 8 * FFI_SIZEOF_ARG)
#define FA_0_1_OFF2 (SIZEOF_FRAME2 - 9 * FFI_SIZEOF_ARG)
#define FA_0_0_OFF2 (SIZEOF_FRAME2 - 10 * FFI_SIZEOF_ARG)
.text .text
.align 2 .align 2
@@ -218,45 +232,45 @@ $LFE0:
ffi_closure_O32: ffi_closure_O32:
$LFB1: $LFB1:
# Prologue # Prologue
.frame $fp, SIZEOF_FRAME2, $31 .frame $fp, SIZEOF_FRAME2, ra
.set noreorder .set noreorder
.cpload $25 .cpload t9
.set reorder .set reorder
SUBU $sp, SIZEOF_FRAME2 SUBU $sp, SIZEOF_FRAME2
.cprestore SIZEOF_FRAME2 - 4*FFI_SIZEOF_ARG .cprestore GP_OFF2
$LCFI4: $LCFI4:
REG_S $16, SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) # Save s0 REG_S $16, S0_OFF2($sp) # Save s0
REG_S $fp, SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer REG_S $fp, FP_OFF2($sp) # Save frame pointer
REG_S ra, SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) # Save return address REG_S ra, RA_OFF2($sp) # Save return address
$LCFI6: $LCFI6:
move $fp, $sp move $fp, $sp
$LCFI7: $LCFI7:
# Store all possible argument registers. If there are more than # Store all possible argument registers. If there are more than
# four arguments, then they should be stored above where we put $7. # four arguments, then they are stored above where we put a3.
REG_S $4, SIZEOF_FRAME2 + 0*FFI_SIZEOF_ARG($fp) REG_S a0, A0_OFF2($fp)
REG_S $5, SIZEOF_FRAME2 + 1*FFI_SIZEOF_ARG($fp) REG_S a1, A1_OFF2($fp)
REG_S $6, SIZEOF_FRAME2 + 2*FFI_SIZEOF_ARG($fp) REG_S a2, A2_OFF2($fp)
REG_S $7, SIZEOF_FRAME2 + 3*FFI_SIZEOF_ARG($fp) REG_S a3, A3_OFF2($fp)
# Load ABI enum to $16 # Load ABI enum to s0
REG_L $16, 20($8) # cif pointer follows tramp. REG_L $16, 20($12) # cif pointer follows tramp.
REG_L $16, 0($16) # abi is first member. REG_L $16, 0($16) # abi is first member.
li $13, 1 # FFI_O32 li $13, 1 # FFI_O32
bne $16, $13, 1f # Skip fp save if FFI_O32_SOFT_FLOAT bne $16, $13, 1f # Skip fp save if FFI_O32_SOFT_FLOAT
# Store all possible float/double registers. # Store all possible float/double registers.
s.d $f12, SIZEOF_FRAME2 - 10*FFI_SIZEOF_ARG($fp) s.d $f12, FA_0_0_OFF2($fp)
s.d $f14, SIZEOF_FRAME2 - 8*FFI_SIZEOF_ARG($fp) s.d $f14, FA_1_0_OFF2($fp)
1: 1:
# Call ffi_closure_mips_inner_O32 to do the work. # Call ffi_closure_mips_inner_O32 to do the work.
la $25, ffi_closure_mips_inner_O32 la t9, ffi_closure_mips_inner_O32
move $4, $8 # Pointer to the ffi_closure move a0, $12 # Pointer to the ffi_closure
addu $5, $fp, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG addu a1, $fp, V0_OFF2
addu $6, $fp, SIZEOF_FRAME2 + 0*FFI_SIZEOF_ARG addu a2, $fp, A0_OFF2
addu $7, $fp, SIZEOF_FRAME2 - 10*FFI_SIZEOF_ARG addu a3, $fp, FA_0_0_OFF2
jalr $31, $25 jalr t9
# Load the return value into the appropriate register. # Load the return value into the appropriate register.
move $8, $2 move $8, $2
@@ -267,28 +281,22 @@ $LCFI7:
bne $16, $13, 1f # Skip fp restore if FFI_O32_SOFT_FLOAT bne $16, $13, 1f # Skip fp restore if FFI_O32_SOFT_FLOAT
li $9, FFI_TYPE_FLOAT li $9, FFI_TYPE_FLOAT
l.s $f0, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp) l.s $f0, V0_OFF2($fp)
beq $8, $9, closure_done beq $8, $9, closure_done
li $9, FFI_TYPE_DOUBLE li $9, FFI_TYPE_DOUBLE
l.d $f0, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp) l.d $f0, V0_OFF2($fp)
beq $8, $9, closure_done beq $8, $9, closure_done
1: 1:
li $9, FFI_TYPE_SINT64 REG_L $3, V1_OFF2($fp)
REG_L $3, SIZEOF_FRAME2 - 5*FFI_SIZEOF_ARG($fp) REG_L $2, V0_OFF2($fp)
beq $8, $9, integer
li $9, FFI_TYPE_UINT64
beq $8, $9, integer
integer:
REG_L $2, SIZEOF_FRAME2 - 6*FFI_SIZEOF_ARG($fp)
closure_done: closure_done:
# Epilogue # Epilogue
move $sp, $fp move $sp, $fp
REG_L $16, SIZEOF_FRAME2 - 3*FFI_SIZEOF_ARG($sp) # Restore s0 REG_L $16, S0_OFF2($sp) # Restore s0
REG_L $fp, SIZEOF_FRAME2 - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer REG_L $fp, FP_OFF2($sp) # Restore frame pointer
REG_L ra, SIZEOF_FRAME2 - 1*FFI_SIZEOF_ARG($sp) # Restore return address REG_L ra, RA_OFF2($sp) # Restore return address
ADDU $sp, SIZEOF_FRAME2 ADDU $sp, SIZEOF_FRAME2
j ra j ra
$LFE1: $LFE1:

View File

@@ -2,6 +2,7 @@
ffi.c - (c) 2003-2004 Randolph Chung <tausq@debian.org> ffi.c - (c) 2003-2004 Randolph Chung <tausq@debian.org>
HPPA Foreign Function Interface HPPA Foreign Function Interface
HP-UX PA ABI support (c) 2006 Free Software Foundation, Inc.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@@ -30,15 +31,19 @@
#include <stdio.h> #include <stdio.h>
#define ROUND_UP(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1)) #define ROUND_UP(v, a) (((size_t)(v) + (a) - 1) & ~((a) - 1))
#define ROUND_DOWN(v, a) (((size_t)(v) - (a) + 1) & ~((a) - 1))
#define MIN_STACK_SIZE 64 #define MIN_STACK_SIZE 64
#define FIRST_ARG_SLOT 9 #define FIRST_ARG_SLOT 9
#define DEBUG_LEVEL 0 #define DEBUG_LEVEL 0
#define fldw(addr, fpreg) asm volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg) #define fldw(addr, fpreg) \
#define fstw(fpreg, addr) asm volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr)) __asm__ volatile ("fldw 0(%0), %%" #fpreg "L" : : "r"(addr) : #fpreg)
#define fldd(addr, fpreg) asm volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg) #define fstw(fpreg, addr) \
#define fstd(fpreg, addr) asm volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr)) __asm__ volatile ("fstw %%" #fpreg "L, 0(%0)" : : "r"(addr))
#define fldd(addr, fpreg) \
__asm__ volatile ("fldd 0(%0), %%" #fpreg : : "r"(addr) : #fpreg)
#define fstd(fpreg, addr) \
__asm__ volatile ("fstd %%" #fpreg "L, 0(%0)" : : "r"(addr))
#define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0) #define debug(lvl, x...) do { if (lvl <= DEBUG_LEVEL) { printf(x); } } while (0)
@@ -47,16 +52,19 @@ static inline int ffi_struct_type(ffi_type *t)
size_t sz = t->size; size_t sz = t->size;
/* Small structure results are passed in registers, /* Small structure results are passed in registers,
larger ones are passed by pointer. */ larger ones are passed by pointer. Note that
small structures of size 2, 4 and 8 differ from
the corresponding integer types in that they have
different alignment requirements. */
if (sz <= 1) if (sz <= 1)
return FFI_TYPE_UINT8; return FFI_TYPE_UINT8;
else if (sz == 2) else if (sz == 2)
return FFI_TYPE_UINT16; return FFI_TYPE_SMALL_STRUCT2;
else if (sz == 3) else if (sz == 3)
return FFI_TYPE_SMALL_STRUCT3; return FFI_TYPE_SMALL_STRUCT3;
else if (sz == 4) else if (sz == 4)
return FFI_TYPE_UINT32; return FFI_TYPE_SMALL_STRUCT4;
else if (sz == 5) else if (sz == 5)
return FFI_TYPE_SMALL_STRUCT5; return FFI_TYPE_SMALL_STRUCT5;
else if (sz == 6) else if (sz == 6)
@@ -64,7 +72,7 @@ static inline int ffi_struct_type(ffi_type *t)
else if (sz == 7) else if (sz == 7)
return FFI_TYPE_SMALL_STRUCT7; return FFI_TYPE_SMALL_STRUCT7;
else if (sz <= 8) else if (sz <= 8)
return FFI_TYPE_UINT64; return FFI_TYPE_SMALL_STRUCT8;
else else
return FFI_TYPE_STRUCT; /* else, we pass it by pointer. */ return FFI_TYPE_STRUCT; /* else, we pass it by pointer. */
} }
@@ -86,13 +94,32 @@ static inline int ffi_struct_type(ffi_type *t)
SP-20 RP SP-20 RP
SP-4 previous SP SP-4 previous SP
First 4 non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23 The first four argument words on the stack are reserved for use by
First 2 non-FP 64-bit args are passed in register pairs, starting the callee. Instead, the general and floating registers replace
on an even numbered register (i.e. r26/r25 and r24+r23) the first four argument slots. Non FP arguments are passed solely
First 4 FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L in the general registers. FP arguments are passed in both general
First 2 FP 64-bit arguments are passed in fr5 and fr7 and floating registers when using libffi.
The rest are passed on the stack starting at SP-52, but 64-bit
arguments need to be aligned to an 8-byte boundary Non-FP 32-bit args are passed in gr26, gr25, gr24 and gr23.
Non-FP 64-bit args are passed in register pairs, starting
on an odd numbered register (i.e. r25+r26 and r23+r24).
FP 32-bit arguments are passed in fr4L, fr5L, fr6L and fr7L.
FP 64-bit arguments are passed in fr5 and fr7.
The registers are allocated in the same manner as stack slots.
This allows the callee to save its arguments on the stack if
necessary:
arg word 3 -> gr23 or fr7L
arg word 2 -> gr24 or fr6L or fr7R
arg word 1 -> gr25 or fr5L
arg word 0 -> gr26 or fr4L or fr5R
Note that fr4R and fr6R are never used for arguments (i.e.,
doubles are not passed in fr4 or fr6).
The rest of the arguments are passed on the stack starting at SP-52,
but 64-bit arguments need to be aligned to an 8-byte boundary
This means we can have holes either in the register allocation, This means we can have holes either in the register allocation,
or in the stack. */ or in the stack. */
@@ -108,17 +135,17 @@ static inline int ffi_struct_type(ffi_type *t)
NOTE: We load floating point args in this function... that means we NOTE: We load floating point args in this function... that means we
assume gcc will not mess with fp regs in here. */ assume gcc will not mess with fp regs in here. */
/*@-exportheader@*/ void ffi_prep_args_pa32(UINT32 *stack, extended_cif *ecif, unsigned bytes)
void ffi_prep_args_LINUX(UINT32 *stack, extended_cif *ecif, unsigned bytes)
/*@=exportheader@*/
{ {
register unsigned int i; register unsigned int i;
register ffi_type **p_arg; register ffi_type **p_arg;
register void **p_argv; register void **p_argv;
unsigned int slot = FIRST_ARG_SLOT - 1; unsigned int slot = FIRST_ARG_SLOT;
char *dest_cpy; char *dest_cpy;
size_t len;
debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack, ecif, bytes); debug(1, "%s: stack = %p, ecif = %p, bytes = %u\n", __FUNCTION__, stack,
ecif, bytes);
p_arg = ecif->cif->arg_types; p_arg = ecif->cif->arg_types;
p_argv = ecif->avalue; p_argv = ecif->avalue;
@@ -130,116 +157,105 @@ void ffi_prep_args_LINUX(UINT32 *stack, extended_cif *ecif, unsigned bytes)
switch (type) switch (type)
{ {
case FFI_TYPE_SINT8: case FFI_TYPE_SINT8:
slot++;
*(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv); *(SINT32 *)(stack - slot) = *(SINT8 *)(*p_argv);
break; break;
case FFI_TYPE_UINT8: case FFI_TYPE_UINT8:
slot++;
*(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv); *(UINT32 *)(stack - slot) = *(UINT8 *)(*p_argv);
break; break;
case FFI_TYPE_SINT16: case FFI_TYPE_SINT16:
slot++;
*(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv); *(SINT32 *)(stack - slot) = *(SINT16 *)(*p_argv);
break; break;
case FFI_TYPE_UINT16: case FFI_TYPE_UINT16:
slot++;
*(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv); *(UINT32 *)(stack - slot) = *(UINT16 *)(*p_argv);
break; break;
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
case FFI_TYPE_POINTER: case FFI_TYPE_POINTER:
slot++; debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv),
debug(3, "Storing UINT32 %u in slot %u\n", *(UINT32 *)(*p_argv), slot); slot);
*(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv); *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
break; break;
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
slot += 2; /* Align slot for 64-bit type. */
if (slot & 1) slot += (slot & 1) ? 1 : 2;
slot++; *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
*(UINT32 *)(stack - slot) = (*(UINT64 *)(*p_argv)) >> 32;
*(UINT32 *)(stack - slot + 1) = (*(UINT64 *)(*p_argv)) & 0xffffffffUL;
break; break;
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
/* First 4 args go in fr4L - fr7L */ /* First 4 args go in fr4L - fr7L. */
slot++;
switch (slot - FIRST_ARG_SLOT)
{
case 0: fldw(*p_argv, fr4); break;
case 1: fldw(*p_argv, fr5); break;
case 2: fldw(*p_argv, fr6); break;
case 3: fldw(*p_argv, fr7); break;
default:
/* Other ones are just passed on the stack. */
debug(3, "Storing UINT32(float) in slot %u\n", slot); debug(3, "Storing UINT32(float) in slot %u\n", slot);
*(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv); *(UINT32 *)(stack - slot) = *(UINT32 *)(*p_argv);
break; switch (slot - FIRST_ARG_SLOT)
{
/* First 4 args go in fr4L - fr7L. */
case 0: fldw(stack - slot, fr4); break;
case 1: fldw(stack - slot, fr5); break;
case 2: fldw(stack - slot, fr6); break;
case 3: fldw(stack - slot, fr7); break;
} }
break; break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
slot += 2; /* Align slot for 64-bit type. */
if (slot & 1) slot += (slot & 1) ? 1 : 2;
slot++;
switch (slot - FIRST_ARG_SLOT + 1)
{
/* First 2 args go in fr5, fr7 */
case 2: fldd(*p_argv, fr5); break;
case 4: fldd(*p_argv, fr7); break;
default:
debug(3, "Storing UINT64(double) at slot %u\n", slot); debug(3, "Storing UINT64(double) at slot %u\n", slot);
*(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv); *(UINT64 *)(stack - slot) = *(UINT64 *)(*p_argv);
break; switch (slot - FIRST_ARG_SLOT)
{
/* First 2 args go in fr5, fr7. */
case 1: fldd(stack - slot, fr5); break;
case 3: fldd(stack - slot, fr7); break;
} }
break; break;
#ifdef PA_HPUX
case FFI_TYPE_LONGDOUBLE:
/* Long doubles are passed in the same manner as structures
larger than 8 bytes. */
*(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
break;
#endif
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
/* Structs smaller or equal than 4 bytes are passed in one /* Structs smaller or equal than 4 bytes are passed in one
register. Structs smaller or equal 8 bytes are passed in two register. Structs smaller or equal 8 bytes are passed in two
registers. Larger structures are passed by pointer. */ registers. Larger structures are passed by pointer. */
if((*p_arg)->size <= 4) len = (*p_arg)->size;
if (len <= 4)
{ {
slot++; dest_cpy = (char *)(stack - slot) + 4 - len;
dest_cpy = (char *)(stack - slot); memcpy(dest_cpy, (char *)*p_argv, len);
dest_cpy += 4 - (*p_arg)->size;
memcpy((char *)dest_cpy, (char *)*p_argv, (*p_arg)->size);
} }
else if ((*p_arg)->size <= 8) else if (len <= 8)
{ {
slot += 2; slot += (slot & 1) ? 1 : 2;
if (slot & 1) dest_cpy = (char *)(stack - slot) + 8 - len;
slot++; memcpy(dest_cpy, (char *)*p_argv, len);
dest_cpy = (char *)(stack - slot);
dest_cpy += 8 - (*p_arg)->size;
memcpy((char *)dest_cpy, (char *)*p_argv, (*p_arg)->size);
} }
else else
{
slot++;
*(UINT32 *)(stack - slot) = (UINT32)(*p_argv); *(UINT32 *)(stack - slot) = (UINT32)(*p_argv);
}
break; break;
default: default:
FFI_ASSERT(0); FFI_ASSERT(0);
} }
slot++;
p_arg++; p_arg++;
p_argv++; p_argv++;
} }
/* Make sure we didn't mess up and scribble on the stack. */ /* Make sure we didn't mess up and scribble on the stack. */
{ {
int n; unsigned int n;
debug(5, "Stack setup:\n"); debug(5, "Stack setup:\n");
for (n = 0; n < (bytes + 3) / 4; n++) for (n = 0; n < (bytes + 3) / 4; n++)
@@ -255,7 +271,7 @@ void ffi_prep_args_LINUX(UINT32 *stack, extended_cif *ecif, unsigned bytes)
return; return;
} }
static void ffi_size_stack_LINUX(ffi_cif *cif) static void ffi_size_stack_pa32(ffi_cif *cif)
{ {
ffi_type **ptr; ffi_type **ptr;
int i; int i;
@@ -273,6 +289,9 @@ static void ffi_size_stack_LINUX(ffi_cif *cif)
z += 2 + (z & 1); /* must start on even regs, so we may waste one */ z += 2 + (z & 1); /* must start on even regs, so we may waste one */
break; break;
#ifdef PA_HPUX
case FFI_TYPE_LONGDOUBLE:
#endif
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
z += 1; /* pass by ptr, callee will copy */ z += 1; /* pass by ptr, callee will copy */
break; break;
@@ -304,6 +323,13 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = (unsigned) cif->rtype->type; cif->flags = (unsigned) cif->rtype->type;
break; break;
#ifdef PA_HPUX
case FFI_TYPE_LONGDOUBLE:
/* Long doubles are treated like a structure. */
cif->flags = FFI_TYPE_STRUCT;
break;
#endif
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
/* For the return type we have to check the size of the structures. /* For the return type we have to check the size of the structures.
If the size is smaller or equal 4 bytes, the result is given back If the size is smaller or equal 4 bytes, the result is given back
@@ -327,8 +353,8 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
own stack sizing. */ own stack sizing. */
switch (cif->abi) switch (cif->abi)
{ {
case FFI_LINUX: case FFI_PA32:
ffi_size_stack_LINUX(cif); ffi_size_stack_pa32(cif);
break; break;
default: default:
@@ -339,20 +365,11 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
/*@-declundef@*/ extern void ffi_call_pa32(void (*)(UINT32 *, extended_cif *, unsigned),
/*@-exportheader@*/ extended_cif *, unsigned, unsigned, unsigned *,
extern void ffi_call_LINUX(void (*)(UINT32 *, extended_cif *, unsigned),
/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)()); void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
void ffi_call(/*@dependent@*/ ffi_cif *cif, void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue)
{ {
extended_cif ecif; extended_cif ecif;
@@ -362,12 +379,15 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
/* If the return value is a struct and we don't have a return /* If the return value is a struct and we don't have a return
value address then we need to make one. */ value address then we need to make one. */
if ((rvalue == NULL) && if (rvalue == NULL
(cif->rtype->type == FFI_TYPE_STRUCT)) #ifdef PA_HPUX
&& (cif->rtype->type == FFI_TYPE_STRUCT
|| cif->rtype->type == FFI_TYPE_LONGDOUBLE))
#else
&& cif->rtype->type == FFI_TYPE_STRUCT)
#endif
{ {
/*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size); ecif.rvalue = alloca(cif->rtype->size);
/*@=sysunrecog@*/
} }
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
@@ -375,12 +395,10 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi) switch (cif->abi)
{ {
case FFI_LINUX: case FFI_PA32:
/*@-usedef@*/ debug(3, "Calling ffi_call_pa32: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn);
debug(2, "Calling ffi_call_LINUX: ecif=%p, bytes=%u, flags=%u, rvalue=%p, fn=%p\n", &ecif, cif->bytes, cif->flags, ecif.rvalue, (void *)fn); ffi_call_pa32(ffi_prep_args_pa32, &ecif, cif->bytes,
ffi_call_LINUX(ffi_prep_args_LINUX, &ecif, cif->bytes,
cif->flags, ecif.rvalue, fn); cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break; break;
default: default:
@@ -394,7 +412,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
the stack, and we need to fill them into a cif structure and invoke the stack, and we need to fill them into a cif structure and invoke
the user function. This really ought to be in asm to make sure the user function. This really ought to be in asm to make sure
the compiler doesn't do things we don't expect. */ the compiler doesn't do things we don't expect. */
UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack) ffi_status ffi_closure_inner_pa32(ffi_closure *closure, UINT32 *stack)
{ {
ffi_cif *cif; ffi_cif *cif;
void **avalue; void **avalue;
@@ -402,7 +420,8 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
UINT32 ret[2]; /* function can return up to 64-bits in registers */ UINT32 ret[2]; /* function can return up to 64-bits in registers */
ffi_type **p_arg; ffi_type **p_arg;
char *tmp; char *tmp;
int i, avn, slot = FIRST_ARG_SLOT - 1; int i, avn;
unsigned int slot = FIRST_ARG_SLOT;
register UINT32 r28 asm("r28"); register UINT32 r28 asm("r28");
cif = closure->cif; cif = closure->cif;
@@ -430,20 +449,23 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
case FFI_TYPE_SINT32: case FFI_TYPE_SINT32:
case FFI_TYPE_UINT32: case FFI_TYPE_UINT32:
case FFI_TYPE_POINTER: case FFI_TYPE_POINTER:
slot++;
avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size; avalue[i] = (char *)(stack - slot) + sizeof(UINT32) - (*p_arg)->size;
break; break;
case FFI_TYPE_SINT64: case FFI_TYPE_SINT64:
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
slot += 2; slot += (slot & 1) ? 1 : 2;
if (slot & 1)
slot++;
avalue[i] = (void *)(stack - slot); avalue[i] = (void *)(stack - slot);
break; break;
case FFI_TYPE_FLOAT: case FFI_TYPE_FLOAT:
slot++; #ifdef PA_LINUX
/* The closure call is indirect. In Linux, floating point
arguments in indirect calls with a prototype are passed
in the floating point registers instead of the general
registers. So, we need to replace what was previously
stored in the current slot with the value in the
corresponding floating point register. */
switch (slot - FIRST_ARG_SLOT) switch (slot - FIRST_ARG_SLOT)
{ {
case 0: fstw(fr4, (void *)(stack - slot)); break; case 0: fstw(fr4, (void *)(stack - slot)); break;
@@ -451,18 +473,20 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
case 2: fstw(fr6, (void *)(stack - slot)); break; case 2: fstw(fr6, (void *)(stack - slot)); break;
case 3: fstw(fr7, (void *)(stack - slot)); break; case 3: fstw(fr7, (void *)(stack - slot)); break;
} }
#endif
avalue[i] = (void *)(stack - slot); avalue[i] = (void *)(stack - slot);
break; break;
case FFI_TYPE_DOUBLE: case FFI_TYPE_DOUBLE:
slot += 2; slot += (slot & 1) ? 1 : 2;
if (slot & 1) #ifdef PA_LINUX
slot++; /* See previous comment for FFI_TYPE_FLOAT. */
switch (slot - FIRST_ARG_SLOT + 1) switch (slot - FIRST_ARG_SLOT)
{ {
case 2: fstd(fr5, (void *)(stack - slot)); break; case 1: fstd(fr5, (void *)(stack - slot)); break;
case 4: fstd(fr7, (void *)(stack - slot)); break; case 3: fstd(fr7, (void *)(stack - slot)); break;
} }
#endif
avalue[i] = (void *)(stack - slot); avalue[i] = (void *)(stack - slot);
break; break;
@@ -470,35 +494,36 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
/* Structs smaller or equal than 4 bytes are passed in one /* Structs smaller or equal than 4 bytes are passed in one
register. Structs smaller or equal 8 bytes are passed in two register. Structs smaller or equal 8 bytes are passed in two
registers. Larger structures are passed by pointer. */ registers. Larger structures are passed by pointer. */
if((*p_arg)->size <= 4) { if((*p_arg)->size <= 4)
slot++; {
avalue[i] = (void *)(stack - slot) + sizeof(UINT32) - avalue[i] = (void *)(stack - slot) + sizeof(UINT32) -
(*p_arg)->size; (*p_arg)->size;
} else if ((*p_arg)->size <= 8) { }
slot += 2; else if ((*p_arg)->size <= 8)
if (slot & 1) {
slot++; slot += (slot & 1) ? 1 : 2;
avalue[i] = (void *)(stack - slot) + sizeof(UINT64) - avalue[i] = (void *)(stack - slot) + sizeof(UINT64) -
(*p_arg)->size; (*p_arg)->size;
} else {
slot++;
avalue[i] = (void *) *(stack - slot);
} }
else
avalue[i] = (void *) *(stack - slot);
break; break;
default: default:
FFI_ASSERT(0); FFI_ASSERT(0);
} }
slot++;
p_arg++; p_arg++;
} }
/* Invoke the closure. */ /* Invoke the closure. */
(closure->fun) (cif, rvalue, avalue, closure->user_data); (closure->fun) (cif, rvalue, avalue, closure->user_data);
debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0], ret[1]); debug(3, "after calling function, ret[0] = %08x, ret[1] = %08x\n", ret[0],
ret[1]);
/* Store the result */ /* Store the result using the lower 2 bytes of the flags. */
switch (cif->flags) switch (cif->flags)
{ {
case FFI_TYPE_UINT8: case FFI_TYPE_UINT8:
@@ -536,7 +561,9 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
/* Don't need a return value, done by caller. */ /* Don't need a return value, done by caller. */
break; break;
case FFI_TYPE_SMALL_STRUCT2:
case FFI_TYPE_SMALL_STRUCT3: case FFI_TYPE_SMALL_STRUCT3:
case FFI_TYPE_SMALL_STRUCT4:
tmp = (void*)(stack - FIRST_ARG_SLOT); tmp = (void*)(stack - FIRST_ARG_SLOT);
tmp += 4 - cif->rtype->size; tmp += 4 - cif->rtype->size;
memcpy((void*)tmp, &ret[0], cif->rtype->size); memcpy((void*)tmp, &ret[0], cif->rtype->size);
@@ -545,6 +572,7 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
case FFI_TYPE_SMALL_STRUCT5: case FFI_TYPE_SMALL_STRUCT5:
case FFI_TYPE_SMALL_STRUCT6: case FFI_TYPE_SMALL_STRUCT6:
case FFI_TYPE_SMALL_STRUCT7: case FFI_TYPE_SMALL_STRUCT7:
case FFI_TYPE_SMALL_STRUCT8:
{ {
unsigned int ret2[2]; unsigned int ret2[2];
int off; int off;
@@ -582,21 +610,26 @@ UINT32 ffi_closure_inner_LINUX(ffi_closure *closure, UINT32 *stack)
cif specifies the argument and result types for fun. cif specifies the argument and result types for fun.
The cif must already be prep'ed. */ The cif must already be prep'ed. */
void ffi_closure_LINUX(void); extern void ffi_closure_pa32(void);
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*), void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data) void *user_data,
void *codeloc)
{ {
UINT32 *tramp = (UINT32 *)(closure->tramp); UINT32 *tramp = (UINT32 *)(closure->tramp);
#ifdef PA_HPUX
UINT32 *tmp;
#endif
FFI_ASSERT (cif->abi == FFI_LINUX); FFI_ASSERT (cif->abi == FFI_PA32);
/* Make a small trampoline that will branch to our /* Make a small trampoline that will branch to our
handler function. Use PC-relative addressing. */ handler function. Use PC-relative addressing. */
#ifdef PA_LINUX
tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */ tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */
tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */ tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */
tramp[2] = 0x4aa10028; /* ldw 20(%r21),%r1 ; load plabel */ tramp[2] = 0x4aa10028; /* ldw 20(%r21),%r1 ; load plabel */
@@ -604,17 +637,66 @@ ffi_prep_closure (ffi_closure* closure,
tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */ tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */
tramp[5] = 0xeac0c000; /* bv%r0(%r22) ; branch to handler */ tramp[5] = 0xeac0c000; /* bv%r0(%r22) ; branch to handler */
tramp[6] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */ tramp[6] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */
tramp[7] = ((UINT32)(ffi_closure_LINUX) & ~2); tramp[7] = ((UINT32)(ffi_closure_pa32) & ~2);
/* Flush d/icache -- have to flush up 2 two lines because of /* Flush d/icache -- have to flush up 2 two lines because of
alignment. */ alignment. */
asm volatile ( __asm__ volatile(
"fdc 0(%0)\n" "fdc 0(%0)\n\t"
"fdc %1(%0)\n" "fdc %1(%0)\n\t"
"fic 0(%%sr4, %0)\n" "fic 0(%%sr4, %0)\n\t"
"fic %1(%%sr4, %0)\n" "fic %1(%%sr4, %0)\n\t"
"sync\n" "sync\n\t"
: : "r"((unsigned long)tramp & ~31), "r"(32 /* stride */)); "nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n"
:
: "r"((unsigned long)tramp & ~31),
"r"(32 /* stride */)
: "memory");
#endif
#ifdef PA_HPUX
tramp[0] = 0xeaa00000; /* b,l .+8,%r21 ; %r21 <- pc+8 */
tramp[1] = 0xd6a01c1e; /* depi 0,31,2,%r21 ; mask priv bits */
tramp[2] = 0x4aa10038; /* ldw 28(%r21),%r1 ; load plabel */
tramp[3] = 0x36b53ff1; /* ldo -8(%r21),%r21 ; get closure addr */
tramp[4] = 0x0c201096; /* ldw 0(%r1),%r22 ; address of handler */
tramp[5] = 0x02c010b4; /* ldsid (%r22),%r20 ; load space id */
tramp[6] = 0x00141820; /* mtsp %r20,%sr0 ; into %sr0 */
tramp[7] = 0xe2c00000; /* be 0(%sr0,%r22) ; branch to handler */
tramp[8] = 0x0c281093; /* ldw 4(%r1),%r19 ; GP of handler */
tramp[9] = ((UINT32)(ffi_closure_pa32) & ~2);
/* Flush d/icache -- have to flush three lines because of alignment. */
__asm__ volatile(
"copy %1,%0\n\t"
"fdc,m %2(%0)\n\t"
"fdc,m %2(%0)\n\t"
"fdc,m %2(%0)\n\t"
"ldsid (%1),%0\n\t"
"mtsp %0,%%sr0\n\t"
"copy %1,%0\n\t"
"fic,m %2(%%sr0,%0)\n\t"
"fic,m %2(%%sr0,%0)\n\t"
"fic,m %2(%%sr0,%0)\n\t"
"sync\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n"
: "=&r" ((unsigned long)tmp)
: "r" ((unsigned long)tramp & ~31),
"r" (32/* stride */)
: "memory");
#endif
closure->cif = cif; closure->cif = cif;
closure->user_data = user_data; closure->user_data = user_data;

View File

@@ -35,9 +35,20 @@ typedef signed long ffi_sarg;
typedef enum ffi_abi { typedef enum ffi_abi {
FFI_FIRST_ABI = 0, FFI_FIRST_ABI = 0,
#ifdef PA #ifdef PA_LINUX
FFI_LINUX, FFI_PA32,
FFI_DEFAULT_ABI = FFI_LINUX, FFI_DEFAULT_ABI = FFI_PA32,
#endif
#ifdef PA_HPUX
FFI_PA32,
FFI_DEFAULT_ABI = FFI_PA32,
#endif
#ifdef PA64_HPUX
#error "PA64_HPUX FFI is not yet implemented"
FFI_PA64,
FFI_DEFAULT_ABI = FFI_PA64,
#endif #endif
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 FFI_LAST_ABI = FFI_DEFAULT_ABI + 1
@@ -49,11 +60,17 @@ typedef enum ffi_abi {
#define FFI_CLOSURES 1 #define FFI_CLOSURES 1
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#ifdef PA_LINUX
#define FFI_TRAMPOLINE_SIZE 32 #define FFI_TRAMPOLINE_SIZE 32
#else
#define FFI_TYPE_SMALL_STRUCT3 -1 #define FFI_TRAMPOLINE_SIZE 40
#define FFI_TYPE_SMALL_STRUCT5 -2
#define FFI_TYPE_SMALL_STRUCT6 -3
#define FFI_TYPE_SMALL_STRUCT7 -4
#endif #endif
#define FFI_TYPE_SMALL_STRUCT2 -1
#define FFI_TYPE_SMALL_STRUCT3 -2
#define FFI_TYPE_SMALL_STRUCT4 -3
#define FFI_TYPE_SMALL_STRUCT5 -4
#define FFI_TYPE_SMALL_STRUCT6 -5
#define FFI_TYPE_SMALL_STRUCT7 -6
#define FFI_TYPE_SMALL_STRUCT8 -7
#endif

View File

@@ -31,7 +31,7 @@
.level 1.1 .level 1.1
.align 4 .align 4
/* void ffi_call_LINUX(void (*)(char *, extended_cif *), /* void ffi_call_pa32(void (*)(char *, extended_cif *),
extended_cif *ecif, extended_cif *ecif,
unsigned bytes, unsigned bytes,
unsigned flags, unsigned flags,
@@ -39,12 +39,12 @@
void (*fn)()); void (*fn)());
*/ */
.export ffi_call_LINUX,code .export ffi_call_pa32,code
.import ffi_prep_args_LINUX,code .import ffi_prep_args_pa32,code
.type ffi_call_LINUX, @function .type ffi_call_pa32, @function
.LFB1: .LFB1:
ffi_call_LINUX: ffi_call_pa32:
.proc .proc
.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4 .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=4
.entry .entry
@@ -63,7 +63,7 @@ ffi_call_LINUX:
[ 64-bytes register save area ] <- %r4 [ 64-bytes register save area ] <- %r4
[ Stack space for actual call, passed as ] <- %arg0 [ Stack space for actual call, passed as ] <- %arg0
[ arg0 to ffi_prep_args_LINUX ] [ arg0 to ffi_prep_args_pa32 ]
[ Stack for calling prep_args ] <- %sp [ Stack for calling prep_args ] <- %sp
*/ */
@@ -80,7 +80,7 @@ ffi_call_LINUX:
%arg0(stack) -- set up above %arg0(stack) -- set up above
%arg1(ecif) -- same as incoming param %arg1(ecif) -- same as incoming param
%arg2(bytes) -- same as incoming param */ %arg2(bytes) -- same as incoming param */
bl ffi_prep_args_LINUX,%r2 bl ffi_prep_args_pa32,%r2
ldo 64(%arg0), %sp ldo 64(%arg0), %sp
ldo -64(%sp), %sp ldo -64(%sp), %sp
@@ -106,90 +106,139 @@ ffi_call_LINUX:
/* Store the result according to the return type. */ /* Store the result according to the return type. */
checksmst3: .Lcheckint:
comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, checksmst567 comib,<>,n FFI_TYPE_INT, %r21, .Lcheckint8
/* 3-byte structs are returned in ret0 as ??xxyyzz. Shift b .Ldone
left 8 bits to write to the result structure. */
zdep %ret0, 23, 24, %r22
b done
stw %r22, 0(%r20)
checksmst567:
/* 5-7 byte values are returned right justified:
ret0 ret1
5: ??????aa bbccddee
6: ????aabb ccddeeff
7: ??aabbcc ddeeffgg
To store this in the result, write the first 4 bytes into a temp
register using shrpw (t1 = aabbccdd), followed by a rotation of
ret1:
ret0 ret1 ret1
5: ??????aa bbccddee -> eebbccdd (rotate 8)
6: ????aabb ccddeeff -> eeffccdd (rotate 16)
7: ??aabbcc ddeeffgg -> eeffggdd (rotate 24)
then we write (t1, ret1) into the result. */
addi,<> -FFI_TYPE_SMALL_STRUCT5,%r21,%r0
ldi 8, %r22
addi,<> -FFI_TYPE_SMALL_STRUCT6,%r21,%r0
ldi 16, %r22
addi,<> -FFI_TYPE_SMALL_STRUCT7,%r21,%r0
ldi 24, %r22
/* This relies on all the FFI_TYPE_*_STRUCT* defines being <0 */
cmpib,<=,n 0, %r21, checkint8
mtsar %r22
shrpw %ret0, %ret1, %sar, %ret0 /* ret0 = aabbccdd */
shrpw %ret1, %ret1, %sar, %ret1 /* rotate ret1 */
stw %ret0, 0(%r20) stw %ret0, 0(%r20)
b done
stw %ret1, 4(%r20)
checkint8: .Lcheckint8:
comib,<>,n FFI_TYPE_UINT8, %r21, checkint16 comib,<>,n FFI_TYPE_UINT8, %r21, .Lcheckint16
b done b .Ldone
stb %ret0, 0(%r20) stb %ret0, 0(%r20)
checkint16: .Lcheckint16:
comib,<>,n FFI_TYPE_UINT16, %r21, checkint32 comib,<>,n FFI_TYPE_UINT16, %r21, .Lcheckdbl
b done b .Ldone
sth %ret0, 0(%r20) sth %ret0, 0(%r20)
checkint32: .Lcheckdbl:
comib,<>,n FFI_TYPE_UINT32, %r21, checkint comib,<>,n FFI_TYPE_DOUBLE, %r21, .Lcheckfloat
b done b .Ldone
stw %ret0, 0(%r20)
checkint:
comib,<>,n FFI_TYPE_INT, %r21, checkll
b done
stw %ret0, 0(%r20)
checkll:
comib,<>,n FFI_TYPE_UINT64, %r21, checkdbl
stw %ret0, 0(%r20)
b done
stw %ret1, 4(%r20)
checkdbl:
comib,<>,n FFI_TYPE_DOUBLE, %r21, checkfloat
b done
fstd %fr4,0(%r20) fstd %fr4,0(%r20)
checkfloat: .Lcheckfloat:
comib,<>,n FFI_TYPE_FLOAT, %r21, done comib,<>,n FFI_TYPE_FLOAT, %r21, .Lcheckll
b .Ldone
fstw %fr4L,0(%r20) fstw %fr4L,0(%r20)
/* structure returns are either handled by one of the .Lcheckll:
INT/UINT64 cases above, or, if passed by pointer, comib,<>,n FFI_TYPE_UINT64, %r21, .Lchecksmst2
is handled by the callee. */ stw %ret0, 0(%r20)
b .Ldone
stw %ret1, 4(%r20)
done: .Lchecksmst2:
comib,<>,n FFI_TYPE_SMALL_STRUCT2, %r21, .Lchecksmst3
/* 2-byte structs are returned in ret0 as ????xxyy. */
extru %ret0, 23, 8, %r22
stbs,ma %r22, 1(%r20)
b .Ldone
stb %ret0, 0(%r20)
.Lchecksmst3:
comib,<>,n FFI_TYPE_SMALL_STRUCT3, %r21, .Lchecksmst4
/* 3-byte structs are returned in ret0 as ??xxyyzz. */
extru %ret0, 15, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret0, 23, 8, %r22
stbs,ma %r22, 1(%r20)
b .Ldone
stb %ret0, 0(%r20)
.Lchecksmst4:
comib,<>,n FFI_TYPE_SMALL_STRUCT4, %r21, .Lchecksmst5
/* 4-byte structs are returned in ret0 as wwxxyyzz. */
extru %ret0, 7, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret0, 15, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret0, 23, 8, %r22
stbs,ma %r22, 1(%r20)
b .Ldone
stb %ret0, 0(%r20)
.Lchecksmst5:
comib,<>,n FFI_TYPE_SMALL_STRUCT5, %r21, .Lchecksmst6
/* 5 byte values are returned right justified:
ret0 ret1
5: ??????aa bbccddee */
stbs,ma %ret0, 1(%r20)
extru %ret1, 7, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret1, 15, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret1, 23, 8, %r22
stbs,ma %r22, 1(%r20)
b .Ldone
stb %ret1, 0(%r20)
.Lchecksmst6:
comib,<>,n FFI_TYPE_SMALL_STRUCT6, %r21, .Lchecksmst7
/* 6 byte values are returned right justified:
ret0 ret1
6: ????aabb ccddeeff */
extru %ret0, 23, 8, %r22
stbs,ma %r22, 1(%r20)
stbs,ma %ret0, 1(%r20)
extru %ret1, 7, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret1, 15, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret1, 23, 8, %r22
stbs,ma %r22, 1(%r20)
b .Ldone
stb %ret1, 0(%r20)
.Lchecksmst7:
comib,<>,n FFI_TYPE_SMALL_STRUCT7, %r21, .Lchecksmst8
/* 7 byte values are returned right justified:
ret0 ret1
7: ??aabbcc ddeeffgg */
extru %ret0, 15, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret0, 23, 8, %r22
stbs,ma %r22, 1(%r20)
stbs,ma %ret0, 1(%r20)
extru %ret1, 7, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret1, 15, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret1, 23, 8, %r22
stbs,ma %r22, 1(%r20)
b .Ldone
stb %ret1, 0(%r20)
.Lchecksmst8:
comib,<>,n FFI_TYPE_SMALL_STRUCT8, %r21, .Ldone
/* 8 byte values are returned right justified:
ret0 ret1
8: aabbccdd eeffgghh */
extru %ret0, 7, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret0, 15, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret0, 23, 8, %r22
stbs,ma %r22, 1(%r20)
stbs,ma %ret0, 1(%r20)
extru %ret1, 7, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret1, 15, 8, %r22
stbs,ma %r22, 1(%r20)
extru %ret1, 23, 8, %r22
stbs,ma %r22, 1(%r20)
stb %ret1, 0(%r20)
.Ldone:
/* all done, return */ /* all done, return */
copy %r4, %sp /* pop arg stack */ copy %r4, %sp /* pop arg stack */
ldw 12(%r3), %r4 ldw 12(%r3), %r4
@@ -201,14 +250,14 @@ done:
.procend .procend
.LFE1: .LFE1:
/* void ffi_closure_LINUX(void); /* void ffi_closure_pa32(void);
Called with closure argument in %r21 */ Called with closure argument in %r21 */
.export ffi_closure_LINUX,code .export ffi_closure_pa32,code
.import ffi_closure_inner_LINUX,code .import ffi_closure_inner_pa32,code
.type ffi_closure_LINUX, @function .type ffi_closure_pa32, @function
.LFB2: .LFB2:
ffi_closure_LINUX: ffi_closure_pa32:
.proc .proc
.callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3 .callinfo FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
.entry .entry
@@ -228,7 +277,7 @@ ffi_closure_LINUX:
stw %arg3, -48(%r3) stw %arg3, -48(%r3)
copy %r21, %arg0 copy %r21, %arg0
bl ffi_closure_inner_LINUX, %r2 bl ffi_closure_inner_pa32, %r2
copy %r3, %arg1 copy %r3, %arg1
ldwm -64(%sp), %r3 ldwm -64(%sp), %r3
@@ -299,7 +348,7 @@ ffi_closure_LINUX:
.sleb128 -5 .sleb128 -5
.byte 0x4 ;# DW_CFA_advance_loc4 .byte 0x4 ;# DW_CFA_advance_loc4
.word .LCFI12-.LCFI11 .word .LCFI22-.LCFI21
.byte 0xd ;# DW_CFA_def_cfa_register = r3 .byte 0xd ;# DW_CFA_def_cfa_register = r3
.uleb128 0x3 .uleb128 0x3

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,11 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1998 Geoffrey Keating ffi_darwin.c
PowerPC Foreign Function Interface Copyright (C) 1998 Geoffrey Keating
Copyright (C) 2001 John Hornkvist
Copyright (C) 2002, 2006, 2007 Free Software Foundation, Inc.
Darwin ABI support (c) 2001 John Hornkvist FFI support for Darwin and AIX.
AIX ABI support (c) 2002 Free Software Foundation, Inc.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@@ -79,9 +80,7 @@ enum { ASM_NEEDS_REGISTERS = 4 };
*/ */
/*@-exportheader@*/
void ffi_prep_args(extended_cif *ecif, unsigned *const stack) void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
/*@=exportheader@*/
{ {
const unsigned bytes = ecif->cif->bytes; const unsigned bytes = ecif->cif->bytes;
const unsigned flags = ecif->cif->flags; const unsigned flags = ecif->cif->flags;
@@ -227,6 +226,48 @@ void ffi_prep_args(extended_cif *ecif, unsigned *const stack)
//FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); //FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4);
} }
/* Adjust the size of S to be correct for Darwin.
On Darwin, the first field of a structure has natural alignment. */
static void
darwin_adjust_aggregate_sizes (ffi_type *s)
{
int i;
if (s->type != FFI_TYPE_STRUCT)
return;
s->size = 0;
for (i = 0; s->elements[i] != NULL; i++)
{
ffi_type *p;
int align;
p = s->elements[i];
darwin_adjust_aggregate_sizes (p);
if (i == 0
&& (p->type == FFI_TYPE_UINT64
|| p->type == FFI_TYPE_SINT64
|| p->type == FFI_TYPE_DOUBLE
|| p->alignment == 8))
align = 8;
else if (p->alignment == 16 || p->alignment < 4)
align = p->alignment;
else
align = 4;
s->size = ALIGN(s->size, align) + p->size;
}
s->size = ALIGN(s->size, s->alignment);
if (s->elements[0]->type == FFI_TYPE_UINT64
|| s->elements[0]->type == FFI_TYPE_SINT64
|| s->elements[0]->type == FFI_TYPE_DOUBLE
|| s->elements[0]->alignment == 8)
s->alignment = s->alignment > 8 ? s->alignment : 8;
/* Do not add additional tail padding. */
}
/* 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)
{ {
@@ -239,8 +280,16 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
unsigned size_al = 0; unsigned size_al = 0;
/* All the machine-independent calculation of cif->bytes will be wrong. /* All the machine-independent calculation of cif->bytes will be wrong.
All the calculation of structure sizes will also be wrong.
Redo the calculation for DARWIN. */ Redo the calculation for DARWIN. */
if (cif->abi == FFI_DARWIN)
{
darwin_adjust_aggregate_sizes (cif->rtype);
for (i = 0; i < cif->nargs; i++)
darwin_adjust_aggregate_sizes (cif->arg_types[i]);
}
/* Space for the frame pointer, callee's LR, CR, etc, and for /* Space for the frame pointer, callee's LR, CR, etc, and for
the asm's temp regs. */ the asm's temp regs. */
@@ -375,25 +424,12 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
/*@-declundef@*/ extern void ffi_call_AIX(extended_cif *, unsigned, unsigned, unsigned *,
/*@-exportheader@*/ void (*fn)(), void (*fn2)());
extern void ffi_call_AIX(/*@out@*/ extended_cif *, extern void ffi_call_DARWIN(extended_cif *, unsigned, unsigned, unsigned *,
unsigned, unsigned, void (*fn)(), void (*fn2)());
/*@out@*/ unsigned *,
void (*fn)(),
void (*fn2)());
extern void ffi_call_DARWIN(/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)(),
void (*fn2)());
/*@=declundef@*/
/*@=exportheader@*/
void ffi_call(/*@dependent@*/ ffi_cif *cif, void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue)
{ {
extended_cif ecif; extended_cif ecif;
@@ -406,9 +442,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
if ((rvalue == NULL) && if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT)) (cif->rtype->type == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size); ecif.rvalue = alloca(cif->rtype->size);
/*@=sysunrecog@*/
} }
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
@@ -416,16 +450,12 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi) switch (cif->abi)
{ {
case FFI_AIX: case FFI_AIX:
/*@-usedef@*/ ffi_call_AIX(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
ffi_call_AIX(&ecif, -cif->bytes, ffi_prep_args);
cif->flags, ecif.rvalue, fn, ffi_prep_args);
/*@=usedef@*/
break; break;
case FFI_DARWIN: case FFI_DARWIN:
/*@-usedef@*/ ffi_call_DARWIN(&ecif, -cif->bytes, cif->flags, ecif.rvalue, fn,
ffi_call_DARWIN(&ecif, -cif->bytes, ffi_prep_args);
cif->flags, ecif.rvalue, fn, ffi_prep_args);
/*@=usedef@*/
break; break;
default: default:
FFI_ASSERT(0); FFI_ASSERT(0);
@@ -498,10 +528,11 @@ SP current --> +---------------------------------------+ 176 <- parent frame
*/ */
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*), void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data) void *user_data,
void *codeloc)
{ {
unsigned int *tramp; unsigned int *tramp;
struct ffi_aix_trampoline_struct *tramp_aix; struct ffi_aix_trampoline_struct *tramp_aix;
@@ -523,14 +554,14 @@ ffi_prep_closure (ffi_closure* closure,
tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */ tramp[8] = 0x816b0004; /* lwz r11,4(r11) static chain */
tramp[9] = 0x4e800420; /* bctr */ tramp[9] = 0x4e800420; /* bctr */
tramp[2] = (unsigned long) ffi_closure_ASM; /* function */ tramp[2] = (unsigned long) ffi_closure_ASM; /* function */
tramp[3] = (unsigned long) closure; /* context */ tramp[3] = (unsigned long) codeloc; /* context */
closure->cif = cif; closure->cif = cif;
closure->fun = fun; closure->fun = fun;
closure->user_data = user_data; closure->user_data = user_data;
/* Flush the icache. Only necessary on Darwin. */ /* Flush the icache. Only necessary on Darwin. */
flush_range(&closure->tramp[0],FFI_TRAMPOLINE_SIZE); flush_range(codeloc, FFI_TRAMPOLINE_SIZE);
break; break;
@@ -543,7 +574,7 @@ ffi_prep_closure (ffi_closure* closure,
tramp_aix->code_pointer = fd->code_pointer; tramp_aix->code_pointer = fd->code_pointer;
tramp_aix->toc = fd->toc; tramp_aix->toc = fd->toc;
tramp_aix->static_chain = closure; tramp_aix->static_chain = codeloc;
closure->cif = cif; closure->cif = cif;
closure->fun = fun; closure->fun = fun;
closure->user_data = user_data; closure->user_data = user_data;

View File

@@ -1,5 +1,6 @@
/* -----------------------------------------------------------------*-C-*- /* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Copyright (C) 2007 Free Software Foundation, Inc
Target configuration macros for PowerPC. Target configuration macros for PowerPC.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
@@ -43,12 +44,22 @@ typedef enum ffi_abi {
FFI_SYSV, FFI_SYSV,
FFI_GCC_SYSV, FFI_GCC_SYSV,
FFI_LINUX64, FFI_LINUX64,
FFI_LINUX,
FFI_LINUX_SOFT_FLOAT,
# ifdef POWERPC64 # ifdef POWERPC64
FFI_DEFAULT_ABI = FFI_LINUX64, FFI_DEFAULT_ABI = FFI_LINUX64,
# else
# if (!defined(__NO_FPRS__) && (__LDBL_MANT_DIG__ == 106))
FFI_DEFAULT_ABI = FFI_LINUX,
# else
# ifdef __NO_FPRS__
FFI_DEFAULT_ABI = FFI_LINUX_SOFT_FLOAT,
# else # else
FFI_DEFAULT_ABI = FFI_GCC_SYSV, FFI_DEFAULT_ABI = FFI_GCC_SYSV,
# endif # endif
# endif # endif
# endif
#endif
#ifdef POWERPC_AIX #ifdef POWERPC_AIX
FFI_AIX, FFI_AIX,
@@ -69,7 +80,7 @@ typedef enum ffi_abi {
FFI_DEFAULT_ABI = FFI_SYSV, FFI_DEFAULT_ABI = FFI_SYSV,
#endif #endif
FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 FFI_LAST_ABI
} ffi_abi; } ffi_abi;
#endif #endif
@@ -78,8 +89,14 @@ typedef enum ffi_abi {
#define FFI_CLOSURES 1 #define FFI_CLOSURES 1
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
/* For additional types like the below, take care about the order in
ppc_closures.S. They must follow after the FFI_TYPE_LAST. */
/* Needed for soft-float long-double-128 support. */
#define FFI_TYPE_UINT128 (FFI_TYPE_LAST + 1)
/* Needed for FFI_SYSV small structure returns. */ /* Needed for FFI_SYSV small structure returns. */
#define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST) #define FFI_SYSV_TYPE_SMALL_STRUCT (FFI_TYPE_LAST + 2)
#if defined(POWERPC64) || defined(POWERPC_AIX) #if defined(POWERPC64) || defined(POWERPC_AIX)
#define FFI_TRAMPOLINE_SIZE 24 #define FFI_TRAMPOLINE_SIZE 24

View File

@@ -47,8 +47,8 @@ ffi_call_LINUX64:
std %r0, 16(%r1) std %r0, 16(%r1)
mr %r28, %r1 /* our AP. */ mr %r28, %r1 /* our AP. */
stdux %r1, %r1, %r4
.LCFI0: .LCFI0:
stdux %r1, %r1, %r4
mr %r31, %r5 /* flags, */ mr %r31, %r5 /* flags, */
mr %r30, %r6 /* rvalue, */ mr %r30, %r6 /* rvalue, */
mr %r29, %r7 /* function address. */ mr %r29, %r7 /* function address. */
@@ -100,6 +100,10 @@ ffi_call_LINUX64:
/* Make the call. */ /* Make the call. */
bctrl bctrl
/* This must follow the call immediately, the unwinder
uses this to find out if r2 has been saved or not. */
ld %r2, 40(%r1)
/* Now, deal with the return value. */ /* Now, deal with the return value. */
mtcrf 0x01, %r31 mtcrf 0x01, %r31
bt- 30, .Ldone_return_value bt- 30, .Ldone_return_value
@@ -109,7 +113,6 @@ ffi_call_LINUX64:
.Ldone_return_value: .Ldone_return_value:
/* Restore the registers we used and return. */ /* Restore the registers we used and return. */
ld %r2, 40(%r1)
mr %r1, %r28 mr %r1, %r28
ld %r0, 16(%r28) ld %r0, 16(%r28)
ld %r28, -32(%r1) ld %r28, -32(%r1)
@@ -120,12 +123,10 @@ ffi_call_LINUX64:
blr blr
.Lfp_return_value: .Lfp_return_value:
bt 27, .Lfd_return_value
bf 28, .Lfloat_return_value bf 28, .Lfloat_return_value
stfd %f1, 0(%r30) stfd %f1, 0(%r30)
b .Ldone_return_value mtcrf 0x02, %r31 /* cr6 */
.Lfd_return_value: bf 27, .Ldone_return_value
stfd %f1, 0(%r30)
stfd %f2, 8(%r30) stfd %f2, 8(%r30)
b .Ldone_return_value b .Ldone_return_value
.Lfloat_return_value: .Lfloat_return_value:

View File

@@ -28,6 +28,7 @@ ENTRY(ffi_closure_SYSV)
stw %r9, 40(%r1) stw %r9, 40(%r1)
stw %r10,44(%r1) stw %r10,44(%r1)
#ifndef __NO_FPRS__
# next save fpr 1 to fpr 8 (aligned to 8) # next save fpr 1 to fpr 8 (aligned to 8)
stfd %f1, 48(%r1) stfd %f1, 48(%r1)
stfd %f2, 56(%r1) stfd %f2, 56(%r1)
@@ -37,6 +38,7 @@ ENTRY(ffi_closure_SYSV)
stfd %f6, 88(%r1) stfd %f6, 88(%r1)
stfd %f7, 96(%r1) stfd %f7, 96(%r1)
stfd %f8, 104(%r1) stfd %f8, 104(%r1)
#endif
# set up registers for the routine that actually does the work # set up registers for the routine that actually does the work
# get the context pointer from the trampoline # get the context pointer from the trampoline
@@ -58,30 +60,18 @@ ENTRY(ffi_closure_SYSV)
# make the call # make the call
bl ffi_closure_helper_SYSV@local bl ffi_closure_helper_SYSV@local
.Lret:
# now r3 contains the return type # now r3 contains the return type
# so use it to look up in a table # so use it to look up in a table
# so we know how to deal with each type # 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 # look up the proper starting point in table
# by using return type as offset # by using return type as offset
addi %r6,%r1,112 # get pointer to results area
bl .Lget_ret_type0_addr # get pointer to .Lret_type0 into LR mflr %r4 # move address of .Lret to r4
mflr %r4 # move to r4
slwi %r3,%r3,4 # now multiply return type by 16 slwi %r3,%r3,4 # now multiply return type by 16
addi %r4, %r4, .Lret_type0 - .Lret
lwz %r0,148(%r1)
add %r3,%r3,%r4 # add contents of table to table address add %r3,%r3,%r4 # add contents of table to table address
mtctr %r3 mtctr %r3
bctr # jump to it bctr # jump to it
@@ -91,190 +81,169 @@ ENTRY(ffi_closure_SYSV)
# (4 instructions). For cache effectiveness we align to a 16 byte boundary # (4 instructions). For cache effectiveness we align to a 16 byte boundary
# first. # first.
.align 4 .align 4
nop
nop
nop
.Lget_ret_type0_addr:
blrl
# case FFI_TYPE_VOID # case FFI_TYPE_VOID
.Lret_type0: .Lret_type0:
b .Lfinish
nop
nop
nop
# case FFI_TYPE_INT
.Lret_type1:
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_FLOAT
.Lret_type2:
lfs %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_DOUBLE
.Lret_type3:
lfd %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_LONGDOUBLE
.Lret_type4:
lfd %f1,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT8
.Lret_type5:
lbz %r3,3(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT8
.Lret_type6:
lbz %r3,3(%r6)
extsb %r3,%r3
b .Lfinish
nop
# case FFI_TYPE_UINT16
.Lret_type7:
lhz %r3,2(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT16
.Lret_type8:
lha %r3,2(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT32
.Lret_type9:
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_SINT32
.Lret_type10:
lwz %r3,0(%r6)
b .Lfinish
nop
nop
# case FFI_TYPE_UINT64
.Lret_type11:
lwz %r3,0(%r6)
lwz %r4,4(%r6)
b .Lfinish
nop
# case FFI_TYPE_SINT64
.Lret_type12:
lwz %r3,0(%r6)
lwz %r4,4(%r6)
b .Lfinish
nop
# case FFI_TYPE_STRUCT
.Lret_type13:
b .Lfinish
nop
nop
nop
# case FFI_TYPE_POINTER
.Lret_type14:
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:
lwz %r0,148(%r1)
mtlr %r0 mtlr %r0
addi %r1,%r1,144 addi %r1,%r1,144
blr blr
nop
# case FFI_TYPE_INT
lwz %r3,112+0(%r1)
mtlr %r0
.Lfinish:
addi %r1,%r1,144
blr
# case FFI_TYPE_FLOAT
lfs %f1,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_DOUBLE
lfd %f1,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_LONGDOUBLE
lfd %f1,112+0(%r1)
lfd %f2,112+8(%r1)
mtlr %r0
b .Lfinish
# case FFI_TYPE_UINT8
lbz %r3,112+3(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_SINT8
lbz %r3,112+3(%r1)
extsb %r3,%r3
mtlr %r0
b .Lfinish
# case FFI_TYPE_UINT16
lhz %r3,112+2(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_SINT16
lha %r3,112+2(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_UINT32
lwz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_SINT32
lwz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_UINT64
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
mtlr %r0
b .Lfinish
# case FFI_TYPE_SINT64
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
mtlr %r0
b .Lfinish
# case FFI_TYPE_STRUCT
mtlr %r0
addi %r1,%r1,144
blr
nop
# case FFI_TYPE_POINTER
lwz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_TYPE_UINT128
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
lwz %r5,112+8(%r1)
bl .Luint128
# The return types below are only used when the ABI type is FFI_SYSV.
# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
lbz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
lhz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
lwz %r3,112+0(%r1)
srwi %r3,%r3,8
mtlr %r0
b .Lfinish
# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
lwz %r3,112+0(%r1)
mtlr %r0
addi %r1,%r1,144
blr
# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
li %r5,24
b .Lstruct567
# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
li %r5,16
b .Lstruct567
# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
li %r5,8
b .Lstruct567
# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
lwz %r3,112+0(%r1)
lwz %r4,112+4(%r1)
mtlr %r0
b .Lfinish
.Lstruct567:
subfic %r6,%r5,32
srw %r4,%r4,%r5
slw %r6,%r3,%r6
srw %r3,%r3,%r5
or %r4,%r6,%r4
mtlr %r0
addi %r1,%r1,144
blr
.Luint128:
lwz %r6,112+12(%r1)
mtlr %r0
addi %r1,%r1,144
blr
END(ffi_closure_SYSV) END(ffi_closure_SYSV)
.section ".eh_frame",EH_FRAME_FLAGS,@progbits .section ".eh_frame",EH_FRAME_FLAGS,@progbits

View File

@@ -1,5 +1,6 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
sysv.h - Copyright (c) 1998 Geoffrey Keating sysv.S - Copyright (c) 1998 Geoffrey Keating
Copyright (C) 2007 Free Software Foundation, Inc
PowerPC Assembly glue. PowerPC Assembly glue.
@@ -98,13 +99,17 @@ ENTRY(ffi_call_SYSV)
bctrl bctrl
/* Now, deal with the return value. */ /* Now, deal with the return value. */
mtcrf 0x01,%r31 mtcrf 0x01,%r31 /* cr7 */
bt- 31,L(small_struct_return_value) bt- 31,L(small_struct_return_value)
bt- 30,L(done_return_value) bt- 30,L(done_return_value)
bt- 29,L(fp_return_value) bt- 29,L(fp_return_value)
stw %r3,0(%r30) stw %r3,0(%r30)
bf+ 28,L(done_return_value) bf+ 28,L(done_return_value)
stw %r4,4(%r30) stw %r4,4(%r30)
mtcrf 0x02,%r31 /* cr6 */
bf 27,L(done_return_value)
stw %r5,8(%r30)
stw %r6,12(%r30)
/* Fall through... */ /* Fall through... */
L(done_return_value): L(done_return_value):
@@ -121,6 +126,9 @@ L(done_return_value):
L(fp_return_value): L(fp_return_value):
bf 28,L(float_return_value) bf 28,L(float_return_value)
stfd %f1,0(%r30) stfd %f1,0(%r30)
mtcrf 0x02,%r31 /* cr6 */
bf 27,L(done_return_value)
stfd %f2,8(%r30)
b L(done_return_value) b L(done_return_value)
L(float_return_value): L(float_return_value):
stfs %f1,0(%r30) stfs %f1,0(%r30)
@@ -140,8 +148,14 @@ L(smst_one_register):
b L(done_return_value) b L(done_return_value)
L(smst_two_register): L(smst_two_register):
rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */ rlwinm %r5,%r31,5+23,32-5,31 /* Extract the value to shift. */
bl __ashldi3 /* libgcc function to shift r3/r4, cmpwi %r5,0
shift value in r5. */ subfic %r9,%r5,32
slw %r29,%r3,%r5
srw %r9,%r4,%r9
beq- L(smst_8byte)
or %r3,%r9,%r29
slw %r4,%r4,%r5
L(smst_8byte):
stw %r3,0(%r30) stw %r3,0(%r30)
stw %r4,4(%r30) stw %r4,4(%r30)
b L(done_return_value) b L(done_return_value)

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. prep_cif.c - Copyright (c) 1996, 1998, 2007 Red Hat, Inc.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
@@ -25,7 +25,6 @@
#include <ffi_common.h> #include <ffi_common.h>
#include <stdlib.h> #include <stdlib.h>
/* Round up to FFI_SIZEOF_ARG. */ /* Round up to FFI_SIZEOF_ARG. */
#define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG)
@@ -33,14 +32,12 @@
/* Perform machine independent initialization of aggregate type /* Perform machine independent initialization of aggregate type
specifications. */ specifications. */
static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) static ffi_status initialize_aggregate(ffi_type *arg)
{ {
ffi_type **ptr; ffi_type **ptr;
FFI_ASSERT(arg != NULL); FFI_ASSERT(arg != NULL);
/*@-usedef@*/
FFI_ASSERT(arg->elements != NULL); FFI_ASSERT(arg->elements != NULL);
FFI_ASSERT(arg->size == 0); FFI_ASSERT(arg->size == 0);
FFI_ASSERT(arg->alignment == 0); FFI_ASSERT(arg->alignment == 0);
@@ -77,8 +74,6 @@ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
return FFI_BAD_TYPEDEF; return FFI_BAD_TYPEDEF;
else else
return FFI_OK; return FFI_OK;
/*@=usedef@*/
} }
#ifndef __CRIS__ #ifndef __CRIS__
@@ -89,10 +84,8 @@ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg)
/* Perform machine independent ffi_cif preparation, then call /* Perform machine independent ffi_cif preparation, then call
machine dependent routine. */ machine dependent routine. */
ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs,
ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes)
/*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype,
/*@dependent@*/ ffi_type **atypes)
{ {
unsigned bytes = 0; unsigned bytes = 0;
unsigned int i; unsigned int i;
@@ -109,10 +102,8 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
cif->flags = 0; cif->flags = 0;
/* Initialize the return type if necessary */ /* Initialize the return type if necessary */
/*@-usedef@*/
if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK))
return FFI_BAD_TYPEDEF; return FFI_BAD_TYPEDEF;
/*@=usedef@*/
/* 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);
@@ -123,6 +114,9 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
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
#ifdef X86_DARWIN
&& (cif->rtype->size > 8)
#endif #endif
) )
bytes = STACK_ARG_SIZE(sizeof(void*)); bytes = STACK_ARG_SIZE(sizeof(void*));
@@ -164,3 +158,16 @@ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif,
return ffi_prep_cif_machdep(cif); return ffi_prep_cif_machdep(cif);
} }
#endif /* not __CRIS__ */ #endif /* not __CRIS__ */
#if FFI_CLOSURES
ffi_status
ffi_prep_closure (ffi_closure* closure,
ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data)
{
return ffi_prep_closure_loc (closure, cif, fun, user_data, closure);
}
#endif

View File

@@ -189,10 +189,7 @@ ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw)
* these following couple of functions will handle the translation forth * these following couple of functions will handle the translation forth
* and back automatically. */ * and back automatically. */
void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, void ffi_raw_call (ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *raw)
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ ffi_raw *raw)
{ {
void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); void **avalue = (void**) alloca (cif->nargs * sizeof (void*));
ffi_raw_to_ptrarray (cif, raw, avalue); ffi_raw_to_ptrarray (cif, raw, avalue);
@@ -212,22 +209,20 @@ ffi_translate_args (ffi_cif *cif, void *rvalue,
(*cl->fun) (cif, rvalue, raw, cl->user_data); (*cl->fun) (cif, rvalue, raw, cl->user_data);
} }
/* Again, here is the generic version of ffi_prep_raw_closure, which
* will install an intermediate "hub" for translation of arguments from
* the pointer-array format, to the raw format */
ffi_status ffi_status
ffi_prep_raw_closure (ffi_raw_closure* cl, ffi_prep_raw_closure_loc (ffi_raw_closure* cl,
ffi_cif *cif, ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*), void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data) void *user_data,
void *codeloc)
{ {
ffi_status status; ffi_status status;
status = ffi_prep_closure ((ffi_closure*) cl, status = ffi_prep_closure_loc ((ffi_closure*) cl,
cif, cif,
&ffi_translate_args, &ffi_translate_args,
(void*)cl); codeloc,
codeloc);
if (status == FFI_OK) if (status == FFI_OK)
{ {
cl->fun = fun; cl->fun = fun;
@@ -239,4 +234,22 @@ ffi_prep_raw_closure (ffi_raw_closure* cl,
#endif /* FFI_CLOSURES */ #endif /* FFI_CLOSURES */
#endif /* !FFI_NATIVE_RAW_API */ #endif /* !FFI_NATIVE_RAW_API */
#if FFI_CLOSURES
/* Again, here is the generic version of ffi_prep_raw_closure, which
* will install an intermediate "hub" for translation of arguments from
* the pointer-array format, to the raw format */
ffi_status
ffi_prep_raw_closure (ffi_raw_closure* cl,
ffi_cif *cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data)
{
return ffi_prep_raw_closure_loc (cl, cif, fun, user_data, cl);
}
#endif /* FFI_CLOSURES */
#endif /* !FFI_NO_RAW_API */ #endif /* !FFI_NO_RAW_API */

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2000 Software AG ffi.c - Copyright (c) 2000, 2007 Software AG
S390 Foreign Function Interface S390 Foreign Function Interface
@@ -207,6 +207,12 @@ ffi_prep_args (unsigned char *stack, extended_cif *ecif)
void *arg = *p_argv; void *arg = *p_argv;
int type = (*ptr)->type; int type = (*ptr)->type;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
/* 16-byte long double is passed like a struct. */
if (type == FFI_TYPE_LONGDOUBLE)
type = FFI_TYPE_STRUCT;
#endif
/* Check how a structure type is passed. */ /* Check how a structure type is passed. */
if (type == FFI_TYPE_STRUCT) if (type == FFI_TYPE_STRUCT)
{ {
@@ -364,6 +370,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = FFI390_RET_DOUBLE; cif->flags = FFI390_RET_DOUBLE;
break; break;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE:
cif->flags = FFI390_RET_STRUCT;
n_gpr++;
break;
#endif
/* Integer values are returned in gpr 2 (and gpr 3 /* Integer values are returned in gpr 2 (and gpr 3
for 64-bit values on 31-bit machines). */ for 64-bit values on 31-bit machines). */
case FFI_TYPE_UINT64: case FFI_TYPE_UINT64:
@@ -400,6 +412,12 @@ ffi_prep_cif_machdep(ffi_cif *cif)
{ {
int type = (*ptr)->type; int type = (*ptr)->type;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
/* 16-byte long double is passed like a struct. */
if (type == FFI_TYPE_LONGDOUBLE)
type = FFI_TYPE_STRUCT;
#endif
/* Check how a structure type is passed. */ /* Check how a structure type is passed. */
if (type == FFI_TYPE_STRUCT) if (type == FFI_TYPE_STRUCT)
{ {
@@ -562,6 +580,12 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
int deref_struct_pointer = 0; int deref_struct_pointer = 0;
int type = (*ptr)->type; int type = (*ptr)->type;
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
/* 16-byte long double is passed like a struct. */
if (type == FFI_TYPE_LONGDOUBLE)
type = FFI_TYPE_STRUCT;
#endif
/* Check how a structure type is passed. */ /* Check how a structure type is passed. */
if (type == FFI_TYPE_STRUCT) if (type == FFI_TYPE_STRUCT)
{ {
@@ -662,6 +686,9 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
/* Void is easy, and so is struct. */ /* Void is easy, and so is struct. */
case FFI_TYPE_VOID: case FFI_TYPE_VOID:
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
case FFI_TYPE_LONGDOUBLE:
#endif
break; break;
/* Floating point values are returned in fpr 0. */ /* Floating point values are returned in fpr 0. */
@@ -709,17 +736,18 @@ ffi_closure_helper_SYSV (ffi_closure *closure,
/*====================================================================*/ /*====================================================================*/
/* */ /* */
/* Name - ffi_prep_closure. */ /* Name - ffi_prep_closure_loc. */
/* */ /* */
/* Function - Prepare a FFI closure. */ /* Function - Prepare a FFI closure. */
/* */ /* */
/*====================================================================*/ /*====================================================================*/
ffi_status ffi_status
ffi_prep_closure (ffi_closure *closure, ffi_prep_closure_loc (ffi_closure *closure,
ffi_cif *cif, ffi_cif *cif,
void (*fun) (ffi_cif *, void *, void **, void *), void (*fun) (ffi_cif *, void *, void **, void *),
void *user_data) void *user_data,
void *codeloc)
{ {
FFI_ASSERT (cif->abi == FFI_SYSV); FFI_ASSERT (cif->abi == FFI_SYSV);
@@ -728,7 +756,7 @@ ffi_prep_closure (ffi_closure *closure,
*(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */ *(short *)&closure->tramp [2] = 0x9801; /* lm %r0,%r1,6(%r1) */
*(short *)&closure->tramp [4] = 0x1006; *(short *)&closure->tramp [4] = 0x1006;
*(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */ *(short *)&closure->tramp [6] = 0x07f1; /* br %r1 */
*(long *)&closure->tramp [8] = (long)closure; *(long *)&closure->tramp [8] = (long)codeloc;
*(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV; *(long *)&closure->tramp[12] = (long)&ffi_closure_SYSV;
#else #else
*(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */ *(short *)&closure->tramp [0] = 0x0d10; /* basr %r1,0 */
@@ -736,7 +764,7 @@ ffi_prep_closure (ffi_closure *closure,
*(short *)&closure->tramp [4] = 0x100e; *(short *)&closure->tramp [4] = 0x100e;
*(short *)&closure->tramp [6] = 0x0004; *(short *)&closure->tramp [6] = 0x0004;
*(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */ *(short *)&closure->tramp [8] = 0x07f1; /* br %r1 */
*(long *)&closure->tramp[16] = (long)closure; *(long *)&closure->tramp[16] = (long)codeloc;
*(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV; *(long *)&closure->tramp[24] = (long)&ffi_closure_SYSV;
#endif #endif

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2002, 2003, 2004, 2005 Kaz Kojima ffi.c - Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 Kaz Kojima
SuperH Foreign Function Interface SuperH Foreign Function Interface
@@ -106,9 +106,7 @@ return_type (ffi_type *arg)
/* ffi_prep_args is called by the assembly routine once stack space /* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */ has been allocated for the function's arguments */
/*@-exportheader@*/
void ffi_prep_args(char *stack, extended_cif *ecif) void ffi_prep_args(char *stack, extended_cif *ecif)
/*@=exportheader@*/
{ {
register unsigned int i; register unsigned int i;
register int tmp; register int tmp;
@@ -406,20 +404,10 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
return FFI_OK; return FFI_OK;
} }
/*@-declundef@*/ extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
/*@-exportheader@*/ unsigned, unsigned, unsigned *, void (*fn)());
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
void ffi_call(/*@dependent@*/ ffi_cif *cif, void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue)
{ {
extended_cif ecif; extended_cif ecif;
UINT64 trvalue; UINT64 trvalue;
@@ -436,9 +424,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
else if ((rvalue == NULL) && else if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT)) (cif->rtype->type == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size); ecif.rvalue = alloca(cif->rtype->size);
/*@=sysunrecog@*/
} }
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
@@ -446,10 +432,8 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi) switch (cif->abi)
{ {
case FFI_SYSV: case FFI_SYSV:
/*@-usedef@*/ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, fn);
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break; break;
default: default:
FFI_ASSERT(0); FFI_ASSERT(0);
@@ -468,10 +452,11 @@ extern void __ic_invalidate (void *line);
#endif #endif
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*), void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data) void *user_data,
void *codeloc)
{ {
unsigned int *tramp; unsigned int *tramp;
unsigned short insn; unsigned short insn;
@@ -491,7 +476,7 @@ ffi_prep_closure (ffi_closure* closure,
tramp[0] = 0xd102d301; tramp[0] = 0xd102d301;
tramp[1] = 0x412b0000 | insn; tramp[1] = 0x412b0000 | insn;
#endif #endif
*(void **) &tramp[2] = (void *)closure; /* ctx */ *(void **) &tramp[2] = (void *)codeloc; /* ctx */
*(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */ *(void **) &tramp[3] = (void *)ffi_closure_SYSV; /* funaddr */
closure->cif = cif; closure->cif = cif;
@@ -500,7 +485,7 @@ ffi_prep_closure (ffi_closure* closure,
#if defined(__SH4__) #if defined(__SH4__)
/* Flush the icache. */ /* Flush the icache. */
__ic_invalidate(&closure->tramp[0]); __ic_invalidate(codeloc);
#endif #endif
return FFI_OK; return FFI_OK;
@@ -535,7 +520,6 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
int freg = 0; int freg = 0;
#endif #endif
ffi_cif *cif; ffi_cif *cif;
double temp;
cif = closure->cif; cif = closure->cif;
avalue = alloca(cif->nargs * sizeof(void *)); avalue = alloca(cif->nargs * sizeof(void *));
@@ -544,7 +528,7 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
returns the data directly to the caller. */ returns the data directly to the caller. */
if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG) if (cif->rtype->type == FFI_TYPE_STRUCT && STRUCT_VALUE_ADDRESS_WITH_ARG)
{ {
rvalue = *pgr++; rvalue = (void *) *pgr++;
ireg = 1; ireg = 1;
} }
else else
@@ -611,6 +595,8 @@ ffi_closure_helper_SYSV (ffi_closure *closure, void *rvalue,
{ {
if (freg + 1 >= NFREGARG) if (freg + 1 >= NFREGARG)
continue; continue;
if (freg & 1)
pfr++;
freg = (freg + 1) & ~1; freg = (freg + 1) & ~1;
freg += 2; freg += 2;
avalue[i] = pfr; avalue[i] = pfr;

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
sysv.S - Copyright (c) 2002, 2003, 2004 Kaz Kojima sysv.S - Copyright (c) 2002, 2003, 2004, 2006 Kaz Kojima
SuperH Foreign Function Interface SuperH Foreign Function Interface
@@ -829,13 +829,13 @@ __FRAME_BEGIN__:
.byte 0x6 /* uleb128 0x6 */ .byte 0x6 /* uleb128 0x6 */
.byte 0x8e /* DW_CFA_offset, column 0xe */ .byte 0x8e /* DW_CFA_offset, column 0xe */
.byte 0x5 /* uleb128 0x5 */ .byte 0x5 /* uleb128 0x5 */
.byte 0x8b /* DW_CFA_offset, column 0xb */ .byte 0x84 /* DW_CFA_offset, column 0x4 */
.byte 0x4 /* uleb128 0x4 */ .byte 0x4 /* uleb128 0x4 */
.byte 0x8a /* DW_CFA_offset, column 0xa */ .byte 0x85 /* DW_CFA_offset, column 0x5 */
.byte 0x3 /* uleb128 0x3 */ .byte 0x3 /* uleb128 0x3 */
.byte 0x89 /* DW_CFA_offset, column 0x9 */ .byte 0x86 /* DW_CFA_offset, column 0x6 */
.byte 0x2 /* uleb128 0x2 */ .byte 0x2 /* uleb128 0x2 */
.byte 0x88 /* DW_CFA_offset, column 0x8 */ .byte 0x87 /* DW_CFA_offset, column 0x7 */
.byte 0x1 /* uleb128 0x1 */ .byte 0x1 /* uleb128 0x1 */
.byte 0x4 /* DW_CFA_advance_loc4 */ .byte 0x4 /* DW_CFA_advance_loc4 */
.4byte .LCFIE-.LCFID .4byte .LCFIE-.LCFID

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1996, 2003, 2004 Red Hat, Inc. ffi.c - Copyright (c) 1996, 2003, 2004, 2007 Red Hat, Inc.
SPARC Foreign Function Interface SPARC Foreign Function Interface
@@ -425,10 +425,11 @@ extern void ffi_closure_v8(void);
#endif #endif
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*), void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data) void *user_data,
void *codeloc)
{ {
unsigned int *tramp = (unsigned int *) &closure->tramp[0]; unsigned int *tramp = (unsigned int *) &closure->tramp[0];
unsigned long fn; unsigned long fn;
@@ -443,7 +444,7 @@ ffi_prep_closure (ffi_closure* closure,
tramp[3] = 0x01000000; /* nop */ tramp[3] = 0x01000000; /* nop */
*((unsigned long *) &tramp[4]) = fn; *((unsigned long *) &tramp[4]) = fn;
#else #else
unsigned long ctx = (unsigned long) closure; unsigned long ctx = (unsigned long) codeloc;
FFI_ASSERT (cif->abi == FFI_V8); FFI_ASSERT (cif->abi == FFI_V8);
fn = (unsigned long) ffi_closure_v8; fn = (unsigned long) ffi_closure_v8;
tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */ tramp[0] = 0x03000000 | fn >> 10; /* sethi %hi(fn), %g1 */

View File

@@ -23,6 +23,10 @@
OTHER DEALINGS IN THE SOFTWARE. OTHER DEALINGS IN THE SOFTWARE.
----------------------------------------------------------------------- */ ----------------------------------------------------------------------- */
/* Hide the basic type definitions from the header file, so that we
can redefine them here as "const". */
#define LIBFFI_HIDE_BASIC_TYPES
#include <ffi.h> #include <ffi.h>
#include <ffi_common.h> #include <ffi_common.h>
@@ -33,14 +37,14 @@ struct struct_align_##name { \
char c; \ char c; \
type x; \ type x; \
}; \ }; \
ffi_type ffi_type_##name = { \ const ffi_type ffi_type_##name = { \
sizeof(type), \ sizeof(type), \
offsetof(struct struct_align_##name, x), \ offsetof(struct struct_align_##name, x), \
id, NULL \ id, NULL \
} }
/* Size and alignment are fake here. They must not be 0. */ /* Size and alignment are fake here. They must not be 0. */
ffi_type ffi_type_void = { const ffi_type ffi_type_void = {
1, 1, FFI_TYPE_VOID, NULL 1, 1, FFI_TYPE_VOID, NULL
}; };
@@ -57,4 +61,16 @@ FFI_TYPEDEF(pointer, void*, FFI_TYPE_POINTER);
FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT); FFI_TYPEDEF(float, float, FFI_TYPE_FLOAT);
FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE); FFI_TYPEDEF(double, double, FFI_TYPE_DOUBLE);
#ifdef __alpha__
/* Even if we're not configured to default to 128-bit long double,
maintain binary compatibility, as -mlong-double-128 can be used
at any time. */
/* Validate the hard-coded number below. */
# if defined(__LONG_DOUBLE_128__) && FFI_TYPE_LONGDOUBLE != 4
# error FFI_TYPE_LONGDOUBLE out of date
# endif
const ffi_type ffi_type_longdouble = { 16, 16, 4, NULL };
#elif FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE); FFI_TYPEDEF(longdouble, long double, FFI_TYPE_LONGDOUBLE);
#endif

View File

@@ -1,5 +1,6 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc. darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005 Red Hat, Inc.
Copyright (C) 2008 Free Software Foundation, Inc.
X86 Foreign Function Interface X86 Foreign Function Interface
@@ -60,16 +61,15 @@ _ffi_call_SYSV:
call *28(%ebp) call *28(%ebp)
/* Remove the space we pushed for the args */
movl 16(%ebp),%ecx
addl %ecx,%esp
/* Load %ecx with the return type code */ /* Load %ecx with the return type code */
movl 20(%ebp),%ecx movl 20(%ebp),%ecx
/* Protect %esi. We're going to pop it in the epilogue. */
pushl %esi
/* If the return value pointer is NULL, assume no return value. */ /* If the return value pointer is NULL, assume no return value. */
cmpl $0,24(%ebp) cmpl $0,24(%ebp)
jne retint jne 0f
/* Even if there is no space for the return value, we are /* Even if there is no space for the return value, we are
obliged to handle floating-point values. */ obliged to handle floating-point values. */
@@ -78,42 +78,68 @@ _ffi_call_SYSV:
fstp %st(0) fstp %st(0)
jmp epilogue jmp epilogue
0:
.align 4
call 1f
.Lstore_table:
.long noretval-.Lstore_table /* FFI_TYPE_VOID */
.long retint-.Lstore_table /* FFI_TYPE_INT */
.long retfloat-.Lstore_table /* FFI_TYPE_FLOAT */
.long retdouble-.Lstore_table /* FFI_TYPE_DOUBLE */
.long retlongdouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */
.long retuint8-.Lstore_table /* FFI_TYPE_UINT8 */
.long retsint8-.Lstore_table /* FFI_TYPE_SINT8 */
.long retuint16-.Lstore_table /* FFI_TYPE_UINT16 */
.long retsint16-.Lstore_table /* FFI_TYPE_SINT16 */
.long retint-.Lstore_table /* FFI_TYPE_UINT32 */
.long retint-.Lstore_table /* FFI_TYPE_SINT32 */
.long retint64-.Lstore_table /* FFI_TYPE_UINT64 */
.long retint64-.Lstore_table /* FFI_TYPE_SINT64 */
.long retstruct-.Lstore_table /* FFI_TYPE_STRUCT */
.long retint-.Lstore_table /* FFI_TYPE_POINTER */
.long retstruct1b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_1B */
.long retstruct2b-.Lstore_table /* FFI_TYPE_SMALL_STRUCT_2B */
1:
pop %esi
add (%esi, %ecx, 4), %esi
jmp *%esi
retint: /* Sign/zero extend as appropriate. */
cmpl $FFI_TYPE_INT,%ecx retsint8:
jne retfloat movsbl %al, %eax
/* Load %ecx with the pointer to storage for the return value */ jmp retint
movl 24(%ebp),%ecx
movl %eax,0(%ecx) retsint16:
jmp epilogue movswl %ax, %eax
jmp retint
retuint8:
movzbl %al, %eax
jmp retint
retuint16:
movzwl %ax, %eax
jmp retint
retfloat: retfloat:
cmpl $FFI_TYPE_FLOAT,%ecx
jne retdouble
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstps (%ecx) fstps (%ecx)
jmp epilogue jmp epilogue
retdouble: retdouble:
cmpl $FFI_TYPE_DOUBLE,%ecx
jne retlongdouble
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstpl (%ecx) fstpl (%ecx)
jmp epilogue jmp epilogue
retlongdouble: retlongdouble:
cmpl $FFI_TYPE_LONGDOUBLE,%ecx
jne retint64
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstpt (%ecx) fstpt (%ecx)
jmp epilogue jmp epilogue
retint64: retint64:
cmpl $FFI_TYPE_SINT64,%ecx
jne retstruct1b
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movl %eax,0(%ecx) movl %eax,0(%ecx)
@@ -121,35 +147,32 @@ retint64:
jmp epilogue jmp epilogue
retstruct1b: retstruct1b:
cmpl $FFI_TYPE_SINT8,%ecx
jne retstruct2b
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movb %al,0(%ecx) movb %al,0(%ecx)
jmp epilogue jmp epilogue
retstruct2b: retstruct2b:
cmpl $FFI_TYPE_SINT16,%ecx
jne retstruct
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movw %ax,0(%ecx) movw %ax,0(%ecx)
jmp epilogue jmp epilogue
retint:
/* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx
movl %eax,0(%ecx)
retstruct: retstruct:
cmpl $FFI_TYPE_STRUCT,%ecx
jne noretval
/* Nothing to do! */ /* Nothing to do! */
addl $4,%esp
popl %ebp
ret
noretval: noretval:
epilogue: epilogue:
addl $8,%esp popl %esi
movl %ebp,%esp movl %ebp,%esp
popl %ebp popl %ebp
ret ret
.LFE1: .LFE1:
.ffi_call_SYSV_end: .ffi_call_SYSV_end:
@@ -177,7 +200,15 @@ _ffi_closure_SYSV:
movl -12(%ebp), %ecx movl -12(%ebp), %ecx
cmpl $FFI_TYPE_INT, %eax cmpl $FFI_TYPE_INT, %eax
je .Lcls_retint je .Lcls_retint
cmpl $FFI_TYPE_FLOAT, %eax
/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */
cmpl $FFI_TYPE_UINT64, %eax
jge 0f
cmpl $FFI_TYPE_UINT8, %eax
jge .Lcls_retint
0: cmpl $FFI_TYPE_FLOAT, %eax
je .Lcls_retfloat je .Lcls_retfloat
cmpl $FFI_TYPE_DOUBLE, %eax cmpl $FFI_TYPE_DOUBLE, %eax
je .Lcls_retdouble je .Lcls_retdouble
@@ -185,10 +216,10 @@ _ffi_closure_SYSV:
je .Lcls_retldouble je .Lcls_retldouble
cmpl $FFI_TYPE_SINT64, %eax cmpl $FFI_TYPE_SINT64, %eax
je .Lcls_retllong je .Lcls_retllong
cmpl $FFI_TYPE_SINT8, %eax cmpl $FFI_TYPE_SMALL_STRUCT_1B, %eax
je .Lcls_retstruct1 je .Lcls_retstruct1b
cmpl $FFI_TYPE_SINT16, %eax cmpl $FFI_TYPE_SMALL_STRUCT_2B, %eax
je .Lcls_retstruct2 je .Lcls_retstruct2b
cmpl $FFI_TYPE_STRUCT, %eax cmpl $FFI_TYPE_STRUCT, %eax
je .Lcls_retstruct je .Lcls_retstruct
.Lcls_epilogue: .Lcls_epilogue:
@@ -211,10 +242,10 @@ _ffi_closure_SYSV:
movl (%ecx), %eax movl (%ecx), %eax
movl 4(%ecx), %edx movl 4(%ecx), %edx
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retstruct1: .Lcls_retstruct1b:
movsbl (%ecx), %eax movsbl (%ecx), %eax
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retstruct2: .Lcls_retstruct2b:
movswl (%ecx), %eax movswl (%ecx), %eax
jmp .Lcls_epilogue jmp .Lcls_epilogue
.Lcls_retstruct: .Lcls_retstruct:
@@ -256,6 +287,14 @@ _ffi_closure_raw_SYSV:
movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
cmpl $FFI_TYPE_INT, %eax cmpl $FFI_TYPE_INT, %eax
je .Lrcls_retint je .Lrcls_retint
/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */
cmpl $FFI_TYPE_UINT64, %eax
jge 0f
cmpl $FFI_TYPE_UINT8, %eax
jge .Lrcls_retint
0:
cmpl $FFI_TYPE_FLOAT, %eax cmpl $FFI_TYPE_FLOAT, %eax
je .Lrcls_retfloat je .Lrcls_retfloat
cmpl $FFI_TYPE_DOUBLE, %eax cmpl $FFI_TYPE_DOUBLE, %eax

View File

@@ -1,8 +1,9 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. ffi.c - Copyright (c) 1996, 1998, 1999, 2001, 2007 Red Hat, Inc.
Copyright (c) 2002 Ranjit Mathew Copyright (c) 2002 Ranjit Mathew
Copyright (c) 2002 Bo Thorsen Copyright (c) 2002 Bo Thorsen
Copyright (c) 2002 Roger Sayle Copyright (c) 2002 Roger Sayle
Copyright (C) 2008 Free Software Foundation, Inc.
x86 Foreign Function Interface x86 Foreign Function Interface
@@ -36,9 +37,7 @@
/* ffi_prep_args is called by the assembly routine once stack space /* ffi_prep_args is called by the assembly routine once stack space
has been allocated for the function's arguments */ has been allocated for the function's arguments */
/*@-exportheader@*/
void ffi_prep_args(char *stack, extended_cif *ecif) void ffi_prep_args(char *stack, extended_cif *ecif)
/*@=exportheader@*/
{ {
register unsigned int i; register unsigned int i;
register void **p_argv; register void **p_argv;
@@ -121,9 +120,16 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
switch (cif->rtype->type) switch (cif->rtype->type)
{ {
case FFI_TYPE_VOID: case FFI_TYPE_VOID:
#ifndef X86_WIN32 #ifdef X86
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
#endif #endif
#if defined(X86) || defined(X86_DARWIN)
case FFI_TYPE_UINT8:
case FFI_TYPE_UINT16:
case FFI_TYPE_SINT8:
case FFI_TYPE_SINT16:
#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:
@@ -135,15 +141,15 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
cif->flags = FFI_TYPE_SINT64; cif->flags = FFI_TYPE_SINT64;
break; break;
#ifdef X86_WIN32 #ifndef X86
case FFI_TYPE_STRUCT: case FFI_TYPE_STRUCT:
if (cif->rtype->size == 1) if (cif->rtype->size == 1)
{ {
cif->flags = FFI_TYPE_SINT8; /* same as char size */ cif->flags = FFI_TYPE_SMALL_STRUCT_1B; /* same as char size */
} }
else if (cif->rtype->size == 2) else if (cif->rtype->size == 2)
{ {
cif->flags = FFI_TYPE_SINT16; /* same as short size */ cif->flags = FFI_TYPE_SMALL_STRUCT_2B; /* same as short size */
} }
else if (cif->rtype->size == 4) else if (cif->rtype->size == 4)
{ {
@@ -165,35 +171,23 @@ ffi_status ffi_prep_cif_machdep(ffi_cif *cif)
break; break;
} }
#ifdef X86_DARWIN
cif->bytes = (cif->bytes + 15) & ~0xF;
#endif
return FFI_OK; return FFI_OK;
} }
/*@-declundef@*/ extern void ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *,
/*@-exportheader@*/ unsigned, unsigned, unsigned *, void (*fn)());
extern void ffi_call_SYSV(void (*)(char *, extended_cif *),
/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
#ifdef X86_WIN32 #ifdef X86_WIN32
/*@-declundef@*/ extern void ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *,
/*@-exportheader@*/ unsigned, unsigned, unsigned *, void (*fn)());
extern void ffi_call_STDCALL(void (*)(char *, extended_cif *),
/*@out@*/ extended_cif *,
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)());
/*@=declundef@*/
/*@=exportheader@*/
#endif /* X86_WIN32 */ #endif /* X86_WIN32 */
void ffi_call(/*@dependent@*/ ffi_cif *cif, void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ void **avalue)
{ {
extended_cif ecif; extended_cif ecif;
@@ -206,9 +200,7 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
if ((rvalue == NULL) && if ((rvalue == NULL) &&
(cif->flags == FFI_TYPE_STRUCT)) (cif->flags == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size); ecif.rvalue = alloca(cif->rtype->size);
/*@=sysunrecog@*/
} }
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
@@ -217,17 +209,13 @@ void ffi_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi) switch (cif->abi)
{ {
case FFI_SYSV: case FFI_SYSV:
/*@-usedef@*/ ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue,
ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, fn);
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break; break;
#ifdef X86_WIN32 #ifdef X86_WIN32
case FFI_STDCALL: case FFI_STDCALL:
/*@-usedef@*/ ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags,
ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, ecif.rvalue, fn);
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break; break;
#endif /* X86_WIN32 */ #endif /* X86_WIN32 */
default: default:
@@ -276,11 +264,9 @@ ffi_closure_SYSV_inner (closure, respp, args)
return cif->flags; return cif->flags;
} }
/*@-exportheader@*/
static void static void
ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue,
void **avalue, ffi_cif *cif) ffi_cif *cif)
/*@=exportheader@*/
{ {
register unsigned int i; register unsigned int i;
register void **p_argv; register void **p_argv;
@@ -324,7 +310,7 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
({ 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 - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \ unsigned int __dis = __fun - (__ctx + FFI_TRAMPOLINE_SIZE); \
*(unsigned char*) &__tramp[0] = 0xb8; \ *(unsigned char*) &__tramp[0] = 0xb8; \
*(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; \
@@ -335,16 +321,17 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue,
/* the cif must already be prep'ed */ /* the cif must already be prep'ed */
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*,void*,void**,void*), void (*fun)(ffi_cif*,void*,void**,void*),
void *user_data) void *user_data,
void *codeloc)
{ {
FFI_ASSERT (cif->abi == FFI_SYSV); FFI_ASSERT (cif->abi == FFI_SYSV);
FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ FFI_INIT_TRAMPOLINE (&closure->tramp[0], \
&ffi_closure_SYSV, \ &ffi_closure_SYSV, \
(void*)closure); codeloc);
closure->cif = cif; closure->cif = cif;
closure->user_data = user_data; closure->user_data = user_data;
@@ -358,10 +345,11 @@ ffi_prep_closure (ffi_closure* closure,
#if !FFI_NO_RAW_API #if !FFI_NO_RAW_API
ffi_status ffi_status
ffi_prep_raw_closure (ffi_raw_closure* closure, ffi_prep_raw_closure_loc (ffi_raw_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*,void*,ffi_raw*,void*), void (*fun)(ffi_cif*,void*,ffi_raw*,void*),
void *user_data) void *user_data,
void *codeloc)
{ {
int i; int i;
@@ -380,7 +368,7 @@ ffi_prep_raw_closure (ffi_raw_closure* closure,
FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV,
(void*)closure); codeloc);
closure->cif = cif; closure->cif = cif;
closure->user_data = user_data; closure->user_data = user_data;
@@ -401,26 +389,17 @@ ffi_prep_args_raw(char *stack, extended_cif *ecif)
*/ */
extern void extern void
ffi_call_SYSV(void (*)(char *, extended_cif *), ffi_call_SYSV(void (*)(char *, extended_cif *), extended_cif *, unsigned,
/*@out@*/ extended_cif *, unsigned, unsigned *, void (*fn)());
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)());
#ifdef X86_WIN32 #ifdef X86_WIN32
extern void extern void
ffi_call_STDCALL(void (*)(char *, extended_cif *), ffi_call_STDCALL(void (*)(char *, extended_cif *), extended_cif *, unsigned,
/*@out@*/ extended_cif *, unsigned, unsigned *, void (*fn)());
unsigned, unsigned,
/*@out@*/ unsigned *,
void (*fn)());
#endif /* X86_WIN32 */ #endif /* X86_WIN32 */
void void
ffi_raw_call(/*@dependent@*/ ffi_cif *cif, ffi_raw_call(ffi_cif *cif, void (*fn)(), void *rvalue, ffi_raw *fake_avalue)
void (*fn)(),
/*@out@*/ void *rvalue,
/*@dependent@*/ ffi_raw *fake_avalue)
{ {
extended_cif ecif; extended_cif ecif;
void **avalue = (void **)fake_avalue; void **avalue = (void **)fake_avalue;
@@ -434,9 +413,7 @@ ffi_raw_call(/*@dependent@*/ ffi_cif *cif,
if ((rvalue == NULL) && if ((rvalue == NULL) &&
(cif->rtype->type == FFI_TYPE_STRUCT)) (cif->rtype->type == FFI_TYPE_STRUCT))
{ {
/*@-sysunrecog@*/
ecif.rvalue = alloca(cif->rtype->size); ecif.rvalue = alloca(cif->rtype->size);
/*@=sysunrecog@*/
} }
else else
ecif.rvalue = rvalue; ecif.rvalue = rvalue;
@@ -445,17 +422,13 @@ ffi_raw_call(/*@dependent@*/ ffi_cif *cif,
switch (cif->abi) switch (cif->abi)
{ {
case FFI_SYSV: case FFI_SYSV:
/*@-usedef@*/ ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, ecif.rvalue, fn);
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break; break;
#ifdef X86_WIN32 #ifdef X86_WIN32
case FFI_STDCALL: case FFI_STDCALL:
/*@-usedef@*/ ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags,
ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, ecif.rvalue, fn);
cif->flags, ecif.rvalue, fn);
/*@=usedef@*/
break; break;
#endif /* X86_WIN32 */ #endif /* X86_WIN32 */
default: default:

View File

@@ -1,5 +1,5 @@
/* ----------------------------------------------------------------------- /* -----------------------------------------------------------------------
ffi.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de> ffi.c - Copyright (c) 2002, 2007 Bo Thorsen <bo@suse.de>
x86-64 Foreign Function Interface x86-64 Foreign Function Interface
@@ -433,10 +433,11 @@ ffi_call (ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue)
extern void ffi_closure_unix64(void); extern void ffi_closure_unix64(void);
ffi_status ffi_status
ffi_prep_closure (ffi_closure* closure, ffi_prep_closure_loc (ffi_closure* closure,
ffi_cif* cif, ffi_cif* cif,
void (*fun)(ffi_cif*, void*, void**, void*), void (*fun)(ffi_cif*, void*, void**, void*),
void *user_data) void *user_data,
void *codeloc)
{ {
volatile unsigned short *tramp; volatile unsigned short *tramp;
@@ -445,7 +446,7 @@ ffi_prep_closure (ffi_closure* closure,
tramp[0] = 0xbb49; /* mov <code>, %r11 */ tramp[0] = 0xbb49; /* mov <code>, %r11 */
*(void * volatile *) &tramp[1] = ffi_closure_unix64; *(void * volatile *) &tramp[1] = ffi_closure_unix64;
tramp[5] = 0xba49; /* mov <data>, %r10 */ tramp[5] = 0xba49; /* mov <data>, %r10 */
*(void * volatile *) &tramp[6] = closure; *(void * volatile *) &tramp[6] = codeloc;
/* Set the carry bit iff the function uses any sse registers. /* Set the carry bit iff the function uses any sse registers.
This is clc or stc, together with the first byte of the jmp. */ This is clc or stc, together with the first byte of the jmp. */

View File

@@ -1,5 +1,7 @@
/* -----------------------------------------------------------------*-C-*- /* -----------------------------------------------------------------*-C-*-
ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc.
Copyright (C) 2008 Free Software Foundation, Inc.
Target configuration macros for x86 and x86-64. Target configuration macros for x86 and x86-64.
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
@@ -68,8 +70,10 @@ typedef enum ffi_abi {
/* ---- Definitions for closures ----------------------------------------- */ /* ---- Definitions for closures ----------------------------------------- */
#define FFI_CLOSURES 1 #define FFI_CLOSURES 1
#define FFI_TYPE_SMALL_STRUCT_1B (FFI_TYPE_LAST + 1)
#define FFI_TYPE_SMALL_STRUCT_2B (FFI_TYPE_LAST + 2)
#ifdef X86_64 #if defined (X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
#define FFI_TRAMPOLINE_SIZE 24 #define FFI_TRAMPOLINE_SIZE 24
#define FFI_NATIVE_RAW_API 0 #define FFI_NATIVE_RAW_API 0
#else #else

View File

@@ -59,16 +59,15 @@ ffi_call_SYSV:
call *28(%ebp) call *28(%ebp)
/* Remove the space we pushed for the args */
movl 16(%ebp),%ecx
addl %ecx,%esp
/* Load %ecx with the return type code */ /* Load %ecx with the return type code */
movl 20(%ebp),%ecx movl 20(%ebp),%ecx
/* Protect %esi. We're going to pop it in the epilogue. */
pushl %esi
/* If the return value pointer is NULL, assume no return value. */ /* If the return value pointer is NULL, assume no return value. */
cmpl $0,24(%ebp) cmpl $0,24(%ebp)
jne retint jne 0f
/* Even if there is no space for the return value, we are /* Even if there is no space for the return value, we are
obliged to handle floating-point values. */ obliged to handle floating-point values. */
@@ -78,51 +77,84 @@ ffi_call_SYSV:
jmp epilogue jmp epilogue
retint: 0:
cmpl $FFI_TYPE_INT,%ecx call 1f
jne retfloat
/* Load %ecx with the pointer to storage for the return value */ .Lstore_table:
movl 24(%ebp),%ecx .long noretval-.Lstore_table /* FFI_TYPE_VOID */
movl %eax,0(%ecx) .long retint-.Lstore_table /* FFI_TYPE_INT */
jmp epilogue .long retfloat-.Lstore_table /* FFI_TYPE_FLOAT */
.long retdouble-.Lstore_table /* FFI_TYPE_DOUBLE */
.long retlongdouble-.Lstore_table /* FFI_TYPE_LONGDOUBLE */
.long retuint8-.Lstore_table /* FFI_TYPE_UINT8 */
.long retsint8-.Lstore_table /* FFI_TYPE_SINT8 */
.long retuint16-.Lstore_table /* FFI_TYPE_UINT16 */
.long retsint16-.Lstore_table /* FFI_TYPE_SINT16 */
.long retint-.Lstore_table /* FFI_TYPE_UINT32 */
.long retint-.Lstore_table /* FFI_TYPE_SINT32 */
.long retint64-.Lstore_table /* FFI_TYPE_UINT64 */
.long retint64-.Lstore_table /* FFI_TYPE_SINT64 */
.long retstruct-.Lstore_table /* FFI_TYPE_STRUCT */
.long retint-.Lstore_table /* FFI_TYPE_POINTER */
1:
pop %esi
add (%esi, %ecx, 4), %esi
jmp *%esi
/* Sign/zero extend as appropriate. */
retsint8:
movsbl %al, %eax
jmp retint
retsint16:
movswl %ax, %eax
jmp retint
retuint8:
movzbl %al, %eax
jmp retint
retuint16:
movzwl %ax, %eax
jmp retint
retfloat: retfloat:
cmpl $FFI_TYPE_FLOAT,%ecx
jne retdouble
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstps (%ecx) fstps (%ecx)
jmp epilogue jmp epilogue
retdouble: retdouble:
cmpl $FFI_TYPE_DOUBLE,%ecx
jne retlongdouble
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstpl (%ecx) fstpl (%ecx)
jmp epilogue jmp epilogue
retlongdouble: retlongdouble:
cmpl $FFI_TYPE_LONGDOUBLE,%ecx
jne retint64
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
fstpt (%ecx) fstpt (%ecx)
jmp epilogue jmp epilogue
retint64: retint64:
cmpl $FFI_TYPE_SINT64,%ecx
jne retstruct
/* Load %ecx with the pointer to storage for the return value */ /* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx movl 24(%ebp),%ecx
movl %eax,0(%ecx) movl %eax,0(%ecx)
movl %edx,4(%ecx) movl %edx,4(%ecx)
jmp epilogue
retint:
/* Load %ecx with the pointer to storage for the return value */
movl 24(%ebp),%ecx
movl %eax,0(%ecx)
retstruct: retstruct:
/* Nothing to do! */ /* Nothing to do! */
noretval: noretval:
epilogue: epilogue:
popl %esi
movl %ebp,%esp movl %ebp,%esp
popl %ebp popl %ebp
ret ret
@@ -162,7 +194,15 @@ ffi_closure_SYSV:
movl -12(%ebp), %ecx movl -12(%ebp), %ecx
cmpl $FFI_TYPE_INT, %eax cmpl $FFI_TYPE_INT, %eax
je .Lcls_retint je .Lcls_retint
cmpl $FFI_TYPE_FLOAT, %eax
/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */
cmpl $FFI_TYPE_UINT64, %eax
jge 0f
cmpl $FFI_TYPE_UINT8, %eax
jge .Lcls_retint
0: cmpl $FFI_TYPE_FLOAT, %eax
je .Lcls_retfloat je .Lcls_retfloat
cmpl $FFI_TYPE_DOUBLE, %eax cmpl $FFI_TYPE_DOUBLE, %eax
je .Lcls_retdouble je .Lcls_retdouble
@@ -226,6 +266,14 @@ ffi_closure_raw_SYSV:
movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */ movl CIF_FLAGS_OFFSET(%esi), %eax /* rtype */
cmpl $FFI_TYPE_INT, %eax cmpl $FFI_TYPE_INT, %eax
je .Lrcls_retint je .Lrcls_retint
/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32. */
cmpl $FFI_TYPE_UINT64, %eax
jge 0f
cmpl $FFI_TYPE_UINT8, %eax
jge .Lrcls_retint
0:
cmpl $FFI_TYPE_FLOAT, %eax cmpl $FFI_TYPE_FLOAT, %eax
je .Lrcls_retfloat je .Lrcls_retfloat
cmpl $FFI_TYPE_DOUBLE, %eax cmpl $FFI_TYPE_DOUBLE, %eax

View File

@@ -120,7 +120,7 @@ proc libffi-init { args } {
if { [is_remote host] == 0 && [which $compiler] != 0 } { if { [is_remote host] == 0 && [which $compiler] != 0 } {
foreach i "[exec $compiler --print-multi-lib]" { foreach i "[exec $compiler --print-multi-lib]" {
set mldir "" set mldir ""
regexp -- "\[a-z0-9=/\.-\]*;" $i mldir regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
set mldir [string trimright $mldir "\;@"] set mldir [string trimright $mldir "\;@"]
if { "$mldir" == "." } { if { "$mldir" == "." } {
continue continue

View File

@@ -1,4 +1,4 @@
# Copyright (C) 2003 Free Software Foundation, Inc. # Copyright (C) 2003, 2006 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -12,7 +12,7 @@
# #
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
# libffi testsuite that uses the 'dg.exp' driver. # libffi testsuite that uses the 'dg.exp' driver.
@@ -23,7 +23,10 @@ libffi-init
global srcdir subdir global srcdir subdir
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" "" dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O0 -W -Wall" ""
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O2" ""
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-O3" ""
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "-Os" ""
dg-finish dg-finish

View File

@@ -6,11 +6,15 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
/* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void static void
closure_test_fn0(ffi_cif* cif,void* resp,void** args, void* userdata) closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{ {
*(ffi_arg*)resp = *(ffi_arg*)resp =
(int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) + (int)*(unsigned long long *)args[0] + (int)(*(int *)args[1]) +
@@ -59,21 +63,21 @@ int main (void)
#endif #endif
cl_arg_types[0] = &ffi_type_uint64; cl_arg_types[0] = &ffi_type_uint64;
cl_arg_types[1] = &ffi_type_uint; cl_arg_types[1] = &ffi_type_sint;
cl_arg_types[2] = &ffi_type_uint64; cl_arg_types[2] = &ffi_type_uint64;
cl_arg_types[3] = &ffi_type_uint; cl_arg_types[3] = &ffi_type_sint;
cl_arg_types[4] = &ffi_type_sshort; cl_arg_types[4] = &ffi_type_sshort;
cl_arg_types[5] = &ffi_type_uint64; cl_arg_types[5] = &ffi_type_uint64;
cl_arg_types[6] = &ffi_type_uint; cl_arg_types[6] = &ffi_type_sint;
cl_arg_types[7] = &ffi_type_uint; cl_arg_types[7] = &ffi_type_sint;
cl_arg_types[8] = &ffi_type_double; cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_uint; cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_uint; cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float; cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_uint; cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_uint; cl_arg_types[13] = &ffi_type_sint;
cl_arg_types[14] = &ffi_type_uint; cl_arg_types[14] = &ffi_type_sint;
cl_arg_types[15] = &ffi_type_uint; cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL; cl_arg_types[16] = NULL;
/* Initialize the cif */ /* Initialize the cif */

View File

@@ -6,11 +6,11 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void closure_test_fn1(ffi_cif* cif,void* resp,void** args, static void closure_test_fn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata) void* userdata)
{ {
*(ffi_arg*)resp = *(ffi_arg*)resp =
@@ -61,15 +61,15 @@ int main (void)
cl_arg_types[4] = &ffi_type_sshort; cl_arg_types[4] = &ffi_type_sshort;
cl_arg_types[5] = &ffi_type_float; cl_arg_types[5] = &ffi_type_float;
cl_arg_types[6] = &ffi_type_float; cl_arg_types[6] = &ffi_type_float;
cl_arg_types[7] = &ffi_type_uint; cl_arg_types[7] = &ffi_type_sint;
cl_arg_types[8] = &ffi_type_double; cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_uint; cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_uint; cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float; cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_uint; cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_uint; cl_arg_types[13] = &ffi_type_sint;
cl_arg_types[14] = &ffi_type_uint; cl_arg_types[14] = &ffi_type_sint;
cl_arg_types[15] = &ffi_type_uint; cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL; cl_arg_types[16] = NULL;
/* Initialize the cif */ /* Initialize the cif */

View File

@@ -6,10 +6,10 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void closure_test_fn2(ffi_cif* cif,void* resp,void** args, static void closure_test_fn2(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata) void* userdata)
{ {
*(ffi_arg*)resp = *(ffi_arg*)resp =
@@ -61,15 +61,15 @@ int main (void)
cl_arg_types[4] = &ffi_type_sshort; cl_arg_types[4] = &ffi_type_sshort;
cl_arg_types[5] = &ffi_type_double; cl_arg_types[5] = &ffi_type_double;
cl_arg_types[6] = &ffi_type_double; cl_arg_types[6] = &ffi_type_double;
cl_arg_types[7] = &ffi_type_uint; cl_arg_types[7] = &ffi_type_sint;
cl_arg_types[8] = &ffi_type_double; cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_uint; cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_uint; cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float; cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_uint; cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_float; cl_arg_types[13] = &ffi_type_float;
cl_arg_types[14] = &ffi_type_uint; cl_arg_types[14] = &ffi_type_sint;
cl_arg_types[15] = &ffi_type_uint; cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL; cl_arg_types[16] = NULL;
/* Initialize the cif */ /* Initialize the cif */

View File

@@ -6,10 +6,10 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void closure_test_fn3(ffi_cif* cif,void* resp,void** args, static void closure_test_fn3(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata) void* userdata)
{ {
*(ffi_arg*)resp = *(ffi_arg*)resp =
@@ -64,13 +64,13 @@ int main (void)
cl_arg_types[6] = &ffi_type_float; cl_arg_types[6] = &ffi_type_float;
cl_arg_types[7] = &ffi_type_float; cl_arg_types[7] = &ffi_type_float;
cl_arg_types[8] = &ffi_type_double; cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_uint; cl_arg_types[9] = &ffi_type_sint;
cl_arg_types[10] = &ffi_type_float; cl_arg_types[10] = &ffi_type_float;
cl_arg_types[11] = &ffi_type_float; cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_uint; cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_float; cl_arg_types[13] = &ffi_type_float;
cl_arg_types[14] = &ffi_type_float; cl_arg_types[14] = &ffi_type_float;
cl_arg_types[15] = &ffi_type_uint; cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL; cl_arg_types[16] = NULL;
/* Initialize the cif */ /* Initialize the cif */

View File

@@ -6,12 +6,13 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20031026 */ Originator: <andreast@gcc.gnu.org> 20031026 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void static void
closure_test_fn0(ffi_cif* cif,void* resp,void** args, void* userdata) closure_test_fn0(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{ {
*(ffi_arg*)resp = *(ffi_arg*)resp =
(int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] + (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
@@ -75,7 +76,7 @@ int main (void)
for (i = 0; i < 15; i++) { for (i = 0; i < 15; i++) {
cl_arg_types[i] = &ffi_type_uint64; cl_arg_types[i] = &ffi_type_uint64;
} }
cl_arg_types[15] = &ffi_type_uint; cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL; cl_arg_types[16] = NULL;
/* Initialize the cif */ /* Initialize the cif */

View File

@@ -6,12 +6,12 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20031026 */ Originator: <andreast@gcc.gnu.org> 20031026 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void static void
closure_test_fn5(ffi_cif* cif,void* resp,void** args, void* userdata) closure_test_fn5(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata)
{ {
*(ffi_arg*)resp = *(ffi_arg*)resp =
(int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] + (int)*(unsigned long long *)args[0] + (int)*(unsigned long long *)args[1] +
@@ -74,11 +74,11 @@ int main (void)
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
cl_arg_types[i] = &ffi_type_uint64; cl_arg_types[i] = &ffi_type_uint64;
} }
cl_arg_types[10] = &ffi_type_uint; cl_arg_types[10] = &ffi_type_sint;
for (i = 11; i < 15; i++) { for (i = 11; i < 15; i++) {
cl_arg_types[i] = &ffi_type_uint64; cl_arg_types[i] = &ffi_type_uint64;
} }
cl_arg_types[15] = &ffi_type_uint; cl_arg_types[15] = &ffi_type_sint;
cl_arg_types[16] = NULL; cl_arg_types[16] = NULL;
/* Initialize the cif */ /* Initialize the cif */

View File

@@ -5,7 +5,7 @@
PR: PR23404 PR: PR23404
Originator: <andreast@gcc.gnu.org> 20050830 */ Originator: <andreast@gcc.gnu.org> 20050830 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void static void
@@ -67,16 +67,16 @@ int main (void)
cl_arg_types[1] = &ffi_type_uint64; cl_arg_types[1] = &ffi_type_uint64;
cl_arg_types[2] = &ffi_type_uint64; cl_arg_types[2] = &ffi_type_uint64;
cl_arg_types[3] = &ffi_type_uint64; cl_arg_types[3] = &ffi_type_uint64;
cl_arg_types[4] = &ffi_type_uint; cl_arg_types[4] = &ffi_type_sint;
cl_arg_types[5] = &ffi_type_double; cl_arg_types[5] = &ffi_type_double;
cl_arg_types[6] = &ffi_type_double; cl_arg_types[6] = &ffi_type_double;
cl_arg_types[7] = &ffi_type_float; cl_arg_types[7] = &ffi_type_float;
cl_arg_types[8] = &ffi_type_double; cl_arg_types[8] = &ffi_type_double;
cl_arg_types[9] = &ffi_type_double; cl_arg_types[9] = &ffi_type_double;
cl_arg_types[10] = &ffi_type_uint; cl_arg_types[10] = &ffi_type_sint;
cl_arg_types[11] = &ffi_type_float; cl_arg_types[11] = &ffi_type_float;
cl_arg_types[12] = &ffi_type_uint; cl_arg_types[12] = &ffi_type_sint;
cl_arg_types[13] = &ffi_type_uint; cl_arg_types[13] = &ffi_type_sint;
cl_arg_types[14] = &ffi_type_double; cl_arg_types[14] = &ffi_type_double;
cl_arg_types[15] = &ffi_type_double; cl_arg_types[15] = &ffi_type_double;
cl_arg_types[16] = NULL; cl_arg_types[16] = NULL;

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_12byte { typedef struct cls_struct_12byte {
@@ -28,7 +28,8 @@ cls_struct_12byte cls_struct_12byte_fn(struct cls_struct_12byte b1,
return result; return result;
} }
static void cls_struct_12byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) static void cls_struct_12byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args , void* userdata __UNUSED__)
{ {
struct cls_struct_12byte b1, b2; struct cls_struct_12byte b1, b2;
@@ -65,9 +66,9 @@ int main (void)
struct cls_struct_12byte j_dbl = { 1, 5, 3 }; struct cls_struct_12byte j_dbl = { 1, 5, 3 };
struct cls_struct_12byte res_dbl; struct cls_struct_12byte res_dbl;
cls_struct_fields[0] = &ffi_type_uint32; cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_uint32; cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = &ffi_type_uint32; cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL; cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[0] = &cls_struct_type;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_16byte { typedef struct cls_struct_16byte {
@@ -29,7 +29,8 @@ cls_struct_16byte cls_struct_16byte_fn(struct cls_struct_16byte b1,
return result; return result;
} }
static void cls_struct_16byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) static void cls_struct_16byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void** args, void* userdata __UNUSED__)
{ {
struct cls_struct_16byte b1, b2; struct cls_struct_16byte b1, b2;
@@ -66,9 +67,9 @@ int main (void)
struct cls_struct_16byte j_dbl = { 1, 9.0, 3 }; struct cls_struct_16byte j_dbl = { 1, 9.0, 3 };
struct cls_struct_16byte res_dbl; struct cls_struct_16byte res_dbl;
cls_struct_fields[0] = &ffi_type_uint32; cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_uint32; cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL; cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[0] = &cls_struct_type;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030915 */ Originator: <andreast@gcc.gnu.org> 20030915 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_18byte { typedef struct cls_struct_18byte {
@@ -33,7 +33,8 @@ cls_struct_18byte cls_struct_18byte_fn(struct cls_struct_18byte a1,
} }
static void static void
cls_struct_18byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_18byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_18byte a1, a2; struct cls_struct_18byte a1, a2;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030915 */ Originator: <andreast@gcc.gnu.org> 20030915 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_19byte { typedef struct cls_struct_19byte {
@@ -36,7 +36,8 @@ cls_struct_19byte cls_struct_19byte_fn(struct cls_struct_19byte a1,
} }
static void static void
cls_struct_19byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_19byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_19byte a1, a2; struct cls_struct_19byte a1, a2;

View File

@@ -6,7 +6,9 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030902 */ Originator: <andreast@gcc.gnu.org> 20030902 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
/* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_1_1byte { typedef struct cls_struct_1_1byte {
@@ -26,7 +28,8 @@ cls_struct_1_1byte cls_struct_1_1byte_fn(struct cls_struct_1_1byte a1,
} }
static void static void
cls_struct_1_1byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_1_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_1_1byte a1, a2; struct cls_struct_1_1byte a1, a2;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_20byte { typedef struct cls_struct_20byte {
@@ -29,7 +29,8 @@ cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
} }
static void static void
cls_struct_20byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_20byte a1, a2; struct cls_struct_20byte a1, a2;
@@ -68,7 +69,7 @@ int main (void)
cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_uint32; cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = NULL; cls_struct_fields[3] = NULL;
dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[0] = &cls_struct_type;

View File

@@ -5,7 +5,9 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
/* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_20byte { typedef struct cls_struct_20byte {
@@ -29,7 +31,8 @@ cls_struct_20byte cls_struct_20byte_fn(struct cls_struct_20byte a1,
} }
static void static void
cls_struct_20byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_20byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_20byte a1, a2; struct cls_struct_20byte a1, a2;
@@ -66,7 +69,7 @@ int main (void)
struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 }; struct cls_struct_20byte f_dbl = { 4, 5.0, 7.0 };
struct cls_struct_20byte res_dbl; struct cls_struct_20byte res_dbl;
cls_struct_fields[0] = &ffi_type_uint32; cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_double; cls_struct_fields[2] = &ffi_type_double;
cls_struct_fields[3] = NULL; cls_struct_fields[3] = NULL;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_24byte { typedef struct cls_struct_24byte {
@@ -38,7 +38,8 @@ cls_struct_24byte cls_struct_24byte_fn(struct cls_struct_24byte b0,
} }
static void static void
cls_struct_24byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_24byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_24byte b0, b1, b2, b3; struct cls_struct_24byte b0, b1, b2, b3;
@@ -81,7 +82,7 @@ int main (void)
cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = &ffi_type_uint32; cls_struct_fields[2] = &ffi_type_sint;
cls_struct_fields[3] = &ffi_type_float; cls_struct_fields[3] = &ffi_type_float;
cls_struct_fields[4] = NULL; cls_struct_fields[4] = NULL;

View File

@@ -6,7 +6,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_2byte { typedef struct cls_struct_2byte {
@@ -28,7 +28,8 @@ cls_struct_2byte cls_struct_2byte_fn(struct cls_struct_2byte a1,
} }
static void static void
cls_struct_2byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_2byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_2byte a1, a2; struct cls_struct_2byte a1, a2;

View File

@@ -6,7 +6,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030902 */ Originator: <andreast@gcc.gnu.org> 20030902 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_3_1byte { typedef struct cls_struct_3_1byte {
@@ -32,7 +32,8 @@ cls_struct_3_1byte cls_struct_3_1byte_fn(struct cls_struct_3_1byte a1,
} }
static void static void
cls_struct_3_1byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_3_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_3_1byte a1, a2; struct cls_struct_3_1byte a1, a2;

View File

@@ -6,7 +6,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_3byte { typedef struct cls_struct_3byte {
@@ -28,7 +28,8 @@ cls_struct_3byte cls_struct_3byte_fn(struct cls_struct_3byte a1,
} }
static void static void
cls_struct_3byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_3byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_3byte a1, a2; struct cls_struct_3byte a1, a2;

View File

@@ -6,7 +6,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_3byte_1 { typedef struct cls_struct_3byte_1 {
@@ -28,7 +28,8 @@ cls_struct_3byte_1 cls_struct_3byte_fn1(struct cls_struct_3byte_1 a1,
} }
static void static void
cls_struct_3byte_gn1(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_3byte_gn1(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_3byte_1 a1, a2; struct cls_struct_3byte_1 a1, a2;

View File

@@ -6,7 +6,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030902 */ Originator: <andreast@gcc.gnu.org> 20030902 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_4_1byte { typedef struct cls_struct_4_1byte {
@@ -34,7 +34,8 @@ cls_struct_4_1byte cls_struct_4_1byte_fn(struct cls_struct_4_1byte a1,
} }
static void static void
cls_struct_4_1byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_4_1byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_4_1byte a1, a2; struct cls_struct_4_1byte a1, a2;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
@@ -28,7 +28,8 @@ cls_struct_4byte cls_struct_4byte_fn(struct cls_struct_4byte a1,
} }
static void static void
cls_struct_4byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_4byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_4byte a1, a2; struct cls_struct_4byte a1, a2;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20050708 */ Originator: <andreast@gcc.gnu.org> 20050708 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_5byte { typedef struct cls_struct_5byte {
@@ -36,7 +36,8 @@ cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
} }
static void static void
cls_struct_5byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_5byte a1, a2; struct cls_struct_5byte a1, a2;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_5byte { typedef struct cls_struct_5byte {
@@ -31,7 +31,8 @@ cls_struct_5byte cls_struct_5byte_fn(struct cls_struct_5byte a1,
} }
static void static void
cls_struct_5byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_5byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_5byte a1, a2; struct cls_struct_5byte a1, a2;

View File

@@ -6,7 +6,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_64byte { typedef struct cls_struct_64byte {
@@ -43,7 +43,8 @@ cls_struct_64byte cls_struct_64byte_fn(struct cls_struct_64byte b0,
} }
static void static void
cls_struct_64byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_64byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_64byte b0, b1, b2, b3; struct cls_struct_64byte b0, b1, b2, b3;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20050708 */ Originator: <andreast@gcc.gnu.org> 20050708 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_6byte { typedef struct cls_struct_6byte {
@@ -38,7 +38,8 @@ cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
} }
static void static void
cls_struct_6byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_6byte a1, a2; struct cls_struct_6byte a1, a2;

View File

@@ -5,7 +5,8 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
/* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_6byte { typedef struct cls_struct_6byte {
@@ -33,7 +34,8 @@ cls_struct_6byte cls_struct_6byte_fn(struct cls_struct_6byte a1,
} }
static void static void
cls_struct_6byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_6byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_6byte a1, a2; struct cls_struct_6byte a1, a2;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20050708 */ Originator: <andreast@gcc.gnu.org> 20050708 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_7byte { typedef struct cls_struct_7byte {
@@ -40,7 +40,8 @@ cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
} }
static void static void
cls_struct_7byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_7byte a1, a2; struct cls_struct_7byte a1, a2;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_7byte { typedef struct cls_struct_7byte {
@@ -33,7 +33,8 @@ cls_struct_7byte cls_struct_7byte_fn(struct cls_struct_7byte a1,
} }
static void static void
cls_struct_7byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_7byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_7byte a1, a2; struct cls_struct_7byte a1, a2;

View File

@@ -5,7 +5,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_8byte { typedef struct cls_struct_8byte {
@@ -27,7 +27,8 @@ cls_struct_8byte cls_struct_8byte_fn(struct cls_struct_8byte a1,
} }
static void static void
cls_struct_8byte_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_8byte_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_8byte a1, a2; struct cls_struct_8byte a1, a2;
@@ -65,7 +66,7 @@ int main (void)
struct cls_struct_8byte f_dbl = { 4, 5.0 }; struct cls_struct_8byte f_dbl = { 4, 5.0 };
struct cls_struct_8byte res_dbl; struct cls_struct_8byte res_dbl;
cls_struct_fields[0] = &ffi_type_uint32; cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_float; cls_struct_fields[1] = &ffi_type_float;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;

View File

@@ -7,7 +7,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030914 */ Originator: <andreast@gcc.gnu.org> 20030914 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_9byte { typedef struct cls_struct_9byte {
@@ -29,8 +29,8 @@ cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
return result; return result;
} }
static void cls_struct_9byte_gn(ffi_cif* cif, void* resp, void** args, static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void* userdata) void** args, void* userdata __UNUSED__)
{ {
struct cls_struct_9byte b1, b2; struct cls_struct_9byte b1, b2;
@@ -67,7 +67,7 @@ int main (void)
struct cls_struct_9byte j_dbl = { 1, 9.0}; struct cls_struct_9byte j_dbl = { 1, 9.0};
struct cls_struct_9byte res_dbl; struct cls_struct_9byte res_dbl;
cls_struct_fields[0] = &ffi_type_uint32; cls_struct_fields[0] = &ffi_type_sint;
cls_struct_fields[1] = &ffi_type_double; cls_struct_fields[1] = &ffi_type_double;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;

View File

@@ -7,7 +7,7 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030914 */ Originator: <andreast@gcc.gnu.org> 20030914 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_9byte { typedef struct cls_struct_9byte {
@@ -29,8 +29,8 @@ cls_struct_9byte cls_struct_9byte_fn(struct cls_struct_9byte b1,
return result; return result;
} }
static void cls_struct_9byte_gn(ffi_cif* cif, void* resp, void** args, static void cls_struct_9byte_gn(ffi_cif* cif __UNUSED__, void* resp,
void* userdata) void** args, void* userdata __UNUSED__)
{ {
struct cls_struct_9byte b1, b2; struct cls_struct_9byte b1, b2;
@@ -68,7 +68,7 @@ int main (void)
struct cls_struct_9byte res_dbl; struct cls_struct_9byte res_dbl;
cls_struct_fields[0] = &ffi_type_double; cls_struct_fields[0] = &ffi_type_double;
cls_struct_fields[1] = &ffi_type_uint32; cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = NULL; cls_struct_fields[2] = NULL;
dbl_arg_types[0] = &cls_struct_type; dbl_arg_types[0] = &cls_struct_type;

View File

@@ -4,7 +4,9 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
/* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -28,7 +30,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
@@ -29,7 +29,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -19,16 +19,19 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
struct cls_struct_align result; struct cls_struct_align result;
result.a = a1.a + a2.a; result.a = a1.a + a2.a;
result.b = (void *)((size_t)a1.b + (size_t)a2.b); result.b = (void *)((unsigned long)a1.b + (unsigned long)a2.b);
result.c = a1.c + a2.c; result.c = a1.c + a2.c;
printf("%d %d %d %d %d %d: %d %d %d\n", a1.a, (size_t)a1.b, a1.c, a2.a, (size_t)a2.b, a2.c, result.a, (size_t)result.b, result.c); printf("%d %lu %d %d %lu %d: %d %lu %d\n", a1.a, (unsigned long)a1.b, a1.c,
a2.a, (unsigned long)a2.b, a2.c, result.a, (unsigned long)result.b,
result.c);
return result; return result;
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;
@@ -84,14 +87,14 @@ int main (void)
ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl); ffi_call(&cif, FFI_FN(cls_struct_align_fn), &res_dbl, args_dbl);
/* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */ /* { dg-output "12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, (size_t)res_dbl.b, res_dbl.c); printf("res: %d %lu %d\n", res_dbl.a, (unsigned long)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */ /* { dg-output "\nres: 13 14271 140" } */
CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, cls_struct_align_gn, NULL) == FFI_OK);
res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl); res_dbl = ((cls_struct_align(*)(cls_struct_align, cls_struct_align))(pcl))(g_dbl, f_dbl);
/* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */ /* { dg-output "\n12 4951 127 1 9320 13: 13 14271 140" } */
printf("res: %d %d %d\n", res_dbl.a, (size_t)res_dbl.b, res_dbl.c); printf("res: %d %lu %d\n", res_dbl.a, (unsigned long)res_dbl.b, res_dbl.c);
/* { dg-output "\nres: 13 14271 140" } */ /* { dg-output "\nres: 13 14271 140" } */
exit(0); exit(0);

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;
@@ -67,7 +68,7 @@ int main (void)
struct cls_struct_align res_dbl; struct cls_struct_align res_dbl;
cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_sint16; cls_struct_fields[1] = &ffi_type_sshort;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL; cls_struct_fields[3] = NULL;

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;
@@ -67,7 +68,7 @@ int main (void)
struct cls_struct_align res_dbl; struct cls_struct_align res_dbl;
cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_sint32; cls_struct_fields[1] = &ffi_type_sint;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL; cls_struct_fields[3] = NULL;

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;
@@ -67,7 +68,7 @@ int main (void)
struct cls_struct_align res_dbl; struct cls_struct_align res_dbl;
cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uint16; cls_struct_fields[1] = &ffi_type_ushort;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL; cls_struct_fields[3] = NULL;

View File

@@ -4,7 +4,7 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -28,7 +28,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;
@@ -67,7 +68,7 @@ int main (void)
struct cls_struct_align res_dbl; struct cls_struct_align res_dbl;
cls_struct_fields[0] = &ffi_type_uchar; cls_struct_fields[0] = &ffi_type_uchar;
cls_struct_fields[1] = &ffi_type_uint32; cls_struct_fields[1] = &ffi_type_uint;
cls_struct_fields[2] = &ffi_type_uchar; cls_struct_fields[2] = &ffi_type_uchar;
cls_struct_fields[3] = NULL; cls_struct_fields[3] = NULL;

View File

@@ -4,7 +4,8 @@
PR: none. PR: none.
Originator: <hos@tamanegi.org> 20031203 */ Originator: <hos@tamanegi.org> 20031203 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */
/* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
typedef struct cls_struct_align { typedef struct cls_struct_align {
@@ -28,7 +29,8 @@ cls_struct_align cls_struct_align_fn(struct cls_struct_align a1,
} }
static void static void
cls_struct_align_gn(ffi_cif* cif, void* resp, void** args, void* userdata) cls_struct_align_gn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata __UNUSED__)
{ {
struct cls_struct_align a1, a2; struct cls_struct_align a1, a2;

View File

@@ -4,11 +4,11 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void cls_ret_double_fn(ffi_cif* cif,void* resp,void** args, static void cls_ret_double_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata) void* userdata __UNUSED__)
{ {
*(double *)resp = *(double *)args[0]; *(double *)resp = *(double *)args[0];

View File

@@ -4,11 +4,11 @@
PR: none. PR: none.
Originator: <andreast@gcc.gnu.org> 20030828 */ Originator: <andreast@gcc.gnu.org> 20030828 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
static void cls_ret_float_fn(ffi_cif* cif,void* resp,void** args, static void cls_ret_float_fn(ffi_cif* cif __UNUSED__, void* resp, void** args,
void* userdata) void* userdata __UNUSED__)
{ {
*(float *)resp = *(float *)args[0]; *(float *)resp = *(float *)args[0];

View File

@@ -4,7 +4,7 @@
PR: PR13221. PR: PR13221.
Originator: <hos@tamanegi.org> 20031129 */ Originator: <hos@tamanegi.org> 20031129 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
signed char test_func_fn(signed char a1, signed char a2) signed char test_func_fn(signed char a1, signed char a2)
@@ -19,7 +19,8 @@ signed char test_func_fn(signed char a1, signed char a2)
} }
static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{ {
signed char a1, a2; signed char a1, a2;
@@ -67,7 +68,7 @@ int main (void)
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "2 125: 127" } */ /* { dg-output "2 125: 127" } */
printf("res: %d\n", res_call); printf("res: %d\n", (signed char)res_call);
/* { dg-output "\nres: 127" } */ /* { dg-output "\nres: 127" } */
CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);

View File

@@ -4,7 +4,7 @@
PR: PR13221. PR: PR13221.
Originator: <andreast@gcc.gnu.org> 20031129 */ Originator: <andreast@gcc.gnu.org> 20031129 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
signed short test_func_fn(signed short a1, signed short a2) signed short test_func_fn(signed short a1, signed short a2)
@@ -19,7 +19,8 @@ signed short test_func_fn(signed short a1, signed short a2)
} }
static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{ {
signed short a1, a2; signed short a1, a2;
@@ -67,7 +68,7 @@ int main (void)
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "2 32765: 32767" } */ /* { dg-output "2 32765: 32767" } */
printf("res: %d\n", res_call); printf("res: %d\n", (unsigned short)res_call);
/* { dg-output "\nres: 32767" } */ /* { dg-output "\nres: 32767" } */
CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);

View File

@@ -4,7 +4,7 @@
PR: PR13221. PR: PR13221.
Originator: <andreast@gcc.gnu.org> 20031129 */ Originator: <andreast@gcc.gnu.org> 20031129 */
/* { dg-do run { xfail mips64*-*-* arm*-*-* strongarm*-*-* xscale*-*-* } } */ /* { dg-do run } */
#include "ffitest.h" #include "ffitest.h"
signed short test_func_fn(signed char a1, signed short a2, signed short test_func_fn(signed char a1, signed short a2,
@@ -20,7 +20,8 @@ signed short test_func_fn(signed char a1, signed short a2,
} }
static void test_func_gn(ffi_cif *cif, void *rval, void **avals, void *data) static void test_func_gn(ffi_cif *cif __UNUSED__, void *rval, void **avals,
void *data __UNUSED__)
{ {
signed char a1, a3; signed char a1, a3;
signed short a2, a4; signed short a2, a4;
@@ -79,7 +80,7 @@ int main (void)
ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl); ffi_call(&cif, FFI_FN(test_func_fn), &res_call, args_dbl);
/* { dg-output "1 32765 127 -128: 32765" } */ /* { dg-output "1 32765 127 -128: 32765" } */
printf("res: %d\n", res_call); printf("res: %d\n", (signed short)res_call);
/* { dg-output "\nres: 32765" } */ /* { dg-output "\nres: 32765" } */
CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK); CHECK(ffi_prep_closure(pcl, &cif, test_func_gn, NULL) == FFI_OK);

Some files were not shown because too many files have changed in this diff Show More