From: green Date: Sun, 22 Apr 2001 18:22:43 +0000 (+0000) Subject: All these files live somewhere else now. X-Git-Tag: v3.0.9~26^2~110 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7247436b5fe71767b29dc02b4da0fe18b08082e6;p=platform%2Fupstream%2Flibffi.git All these files live somewhere else now. --- diff --git a/libffi/src/Makefile.am b/libffi/src/Makefile.am deleted file mode 100644 index d791042..0000000 --- a/libffi/src/Makefile.am +++ /dev/null @@ -1,101 +0,0 @@ -## Process this with automake to create Makefile.in - -AUTOMAKE_OPTIONS = foreign - -SUFFIXES = .c .lo .o .s .S - -.deps/%.P: $(srcdir)/%.s - @echo "Computing dependencies for $<..." - @o='o'; \ - test -n "$o" && o='$$o'; \ - $(MKDEP) $< | sed "s,^\(.*\)\.o:,\1.$$o \1.l$$o $@:," > $@ - -.deps/%.P: $(srcdir)/%.S - @echo "Computing dependencies for $<..." - @o='o'; \ - test -n "$o" && o='$$o'; \ - $(MKDEP) $< | sed "s,^\(.*\)\.o:,\1.$$o \1.l$$o $@:," > $@ - -lib_LTLIBRARIES = libffi.la -noinst_PROGRAMS = ffitest - -TARGET_SRC_MIPS_GCC = mips/ffi.c mips/o32.S mips/n32.S -TARGET_SRC_MIPS_SGI = mips/ffi.c mips/o32.s mips/n32.s -TARGET_SRC_X86 = x86/ffi.c x86/sysv.S -TARGET_SRC_SPARC = sparc/ffi.c sparc/v8.S -TARGET_SRC_ALPHA = alpha/ffi.c alpha/osf.S -TARGET_SRC_M68K = m68k/ffi.c m68k/sysv.S -TARGET_SRC_POWERPC = powerpc/ffi.c powerpc/sysv.S -TARGET_SRC_ARM = arm/sysv.S arm/ffi.c -TARGET_SRC_S390 = s390/sysv.S s390/ffi.c - -##libffi_la_SOURCES = debug.c prep_cif.c types.c $(TARGET_SRC_@TARGET@) -## Work around automake deficiency -libffi_la_common_SOURCES = debug.c prep_cif.c types.c -if MIPS_GCC -libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC) -endif -if MIPS_SGI -libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI) -endif -if X86 -libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_X86) -endif -if SPARC -libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_SPARC) -endif -if ALPHA -libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_ALPHA) -endif -if M68K -libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_M68K) -endif -if POWERPC -libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC) -endif -if ARM -libffi_la_SOURCES = $(libffi_la_common_SOURCES) $(TARGET_SRC_ARM) -endif - -libffi_la_LDFLAGS = -version-info 2:3:1 -ffitest_SOURCES = ffitest.c -ffitest_LDADD = libffi.la - -EXTRA_DIST = mips/ffi.c mips/n32.S mips/n32.s mips/o32.S mips/o32.s \ -sparc/ffi.c sparc/v8.S \ -x86/ffi.c x86/sysv.S \ -alpha/ffi.c alpha/osf.S \ -m68k/ffi.c m68k/sysv.S \ -powerpc/ffi.c powerpc/sysv.S powerpc/asm.h \ -arm/ffi.c arm/sysv.S - -VPATH = @srcdir@:@srcdir@/@TARGETDIR@ - -if MIPS_SGI - -%.o: %.s - $(COMPILE) -c $< - -# This rule should only be used for compiling with the SGI assembler. -%.lo: %.s - $(LTCOMPILE) -c $< - -else - -# This is the general rule. -%.o: %.S - $(COMPILE) -c $< - -# This is the general rule. -%.lo: %.S - $(LTCOMPILE) -c $< - -endif - -INCLUDES = -I$(top_srcdir)/include -I../include - -test: ffitest - ./ffitest - -lint: - $(LINT) $(INCLUDES) $(srcdir)/*.c $(srcdir)/@TARGETDIR@/*.c diff --git a/libffi/src/Makefile.in b/libffi/src/Makefile.in deleted file mode 100644 index dc187a3..0000000 --- a/libffi/src/Makefile.in +++ /dev/null @@ -1,428 +0,0 @@ -# Makefile.in generated automatically by automake 1.4a from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_FLAG = -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ -AMTAR = @AMTAR@ -AMTARFLAGS = @AMTARFLAGS@ -AS = @AS@ -CC = @CC@ -DLLTOOL = @DLLTOOL@ -EXEEXT = @EXEEXT@ -LD = @LD@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -NM = @NM@ -PACKAGE = @PACKAGE@ -RANLIB = @RANLIB@ -SHELL = @SHELL@ -TARGET = @TARGET@ -TARGETDIR = @TARGETDIR@ -USE_SYMBOL_UNDERSCORE = @USE_SYMBOL_UNDERSCORE@ -VERSION = @VERSION@ - - -AUTOMAKE_OPTIONS = foreign - -SUFFIXES = .c .lo .o .s .S - -lib_LTLIBRARIES = libffi.la -noinst_PROGRAMS = ffitest - -TARGET_SRC_MIPS_GCC = mips/ffi.c mips/o32.S mips/n32.S -TARGET_SRC_MIPS_SGI = mips/ffi.c mips/o32.s mips/n32.s -TARGET_SRC_X86 = x86/ffi.c x86/sysv.S -TARGET_SRC_SPARC = sparc/ffi.c sparc/v8.S -TARGET_SRC_ALPHA = alpha/ffi.c alpha/osf.S -TARGET_SRC_M68K = m68k/ffi.c m68k/sysv.S -TARGET_SRC_POWERPC = powerpc/ffi.c powerpc/sysv.S -TARGET_SRC_ARM = arm/sysv.S arm/ffi.c - -libffi_la_common_SOURCES = debug.c prep_cif.c types.c -@MIPS_GCC_TRUE@libffi_la_SOURCES = @MIPS_GCC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_GCC) -@MIPS_SGI_TRUE@libffi_la_SOURCES = @MIPS_SGI_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_MIPS_SGI) -@X86_TRUE@libffi_la_SOURCES = @X86_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_X86) -@SPARC_TRUE@libffi_la_SOURCES = @SPARC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_SPARC) -@ALPHA_TRUE@libffi_la_SOURCES = @ALPHA_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ALPHA) -@M68K_TRUE@libffi_la_SOURCES = @M68K_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_M68K) -@POWERPC_TRUE@libffi_la_SOURCES = @POWERPC_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_POWERPC) -@ARM_TRUE@libffi_la_SOURCES = @ARM_TRUE@$(libffi_la_common_SOURCES) $(TARGET_SRC_ARM) - -libffi_la_LDFLAGS = -version-info 2:3:1 -ffitest_SOURCES = ffitest.c -ffitest_LDADD = libffi.la - -EXTRA_DIST = mips/ffi.c mips/n32.S mips/n32.s mips/o32.S mips/o32.s \ -sparc/ffi.c sparc/v8.S \ -x86/ffi.c x86/sysv.S \ -alpha/ffi.c alpha/osf.S \ -m68k/ffi.c m68k/sysv.S \ -powerpc/ffi.c powerpc/sysv.S powerpc/asm.h \ -arm/ffi.c arm/sysv.S - - -VPATH = @srcdir@:@srcdir@/@TARGETDIR@ - -INCLUDES = -I$(top_srcdir)/include -I../include -subdir = src -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = ../fficonfig.h -CONFIG_CLEAN_FILES = -LTLIBRARIES = $(lib_LTLIBRARIES) - - -DEFS = @DEFS@ -I. -I$(srcdir) -I.. -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -libffi_la_LIBADD = -@ALPHA_TRUE@am_libffi_la_OBJECTS = debug.lo prep_cif.lo types.lo ffi.lo \ -@ALPHA_TRUE@osf.lo -@ARM_TRUE@am_libffi_la_OBJECTS = debug.lo prep_cif.lo types.lo sysv.lo \ -@ARM_TRUE@ffi.lo -@M68K_TRUE@am_libffi_la_OBJECTS = debug.lo prep_cif.lo types.lo ffi.lo \ -@M68K_TRUE@sysv.lo -@MIPS_GCC_TRUE@am_libffi_la_OBJECTS = debug.lo prep_cif.lo types.lo \ -@MIPS_GCC_TRUE@ffi.lo o32.lo n32.lo -@MIPS_SGI_TRUE@am_libffi_la_OBJECTS = debug.lo prep_cif.lo types.lo \ -@MIPS_SGI_TRUE@ffi.lo o32.lo n32.lo -@POWERPC_TRUE@am_libffi_la_OBJECTS = debug.lo prep_cif.lo types.lo \ -@POWERPC_TRUE@ffi.lo sysv.lo -@SPARC_TRUE@am_libffi_la_OBJECTS = debug.lo prep_cif.lo types.lo ffi.lo \ -@SPARC_TRUE@v8.lo -@X86_TRUE@am_libffi_la_OBJECTS = debug.lo prep_cif.lo types.lo ffi.lo \ -@X86_TRUE@sysv.lo -libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) -noinst_PROGRAMS = ffitest$(EXEEXT) -PROGRAMS = $(noinst_PROGRAMS) - -am_ffitest_OBJECTS = ffitest.o -ffitest_OBJECTS = $(am_ffitest_OBJECTS) -ffitest_DEPENDENCIES = libffi.la -ffitest_LDFLAGS = -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CFLAGS = @CFLAGS@ -CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -DIST_SOURCES = $(libffi_la_SOURCES) $(ffitest_SOURCES) -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) - -GZIP_ENV = --best -SOURCES = $(libffi_la_SOURCES) $(ffitest_SOURCES) -OBJECTS = $(am_libffi_la_OBJECTS) $(am_ffitest_OBJECTS) - -all: all-redirect -.SUFFIXES: -.SUFFIXES: .S .c .lo .o .s -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --cygnus src/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -mostlyclean-libLTLIBRARIES: - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - -distclean-libLTLIBRARIES: - -maintainer-clean-libLTLIBRARIES: - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(libdir) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ - $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ - else :; fi; \ - done - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \ - $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ - done - -mostlyclean-compile: - -rm -f *.o core *.core - -clean-compile: - -distclean-compile: - -rm -f *.tab.c - -maintainer-clean-compile: - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -maintainer-clean-libtool: -ffi.lo: alpha/ffi.c -osf.lo: alpha/osf.S -sysv.lo: arm/sysv.S -o32.lo: mips/o32.S -n32.lo: mips/n32.S -v8.lo: sparc/v8.S - -libffi.la: $(libffi_la_OBJECTS) $(libffi_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libffi_la_LDFLAGS) $(libffi_la_OBJECTS) $(libffi_la_LIBADD) $(LIBS) - -mostlyclean-noinstPROGRAMS: - -clean-noinstPROGRAMS: - -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) - -distclean-noinstPROGRAMS: - -maintainer-clean-noinstPROGRAMS: - -ffitest$(EXEEXT): $(ffitest_OBJECTS) $(ffitest_DEPENDENCIES) - @rm -f ffitest$(EXEEXT) - $(LINK) $(ffitest_LDFLAGS) $(ffitest_OBJECTS) $(ffitest_LDADD) $(LIBS) -.S.o: - $(COMPILE) -c $< -.S.lo: - $(LTCOMPILE) -c -o $@ $< -.c.o: - $(COMPILE) -c $< -.c.lo: - $(LTCOMPILE) -c -o $@ $< -.s.o: - $(COMPILE) -c $< -.s.lo: - $(LTCOMPILE) -c -o $@ $< - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -distdir: $(DISTFILES) - $(mkinstalldirs) $(distdir)/alpha $(distdir)/arm $(distdir)/m68k \ - $(distdir)/mips $(distdir)/powerpc $(distdir)/sparc \ - $(distdir)/x86 - @for file in $(DISTFILES); do \ - if test -f $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: -check: check-am -installcheck-am: -installcheck: installcheck-am -install-info-am: -install-info: install-info-am -install-exec-am: install-libLTLIBRARIES -install-exec: install-exec-am - -install-data-am: -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-libLTLIBRARIES -uninstall: uninstall-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(libdir) - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ - mostlyclean-libtool mostlyclean-noinstPROGRAMS \ - mostlyclean-tags mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \ - clean-noinstPROGRAMS clean-tags clean-generic \ - mostlyclean-am - -clean: clean-am - -distclean-am: distclean-libLTLIBRARIES distclean-compile \ - distclean-libtool distclean-noinstPROGRAMS \ - distclean-tags distclean-generic clean-am - -rm -f libtool - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ - maintainer-clean-compile maintainer-clean-libtool \ - maintainer-clean-noinstPROGRAMS maintainer-clean-tags \ - maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ -clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ -uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ -distclean-compile clean-compile maintainer-clean-compile \ -mostlyclean-libtool distclean-libtool clean-libtool \ -maintainer-clean-libtool mostlyclean-noinstPROGRAMS \ -distclean-noinstPROGRAMS clean-noinstPROGRAMS \ -maintainer-clean-noinstPROGRAMS tags mostlyclean-tags distclean-tags \ -clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ -check-am installcheck-am installcheck install-info-am install-info \ -install-exec-am install-exec install-data-am install-data install-am \ -install uninstall-am uninstall all-redirect all-am all install-strip \ -installdirs mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -.deps/%.P: $(srcdir)/%.s - @echo "Computing dependencies for $<..." - @o='o'; \ - test -n "$o" && o='$$o'; \ - $(MKDEP) $< | sed "s,^\(.*\)\.o:,\1.$$o \1.l$$o $@:," > $@ - -.deps/%.P: $(srcdir)/%.S - @echo "Computing dependencies for $<..." - @o='o'; \ - test -n "$o" && o='$$o'; \ - $(MKDEP) $< | sed "s,^\(.*\)\.o:,\1.$$o \1.l$$o $@:," > $@ - -@MIPS_SGI_TRUE@%.o: %.s -@MIPS_SGI_TRUE@ $(COMPILE) -c $< - -# This rule should only be used for compiling with the SGI assembler. -@MIPS_SGI_TRUE@%.lo: %.s -@MIPS_SGI_TRUE@ $(LTCOMPILE) -c $< - -# This is the general rule. -@MIPS_SGI_FALSE@%.o: %.S -@MIPS_SGI_FALSE@ $(COMPILE) -c $< - -# This is the general rule. -@MIPS_SGI_FALSE@%.lo: %.S -@MIPS_SGI_FALSE@ $(LTCOMPILE) -c $< - -test: ffitest - ./ffitest - -lint: - $(LINT) $(INCLUDES) $(srcdir)/*.c $(srcdir)/@TARGETDIR@/*.c - -# 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. -.NOEXPORT: diff --git a/libffi/src/alpha/ffi.c b/libffi/src/alpha/ffi.c deleted file mode 100644 index a0becb3..0000000 --- a/libffi/src/alpha/ffi.c +++ /dev/null @@ -1,247 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Cygnus Solutions - - Alpha Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -extern void ffi_call_osf(void *, unsigned long, unsigned, void *, void (*)()); -extern void ffi_closure_osf(void); - - -ffi_status -ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Adjust cif->bytes to represent a minimum 6 words for the temporary - register argument loading area. */ - if (cif->bytes < 6*SIZEOF_ARG) - cif->bytes = 6*SIZEOF_ARG; - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_STRUCT: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags = cif->rtype->type; - break; - - default: - cif->flags = FFI_TYPE_INT; - break; - } - - return FFI_OK; -} - -void -ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) -{ - unsigned long *stack, *argp; - long i, avn; - ffi_type **arg_types; - - FFI_ASSERT (cif->abi == FFI_OSF); - - /* If the return value is a struct and we don't have a return - value address then we need to make one. */ - if (rvalue == NULL && cif->flags == FFI_TYPE_STRUCT) - rvalue = alloca(cif->rtype->size); - - /* Allocate the space for the arguments, plus 4 words of temp - space for ffi_call_osf. */ - argp = stack = alloca(cif->bytes + 4*SIZEOF_ARG); - - if (cif->flags == FFI_TYPE_STRUCT) - *(void **) argp++ = rvalue; - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - while (i < avn) - { - switch ((*arg_types)->type) - { - case FFI_TYPE_SINT8: - *(SINT64 *) argp = *(SINT8 *)(* avalue); - break; - - case FFI_TYPE_UINT8: - *(SINT64 *) argp = *(UINT8 *)(* avalue); - break; - - case FFI_TYPE_SINT16: - *(SINT64 *) argp = *(SINT16 *)(* avalue); - break; - - case FFI_TYPE_UINT16: - *(SINT64 *) argp = *(UINT16 *)(* avalue); - break; - - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - /* Note that unsigned 32-bit quantities are sign extended. */ - *(SINT64 *) argp = *(SINT32 *)(* avalue); - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - *(UINT64 *) argp = *(UINT64 *)(* avalue); - break; - - case FFI_TYPE_FLOAT: - if (argp - stack < 6) - { - /* Note the conversion -- all the fp regs are loaded as - doubles. The in-register format is the same. */ - *(double *) argp = *(float *)(* avalue); - } - else - *(float *) argp = *(float *)(* avalue); - break; - - case FFI_TYPE_DOUBLE: - *(double *) argp = *(double *)(* avalue); - break; - - case FFI_TYPE_STRUCT: - memcpy(argp, *avalue, (*arg_types)->size); - break; - - default: - FFI_ASSERT(0); - } - - argp += ALIGN((*arg_types)->size, SIZEOF_ARG) / SIZEOF_ARG; - i++, arg_types++, avalue++; - } - - ffi_call_osf(stack, cif->bytes, cif->flags, rvalue, fn); -} - - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) -{ - unsigned int *tramp; - - FFI_ASSERT (cif->abi == FFI_OSF); - - tramp = (unsigned int *) &closure->tramp[0]; - tramp[0] = 0x47fb0401; /* mov $27,$1 */ - tramp[1] = 0xa77b0010; /* ldq $27,16($27) */ - tramp[2] = 0x6bfb0000; /* jmp $31,($27),0 */ - tramp[3] = 0x47ff041f; /* nop */ - *(void **) &tramp[4] = ffi_closure_osf; - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - /* Flush the Icache. */ - asm volatile ("imb" : : : "memory"); - - return FFI_OK; -} - -int -ffi_closure_osf_inner(ffi_closure *closure, void *rvalue, unsigned long *argp) -{ - ffi_cif *cif; - void **avalue; - ffi_type **arg_types; - long i, avn, argn; - - cif = closure->cif; - avalue = alloca(cif->nargs * sizeof(void *)); - - argn = 0; - - /* Copy the caller's structure return address to that the closure - returns the data directly to the caller. */ - if (cif->flags == FFI_TYPE_STRUCT) - { - rvalue = (void *) argp[0]; - argn = 1; - } - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - /* Grab the addresses of the arguments from the stack frame. */ - while (i < avn) - { - switch (arg_types[i]->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - case FFI_TYPE_STRUCT: - avalue[i] = &argp[argn]; - break; - - case FFI_TYPE_FLOAT: - if (argn < 6) - { - /* Floats coming from registers need conversion from double - back to float format. */ - *(float *)&argp[argn - 6] = *(double *)&argp[argn - 6]; - avalue[i] = &argp[argn - 6]; - } - else - avalue[i] = &argp[argn]; - break; - - case FFI_TYPE_DOUBLE: - avalue[i] = &argp[argn - (argn < 6 ? 6 : 0)]; - break; - - default: - FFI_ASSERT(0); - } - - argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG; - i++; - } - - /* Invoke the closure. */ - (closure->fun) (cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_osf how to perform return type promotions. */ - return cif->rtype->type; -} diff --git a/libffi/src/alpha/osf.S b/libffi/src/alpha/osf.S deleted file mode 100644 index b3dc477..0000000 --- a/libffi/src/alpha/osf.S +++ /dev/null @@ -1,277 +0,0 @@ -/* ----------------------------------------------------------------------- - osf.S - Copyright (c) 1998 Cygnus Solutions - - Alpha/OSF Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include - - .arch ev6 - .text - -/* ffi_call_osf (void *args, unsigned long bytes, unsigned flags, - void *raddr, void (*fnaddr)()); - - Bit o trickiness here -- ARGS+BYTES is the base of the stack frame - for this function. This has been allocated by ffi_call. We also - deallocate some of the stack that has been alloca'd. */ - - .align 3 - .globl ffi_call_osf - .ent ffi_call_osf -ffi_call_osf: - .frame $15, 32, $26, 0 - .mask 0x4008000, -32 - addq $16,$17,$1 - mov $16, $30 - stq $26, 0($1) - stq $15, 8($1) - stq $18, 16($1) - mov $1, $15 - .prologue 0 - - stq $19, 24($1) - mov $20, $27 - - # Load up all of the (potential) argument registers. - ldq $16, 0($30) - ldt $f16, 0($30) - ldt $f17, 8($30) - ldq $17, 8($30) - ldt $f18, 16($30) - ldq $18, 16($30) - ldt $f19, 24($30) - ldq $19, 24($30) - ldt $f20, 32($30) - ldq $20, 32($30) - ldt $f21, 40($30) - ldq $21, 40($30) - - # Deallocate the register argument area. - lda $30, 48($30) - - jsr $26, ($27), 0 - ldgp $29, 0($26) - - # If the return value pointer is NULL, assume no return value. - ldq $19, 24($15) - ldq $18, 16($15) - ldq $26, 0($15) - beq $19, $noretval - - # Store the return value out in the proper type. - cmpeq $18, FFI_TYPE_INT, $1 - bne $1, $retint - cmpeq $18, FFI_TYPE_FLOAT, $2 - bne $2, $retfloat - cmpeq $18, FFI_TYPE_DOUBLE, $3 - bne $3, $retdouble - -$noretval: - ldq $15, 8($15) - ret - -$retint: - stq $0, 0($19) - nop - ldq $15, 8($15) - ret - -$retfloat: - sts $f0, 0($19) - nop - ldq $15, 8($15) - ret - -$retdouble: - stt $f0, 0($19) - nop - ldq $15, 8($15) - ret - - .end ffi_call_osf - -/* ffi_closure_osf(...) - - Receives the closure argument in $1. */ - - .align 3 - .globl ffi_closure_osf - .ent ffi_closure_osf -ffi_closure_osf: - .frame $30, 16*8, $26, 0 - .mask 0x4000000, -16*8 - ldgp $29, 0($27) - subq $30, 16*8, $30 - stq $26, 0($30) - .prologue 1 - - # Store all of the potential argument registers in va_list format. - stt $f16, 4*8($30) - stt $f17, 5*8($30) - stt $f18, 6*8($30) - stt $f19, 7*8($30) - stt $f20, 8*8($30) - stt $f21, 9*8($30) - stq $16, 10*8($30) - stq $17, 11*8($30) - stq $18, 12*8($30) - stq $19, 13*8($30) - stq $20, 14*8($30) - stq $21, 15*8($30) - - # Call ffi_closure_osf_inner to do the bulk of the work. - mov $1, $16 - lda $17, 2*8($30) - lda $18, 10*8($30) - jsr $26, ffi_closure_osf_inner - ldgp $29, 0($26) - ldq $26, 0($30) - - # Load up the return value in the proper type. - lda $1, $load_table - s4addq $0, $1, $1 - ldl $1, 0($1) - addq $1, $29, $1 - jmp $31, ($1), $load_32 - - .align 4 -$load_none: - addq $30, 16*8, $30 - ret - - .align 4 -$load_float: - lds $f0, 16($30) - nop - addq $30, 16*8, $30 - ret - - .align 4 -$load_double: - ldt $f0, 16($30) - nop - addq $30, 16*8, $30 - ret - - .align 4 -$load_u8: -#ifdef __alpha_bwx__ - ldbu $0, 16($30) - nop -#else - ldq $0, 16($30) - and $0, 255, $0 -#endif - addq $30, 16*8, $30 - ret - - .align 4 -$load_s8: -#ifdef __alpha_bwx__ - ldbu $0, 16($30) - sextb $0, $0 -#else - ldq $0, 16($30) - sll $0, 56, $0 - sra $0, 56, $0 -#endif - addq $30, 16*8, $30 - ret - - .align 4 -$load_u16: -#ifdef __alpha_bwx__ - ldwu $0, 16($30) - nop -#else - ldq $0, 16($30) - zapnot $0, 3, $0 -#endif - addq $30, 16*8, $30 - ret - - .align 4 -$load_s16: -#ifdef __alpha_bwx__ - ldwu $0, 16($30) - sextw $0, $0 -#else - ldq $0, 16($30) - sll $0, 48, $0 - sra $0, 48, $0 -#endif - addq $30, 16*8, $30 - ret - - .align 4 -$load_32: - ldl $0, 16($30) - nop - addq $30, 16*8, $30 - ret - - .align 4 -$load_64: - ldq $0, 16($30) - nop - addq $30, 16*8, $30 - ret - - .end ffi_closure_osf - -.section .rodata -$load_table: - .gprel32 $load_none # FFI_TYPE_VOID - .gprel32 $load_32 # FFI_TYPE_INT - .gprel32 $load_float # FFI_TYPE_FLOAT - .gprel32 $load_double # FFI_TYPE_DOUBLE - .gprel32 $load_double # FFI_TYPE_LONGDOUBLE - .gprel32 $load_u8 # FFI_TYPE_UINT8 - .gprel32 $load_s8 # FFI_TYPE_SINT8 - .gprel32 $load_u16 # FFI_TYPE_UINT16 - .gprel32 $load_s16 # FFI_TYPE_SINT16 - .gprel32 $load_32 # FFI_TYPE_UINT32 - .gprel32 $load_32 # FFI_TYPE_SINT32 - .gprel32 $load_64 # FFI_TYPE_UINT64 - .gprel32 $load_64 # FFI_TYPE_SINT64 - .gprel32 $load_none # FFI_TYPE_STRUCT - .gprel32 $load_64 # FFI_TYPE_POINTER - -/* Assert that the table above is in sync with ffi.h. */ - -#if FFI_TYPE_FLOAT != 2 \ - || FFI_TYPE_DOUBLE != 3 \ - || FFI_TYPE_UINT8 != 5 \ - || FFI_TYPE_SINT8 != 6 \ - || FFI_TYPE_UINT16 != 7 \ - || FFI_TYPE_SINT16 != 8 \ - || FFI_TYPE_UINT32 != 9 \ - || FFI_TYPE_SINT32 != 10 \ - || FFI_TYPE_UINT64 != 11 \ - || FFI_TYPE_SINT64 != 12 \ - || FFI_TYPE_STRUCT != 13 \ - || FFI_TYPE_POINTER != 14 \ - || FFI_TYPE_LAST != 14 -#error "osf.S out of sync with ffi.h" -#endif diff --git a/libffi/src/arm/ffi.c b/libffi/src/arm/ffi.c deleted file mode 100644 index 0ede742..0000000 --- a/libffi/src/arm/ffi.c +++ /dev/null @@ -1,183 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Cygnus Solutions - - ARM Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -/*@-exportheader@*/ -void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ -{ - register unsigned int i; - register int tmp; - register unsigned int avn; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - tmp = 0; - argp = stack; - - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) { - *(void **) argp = ecif->rvalue; - argp += 4; - } - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - (i != 0) && (avn != 0); - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, (*p_arg)->alignment); - } - - if (avn != 0) - { - avn--; - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } - else if (z == sizeof(int)) - { - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - } - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } - } - - return; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags = (unsigned) cif->rtype->type; - break; - - default: - cif->flags = FFI_TYPE_INT; - break; - } - - return FFI_OK; -} - -/*@-declundef@*/ -/*@-exportheader@*/ -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 (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - default: - FFI_ASSERT(0); - break; - } -} diff --git a/libffi/src/arm/sysv.S b/libffi/src/arm/sysv.S deleted file mode 100644 index 84744d7..0000000 --- a/libffi/src/arm/sysv.S +++ /dev/null @@ -1,111 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1998 Cygnus Solutions - - ARM Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include -#ifdef HAVE_MACHINE_ASM_H -#include -#else -/* XXX these lose for some platforms, I'm sure. */ -#define CNAME(x) x -#define ENTRY(x) .globl CNAME(x); .type CNAME(x),%function; CNAME(x): -#endif - -.text - - # a1: ffi_prep_args - # a2: &ecif - # a3: cif->bytes - # a4: fig->flags - # sp+0: ecif.rvalue - # sp+4: fn - - # This assumes we are using gas. -ENTRY(ffi_call_SYSV) - # Save registers - stmfd sp!, {a1-a4, fp, lr} - mov fp, sp - - # Make room for all of the new args. - sub sp, fp, a3 - - # Place all of the ffi_prep_args in position - mov ip, a1 - mov a1, sp - # a2 already set - - # And call - mov lr, pc - mov pc, ip - - # move first 4 parameters in registers - ldr a1, [sp, #0] - ldr a2, [sp, #4] - ldr a3, [sp, #8] - ldr a4, [sp, #12] - - # and adjust stack - ldr ip, [fp, #8] - cmp ip, #16 - movge ip, #16 - add sp, sp, ip - - # call function - mov lr, pc - ldr pc, [fp, #28] - - # Remove the space we pushed for the args - mov sp, fp - - # Load a3 with the pointer to storage for the return value - ldr a3, [sp, #24] - - # Load a4 with the return type code - ldr a4, [sp, #12] - - # If the return value pointer is NULL, assume no return value. - cmp a3, #0 - beq epilogue - -# return INT - cmp a4, #FFI_TYPE_INT - streq a1, [a3] - beq epilogue - -# return FLOAT - cmp a4, #FFI_TYPE_FLOAT - stfeqs f0, [a3] - beq epilogue - -# return DOUBLE or LONGDOUBLE - cmp a4, #FFI_TYPE_DOUBLE - stfeqd f0, [a3] - -epilogue: - ldmfd sp!, {a1-a4, fp, pc} - -.ffi_call_SYSV_end: - .size CNAME(ffi_call_SYSV),.ffi_call_SYSV_end-CNAME(ffi_call_SYSV) - diff --git a/libffi/src/debug.c b/libffi/src/debug.c deleted file mode 100644 index 17196ba..0000000 --- a/libffi/src/debug.c +++ /dev/null @@ -1,65 +0,0 @@ -/* ----------------------------------------------------------------------- - debug.c - Copyright (c) 1996 Red Hat, Inc. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include -#include -#include - -/* General debugging routines */ - -void ffi_stop_here(void) -{ - /* This function is only useful for debugging purposes. - Place a breakpoint on ffi_stop_here to be notified of - significant events. */ -} - -/* This function should only be called via the FFI_ASSERT() macro */ - -int ffi_assert(char *file, int line) -{ - fprintf(stderr, "ASSERTION FAILURE: %s line %d\n", file, line); - ffi_stop_here(); - abort(); - - /* This has to return something for the compiler not to complain */ - /*@notreached@*/ - return 0; -} - -/* Perform a sanity check on an ffi_type structure */ - -bool ffi_type_test(ffi_type *a) -{ - /*@-usedef@*/ - FFI_ASSERT(a->type <= FFI_TYPE_LAST); - FFI_ASSERT(a->type > FFI_TYPE_VOID ? a->size > 0 : 1); - FFI_ASSERT(a->type > FFI_TYPE_VOID ? a->alignment > 0 : 1); - FFI_ASSERT(a->type == FFI_TYPE_STRUCT ? a->elements != NULL : 1); - /*@=usedef@*/ - - /* This is a silly thing to return, but it keeps the compiler from - issuing warnings about "a" not being used in non-debug builds. */ - return (a != NULL); -} diff --git a/libffi/src/ffitest.c b/libffi/src/ffitest.c deleted file mode 100644 index ca7db26..0000000 --- a/libffi/src/ffitest.c +++ /dev/null @@ -1,736 +0,0 @@ -/* ----------------------------------------------------------------------- - ffitest.c - Copyright (c) 1996, 1997, 1998 Cygnus Solutions - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include -#include -#include -#include - -/* This is lame. Long double support is barely there under SunOS 4.x */ -#if defined(SPARC) && (SIZEOF_LONG_DOUBLE != 16) -#define BROKEN_LONG_DOUBLE -#endif - -#define CHECK(x) !(x) ? fail(__FILE__, __LINE__) : 0 - -static int fail(char *file, int line) -{ - fprintf(stderr, "Test failure: %s line %d\n", file, line); - exit(EXIT_FAILURE); - /*@notreached@*/ - return 0; -} - -#define MAX_ARGS 256 - -static size_t my_strlen(char *s) -{ - return (strlen(s)); -} - -static int promotion(signed char sc, signed short ss, - unsigned char uc, unsigned short us) -{ - int r = (int) sc + (int) ss + (int) uc + (int) us; - - return r; -} - -static signed char return_sc(signed char sc) -{ - return sc; -} - -static unsigned char return_uc(unsigned char uc) -{ - return uc; -} - -static long long return_ll(long long ll) -{ - return ll; -} - -static int floating(int a, float b, double c, long double d, int e) -{ - int i; - -#if 0 - /* This is ifdef'd out for now. long double support under SunOS/gcc - is pretty much non-existent. You'll get the odd bus error in library - routines like printf(). */ - printf("%d %f %f %Lf %d\n", a, (double)b, c, d, e); -#endif - - i = (int) ((float)a/b + ((float)c/(float)d)); - - return i; -} - -static float many(float f1, - float f2, - float f3, - float f4, - float f5, - float f6, - float f7, - float f8, - float f9, - float f10, - float f11, - float f12, - float f13) -{ -#if 0 - printf("%f %f %f %f %f %f %f %f %f %f %f %f %f\n", - (double) f1, (double) f2, (double) f3, (double) f4, (double) f5, - (double) f6, (double) f7, (double) f8, (double) f9, (double) f10, - (double) f11, (double) f12, (double) f13); -#endif - - return ((f1/f2+f3/f4+f5/f6+f7/f8+f9/f10+f11/f12) * f13); -} - -static double dblit(float f) -{ - return f/3.0; -} - -static long double ldblit(float f) -{ - return (long double) (((long double) f)/ (long double) 3.0); -} - -typedef struct -{ - unsigned char uc; - double d; - unsigned int ui; -} test_structure_1; - -typedef struct -{ - double d1; - double d2; -} test_structure_2; - -typedef struct -{ - int si; -} test_structure_3; - -typedef struct -{ - unsigned ui1; - unsigned ui2; - unsigned ui3; -} test_structure_4; - -typedef struct -{ - char c1; - char c2; -} test_structure_5; - -static test_structure_1 struct1(test_structure_1 ts) -{ - /*@-type@*/ - ts.uc++; - /*@=type@*/ - ts.d--; - ts.ui++; - - return ts; -} - -static test_structure_2 struct2(test_structure_2 ts) -{ - ts.d1--; - ts.d2--; - - return ts; -} - -static test_structure_3 struct3(test_structure_3 ts) -{ - ts.si = -(ts.si*2); - - return ts; -} - -static test_structure_4 struct4(test_structure_4 ts) -{ - ts.ui3 = ts.ui1 * ts.ui2 * ts.ui3; - - return ts; -} - -static test_structure_5 struct5(test_structure_5 ts1, test_structure_5 ts2) -{ - ts1.c1 += ts2.c1; - ts1.c2 -= ts2.c2; - - return ts1; -} - -/* Take an int and a float argument, together with int userdata, and */ -/* return the sum. */ -static void closure_test_fn(ffi_cif* cif,void* resp,void** args, void* userdata) -{ - *(int*)resp = - *(int *)args[0] + (int)(*(float *)args[1]) + (int)(long)userdata; -} - -typedef int (*closure_test_type)(int, float); - -int main(/*@unused@*/ int argc, /*@unused@*/ char *argv[]) -{ - ffi_cif cif; - ffi_type *args[MAX_ARGS]; - void *values[MAX_ARGS]; - char *s; - signed char sc; - unsigned char uc; - signed short ss; - unsigned short us; - unsigned long ul; - long long ll; - float f; - double d; - long double ld; - signed int si1; - signed int si2; - -#if defined(ALPHA) || defined(IA64) || defined(SPARC64) || (defined(MIPS) && (_MIPS_SIM == _ABIN32)) - long long rint; -#else - int rint; -#endif - long long rlonglong; - - ffi_type ts1_type; - ffi_type ts2_type; - ffi_type ts3_type; - ffi_type ts4_type; - ffi_type ts5_type; - ffi_type *ts1_type_elements[4]; - ffi_type *ts2_type_elements[3]; - ffi_type *ts3_type_elements[2]; - ffi_type *ts4_type_elements[4]; - ffi_type *ts5_type_elements[3]; - - ts1_type.size = 0; - ts1_type.alignment = 0; - ts1_type.type = FFI_TYPE_STRUCT; - - ts2_type.size = 0; - ts2_type.alignment = 0; - ts2_type.type = FFI_TYPE_STRUCT; - - ts3_type.size = 0; - ts3_type.alignment = 0; - ts3_type.type = FFI_TYPE_STRUCT; - - ts4_type.size = 0; - ts4_type.alignment = 0; - ts4_type.type = FFI_TYPE_STRUCT; - - ts5_type.size = 0; - ts5_type.alignment = 0; - ts5_type.type = FFI_TYPE_STRUCT; - - /*@-immediatetrans@*/ - ts1_type.elements = ts1_type_elements; - ts2_type.elements = ts2_type_elements; - ts3_type.elements = ts3_type_elements; - ts4_type.elements = ts4_type_elements; - ts5_type.elements = ts5_type_elements; - /*@=immediatetrans@*/ - - ts1_type_elements[0] = &ffi_type_uchar; - ts1_type_elements[1] = &ffi_type_double; - ts1_type_elements[2] = &ffi_type_uint; - ts1_type_elements[3] = NULL; - - ts2_type_elements[0] = &ffi_type_double; - ts2_type_elements[1] = &ffi_type_double; - ts2_type_elements[2] = NULL; - - ts3_type_elements[0] = &ffi_type_sint; - ts3_type_elements[1] = NULL; - - ts4_type_elements[0] = &ffi_type_uint; - ts4_type_elements[1] = &ffi_type_uint; - ts4_type_elements[2] = &ffi_type_uint; - ts4_type_elements[3] = NULL; - - ts5_type_elements[0] = &ffi_type_schar; - ts5_type_elements[1] = &ffi_type_schar; - ts5_type_elements[2] = NULL; - - ul = 0; - - /* return value tests */ - { -#if defined(MIPS) /* || defined(ARM) */ - puts ("long long tests not run. This is a known bug on this architecture."); -#else - args[0] = &ffi_type_sint64; - values[0] = ≪ - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_sint64, args) == FFI_OK); - - for (ll = 0LL; ll < 100LL; ll++) - { - ul++; - ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); - CHECK(rlonglong == ll); - } - - for (ll = 55555555555000LL; ll < 55555555555100LL; ll++) - { - ul++; - ffi_call(&cif, FFI_FN(return_ll), &rlonglong, values); - CHECK(rlonglong == ll); - } -#endif - - args[0] = &ffi_type_schar; - values[0] = ≻ - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_schar, args) == FFI_OK); - - for (sc = (signed char) -127; - sc < (signed char) 127; /*@-type@*/ sc++ /*@=type@*/) - { - ul++; - ffi_call(&cif, FFI_FN(return_sc), &rint, values); - CHECK(rint == (int) sc); - } - - args[0] = &ffi_type_uchar; - values[0] = &uc; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_uchar, args) == FFI_OK); - - for (uc = (unsigned char) '\x00'; - uc < (unsigned char) '\xff'; /*@-type@*/ uc++ /*@=type@*/) - { - ul++; - ffi_call(&cif, FFI_FN(return_uc), &rint, values); - CHECK(rint == (signed int) uc); - } - - printf("%lu return value tests run\n", ul); - } - -#ifdef BROKEN_LONG_DOUBLE - printf ("This architecture has broken `long double' support. No floating point\ntests have been run.\n"); -#else - /* float arg tests */ - { - args[0] = &ffi_type_float; - values[0] = &f; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_longdouble, args) == FFI_OK); - - f = 3.14159; - -#if 0 - /* This is ifdef'd out for now. long double support under SunOS/gcc - is pretty much non-existent. You'll get the odd bus error in library - routines like printf(). */ - printf ("%Lf\n", ldblit(f)); -#endif - ld = 666; - ffi_call(&cif, FFI_FN(ldblit), &ld, values); - -#if 0 - /* This is ifdef'd out for now. long double support under SunOS/gcc - is pretty much non-existent. You'll get the odd bus error in library - routines like printf(). */ - printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON); -#endif - - /* These are not always the same!! Check for a reasonable delta */ - /*@-realcompare@*/ - if (ld - ldblit(f) < LDBL_EPSILON) - /*@=realcompare@*/ - puts("long double return value tests ok!"); - else - CHECK(0); - } - - /* float arg tests */ - { - args[0] = &ffi_type_sint; - values[0] = &si1; - args[1] = &ffi_type_float; - values[1] = &f; - args[2] = &ffi_type_double; - values[2] = &d; - args[3] = &ffi_type_longdouble; - values[3] = &ld; - args[4] = &ffi_type_sint; - values[4] = &si2; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 5, - &ffi_type_sint, args) == FFI_OK); - - si1 = 6; - f = 3.14159; - d = (double)1.0/(double)3.0; - ld = 2.71828182846L; - si2 = 10; - - floating (si1, f, d, ld, si2); - - ffi_call(&cif, FFI_FN(floating), &rint, values); - - printf ("%d vs %d\n", rint, floating (si1, f, d, ld, si2)); - - CHECK(rint == floating(si1, f, d, ld, si2)); - - printf("float arg tests ok!\n"); - } -#endif - - /* strlen tests */ - { - args[0] = &ffi_type_pointer; - values[0] = (void*) &s; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_sint, args) == FFI_OK); - - s = "a"; - ffi_call(&cif, FFI_FN(my_strlen), &rint, values); - CHECK(rint == 1); - - s = "1234567"; - ffi_call(&cif, FFI_FN(my_strlen), &rint, values); - CHECK(rint == 7); - - s = "1234567890123456789012345"; - ffi_call(&cif, FFI_FN(my_strlen), &rint, values); - CHECK(rint == 25); - - printf("strlen tests passed\n"); - } - - /* float arg tests */ - { - args[0] = &ffi_type_float; - values[0] = &f; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ffi_type_double, args) == FFI_OK); - - f = 3.14159; - - ffi_call(&cif, FFI_FN(dblit), &d, values); - - /* These are not always the same!! Check for a reasonable delta */ - /*@-realcompare@*/ - CHECK(d - dblit(f) < DBL_EPSILON); - /*@=realcompare@*/ - - printf("double return value tests ok!\n"); - } - - /* many arg tests */ - { - float ff; - float fa[13]; - - for (ul = 0; ul < 13; ul++) - { - args[ul] = &ffi_type_float; - values[ul] = &fa[ul]; - fa[ul] = (float) ul; - } - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 13, - &ffi_type_float, args) == FFI_OK); - - /*@-usedef@*/ - ff = many(fa[0], fa[1], - fa[2], fa[3], - fa[4], fa[5], - fa[6], fa[7], - fa[8], fa[9], - fa[10],fa[11],fa[12]); - /*@=usedef@*/ - - ffi_call(&cif, FFI_FN(many), &f, values); - - /*@-realcompare@*/ - if (f - ff < FLT_EPSILON) - /*@=realcompare@*/ - printf("many arg tests ok!\n"); - else -#ifdef POWERPC - printf("many arg tests failed! This is a gcc bug.\n"); -#else - CHECK(0); -#endif - } - - /* promotion tests */ - { - args[0] = &ffi_type_schar; - args[1] = &ffi_type_sshort; - args[2] = &ffi_type_uchar; - args[3] = &ffi_type_ushort; - values[0] = ≻ - values[1] = &ss; - values[2] = &uc; - values[3] = &us; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, - &ffi_type_sint, args) == FFI_OK); - - us = 0; - ul = 0; - - for (sc = (signed char) -127; - sc <= (signed char) 120; /*@-type@*/ sc += 1 /*@=type@*/) - for (ss = -30000; ss <= 30000; ss += 10000) - for (uc = (unsigned char) 0; - uc <= (unsigned char) 200; /*@-type@*/ uc += 20 /*@=type@*/) - for (us = 0; us <= 60000; us += 10000) - { - ul++; - ffi_call(&cif, FFI_FN(promotion), &rint, values); - CHECK(rint == (int) sc + (int) ss + (int) uc + (int) us); - } - printf("%lu promotion tests run\n", ul); - } - -#ifndef X86_WIN32 /* Structures dont work on Win32 */ - - /* struct tests */ - { - test_structure_1 ts1_arg; - /* This is a hack to get a properly aligned result buffer */ - test_structure_1 *ts1_result = - (test_structure_1 *) malloc (sizeof(test_structure_1)); - - args[0] = &ts1_type; - values[0] = &ts1_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ts1_type, args) == FFI_OK); - - ts1_arg.uc = '\x01'; - ts1_arg.d = 3.14159; - ts1_arg.ui = 555; - - ffi_call(&cif, FFI_FN(struct1), ts1_result, values); - - CHECK(ts1_result->ui == 556); - CHECK(ts1_result->d == 3.14159 - 1); - - puts ("structure test 1 ok!\n"); - - free (ts1_result); - } - - /* struct tests */ - { - test_structure_2 ts2_arg; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_2 *ts2_result = - (test_structure_2 *) malloc (sizeof(test_structure_2)); - - args[0] = &ts2_type; - values[0] = &ts2_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ts2_type, args) == FFI_OK); - - ts2_arg.d1 = 5.55; - ts2_arg.d2 = 6.66; - - printf ("%g\n", ts2_result->d1); - printf ("%g\n", ts2_result->d2); - - ffi_call(&cif, FFI_FN(struct2), ts2_result, values); - - printf ("%g\n", ts2_result->d1); - printf ("%g\n", ts2_result->d2); - - CHECK(ts2_result->d1 == 5.55 - 1); - CHECK(ts2_result->d2 == 6.66 - 1); - - printf("structure test 2 ok!\n"); - - free (ts2_result); - } - - /* struct tests */ - { - int compare_value; - test_structure_3 ts3_arg; - test_structure_3 *ts3_result = - (test_structure_3 *) malloc (sizeof(test_structure_3)); - - args[0] = &ts3_type; - values[0] = &ts3_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ts3_type, args) == FFI_OK); - - ts3_arg.si = -123; - compare_value = ts3_arg.si; - - ffi_call(&cif, FFI_FN(struct3), ts3_result, values); - - printf ("%d %d\n", ts3_result->si, -(compare_value*2)); - - if (ts3_result->si == -(ts3_arg.si*2)) - puts ("structure test 3 ok!"); - else - { - puts ("Structure test 3 found structure passing bug."); - puts (" Current versions of GCC are not 100% compliant with the"); - puts (" n32 ABI. There is a known problem related to passing"); - puts (" small structures. Send a bug report to the gcc maintainers."); - } - - free (ts3_result); - } - - /* struct tests */ - { - test_structure_4 ts4_arg; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_4 *ts4_result = - (test_structure_4 *) malloc (sizeof(test_structure_4)); - - args[0] = &ts4_type; - values[0] = &ts4_arg; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, - &ts4_type, args) == FFI_OK); - - ts4_arg.ui1 = 2; - ts4_arg.ui2 = 3; - ts4_arg.ui3 = 4; - - ffi_call (&cif, FFI_FN(struct4), ts4_result, values); - - if (ts4_result->ui3 == 2U * 3U * 4U) - puts ("structure test 4 ok!"); - else - puts ("Structure test 4 found GCC's structure passing bug."); - - free (ts4_result); - } - - /* struct tests */ - { - test_structure_5 ts5_arg1, ts5_arg2; - - /* This is a hack to get a properly aligned result buffer */ - test_structure_5 *ts5_result = - (test_structure_5 *) malloc (sizeof(test_structure_5)); - - args[0] = &ts5_type; - args[1] = &ts5_type; - values[0] = &ts5_arg1; - values[1] = &ts5_arg2; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, - &ts5_type, args) == FFI_OK); - - ts5_arg1.c1 = 2; - ts5_arg1.c2 = 6; - ts5_arg2.c1 = 5; - ts5_arg2.c2 = 3; - - ffi_call (&cif, FFI_FN(struct5), ts5_result, values); - - if (ts5_result->c1 == 7 - && ts5_result->c2 == 3) - puts ("structure test 5 ok!"); - else - puts ("Structure test 5 found GCC's structure passing bug."); - - free (ts5_result); - } - -#else - printf("Structure passing doesn't work on Win32.\n"); -#endif /* X86_WIN32 */ - -# if FFI_CLOSURES - /* A simple closure test */ - { - ffi_closure cl; - ffi_type * cl_arg_types[3]; - - cl_arg_types[0] = &ffi_type_sint; - cl_arg_types[1] = &ffi_type_float; - cl_arg_types[2] = NULL; - - /* Initialize the cif */ - CHECK(ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 2, - &ffi_type_sint, cl_arg_types) == FFI_OK); - - CHECK(ffi_prep_closure(&cl, &cif, closure_test_fn, - (void *) 3 /* userdata */) - == FFI_OK); - CHECK((*((closure_test_type)(&cl)))(1, 2.0) == 6); - } -# endif - - /* If we arrived here, all is good */ - (void) puts("\nLooks good. No surprises.\n"); - - /*@-compdestroy@*/ - - return 0; -} - diff --git a/libffi/src/ia64/ffi.c b/libffi/src/ia64/ffi.c deleted file mode 100644 index bb4fbb7..0000000 --- a/libffi/src/ia64/ffi.c +++ /dev/null @@ -1,670 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Cygnus Solutions - Copyright (c) 2000 Hewlett Packard Company - - IA64 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -#include "ia64_flags.h" - -/* Memory image of fp register contents. Should eventually be an fp */ -/* type long enough to hold an entire register. For now we use double. */ -typedef double float80; - -/* The stack layout at call to ffi_prep_regs. Other_args will remain */ -/* on the stack for the actual call. Everything else we be transferred */ -/* to registers and popped by the assembly code. */ - -struct ia64_args { - long scratch[2]; /* Two scratch words at top of stack. */ - /* Allows sp to passed as arg pointer. */ - void * r8_contents; /* Value to be passed in r8 */ - long spare; /* Not used. */ - float80 fp_regs[8]; /* Contents of 8 floating point argument */ - /* registers. */ - long out_regs[8]; /* Contents of the 8 out registers used */ - /* for integer parameters. */ - long other_args[0]; /* Arguments passed on stack, variable size */ - /* Treated as continuation of out_regs. */ -}; - -static size_t float_type_size(unsigned short tp) -{ - switch(tp) { - case FFI_TYPE_FLOAT: - return sizeof(float); - case FFI_TYPE_DOUBLE: - return sizeof(double); -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - return sizeof(long double); -#endif - default: - FFI_ASSERT(0); - } -} - -/* - * Is type a struct containing at most n floats, doubles, or extended - * doubles, all of the same fp type? - * If so, set *element_type to the fp type. - */ -static bool is_homogeneous_fp_aggregate(ffi_type * type, int n, - unsigned short * element_type) -{ - ffi_type **ptr; - unsigned short element, struct_element; - - int type_set = 0; - - FFI_ASSERT(type != NULL); - - FFI_ASSERT(type->elements != NULL); - - ptr = &(type->elements[0]); - - while ((*ptr) != NULL) - { - switch((*ptr) -> type) { - case FFI_TYPE_FLOAT: - if (type_set && element != FFI_TYPE_FLOAT) return 0; - if (--n < 0) return FALSE; - type_set = 1; - element = FFI_TYPE_FLOAT; - break; - case FFI_TYPE_DOUBLE: - if (type_set && element != FFI_TYPE_DOUBLE) return 0; - if (--n < 0) return FALSE; - type_set = 1; - element = FFI_TYPE_DOUBLE; - break; - case FFI_TYPE_STRUCT: - if (!is_homogeneous_fp_aggregate(type, n, &struct_element)) - return FALSE; - if (type_set && struct_element != element) return FALSE; - n -= (type -> size)/float_type_size(element); - element = struct_element; - if (n < 0) return FALSE; - break; - /* case FFI_TYPE_LONGDOUBLE: - Not yet implemented. */ - default: - return FALSE; - } - ptr++; - } - *element_type = element; - return TRUE; - -} - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments. Returns nonzero - if fp registers are used for arguments. */ - -static bool -ffi_prep_args(struct ia64_args *stack, extended_cif *ecif, int bytes) -{ - register long i, avn; - register void **p_argv; - register long *argp = stack -> out_regs; - register float80 *fp_argp = stack -> fp_regs; - register ffi_type **p_arg; - - /* For big return structs, r8 needs to contain the target address. */ - /* Since r8 is otherwise dead, we set it unconditionally. */ - stack -> r8_contents = ecif -> rvalue; - i = 0; - avn = ecif->cif->nargs; - p_arg = ecif->cif->arg_types; - p_argv = ecif->avalue; - while (i < avn) - { - size_t z; /* z is in units of arg slots or words, not bytes. */ - - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - z = 1; - *(SINT64 *) argp = *(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - z = 1; - *(UINT64 *) argp = *(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - z = 1; - *(SINT64 *) argp = *(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - z = 1; - *(UINT64 *) argp = *(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - z = 1; - *(SINT64 *) argp = *(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - z = 1; - *(UINT64 *) argp = *(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - z = 1; - *(UINT64 *) argp = *(UINT64 *)(* p_argv); - break; - - case FFI_TYPE_FLOAT: - z = 1; - if (fp_argp - stack->fp_regs < 8) - { - /* Note the conversion -- all the fp regs are loaded as - doubles. */ - *fp_argp++ = *(float *)(* p_argv); - } - /* Also put it into the integer registers or memory: */ - *(UINT64 *) argp = *(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_DOUBLE: - z = 1; - if (fp_argp - stack->fp_regs < 8) - *fp_argp++ = *(double *)(* p_argv); - /* Also put it into the integer registers or memory: */ - *(double *) argp = *(double *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - { - size_t sz = (*p_arg)->size; - unsigned short element_type; - z = ((*p_arg)->size + SIZEOF_ARG - 1)/SIZEOF_ARG; - if (is_homogeneous_fp_aggregate(*p_arg, 8, &element_type)) { - int i; - int nelements = sz/float_type_size(element_type); - for (i = 0; i < nelements; ++i) { - switch (element_type) { - case FFI_TYPE_FLOAT: - if (fp_argp - stack->fp_regs < 8) - *fp_argp++ = ((float *)(* p_argv))[i]; - break; - case FFI_TYPE_DOUBLE: - if (fp_argp - stack->fp_regs < 8) - *fp_argp++ = ((double *)(* p_argv))[i]; - break; - default: - /* Extended precision not yet implemented. */ - abort(); - } - } - } - /* And pass it in integer registers as a struct, with */ - /* its actual field sizes packed into registers. */ - memcpy(argp, *p_argv, (*p_arg)->size); - } - break; - - default: - FFI_ASSERT(0); - } - - argp += z; - i++, p_arg++, p_argv++; - } - return (fp_argp != stack -> fp_regs); -} - -/* Perform machine dependent cif processing */ -ffi_status -ffi_prep_cif_machdep(ffi_cif *cif) -{ - long i, avn; - bool is_simple = TRUE; - long simple_flag = FFI_SIMPLE_V; - /* Adjust cif->bytes to include space for the 2 scratch words, - r8 register contents, spare word, - the 8 fp register contents, and all 8 integer register contents. - This will be removed before the call, though 2 scratch words must - remain. */ - - cif->bytes += 4*sizeof(long) + 8 *sizeof(float80); - if (cif->bytes < sizeof(struct ia64_args)) - cif->bytes = sizeof(struct ia64_args); - - /* The stack must be double word aligned, so round bytes up - appropriately. */ - - cif->bytes = ALIGN(cif->bytes, 2*sizeof(void*)); - - avn = cif->nargs; - if (avn <= 2) { - for (i = 0; i < avn; ++i) { - switch(cif -> arg_types[i] -> type) { - case FFI_TYPE_SINT32: - simple_flag = FFI_ADD_INT_ARG(simple_flag); - break; - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - simple_flag = FFI_ADD_LONG_ARG(simple_flag); - break; - default: - is_simple = FALSE; - } - } - } else { - is_simple = FALSE; - } - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - cif->flags = FFI_TYPE_VOID; - break; - - case FFI_TYPE_STRUCT: - { - size_t sz = cif -> rtype -> size; - unsigned short element_type; - - is_simple = FALSE; - if (is_homogeneous_fp_aggregate(cif -> rtype, 8, &element_type)) { - int nelements = sz/float_type_size(element_type); - if (nelements <= 1) { - if (0 == nelements) { - cif -> flags = FFI_TYPE_VOID; - } else { - cif -> flags = element_type; - } - } else { - switch(element_type) { - case FFI_TYPE_FLOAT: - cif -> flags = FFI_IS_FLOAT_FP_AGGREGATE | nelements; - break; - case FFI_TYPE_DOUBLE: - cif -> flags = FFI_IS_DOUBLE_FP_AGGREGATE | nelements; - break; - default: - /* long double NYI */ - abort(); - } - } - break; - } - if (sz <= 32) { - if (sz <= 8) { - cif->flags = FFI_TYPE_INT; - } else if (sz <= 16) { - cif->flags = FFI_IS_SMALL_STRUCT2; - } else if (sz <= 24) { - cif->flags = FFI_IS_SMALL_STRUCT3; - } else { - cif->flags = FFI_IS_SMALL_STRUCT4; - } - } else { - cif->flags = FFI_TYPE_STRUCT; - } - } - break; - - case FFI_TYPE_FLOAT: - is_simple = FALSE; - cif->flags = FFI_TYPE_FLOAT; - break; - - case FFI_TYPE_DOUBLE: - is_simple = FALSE; - cif->flags = FFI_TYPE_DOUBLE; - break; - - default: - cif->flags = FFI_TYPE_INT; - /* This seems to depend on little endian mode, and the fact that */ - /* the return pointer always points to at least 8 bytes. But */ - /* that also seems to be true for other platforms. */ - break; - } - - if (is_simple) cif -> flags |= simple_flag; - return FFI_OK; -} - -extern int ffi_call_unix(bool (*)(struct ia64_args *, extended_cif *, int), - extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); - -void -ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) -{ - extended_cif ecif; - long simple = cif -> flags & FFI_SIMPLE; - - /* Should this also check for Unix ABI? */ - /* This is almost, but not quite, machine independent. Note that */ - /* we can get away with not caring about length of the result because */ - /* we assume we are little endian, and the result buffer is large */ - /* enough. */ - /* This needs work for HP/UX. */ - if (simple) { - long (*lfn)() = (long (*)())fn; - long result; - switch(simple) { - case FFI_SIMPLE_V: - result = lfn(); - break; - case FFI_SIMPLE_I: - result = lfn(*(int *)avalue[0]); - break; - case FFI_SIMPLE_L: - result = lfn(*(long *)avalue[0]); - break; - case FFI_SIMPLE_II: - result = lfn(*(int *)avalue[0], *(int *)avalue[1]); - break; - case FFI_SIMPLE_IL: - result = lfn(*(int *)avalue[0], *(long *)avalue[1]); - break; - case FFI_SIMPLE_LI: - result = lfn(*(long *)avalue[0], *(int *)avalue[1]); - break; - case FFI_SIMPLE_LL: - result = lfn(*(long *)avalue[0], *(long *)avalue[1]); - break; - } - if ((cif->flags & ~FFI_SIMPLE) != FFI_TYPE_VOID && 0 != rvalue) { - * (long *)rvalue = result; - } - return; - } - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return - value address then we need to make one. */ - - if (rvalue == NULL && cif->rtype->type == FFI_TYPE_STRUCT) - ecif.rvalue = alloca(cif->rtype->size); - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { - case FFI_UNIX: - ffi_call_unix(ffi_prep_args, &ecif, cif->bytes, - cif->flags, rvalue, fn); - break; - - default: - FFI_ASSERT(0); - break; - } -} - -/* - * Closures represent a pair consisting of a function pointer, and - * some user data. A closure is invoked by reinterpreting the closure - * as a function pointer, and branching to it. Thus we can make an - * interpreted function callable as a C function: We turn the interpreter - * itself, together with a pointer specifying the interpreted procedure, - * into a closure. - * On X86, the first few words of the closure structure actually contain code, - * which will do the right thing. On most other architectures, this - * would raise some Icache/Dcache coherence issues (which can be solved, but - * often not cheaply). - * For IA64, function pointer are already pairs consisting of a code - * pointer, and a gp pointer. The latter is needed to access global variables. - * Here we set up such a pair as the first two words of the closure (in - * the "trampoline" area), but we replace the gp pointer with a pointer - * to the closure itself. We also add the real gp pointer to the - * closure. This allows the function entry code to both retrieve the - * user data, and to restire the correct gp pointer. - */ - -static void -ffi_prep_incoming_args_UNIX(struct ia64_args *args, void **rvalue, - void **avalue, ffi_cif *cif); - -/* This function is entered with the doctored gp (r1) value. - * This code is extremely gcc specific. There is some argument that - * it should really be written in assembly code, since it depends on - * gcc properties that might change over time. - */ - -/* ffi_closure_UNIX is an assembly routine, which copies the register */ -/* state into s struct ia64_args, and the invokes */ -/* ffi_closure_UNIX_inner. It also recovers the closure pointer */ -/* from its fake gp pointer. */ -void ffi_closure_UNIX(); - -#ifndef __GNUC__ -# error This requires gcc -#endif -void -ffi_closure_UNIX_inner (ffi_closure *closure, struct ia64_args * args) -/* Hopefully declarint this as a varargs function will force all args */ -/* to memory. */ -{ - // this is our return value storage - long double res; - - // our various things... - ffi_cif *cif; - unsigned short rtype; - void *resp; - void **arg_area; - - resp = (void*)&res; - 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_UNIX(args, (void**)&resp, arg_area, cif); - - (closure->fun) (cif, resp, arg_area, closure->user_data); - - rtype = cif->flags; - - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm volatile ("ld8 r8=[%0]" : : "r" (resp) : "r8"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm volatile ("ldfs f8=[%0]" : : "r" (resp) : "f8"); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm volatile ("ldfd f8=[%0]" : : "r" (resp) : "f8"); - } - else if (rtype == FFI_IS_SMALL_STRUCT2) - { - asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]" - : : "r" (resp), "r" (resp+8) : "r8","r9"); - } - else if (rtype == FFI_IS_SMALL_STRUCT3) - { - asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]; ld8 r10=[%2]" - : : "r" (resp), "r" (resp+8), "r" (resp+16) - : "r8","r9","r10"); - } - else if (rtype == FFI_IS_SMALL_STRUCT4) - { - asm volatile ("ld8 r8=[%0]; ld8 r9=[%1]; ld8 r10=[%2]; ld8 r11=[%3]" - : : "r" (resp), "r" (resp+8), "r" (resp+16), "r" (resp+24) - : "r8","r9","r10","r11"); - } - else if (rtype != FFI_TYPE_VOID && rtype != FFI_TYPE_STRUCT) - { - /* Can only happen for homogeneous FP aggregates? */ - abort(); - } -} - -static void -ffi_prep_incoming_args_UNIX(struct ia64_args *args, void **rvalue, - void **avalue, ffi_cif *cif) -{ - register unsigned int i; - register unsigned int avn; - register void **p_argv; - register unsigned long *argp = args -> out_regs; - unsigned fp_reg_num = 0; - register ffi_type **p_arg; - - avn = cif->nargs; - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; i != 0; i--, p_arg++) - { - size_t z; /* In units of words or argument slots. */ - - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - case FFI_TYPE_POINTER: - z = 1; - *p_argv = (void *)argp; - break; - - case FFI_TYPE_FLOAT: - z = 1; - /* Convert argument back to float in place from the saved value */ - if (fp_reg_num < 8) { - *(float *)argp = args -> fp_regs[fp_reg_num++]; - } else { - *(float *)argp = *(double *)argp; - } - *p_argv = (void *)argp; - break; - - case FFI_TYPE_DOUBLE: - z = 1; - if (fp_reg_num < 8) { - *p_argv = args -> fp_regs + fp_reg_num++; - } else { - *p_argv = (void *)argp; - } - break; - - case FFI_TYPE_STRUCT: - { - size_t sz = (*p_arg)->size; - unsigned short element_type; - z = ((*p_arg)->size + SIZEOF_ARG - 1)/SIZEOF_ARG; - if (is_homogeneous_fp_aggregate(*p_arg, 8, &element_type)) { - int nelements = sz/float_type_size(element_type); - if (nelements + fp_reg_num >= 8) { - /* hard case NYI. */ - abort(); - } - if (element_type == FFI_TYPE_DOUBLE) { - *p_argv = args -> fp_regs + fp_reg_num; - fp_reg_num += nelements; - break; - } - if (element_type == FFI_TYPE_FLOAT) { - int j; - for (j = 0; j < nelements; ++ j) { - ((float *)argp)[j] = args -> fp_regs[fp_reg_num + j]; - } - *p_argv = (void *)argp; - fp_reg_num += nelements; - break; - } - abort(); /* Other fp types NYI */ - } - } - break; - - default: - FFI_ASSERT(0); - } - - argp += z; - p_argv++; - - } - - return; -} - - -/* Fill in a closure to refer to the specified fun and user_data. */ -/* cif specifies the argument and result types for fun. */ -/* the cif must already be prep'ed */ - -/* The layout of a function descriptor. A C function pointer really */ -/* points to one of these. */ -typedef struct ia64_fd_struct { - void *code_pointer; - void *gp; -} ia64_fd; - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) -{ - struct ffi_ia64_trampoline_struct *tramp = - (struct ffi_ia64_trampoline_struct *) (closure -> tramp); - ia64_fd *fd = (ia64_fd *)(void *)ffi_closure_UNIX; - - FFI_ASSERT (cif->abi == FFI_UNIX); - - tramp -> code_pointer = fd -> code_pointer; - tramp -> real_gp = fd -> gp; - tramp -> fake_gp = closure; - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - - diff --git a/libffi/src/ia64/ia64_flags.h b/libffi/src/ia64/ia64_flags.h deleted file mode 100644 index 23dbd3e..0000000 --- a/libffi/src/ia64/ia64_flags.h +++ /dev/null @@ -1,62 +0,0 @@ -/* ----------------------------------------------------------------------- - ia64_flags.h - Copyright (c) 2000 Hewlett Packard Company - - IA64/unix Foreign Function Interface - - Original author: Hans Boehm, HP Labs - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - - -/* Homogeneous Floating Point Aggregates (HFAs) which are returned */ -/* in FP registers. The least significant bits specify the size in */ -/* words. */ -#define FFI_IS_FLOAT_FP_AGGREGATE 0x1000 -#define FFI_IS_DOUBLE_FP_AGGREGATE 0x0800 -#define FLOAT_FP_AGGREGATE_BIT 12 -#define DOUBLE_FP_AGGREGATE_BIT 11 - -/* Small structures containing N words. If N=1, they are returned */ -/* as though they were integers. */ -#define FFI_IS_SMALL_STRUCT2 0x40 /* Struct > 8, <=16 bytes */ -#define FFI_IS_SMALL_STRUCT3 0x41 /* Struct > 16 <= 24 bytes */ -#define FFI_IS_SMALL_STRUCT4 0x42 /* Struct > 24, <=32 bytes */ - -/* Flag values identifying particularly simple cases, which are */ -/* handled specially. We treat functions as simple if they take all */ -/* arguments can be passed as 32 or 64 bit integer quantities, there is */ -/* either no return value or it can be treated as a 64bit integer, and */ -/* if there are at most 2 arguments. */ -/* This is OR'ed with the normal flag values. */ -#define FFI_SIMPLE_V 0x10000 /* () -> X */ -#define FFI_SIMPLE_I 0x20000 /* (int) -> X */ -#define FFI_SIMPLE_L 0x30000 /* (long) -> X */ -#define FFI_SIMPLE_II 0x40000 /* (int,int) -> X */ -#define FFI_SIMPLE_IL 0x50000 /* (int,long) -> X */ -#define FFI_SIMPLE_LI 0x60000 /* (long,int) -> X */ -#define FFI_SIMPLE_LL 0x70000 /* (long,long) -> X */ - -/* Mask for all of the FFI_SIMPLE bits: */ -#define FFI_SIMPLE 0xf0000 - -/* An easy way to build FFI_SIMPLE flags from FFI_SIMPLE_V: */ -#define FFI_ADD_LONG_ARG(flag) (((flag) << 1) | 0x10000) -#define FFI_ADD_INT_ARG(flag) ((flag) << 1) diff --git a/libffi/src/ia64/unix.S b/libffi/src/ia64/unix.S deleted file mode 100644 index fdaf8be..0000000 --- a/libffi/src/ia64/unix.S +++ /dev/null @@ -1,301 +0,0 @@ -/* ----------------------------------------------------------------------- - unix.S - Copyright (c) 1998 Cygnus Solutions - Copyright (c) 2000 Hewlett Packard Company - - IA64/unix Foreign Function Interface - - Primary author: Hans Boehm, HP Labs - - Loosely modeled on Cygnus code for other platforms. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include -#include "ia64_flags.h" - -/* parameters: */ -#define callback in0 -#define ecifp in1 -#define bytes in2 -#define flags in3 -#define raddr in4 -#define fn in5 - -#define FLOAT_SZ 8 /* in-memory size of fp operands */ - -.text - .align 16 - .global ffi_call_unix# - .proc ffi_call_unix# -ffi_call_unix: - alloc loc0=ar.pfs,6,5,8,0 - mov loc1=b0; - sub sp=sp,bytes - mov loc4=r1 /* Save gp */ - ld8 r8=[callback],8 /* code address of callback */ - ;; - mov out0=sp - mov out1=ecifp - mov out2=bytes - ld8 r1=[callback] /* Set up gp for callback. Unnecessary? */ - mov b6=r8 - ;; - br.call.sptk.many b0 = b6 /* call ffi_prep_args */ - cmp.eq p6,p0=0,r8 /* r8 nonzero ==> need fp regs */ - ;; -(p6) add loc2=32+8*FLOAT_SZ,sp -(p6) br.cond.dptk.many fp_done - ;; /* Quiets warning; needed? */ - add loc2=32,sp - add loc3=32+FLOAT_SZ,sp - ;; - ldfd f8=[loc2],2*FLOAT_SZ - ldfd f9=[loc3],2*FLOAT_SZ - ;; - ldfd f10=[loc2],2*FLOAT_SZ - ldfd f11=[loc3],2*FLOAT_SZ - ;; - ldfd f12=[loc2],2*FLOAT_SZ - ldfd f13=[loc3],2*FLOAT_SZ - ;; - ldfd f14=[loc2],2*FLOAT_SZ - ldfd f15=[loc3] -fp_done: - add r9=16,sp /* Pointer to r8_contents */ - /* loc2 points at first integer register value. */ - add loc3=8,loc2 - ;; - ld8 r8=[r9] /* Just in case we return large struct */ - ld8 out0=[loc2],16 - ld8 out1=[loc3],16 - ;; - ld8 out2=[loc2],16 - ld8 out3=[loc3],16 - ;; - ld8 out4=[loc2],16 - ld8 out5=[loc3],16 - ;; - ld8 out6=[loc2],16 - ld8 out7=[loc3] - /* loc2 points at first stack parameter. Set sp to 16 bytes */ - /* below that. */ - add sp=-16,loc2 - - ld8 r8=[fn],8 - ;; - ld8 r1=[fn] /* Set up gp */ - mov b6=r8;; - br.call.sptk.many b0 = b6 /* call ffi_prep_args */ - - /* Handle return value. */ - cmp.eq p6,p0=0,raddr - cmp.eq p7,p0=FFI_TYPE_INT,flags - cmp.eq p10,p0=FFI_IS_SMALL_STRUCT2,flags - cmp.eq p11,p0=FFI_IS_SMALL_STRUCT3,flags - cmp.eq p12,p0=FFI_IS_SMALL_STRUCT4,flags - ;; -(p6) br.cond.dpnt.few done /* Dont copy ret values if raddr = 0 */ -(p7) br.cond.dptk.few copy1 -(p10) br.cond.dpnt.few copy2 -(p11) br.cond.dpnt.few copy3 -(p12) br.cond.dpnt.few copy4 - cmp.eq p8,p0=FFI_TYPE_FLOAT,flags - cmp.eq p9,p0=FFI_TYPE_DOUBLE,flags - tbit.nz p6,p0=flags,FLOAT_FP_AGGREGATE_BIT - tbit.nz p7,p0=flags,DOUBLE_FP_AGGREGATE_BIT - ;; -(p8) stfs [raddr]=f8 -(p9) stfd [raddr]=f8 - ;; -(p6) br.cond.dpnt.few handle_float_hfa -(p7) br.cond.dpnt.few handle_double_hfa - br done - -copy4: - add loc3=24,raddr - ;; - st8 [loc3]=r11 -copy3: - add loc3=16,raddr - ;; - st8 [loc3]=r10 -copy2: - add loc3=8,raddr - ;; - st8 [loc3]=r9 -copy1: - st8 [raddr]=r8 - /* In the big struct case, raddr was passed as an argument. */ - /* In the void case there was nothing to do. */ - -done: - mov r1=loc4 /* Restore gp */ - mov ar.pfs = loc0 - mov b0 = loc1 - br.ret.sptk.many b0 - -handle_double_hfa: - /* Homogeneous floating point array of doubles is returned in */ - /* registers f8-f15. Save one at a time to return area. */ - and flags=0xf,flags /* Retrieve size */ - ;; - cmp.eq p6,p0=2,flags - cmp.eq p7,p0=3,flags - cmp.eq p8,p0=4,flags - cmp.eq p9,p0=5,flags - cmp.eq p10,p0=6,flags - cmp.eq p11,p0=7,flags - cmp.eq p12,p0=8,flags - ;; -(p6) br.cond.dptk.few dhfa2 -(p7) br.cond.dptk.few dhfa3 -(p8) br.cond.dptk.few dhfa4 -(p9) br.cond.dptk.few dhfa5 -(p10) br.cond.dptk.few dhfa6 -(p11) br.cond.dptk.few dhfa7 -dhfa8: add loc3=7*8,raddr - ;; - stfd [loc3]=f15 -dhfa7: add loc3=6*8,raddr - ;; - stfd [loc3]=f14 -dhfa6: add loc3=5*8,raddr - ;; - stfd [loc3]=f13 -dhfa5: add loc3=4*8,raddr - ;; - stfd [loc3]=f12 -dhfa4: add loc3=3*8,raddr - ;; - stfd [loc3]=f11 -dhfa3: add loc3=2*8,raddr - ;; - stfd [loc3]=f10 -dhfa2: add loc3=1*8,raddr - ;; - stfd [loc3]=f9 - stfd [raddr]=f8 - br done - -handle_float_hfa: - /* Homogeneous floating point array of floats is returned in */ - /* registers f8-f15. Save one at a time to return area. */ - and flags=0xf,flags /* Retrieve size */ - ;; - cmp.eq p6,p0=2,flags - cmp.eq p7,p0=3,flags - cmp.eq p8,p0=4,flags - cmp.eq p9,p0=5,flags - cmp.eq p10,p0=6,flags - cmp.eq p11,p0=7,flags - cmp.eq p12,p0=8,flags - ;; -(p6) br.cond.dptk.few shfa2 -(p7) br.cond.dptk.few shfa3 -(p8) br.cond.dptk.few shfa4 -(p9) br.cond.dptk.few shfa5 -(p10) br.cond.dptk.few shfa6 -(p11) br.cond.dptk.few shfa7 -shfa8: add loc3=7*4,raddr - ;; - stfd [loc3]=f15 -shfa7: add loc3=6*4,raddr - ;; - stfd [loc3]=f14 -shfa6: add loc3=5*4,raddr - ;; - stfd [loc3]=f13 -shfa5: add loc3=4*4,raddr - ;; - stfd [loc3]=f12 -shfa4: add loc3=3*4,raddr - ;; - stfd [loc3]=f11 -shfa3: add loc3=2*4,raddr - ;; - stfd [loc3]=f10 -shfa2: add loc3=1*4,raddr - ;; - stfd [loc3]=f9 - stfd [raddr]=f8 - br done - - .endp ffi_call_unix - - -.text - .align 16 - .global ffi_closure_UNIX - .proc ffi_closure_UNIX -ffi_closure_UNIX: - alloc loc0=ar.pfs,8,2,2,0 - mov loc1=b0 - /* Retrieve closure pointer and real gp. */ - mov out0=gp - add gp=16,gp - ;; - ld8 gp=[gp] - /* Reserve a structia64_args on the stack such that arguments */ - /* past the first 8 are automatically placed in the right */ - /* slot. Note that when we start the sp points at 2 8-byte */ - /* scratch words, followed by the extra arguments. */ -# define BASIC_ARGS_SZ (8*FLOAT_SZ+8*8+2*8) -# define FIRST_FP_OFFSET (4*8) - add r14=-(BASIC_ARGS_SZ-FIRST_FP_OFFSET),sp - add r15=-(BASIC_ARGS_SZ-FIRST_FP_OFFSET-FLOAT_SZ),sp - add sp=-BASIC_ARGS_SZ,sp - /* r14 points to fp_regs[0], r15 points to fp_regs[1] */ - ;; - stfd [r14]=f8,2*FLOAT_SZ - stfd [r15]=f9,2*FLOAT_SZ - ;; - stfd [r14]=f10,2*FLOAT_SZ - stfd [r15]=f11,2*FLOAT_SZ - ;; - stfd [r14]=f12,2*FLOAT_SZ - stfd [r15]=f13,2*FLOAT_SZ - ;; - stfd [r14]=f14,FLOAT_SZ+8 - stfd [r15]=f15,2*8 - ;; - /* r14 points to first parameter register area, r15 to second. */ - st8 [r14]=in0,2*8 - st8 [r15]=in1,2*8 - ;; - st8 [r14]=in2,2*8 - st8 [r15]=in3,2*8 - ;; - st8 [r14]=in4,2*8 - st8 [r15]=in5,2*8 - ;; - st8 [r14]=in6,2*8 - st8 [r15]=in7,2*8 - /* Call ffi_closure_UNIX_inner */ - mov out1=sp - br.call.sptk.many b0=ffi_closure_UNIX_inner - ;; - mov b0=loc1 - mov ar.pfs=loc0 - br.ret.sptk.many b0 - .endp ffi_closure_UNIX - - diff --git a/libffi/src/java_raw_api.c b/libffi/src/java_raw_api.c deleted file mode 100644 index d330507..0000000 --- a/libffi/src/java_raw_api.c +++ /dev/null @@ -1,271 +0,0 @@ -/* ----------------------------------------------------------------------- - java_raw_api.c - Copyright (c) 1999 Cygnus Solutions - - Cloned from raw_api.c - - Raw_api.c author: Kresten Krab Thorup - Java_raw_api.c author: Hans-J. Boehm - - $Id $ - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -/* This defines a Java- and 64-bit specific variant of the raw API. */ -/* It assumes that "raw" argument blocks look like Java stacks on a */ -/* 64-bit machine. Arguments that can be stored in a single stack */ -/* stack slots (longs, doubles) occupy 128 bits, but only the first */ -/* 64 bits are actually used. */ - -#include -#include - -#if !defined(NO_JAVA_RAW_API) && !defined(FFI_NO_RAW_API) - -size_t -ffi_java_raw_size (ffi_cif *cif) -{ - size_t result = 0; - int i; - - ffi_type **at = cif->arg_types; - - for (i = cif->nargs-1; i >= 0; i--, at++) - { - switch((*at) -> type) { - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - result += 2 * SIZEOF_ARG; - break; - case FFI_TYPE_STRUCT: - /* No structure parameters in Java. */ - abort(); - default: - result += SIZEOF_ARG; - } - } - - return result; -} - - -void -ffi_java_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) -{ - unsigned i; - ffi_type **tp = cif->arg_types; - -#if WORDS_BIGENDIAN - - for (i = 0; i < cif->nargs; i++, tp++, args++) - { - switch ((*tp)->type) - { - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 1); - break; - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 2); - break; - -#if SIZEOF_ARG >= 4 - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 4); - break; -#endif - -#if SIZEOF_ARG == 8 - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - *args = (void *)raw; - raw += 2; - break; -#endif - - case FFI_TYPE_POINTER: - *args = (void*) &(raw++)->ptr; - break; - - default: - *args = raw; - raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG; - } - } - -#else /* WORDS_BIGENDIAN */ - -#if !PDP - - /* then assume little endian */ - for (i = 0; i < cif->nargs; i++, tp++, args++) - { -#if SIZEOF_ARG == 8 - switch((*tp)->type) { - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - *args = (void*) raw; - raw += 2; - break; - default: - *args = (void*) raw++; - } -#else /* SIZEOF_ARG != 8 */ - *args = (void*) raw; - raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); -#endif /* SIZEOF_ARG == 8 */ - } - -#else -#error "pdp endian not supported" -#endif /* ! PDP */ - -#endif /* WORDS_BIGENDIAN */ -} - -void -ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) -{ - unsigned i; - ffi_type **tp = cif->arg_types; - - for (i = 0; i < cif->nargs; i++, tp++, args++) - { - switch ((*tp)->type) - { - case FFI_TYPE_UINT8: - (raw++)->uint = *(UINT8*) (*args); - break; - - case FFI_TYPE_SINT8: - (raw++)->sint = *(SINT8*) (*args); - break; - - case FFI_TYPE_UINT16: - (raw++)->uint = *(UINT16*) (*args); - break; - - case FFI_TYPE_SINT16: - (raw++)->sint = *(SINT16*) (*args); - break; - -#if SIZEOF_ARG >= 4 - case FFI_TYPE_UINT32: - (raw++)->uint = *(UINT32*) (*args); - break; - - case FFI_TYPE_SINT32: - (raw++)->sint = *(SINT32*) (*args); - break; -#endif - case FFI_TYPE_FLOAT: - (raw++)->flt = *(FLOAT32*) (*args); - break; - -#if SIZEOF_ARG == 8 - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - case FFI_TYPE_DOUBLE: - raw->uint = *(UINT64*) (*args); - raw += 2; - break; -#endif - - case FFI_TYPE_POINTER: - (raw++)->ptr = **(void***) args; - break; - - default: -#if SIZEOF_ARG == 8 - FFI_ASSERT(FALSE); /* Should have covered all cases */ -#else - memcpy ((void*) raw->data, (void*)*args, (*tp)->size); - raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG; -#endif - } - } -} - -#if !FFI_NATIVE_RAW_API - - -/* This is a generic definition of ffi_raw_call, to be used if the - * native system does not provide a machine-specific implementation. - * Having this, allows code to be written for the raw API, without - * the need for system-specific code to handle input in that format; - * these following couple of functions will handle the translation forth - * and back automatically. */ - -void ffi_java_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *raw) -{ - void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); - ffi_java_raw_to_ptrarray (cif, raw, avalue); - ffi_call (cif, fn, rvalue, avalue); -} - -#if FFI_CLOSURES /* base system provides closures */ - -static void -ffi_java_translate_args (ffi_cif *cif, void *rvalue, - void **avalue, void *user_data) -{ - ffi_raw *raw = (ffi_raw*)alloca (ffi_java_raw_size (cif)); - ffi_raw_closure *cl = (ffi_raw_closure*)user_data; - - ffi_java_ptrarray_to_raw (cif, avalue, raw); - (*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_prep_java_raw_closure (ffi_raw_closure* cl, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) -{ - ffi_status status; - - status = ffi_prep_closure ((ffi_closure*) cl, - cif, - &ffi_java_translate_args, - (void*)cl); - if (status == FFI_OK) - { - cl->fun = fun; - cl->user_data = user_data; - } - - return status; -} - -#endif /* FFI_CLOSURES */ -#endif /* !FFI_NATIVE_RAW_API */ -#endif /* !FFI_NO_RAW_API */ diff --git a/libffi/src/m68k/ffi.c b/libffi/src/m68k/ffi.c deleted file mode 100644 index c5d9507..0000000 --- a/libffi/src/m68k/ffi.c +++ /dev/null @@ -1,184 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - - m68k Foreign Function Interface - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -/* ffi_prep_args is called by the assembly routine once stack space has - been allocated for the function's arguments. */ - -static void * -ffi_prep_args (void *stack, extended_cif *ecif) -{ - unsigned int i; - int tmp; - unsigned int avn; - void **p_argv; - char *argp; - ffi_type **p_arg; - void *struct_value_ptr; - - tmp = 0; - argp = stack; - - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT - && ecif->cif->rtype->size > 8) - struct_value_ptr = ecif->rvalue; - else - struct_value_ptr = NULL; - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i != 0 && avn != 0; - i--, p_arg++) - { - size_t z; - - /* Align if necessary. */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) - argp = (char *) ALIGN (argp, (*p_arg)->alignment); - - if (avn != 0) - { - avn--; - z = (*p_arg)->size; - if (z < sizeof (int)) - { - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int) *(SINT8 *) *p_argv; - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int) *(UINT8 *) *p_argv; - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int) *(SINT16 *) *p_argv; - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int) *(UINT16 *) *p_argv; - break; - - case FFI_TYPE_STRUCT: - memcpy (argp + sizeof (int) - z, *p_argv, z); - break; - - default: - FFI_ASSERT (0); - } - z = sizeof (int); - } - else - memcpy (argp, *p_argv, z); - p_argv++; - argp += z; - } - } - - return struct_value_ptr; -} - -#define CIF_FLAGS_INT 1 -#define CIF_FLAGS_DINT 2 -#define CIF_FLAGS_FLOAT 4 -#define CIF_FLAGS_DOUBLE 8 -#define CIF_FLAGS_LDOUBLE 16 -#define CIF_FLAGS_POINTER 32 -#define CIF_FLAGS_STRUCT 64 - -/* Perform machine dependent cif processing */ -ffi_status -ffi_prep_cif_machdep (ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - cif->flags = 0; - break; - - case FFI_TYPE_STRUCT: - if (cif->rtype->size > 4 && cif->rtype->size <= 8) - cif->flags = CIF_FLAGS_DINT; - else if (cif->rtype->size <= 4) - cif->flags = CIF_FLAGS_STRUCT; - else - cif->flags = 0; - break; - - case FFI_TYPE_FLOAT: - cif->flags = CIF_FLAGS_FLOAT; - break; - - case FFI_TYPE_DOUBLE: - cif->flags = CIF_FLAGS_DOUBLE; - break; - - case FFI_TYPE_LONGDOUBLE: - cif->flags = CIF_FLAGS_LDOUBLE; - break; - - case FFI_TYPE_POINTER: - cif->flags = CIF_FLAGS_POINTER; - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - cif->flags = CIF_FLAGS_DINT; - break; - - default: - cif->flags = CIF_FLAGS_INT; - break; - } - - return FFI_OK; -} - -extern void ffi_call_SYSV (void *(*) (void *, extended_cif *), - extended_cif *, - unsigned, unsigned, unsigned, - void *, void (*fn) ()); - -void -ffi_call (ffi_cif *cif, void (*fn) (), void *rvalue, void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return value - address then we need to make one. */ - - if (rvalue == NULL - && cif->rtype->type == FFI_TYPE_STRUCT - && cif->rtype->size > 8) - ecif.rvalue = alloca (cif->rtype->size); - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - ffi_call_SYSV (ffi_prep_args, &ecif, cif->bytes, - cif->flags, cif->rtype->size * 8, - ecif.rvalue, fn); - break; - - default: - FFI_ASSERT (0); - break; - } -} diff --git a/libffi/src/m68k/sysv.S b/libffi/src/m68k/sysv.S deleted file mode 100644 index a925d99..0000000 --- a/libffi/src/m68k/sysv.S +++ /dev/null @@ -1,96 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - - m68k Foreign Function Interface - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include - - .text - - .globl ffi_call_SYSV - .type ffi_call_SYSV,@function - -ffi_call_SYSV: - link %fp,#0 - move.l %d2,-(%sp) - - | Make room for all of the new args. - sub.l 16(%fp),%sp - - | Call ffi_prep_args - move.l 12(%fp),-(%sp) - pea 4(%sp) - move.l 8(%fp),%a0 - jsr (%a0) - addq.l #8,%sp - - | Pass pointer to struct value, if any - move.l %a0,%a1 - - | Call the function - move.l 32(%fp),%a0 - jsr (%a0) - - | Remove the space we pushed for the args - add.l 16(%fp),%sp - - | Load the pointer to storage for the return value - move.l 28(%fp),%a1 - - | Load the return type code - move.l 20(%fp),%d2 - - | If the return value pointer is NULL, assume no return value. - tst.l %a1 - jbeq noretval - - btst #0,%d2 - jbeq retlongint - move.l %d0,(%a1) - jbra epilogue - -retlongint: - btst #1,%d2 - jbeq retfloat - move.l %d0,(%a1) - move.l %d1,4(%a1) - jbra epilogue - -retfloat: - btst #2,%d2 - jbeq retdouble - fmove.s %fp0,(%a1) - jbra epilogue - -retdouble: - btst #3,%d2 - jbeq retlongdouble - fmove.d %fp0,(%a1) - jbra epilogue - -retlongdouble: - btst #4,%d2 - jbeq retpointer - fmove.x %fp0,(%a1) - jbra epilogue - -retpointer: - btst #5,%d2 - jbeq retstruct - move.l %a0,(%a1) - jbra epilogue - -retstruct: - btst #6,%d2 - jbeq noretval - move.l 24(%fp),%d2 - bfins %d0,(%a1){#0,%d2} - -noretval: -epilogue: - move.l (%sp)+,%d2 - unlk %a6 - rts - .size ffi_call_SYSV,.-ffi_call_SYSV diff --git a/libffi/src/mips/ffi.c b/libffi/src/mips/ffi.c deleted file mode 100644 index ca3971f..0000000 --- a/libffi/src/mips/ffi.c +++ /dev/null @@ -1,469 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996 Cygnus Solutions - - MIPS Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -#if _MIPS_SIM == _MIPS_SIM_NABI32 -#define FIX_ARGP \ -FFI_ASSERT(argp <= &stack[bytes]); \ -if (argp == &stack[bytes]) \ -{ \ - argp = stack; \ - ffi_stop_here(); \ -} -#else -#define FIX_ARGP -#endif - - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -static void ffi_prep_args(char *stack, - extended_cif *ecif, - int bytes, - int flags) -{ - register int i; - register int avn; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - /* If more than 8 double words are used, the remainder go - on the stack. We reorder stuff on the stack here to - support this easily. */ - if (bytes > 8 * SIZEOF_ARG) - argp = &stack[bytes - (8 * SIZEOF_ARG)]; - else - argp = stack; -#else - argp = stack; -#endif - - memset(stack, 0, bytes); - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - if ( ecif->cif->rstruct_flag != 0 ) -#else - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) -#endif - { - *(SLOT_TYPE_UNSIGNED *) argp = (SLOT_TYPE_UNSIGNED) ecif->rvalue; - argp += sizeof(SLOT_TYPE_UNSIGNED); - FIX_ARGP; - } - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i && avn; - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, (*p_arg)->alignment); - FIX_ARGP; - } - -#if _MIPS_SIM == _MIPS_SIM_ABI32 -#define OFFSET 0 -#else -#define OFFSET sizeof(int) -#endif - - if (avn) - { - avn--; - z = (*p_arg)->size; - if (z < sizeof(SLOT_TYPE_UNSIGNED)) - { - z = sizeof(SLOT_TYPE_UNSIGNED); - - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(SINT32 *) &argp[OFFSET] = (SINT32)*(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - case FFI_TYPE_POINTER: - *(UINT32 *) &argp[OFFSET] = (UINT32)*(UINT32 *)(* p_argv); - break; - - /* This can only happen with 64bit slots */ - case FFI_TYPE_FLOAT: - *(float *) argp = *(float *)(* p_argv); - break; - - /* Handle small structures */ - case FFI_TYPE_STRUCT: - memcpy(argp, *p_argv, (*p_arg)->size); - break; - - default: - FFI_ASSERT(0); - } - } - else - { -#if _MIPS_SIM == _MIPS_SIM_ABI32 - memcpy(argp, *p_argv, z); -#else - { - unsigned end = (unsigned) argp+z; - unsigned cap = (unsigned) stack+bytes; - - /* Check if the data will fit within the register - space. Handle it if it doesn't. */ - - if (end <= cap) - memcpy(argp, *p_argv, z); - else - { - unsigned portion = end - cap; - - memcpy(argp, *p_argv, portion); - argp = stack; - memcpy(argp, - (void*)((unsigned)(*p_argv)+portion), z - portion); - } - } -#endif - } - p_argv++; - argp += z; - FIX_ARGP; - } - } - - return; -} - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - -/* 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 - is passed in a floating point register. Any other chunk is - passed in an integer register". This code traverses structure - definitions and generates the appropriate flags. */ - -unsigned calc_n32_struct_flags(ffi_type *arg, unsigned *shift) -{ - unsigned flags = 0; - unsigned index = 0; - - ffi_type *e; - - while (e = arg->elements[index]) - { - if (e->type == FFI_TYPE_DOUBLE) - { - flags += (FFI_TYPE_DOUBLE << *shift); - *shift += FFI_FLAG_BITS; - } - else if (e->type == FFI_TYPE_STRUCT) - flags += calc_n32_struct_flags(e, shift); - else - *shift += FFI_FLAG_BITS; - - index++; - } - - return flags; -} - -unsigned calc_n32_return_struct_flags(ffi_type *arg) -{ - unsigned flags = 0; - unsigned index = 0; - unsigned small = FFI_TYPE_SMALLSTRUCT; - ffi_type *e; - - /* Returning structures under n32 is a tricky thing. - A struct with only one or two floating point fields - is returned in $f0 (and $f2 if necessary). Any other - struct results at most 128 bits are returned in $2 - (the first 64 bits) and $3 (remainder, if necessary). - Larger structs are handled normally. */ - - if (arg->size > 16) - return 0; - - if (arg->size > 8) - small = FFI_TYPE_SMALLSTRUCT2; - - e = arg->elements[0]; - if (e->type == FFI_TYPE_DOUBLE) - flags = FFI_TYPE_DOUBLE << FFI_FLAG_BITS; - else if (e->type == FFI_TYPE_FLOAT) - flags = FFI_TYPE_FLOAT << FFI_FLAG_BITS; - - if (flags && (e = arg->elements[1])) - { - if (e->type == FFI_TYPE_DOUBLE) - flags += FFI_TYPE_DOUBLE; - else if (e->type == FFI_TYPE_FLOAT) - flags += FFI_TYPE_FLOAT; - else - return small; - - if (flags && (arg->elements[2])) - { - /* There are three arguments and the first two are - floats! This must be passed the old way. */ - return small; - } - } - else - if (!flags) - return small; - - return flags; -} - -#endif - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - cif->flags = 0; - -#if _MIPS_SIM == _MIPS_SIM_ABI32 - /* Set the flags necessary for O32 processing */ - - if (cif->rtype->type != FFI_TYPE_STRUCT) - { - if (cif->nargs > 0) - { - switch ((cif->arg_types)[0]->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += (cif->arg_types)[0]->type; - break; - - default: - break; - } - - if (cif->nargs > 1) - { - /* Only handle the second argument if the first - is a float or double. */ - if (cif->flags) - { - switch ((cif->arg_types)[1]->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += (cif->arg_types)[1]->type << FFI_FLAG_BITS; - break; - - default: - break; - } - } - } - } - } - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 2); - break; - - default: - cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 2); - break; - } -#endif - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - /* Set the flags necessary for N32 processing */ - { - unsigned shift = 0; - unsigned count = (cif->nargs < 8) ? cif->nargs : 8; - unsigned index = 0; - - unsigned struct_flags = 0; - - if (cif->rtype->type == FFI_TYPE_STRUCT) - { - struct_flags = calc_n32_return_struct_flags(cif->rtype); - - if (struct_flags == 0) - { - /* This means that the structure is being passed as - a hidden argument */ - - shift = FFI_FLAG_BITS; - count = (cif->nargs < 7) ? cif->nargs : 7; - - cif->rstruct_flag = !0; - } - else - cif->rstruct_flag = 0; - } - else - cif->rstruct_flag = 0; - - while (count-- > 0) - { - switch ((cif->arg_types)[index]->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += ((cif->arg_types)[index]->type << shift); - shift += FFI_FLAG_BITS; - break; - - case FFI_TYPE_STRUCT: - cif->flags += calc_n32_struct_flags((cif->arg_types)[index], - &shift); - break; - - default: - shift += FFI_FLAG_BITS; - } - - index++; - } - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_STRUCT: - { - if (struct_flags == 0) - { - /* The structure is returned through a hidden - first argument. Do nothing, 'cause FFI_TYPE_VOID - is 0 */ - } - else - { - /* The structure is returned via some tricky - mechanism */ - cif->flags += FFI_TYPE_STRUCT << (FFI_FLAG_BITS * 8); - cif->flags += struct_flags << (4 + (FFI_FLAG_BITS * 8)); - } - break; - } - - case FFI_TYPE_VOID: - /* Do nothing, 'cause FFI_TYPE_VOID is 0 */ - break; - - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); - break; - - default: - cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); - break; - } - } -#endif - - return FFI_OK; -} - -/* Low level routine for calling O32 functions */ -extern int ffi_call_O32(void (*)(char *, extended_cif *, int, int), - extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); - -/* Low level routine for calling N32 functions */ -extern int ffi_call_N32(void (*)(char *, extended_cif *, int, int), - extended_cif *, unsigned, - unsigned, unsigned *, void (*)()); - -void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - ecif.rvalue = alloca(cif->rtype->size); - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { -#if _MIPS_SIM == _MIPS_SIM_ABI32 - case FFI_O32: - ffi_call_O32(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - break; -#endif - -#if _MIPS_SIM == _MIPS_SIM_NABI32 - case FFI_N32: - ffi_call_N32(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - break; -#endif - - default: - FFI_ASSERT(0); - break; - } -} diff --git a/libffi/src/mips/n32.S b/libffi/src/mips/n32.S deleted file mode 100644 index 04b5e40..0000000 --- a/libffi/src/mips/n32.S +++ /dev/null @@ -1,318 +0,0 @@ -/* ----------------------------------------------------------------------- - n32.S - Copyright (c) 1996, 1998 Cygnus Solutions - - MIPS Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include - -/* Only build this code if we are compiling for n32 */ - -#if defined(FFI_MIPS_N32) - -#define callback a0 -#define bytes a2 -#define flags a3 -#define raddr a4 -#define fn a5 - -#define SIZEOF_FRAME ( 8 * SIZEOF_ARG ) - - .text - .align 2 - .globl ffi_call_N32 - .ent ffi_call_N32 -ffi_call_N32: - - # Prologue - SUBU $sp, SIZEOF_FRAME # Frame size - REG_S $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Save frame pointer - REG_S ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Save return address - move $fp, $sp - - move t9, callback # callback function pointer - REG_S bytes, 2*SIZEOF_ARG($fp) # bytes - REG_S flags, 3*SIZEOF_ARG($fp) # flags - REG_S raddr, 4*SIZEOF_ARG($fp) # raddr - REG_S fn, 5*SIZEOF_ARG($fp) # fn - - # Allocate at least 4 words in the argstack - move v0, bytes - bge bytes, 4 * SIZEOF_ARG, bigger - LI v0, 4 * SIZEOF_ARG - b sixteen - - bigger: - ADDU t4, v0, 2 * SIZEOF_ARG -1 # make sure it is aligned - and v0, t4, -2 * SIZEOF_ARG # to a proper boundry. - -sixteen: - SUBU $sp, $sp, v0 # move the stack pointer to reflect the - # arg space - - ADDU a0, $sp, 0 # 4 * SIZEOF_ARG - ADDU a3, $fp, 3 * SIZEOF_ARG - - # Call ffi_prep_args - jal t9 - - # ADDU $sp, $sp, 4 * SIZEOF_ARG # adjust $sp to new args - - # Copy the stack pointer to t9 - move t9, $sp - - # Fix the stack if there are more than 8 64bit slots worth - # of arguments. - - # Load the number of bytes - REG_L t6, 2*SIZEOF_ARG($fp) - - # Is it bigger than 8 * SIZEOF_ARG? - dadd t7, $0, 8 * SIZEOF_ARG - dsub t8, t6, t7 - bltz t8, loadregs - - add t9, t9, t8 - -loadregs: - - REG_L t4, 3*SIZEOF_ARG($fp) # load the flags word - add t6, t4, 0 # and copy it into t6 - - and t4, ((1< - -/* Only build this code if we are compiling for o32 */ - -#if defined(FFI_MIPS_O32) - -#define callback a0 -#define bytes a2 -#define flags a3 - -#define SIZEOF_FRAME ( 4 * SIZEOF_ARG + 2 * SIZEOF_ARG ) - - .text - .align 2 - .globl ffi_call_O32 - .ent ffi_call_O32 -ffi_call_O32: - - # Prologue - SUBU $sp, SIZEOF_FRAME # Frame size - REG_S $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Save frame pointer - REG_S ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Save return address - move $fp, $sp - - move t9, callback # callback function pointer - REG_S flags, SIZEOF_FRAME + 3*SIZEOF_ARG($fp) # flags - - # Allocate at least 4 words in the argstack - move v0, bytes - bge bytes, 4 * SIZEOF_ARG, bigger - LI v0, 4 * SIZEOF_ARG - b sixteen - -bigger: - ADDU t0, v0, 2 * SIZEOF_ARG -1 # make sure it is aligned - and v0, t0, -2 * SIZEOF_ARG # to an 8 byte boundry - -sixteen: - SUBU $sp, $sp, v0 # move the stack pointer to reflect the - # arg space - - ADDU a0, $sp, 4 * SIZEOF_ARG - ADDU a3, $fp, SIZEOF_FRAME + 3*SIZEOF_ARG - - jal t9 - - REG_L t0, SIZEOF_FRAME + 3*SIZEOF_ARG($fp) # load the flags word - add t2, t0, 0 # and copy it into t2 - - and t0, ((1<<4)-1) # mask out the return type - SRL t2, 4 # shift our arg info - - ADDU $sp, $sp, 4 * SIZEOF_ARG # adjust $sp to new args - - bnez t0, pass_d # make it quick for int - REG_L a0, 0*SIZEOF_ARG($sp) # just go ahead and load the - REG_L a1, 1*SIZEOF_ARG($sp) # four regs. - REG_L a2, 2*SIZEOF_ARG($sp) - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_d: - bne t0, FFI_ARGS_D, pass_f - l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - REG_L a2, 2*SIZEOF_ARG($sp) # passing a double - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_f: - bne t0, FFI_ARGS_F, pass_d_d - l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - REG_L a1, 1*SIZEOF_ARG($sp) # passing a float - REG_L a2, 2*SIZEOF_ARG($sp) - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_d_d: - bne t0, FFI_ARGS_DD, pass_f_f - l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - l.d $f14, 2*SIZEOF_ARG($sp) # passing two doubles - b call_it - -pass_f_f: - bne t0, FFI_ARGS_FF, pass_d_f - l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - l.s $f14, 1*SIZEOF_ARG($sp) # passing two floats - REG_L a2, 2*SIZEOF_ARG($sp) - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_d_f: - bne t0, FFI_ARGS_DF, pass_f_d - l.d $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - l.s $f14, 2*SIZEOF_ARG($sp) # passing double and float - REG_L a3, 3*SIZEOF_ARG($sp) - b call_it - -pass_f_d: - # assume that the only other combination must be float then double - # bne t0, FFI_ARGS_F_D, call_it - l.s $f12, 0*SIZEOF_ARG($sp) # load $fp regs from args - l.d $f14, 2*SIZEOF_ARG($sp) # passing double and float - -call_it: - # Load the function pointer - REG_L t9, SIZEOF_FRAME + 5*SIZEOF_ARG($fp) - - # If the return value pointer is NULL, assume no return value. - REG_L t1, SIZEOF_FRAME + 4*SIZEOF_ARG($fp) - beqz t1, noretval - - bne t2, FFI_TYPE_INT, retfloat - jal t9 - REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp) - REG_S v0, 0(t0) - b epilogue - -retfloat: - bne t2, FFI_TYPE_FLOAT, retdouble - jal t9 - REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp) - s.s $f0, 0(t0) - b epilogue - -retdouble: - bne t2, FFI_TYPE_DOUBLE, noretval - jal t9 - REG_L t0, SIZEOF_FRAME + 4*SIZEOF_ARG($fp) - s.d $f0, 0(t0) - b epilogue - -noretval: - jal t9 - - # Epilogue -epilogue: - move $sp, $fp - REG_L $fp, SIZEOF_FRAME - 2*SIZEOF_ARG($sp) # Restore frame pointer - REG_L ra, SIZEOF_FRAME - 1*SIZEOF_ARG($sp) # Restore return address - ADDU $sp, SIZEOF_FRAME # Fix stack pointer - j ra - - .end ffi_call_O32 - -#endif diff --git a/libffi/src/powerpc/asm.h b/libffi/src/powerpc/asm.h deleted file mode 100644 index 40073d7..0000000 --- a/libffi/src/powerpc/asm.h +++ /dev/null @@ -1,128 +0,0 @@ -/* ----------------------------------------------------------------------- - asm.h - Copyright (c) 1998 Geoffrey Keating - - PowerPC Assembly glue. - - $Id: asm.h,v 1.1 1998/11/29 16:48:16 green Exp $ - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define ASM_GLOBAL_DIRECTIVE .globl - - -#define C_SYMBOL_NAME(name) name -/* Macro for a label. */ -#ifdef __STDC__ -#define C_LABEL(name) name##: -#else -#define C_LABEL(name) name/**/: -#endif - -/* This seems to always be the case on PPC. */ -#define ALIGNARG(log2) log2 -/* For ELF we need the `.type' directive to make shared libs work right. */ -#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg; -#define ASM_SIZE_DIRECTIVE(name) .size name,.-name - -/* If compiled for profiling, call `_mcount' at the start of each function. */ -#ifdef PROF -/* The mcount code relies on a the return address being on the stack - to locate our caller and so it can restore it; so store one just - for its benefit. */ -#ifdef PIC -#define CALL_MCOUNT \ - .pushsection; \ - .section ".data"; \ - .align ALIGNARG(2); \ -0:.long 0; \ - .previous; \ - mflr %r0; \ - stw %r0,4(%r1); \ - bl _GLOBAL_OFFSET_TABLE_@local-4; \ - mflr %r11; \ - lwz %r0,0b@got(%r11); \ - bl JUMPTARGET(_mcount); -#else /* PIC */ -#define CALL_MCOUNT \ - .section ".data"; \ - .align ALIGNARG(2); \ -0:.long 0; \ - .previous; \ - mflr %r0; \ - lis %r11,0b@ha; \ - stw %r0,4(%r1); \ - addi %r0,%r11,0b@l; \ - bl JUMPTARGET(_mcount); -#endif /* PIC */ -#else /* PROF */ -#define CALL_MCOUNT /* Do nothing. */ -#endif /* PROF */ - -#define ENTRY(name) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ - .align ALIGNARG(2); \ - C_LABEL(name) \ - CALL_MCOUNT - -#define EALIGN_W_0 /* No words to insert. */ -#define EALIGN_W_1 nop -#define EALIGN_W_2 nop;nop -#define EALIGN_W_3 nop;nop;nop -#define EALIGN_W_4 EALIGN_W_3;nop -#define EALIGN_W_5 EALIGN_W_4;nop -#define EALIGN_W_6 EALIGN_W_5;nop -#define EALIGN_W_7 EALIGN_W_6;nop - -/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes - past a 2^align boundary. */ -#ifdef PROF -#define EALIGN(name, alignt, words) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ - .align ALIGNARG(2); \ - C_LABEL(name) \ - CALL_MCOUNT \ - b 0f; \ - .align ALIGNARG(alignt); \ - EALIGN_W_##words; \ - 0: -#else /* PROF */ -#define EALIGN(name, alignt, words) \ - ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name); \ - ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function) \ - .align ALIGNARG(alignt); \ - EALIGN_W_##words; \ - C_LABEL(name) -#endif - -#define END(name) \ - ASM_SIZE_DIRECTIVE(name) - -#ifdef PIC -#define JUMPTARGET(name) name##@plt -#else -#define JUMPTARGET(name) name -#endif - -/* Local labels stripped out by the linker. */ -#define L(x) .L##x - diff --git a/libffi/src/powerpc/ffi.c b/libffi/src/powerpc/ffi.c deleted file mode 100644 index 05454d5..0000000 --- a/libffi/src/powerpc/ffi.c +++ /dev/null @@ -1,680 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1998 Geoffrey Keating - - PowerPC Foreign Function Interface - - $Id: ffi.c,v 1.2 2001/04/09 00:58:37 green Exp $ - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include -#include - -extern void ffi_closure_SYSV(void); - -enum { - /* The assembly depends on these exact flags. */ - FLAG_RETURNS_NOTHING = 1 << (31-30), /* These go in cr7 */ - FLAG_RETURNS_FP = 1 << (31-29), - FLAG_RETURNS_64BITS = 1 << (31-28), - - FLAG_ARG_NEEDS_COPY = 1 << (31- 7), - FLAG_FP_ARGUMENTS = 1 << (31- 6), /* cr1.eq; specified by ABI */ - FLAG_4_GPR_ARGUMENTS = 1 << (31- 5), - FLAG_RETVAL_REFERENCE = 1 << (31- 4) -}; - -/* About the SYSV ABI. */ -enum { - NUM_GPR_ARG_REGISTERS = 8, - NUM_FPR_ARG_REGISTERS = 8 -}; -enum { ASM_NEEDS_REGISTERS = 4 }; - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments. - - The stack layout we want looks like this: - - | Return address from ffi_call_SYSV 4bytes | higher addresses - |--------------------------------------------| - | Previous backchain pointer 4 | stack pointer here - |--------------------------------------------|<+ <<< on entry to - | Saved r28-r31 4*4 | | ffi_call_SYSV - |--------------------------------------------| | - | GPR registers r3-r10 8*4 | | ffi_call_SYSV - |--------------------------------------------| | - | FPR registers f1-f8 (optional) 8*8 | | - |--------------------------------------------| | stack | - | Space for copied structures | | grows | - |--------------------------------------------| | down V - | Parameters that didn't fit in registers | | - |--------------------------------------------| | lower addresses - | Space for callee's LR 4 | | - |--------------------------------------------| | stack pointer here - | Current backchain pointer 4 |-/ during - |--------------------------------------------| <<< ffi_call_SYSV - - */ - -/*@-exportheader@*/ -void ffi_prep_args(extended_cif *ecif, unsigned *const stack) -/*@=exportheader@*/ -{ - const unsigned bytes = ecif->cif->bytes; - const unsigned flags = ecif->cif->flags; - - /* 'stacktop' points at the previous backchain pointer. */ - unsigned *const stacktop = stack + (ecif->cif->bytes / sizeof(unsigned)); - - /* 'gpr_base' points at the space for gpr3, and grows upwards as - we use GPR registers. */ - unsigned *gpr_base = stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS; - int intarg_count = 0; - - /* 'fpr_base' points at the space for fpr1, and grows upwards as - we use FPR registers. */ - double *fpr_base = (double *)gpr_base - NUM_FPR_ARG_REGISTERS; - int fparg_count = 0; - - /* 'copy_space' grows down as we put structures in it. It should - stay 16-byte aligned. */ - char *copy_space = ((flags & FLAG_FP_ARGUMENTS) - ? (char *)fpr_base - : (char *)gpr_base); - - /* 'next_arg' grows up as we put parameters in it. */ - unsigned *next_arg = stack + 2; - - int i; - ffi_type **ptr; - double double_tmp; - void **p_argv; - size_t struct_copy_size; - unsigned gprvalue; - - /* Check that everything starts aligned properly. */ - FFI_ASSERT(((unsigned)(char *)stack & 0xF) == 0); - FFI_ASSERT(((unsigned)(char *)copy_space & 0xF) == 0); - FFI_ASSERT(((unsigned)(char *)stacktop & 0xF) == 0); - FFI_ASSERT((bytes & 0xF) == 0); - FFI_ASSERT(copy_space >= (char *)next_arg); - - /* Deal with return values that are actually pass-by-reference. */ - if (flags & FLAG_RETVAL_REFERENCE) - { - *gpr_base++ = (unsigned)(char *)ecif->rvalue; - intarg_count++; - } - - /* Now for the arguments. */ - p_argv = ecif->avalue; - for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; - i > 0; - i--, ptr++, p_argv++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - if ((*ptr)->type == FFI_TYPE_FLOAT) - double_tmp = *(float *)*p_argv; - else - double_tmp = *(double *)*p_argv; - - if (fparg_count >= NUM_FPR_ARG_REGISTERS) - { - if (intarg_count%2 != 0) - { - intarg_count++; - next_arg++; - } - *(double *)next_arg = double_tmp; - next_arg += 2; - } - else - *fpr_base++ = double_tmp; - fparg_count++; - FFI_ASSERT(flags & FLAG_FP_ARGUMENTS); - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - if (intarg_count == NUM_GPR_ARG_REGISTERS-1) - intarg_count++; - if (intarg_count >= NUM_GPR_ARG_REGISTERS) - { - if (intarg_count%2 != 0) - { - intarg_count++; - next_arg++; - } - *(long long *)next_arg = *(long long *)*p_argv; - next_arg += 2; - } - else - { - /* whoops: abi states only certain register pairs - * can be used for passing long long int - * specifically (r3,r4), (r5,r6), (r7,r8), - * (r9,r10) and if next arg is long long but - * not correct starting register of pair then skip - * until the proper starting register - */ - if (intarg_count%2 != 0) - { - intarg_count ++; - gpr_base++; - } - *(long long *)gpr_base = *(long long *)*p_argv; - gpr_base += 2; - } - intarg_count += 2; - break; - - case FFI_TYPE_STRUCT: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - struct_copy_size = ((*ptr)->size + 15) & ~0xF; - copy_space -= struct_copy_size; - memcpy(copy_space, (char *)*p_argv, (*ptr)->size); - - gprvalue = (unsigned)copy_space; - - FFI_ASSERT(copy_space > (char *)next_arg); - FFI_ASSERT(flags & FLAG_ARG_NEEDS_COPY); - goto putgpr; - - case FFI_TYPE_UINT8: - gprvalue = *(unsigned char *)*p_argv; - goto putgpr; - case FFI_TYPE_SINT8: - gprvalue = *(signed char *)*p_argv; - goto putgpr; - case FFI_TYPE_UINT16: - gprvalue = *(unsigned short *)*p_argv; - goto putgpr; - case FFI_TYPE_SINT16: - gprvalue = *(signed short *)*p_argv; - goto putgpr; - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - gprvalue = *(unsigned *)*p_argv; - putgpr: - if (intarg_count >= NUM_GPR_ARG_REGISTERS) - *next_arg++ = gprvalue; - else - *gpr_base++ = gprvalue; - intarg_count++; - break; - } - } - - /* Check that we didn't overrun the stack... */ - FFI_ASSERT(copy_space >= (char *)next_arg); - FFI_ASSERT(gpr_base <= stacktop - ASM_NEEDS_REGISTERS); - FFI_ASSERT((unsigned *)fpr_base - <= stacktop - ASM_NEEDS_REGISTERS - NUM_GPR_ARG_REGISTERS); - FFI_ASSERT(flags & FLAG_4_GPR_ARGUMENTS || intarg_count <= 4); -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* All this is for the SYSV ABI. */ - int i; - ffi_type **ptr; - unsigned bytes; - int fparg_count = 0, intarg_count = 0; - unsigned flags = 0; - unsigned struct_copy_size = 0; - - /* All the machine-independent calculation of cif->bytes will be wrong. - Redo the calculation for SYSV. */ - - /* Space for the frame pointer, callee's LR, and the asm's temp regs. */ - bytes = (2 + ASM_NEEDS_REGISTERS) * sizeof(int); - - /* Space for the GPR registers. */ - bytes += NUM_GPR_ARG_REGISTERS * sizeof(int); - - /* Return value handling. The rules are as follows: - - 32-bit (or less) integer values are returned in gpr3; - - Structures of size <= 4 bytes also returned in gpr3; - - 64-bit integer values and structures between 5 and 8 bytes are returned - in gpr3 and gpr4; - - Single/double FP values are returned in fpr1; - - Larger structures and long double (if not equivalent to double) values - are allocated space and a pointer is passed as the first argument. */ - switch (cif->rtype->type) - { - case FFI_TYPE_DOUBLE: - flags |= FLAG_RETURNS_64BITS; - /* Fall through. */ - case FFI_TYPE_FLOAT: - flags |= FLAG_RETURNS_FP; - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - flags |= FLAG_RETURNS_64BITS; - break; - - case FFI_TYPE_STRUCT: - if (cif->abi != FFI_GCC_SYSV) - if (cif->rtype->size <= 4) - break; - else if (cif->rtype->size <= 8) - { - flags |= FLAG_RETURNS_64BITS; - break; - } - /* else fall through. */ -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - intarg_count++; - flags |= FLAG_RETVAL_REFERENCE; - /* Fall through. */ - case FFI_TYPE_VOID: - flags |= FLAG_RETURNS_NOTHING; - break; - - default: - /* Returns 32-bit integer, or similar. Nothing to do here. */ - break; - } - - /* The first NUM_GPR_ARG_REGISTERS words of integer arguments, and the - first NUM_FPR_ARG_REGISTERS fp arguments, go in registers; the rest - goes on the stack. Structures and long doubles (if not equivalent - to double) are passed as a pointer to a copy of the structure. - Stuff on the stack needs to keep proper alignment. */ - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - fparg_count++; - /* If this FP arg is going on the stack, it must be - 8-byte-aligned. */ - if (fparg_count > NUM_FPR_ARG_REGISTERS - && intarg_count%2 != 0) - intarg_count++; - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - /* 'long long' arguments are passed as two words, but - either both words must fit in registers or both go - on the stack. If they go on the stack, they must - be 8-byte-aligned. */ - if (intarg_count == NUM_GPR_ARG_REGISTERS-1 - || intarg_count >= NUM_GPR_ARG_REGISTERS && intarg_count%2 != 0) - intarg_count++; - intarg_count += 2; - break; - - case FFI_TYPE_STRUCT: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - /* We must allocate space for a copy of these to enforce - pass-by-value. Pad the space up to a multiple of 16 - bytes (the maximum alignment required for anything under - the SYSV ABI). */ - struct_copy_size += ((*ptr)->size + 15) & ~0xF; - /* Fall through (allocate space for the pointer). */ - - default: - /* Everything else is passed as a 4-byte word in a GPR, either - the object itself or a pointer to it. */ - intarg_count++; - break; - } - } - - if (fparg_count != 0) - flags |= FLAG_FP_ARGUMENTS; - if (intarg_count > 4) - flags |= FLAG_4_GPR_ARGUMENTS; - if (struct_copy_size != 0) - flags |= FLAG_ARG_NEEDS_COPY; - - /* Space for the FPR registers, if needed. */ - if (fparg_count != 0) - bytes += NUM_FPR_ARG_REGISTERS * sizeof(double); - - /* Stack space. */ - if (intarg_count > NUM_GPR_ARG_REGISTERS) - bytes += (intarg_count - NUM_GPR_ARG_REGISTERS) * sizeof(int); - if (fparg_count > NUM_FPR_ARG_REGISTERS) - bytes += (fparg_count - NUM_FPR_ARG_REGISTERS) * sizeof(double); - - /* The stack space allocated needs to be a multiple of 16 bytes. */ - bytes = (bytes + 15) & ~0xF; - - /* Add in the space for the copied structures. */ - bytes += struct_copy_size; - - cif->flags = flags; - cif->bytes = bytes; - - return FFI_OK; -} - -/*@-declundef@*/ -/*@-exportheader@*/ -extern void ffi_call_SYSV(/*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); -/*@=declundef@*/ -/*@=exportheader@*/ - -void ffi_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - case FFI_GCC_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(&ecif, -cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - default: - FFI_ASSERT(0); - break; - } -} - - -static void flush_icache(char *, int); - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*, void*, void**, void*), - void *user_data) -{ - unsigned int *tramp; - - FFI_ASSERT (cif->abi == FFI_GCC_SYSV); - - tramp = (unsigned int *) &closure->tramp[0]; - tramp[0] = 0x7c0802a6; /* mflr r0 */ - tramp[1] = 0x4800000d; /* bl 10 */ - tramp[4] = 0x7d6802a6; /* mflr r11 */ - tramp[5] = 0x7c0803a6; /* mtlr r0 */ - tramp[6] = 0x800b0000; /* lwz r0,0(r11) */ - tramp[7] = 0x816b0004; /* lwz r11,4(r11) */ - tramp[8] = 0x7c0903a6; /* mtctr r0 */ - tramp[9] = 0x4e800420; /* bctr */ - *(void **) &tramp[2] = (void *)ffi_closure_SYSV; /* function */ - *(void **) &tramp[3] = (void *)closure; /* context */ - - closure->cif = cif; - closure->fun = fun; - closure->user_data = user_data; - - /* Flush the icache. */ - flush_icache(&closure->tramp[0],FFI_TRAMPOLINE_SIZE); - - return FFI_OK; -} - - -#define MIN_CACHE_LINE_SIZE 8 - -static void flush_icache(char * addr1, int size) -{ - int i; - char * addr; - for (i = 0; i < size; i += MIN_CACHE_LINE_SIZE) { - addr = addr1 + i; - __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" : : "r"(addr) : "memory"); - } - addr = addr1 + size - 1; - __asm__ volatile ("icbi 0,%0;" "dcbf 0,%0;" "sync;" "isync;" : : "r"(addr) : "memory"); -} - - -int ffi_closure_helper_SYSV (ffi_closure*, void*, unsigned long*, - unsigned long*, unsigned long*); - -/* Basically the trampoline invokes ffi_closure_SYSV, and on - * entry, r11 holds the address of the closure. - * After storing the registers that could possibly contain - * parameters to be passed into the stack frame and setting - * up space for a return value, ffi_closure_SYSV invokes the - * following helper function to do most of the work - */ - -int -ffi_closure_helper_SYSV (ffi_closure* closure, void * rvalue, - unsigned long * pgr, unsigned long * pfr, - unsigned long * pst) -{ - /* rvalue is the pointer to space for return value in closure assembly */ - /* pgr is the pointer to where r3-r10 are stored in ffi_closure_SYSV */ - /* pfr is the pointer to where f1-f8 are stored in ffi_closure_SYSV */ - /* pst is the pointer to outgoing parameter stack in original caller */ - - void ** avalue; - ffi_type ** arg_types; - long i, avn; - long nf; /* number of floating registers already used */ - long ng; /* number of general registers already used */ - ffi_cif * cif; - double temp; - - cif = closure->cif; - avalue = alloca(cif->nargs * sizeof(void *)); - - nf = 0; - ng = 0; - - /* Copy the caller's structure return value address so that the closure - returns the data directly to the caller. */ - if (cif->rtype->type == FFI_TYPE_STRUCT) - { - rvalue = *pgr; - ng++; - pgr++; - } - - i = 0; - avn = cif->nargs; - arg_types = cif->arg_types; - - /* Grab the addresses of the arguments from the stack frame. */ - while (i < avn) - { - switch (arg_types[i]->type) - { - case FFI_TYPE_SINT8: - case FFI_TYPE_UINT8: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) { - avalue[i] = (((char *)pgr)+3); - ng++; - pgr++; - } else { - avalue[i] = (((char *)pst)+3); - pst++; - } - break; - - case FFI_TYPE_SINT16: - case FFI_TYPE_UINT16: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) { - avalue[i] = (((char *)pgr)+2); - ng++; - pgr++; - } else { - avalue[i] = (((char *)pst)+2); - pst++; - } - break; - - case FFI_TYPE_SINT32: - case FFI_TYPE_UINT32: - case FFI_TYPE_POINTER: - case FFI_TYPE_STRUCT: - /* there are 8 gpr registers used to pass values */ - if (ng < 8) { - avalue[i] = pgr; - ng++; - pgr++; - } else { - avalue[i] = pst; - pst++; - } - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - /* passing long long ints are complex, they must - * be passed in suitable register pairs such as - * (r3,r4) or (r5,r6) or (r6,r7), or (r7,r8) or (r9,r10) - * and if the entire pair aren't available then the outgoing - * parameter stack is used for both but an alignment of 8 - * must will be kept. So we must either look in pgr - * or pst to find the correct address for this type - * of parameter. - */ - if (ng < 7) { - if (ng & 0x01) { - /* skip r4, r6, r8 as starting points */ - ng++; - pgr++; - } - avalue[i] = pgr; - ng+=2; - pgr+=2; - } else { - if (((long)pst) & 4) pst++; - avalue[i] = pst; - pst+=2; - } - break; - - case FFI_TYPE_FLOAT: - /* unfortunately float values are stored as doubles - * in the ffi_closure_SYSV code (since we don't check - * the type in that routine). This is also true - * of floats passed on the outgoing parameter stack. - * Also, on the outgoing stack all values are aligned - * to 8 - * - * Don't you just love the simplicity of this ABI! - */ - - /* there are 8 64bit floating point registers */ - - if (nf < 8) { - temp = *(double*)pfr; - *(float*)pfr = (float)temp; - avalue[i] = pfr; - nf++; - pfr+=2; - } else { - /* FIXME? here we are really changing the values - * stored in the original calling routines outgoing - * parameter stack. This is probably a really - * naughty thing to do but... - */ - if (((long)pst) & 4) pst++; - temp = *(double*)pst; - *(float*)pst = (float)temp; - avalue[i] = pst; - nf++; - pst+=2; - } - break; - - case FFI_TYPE_DOUBLE: - /* On the outgoing stack all values are aligned to 8 */ - /* there are 8 64bit floating point registers */ - - if (nf < 8) { - avalue[i] = pfr; - nf++; - pfr+=2; - } else { - if (((long)pst) & 4) pst++; - avalue[i] = pst; - nf++; - pst+=2; - } - break; - - default: - FFI_ASSERT(0); - } - - i++; - } - - - (closure->fun) (cif, rvalue, avalue, closure->user_data); - - /* Tell ffi_closure_osf how to perform return type promotions. */ - return cif->rtype->type; - -} - - - - - diff --git a/libffi/src/powerpc/ppc_closure.S b/libffi/src/powerpc/ppc_closure.S deleted file mode 100644 index 3118577..0000000 --- a/libffi/src/powerpc/ppc_closure.S +++ /dev/null @@ -1,148 +0,0 @@ -#define LIBFFI_ASM -#include - -.globl ffi_closure_helper_SYSV - -ENTRY(ffi_closure_SYSV) - stwu %r1,-144(%r1) - mflr %r0 - stw %r31,140(%r1) - stw %r0,148(%r1) - -# we want to build up an areas for the parameters passed -# in registers (both floating point and integer) - - # so first save gpr 3 to gpr 10 (aligned to 4) - stw %r3, 16(%r1) - stw %r4, 20(%r1) - stw %r5, 24(%r1) - stw %r6, 28(%r1) - stw %r7, 32(%r1) - stw %r8, 36(%r1) - stw %r9, 40(%r1) - stw %r10,44(%r1) - - # next save fpr 1 to fpr 8 (aligned to 8) - stfd %f1, 48(%r1) - stfd %f2, 56(%r1) - stfd %f3, 64(%r1) - stfd %f4, 72(%r1) - stfd %f5, 80(%r1) - stfd %f6, 88(%r1) - stfd %f7, 96(%r1) - stfd %f8, 104(%r1) - - # set up registers for the routine that actually does the work - # get the context pointer from the trampoline - mr %r3,%r11 - - # now load up the pointer to the result storage - addi %r4,%r1,112 - - # now load up the pointer to the saved gpr registers - addi %r5,%r1,16 - - # now load up the pointer to the saved fpr registers */ - addi %r6,%r1,48 - - # now load up the pointer to the outgoing parameter - # stack in the previous frame - # i.e. the previous frame pointer + 8 - addi %r7,%r1,152 - - # make the call - bl JUMPTARGET(ffi_closure_helper_SYSV) - - # now r3 contains the return type - # so use it to look up in a table - # so we know how to deal with each type - - # look up the proper starting point in table - # by using return type as offset - addi %r5,%r1,112 # get pointer to results area - addis %r4,0,.L60@ha # get address of jump table - addi %r4,%r4,.L60@l - slwi %r3,%r3,2 # now multiply return type by 4 - lwzx %r3,%r4,%r3 # get the contents of that table value - add %r3,%r3,%r4 # add contents of table to table address - mtctr %r3 - bctr # jump to it - .align 2 -.L60: - .long .L44-.L60 # FFI_TYPE_VOID - .long .L50-.L60 # FFI_TYPE_INT - .long .L47-.L60 # FFI_TYPE_FLOAT - .long .L46-.L60 # FFI_TYPE_DOUBLE - .long .L46-.L60 # FFI_TYPE_LONGDOUBLE - .long .L56-.L60 # FFI_TYPE_UINT8 - .long .L55-.L60 # FFI_TYPE_SINT8 - .long .L58-.L60 # FFI_TYPE_UINT16 - .long .L57-.L60 # FFI_TYPE_SINT16 - .long .L50-.L60 # FFI_TYPE_UINT32 - .long .L50-.L60 # FFI_TYPE_SINT32 - .long .L48-.L60 # FFI_TYPE_UINT64 - .long .L48-.L60 # FFI_TYPE_SINT64 - .long .L44-.L60 # FFI_TYPE_STRUCT - .long .L50-.L60 # FFI_TYPE_POINTER - - -# case double -.L46: - lfd %f1,0(%r5) - b .L44 - -# case float -.L47: - lfs %f1,0(%r5) - b .L44 - -# case long long -.L48: - lwz %r3,0(%r5) - lwz %r4,4(%r5) - b .L44 - -# case default / int32 / pointer -.L50: - lwz %r3,0(%r5) - b .L44 - -# case signed int8 -.L55: - addi %r5,%r5,3 - lbz %r3,0(%r5) - extsb %r3,%r3 - b .L44 - -# case unsigned int8 -.L56: - addi %r5,%r5,3 - lbz %r3,0(%r5) - b .L44 - -# case signed int16 -.L57: - addi %r5,%r5,2 - lhz %r3,0(%r5) - extsh %r3,%r3 - b .L44 - -#case unsigned int16 -.L58: - addi %r5,%r5,2 - lhz %r3,0(%r5) - -# case void / done -.L44: - - lwz %r11,0(%r1) - lwz %r0,4(%r11) - mtlr %r0 - lwz %r31,-4(%r11) - mr %r1,%r11 - blr -END(ffi_closure_SYSV) - - - - diff --git a/libffi/src/powerpc/sysv.S b/libffi/src/powerpc/sysv.S deleted file mode 100644 index d3c5a51..0000000 --- a/libffi/src/powerpc/sysv.S +++ /dev/null @@ -1,119 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.h - Copyright (c) 1998 Geoffrey Keating - - PowerPC Assembly glue. - - $Id: sysv.S,v 1.1 1998/11/29 16:48:16 green Exp $ - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include -#include - - .globl ffi_prep_args -ENTRY(ffi_call_SYSV) - /* Save the old stack pointer as AP. */ - mr %r8,%r1 - - /* Allocate the stack space we need. */ - stwux %r1,%r1,%r4 - /* Save registers we use. */ - mflr %r9 - stw %r28,-16(%r8) - stw %r29,-12(%r8) - stw %r30, -8(%r8) - stw %r31, -4(%r8) - stw %r9, 4(%r8) - - /* Save arguments over call... */ - mr %r31,%r5 /* flags, */ - mr %r30,%r6 /* rvalue, */ - mr %r29,%r7 /* function address, */ - mr %r28,%r8 /* our AP. */ - - /* Call ffi_prep_args. */ - mr %r4,%r1 - bl JUMPTARGET(ffi_prep_args) - - /* Now do the call. */ - /* Set up cr1 with bits 4-7 of the flags. */ - mtcrf 0x40,%r31 - /* Get the address to call into CTR. */ - mtctr %r29 - /* Load all those argument registers. */ - lwz %r3,-16-(8*4)(%r28) - lwz %r4,-16-(7*4)(%r28) - lwz %r5,-16-(6*4)(%r28) - lwz %r6,-16-(5*4)(%r28) - bf- 5,1f - nop - lwz %r7,-16-(4*4)(%r28) - lwz %r8,-16-(3*4)(%r28) - lwz %r9,-16-(2*4)(%r28) - lwz %r10,-16-(1*4)(%r28) - nop -1: - - /* Load all the FP registers. */ - bf- 6,2f - lfd %f1,-16-(8*4)-(8*8)(%r28) - lfd %f2,-16-(8*4)-(7*8)(%r28) - lfd %f3,-16-(8*4)-(6*8)(%r28) - lfd %f4,-16-(8*4)-(5*8)(%r28) - nop - lfd %f5,-16-(8*4)-(4*8)(%r28) - lfd %f6,-16-(8*4)-(3*8)(%r28) - lfd %f7,-16-(8*4)-(2*8)(%r28) - lfd %f8,-16-(8*4)-(1*8)(%r28) -2: - - /* Make the call. */ - bctrl - - /* Now, deal with the return value. */ - mtcrf 0x01,%r31 - bt- 30,L(done_return_value) - bt- 29,L(fp_return_value) - stw %r3,0(%r30) - bf+ 28,L(done_return_value) - stw %r4,4(%r30) - /* Fall through... */ - -L(done_return_value): - /* Restore the registers we used and return. */ - lwz %r9, 4(%r28) - lwz %r31, -4(%r28) - mtlr %r9 - lwz %r30, -8(%r28) - lwz %r29,-12(%r28) - lwz %r28,-16(%r28) - lwz %r1,0(%r1) - blr - -L(fp_return_value): - bf 28,L(float_return_value) - stfd %f1,0(%r30) - b L(done_return_value) -L(float_return_value): - stfs %f1,0(%r30) - b L(done_return_value) -END(ffi_call_SYSV) diff --git a/libffi/src/prep_cif.c b/libffi/src/prep_cif.c deleted file mode 100644 index 79e3e93..0000000 --- a/libffi/src/prep_cif.c +++ /dev/null @@ -1,146 +0,0 @@ -/* ----------------------------------------------------------------------- - prep_cif.c - Copyright (c) 1996, 1998 Cygnus Solutions - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include -#include - - -/* Round up to SIZEOF_ARG. */ - -#define STACK_ARG_SIZE(x) ALIGN(x, SIZEOF_ARG) - -/* Perform machine independent initialization of aggregate type - specifications. */ - -static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) -{ - ffi_type **ptr; - - FFI_ASSERT(arg != NULL); - - /*@-usedef@*/ - - FFI_ASSERT(arg->elements != NULL); - FFI_ASSERT(arg->size == 0); - FFI_ASSERT(arg->alignment == 0); - - ptr = &(arg->elements[0]); - - while ((*ptr) != NULL) - { - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - - /* Perform a sanity check on the argument type */ - FFI_ASSERT(ffi_type_test((*ptr))); - - arg->size = ALIGN(arg->size, (*ptr)->alignment); - arg->size += (*ptr)->size; - - arg->alignment = (arg->alignment > (*ptr)->alignment) ? - arg->alignment : (*ptr)->alignment; - - ptr++; - } - - if (arg->size == 0) - return FFI_BAD_TYPEDEF; - else - return FFI_OK; - - /*@=usedef@*/ -} - -/* Perform machine independent ffi_cif preparation, then call - machine dependent routine. */ - -ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, - ffi_abi abi, unsigned int nargs, - /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, - /*@dependent@*/ ffi_type **atypes) -{ - unsigned bytes = 0; - unsigned int i; - ffi_type **ptr; - - FFI_ASSERT(cif != NULL); - FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi < FFI_LAST_ABI)); - - cif->abi = abi; - cif->arg_types = atypes; - cif->nargs = nargs; - cif->rtype = rtype; - - cif->flags = 0; - - /* Initialize the return type if necessary */ - /*@-usedef@*/ - if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) - return FFI_BAD_TYPEDEF; - /*@=usedef@*/ - - /* Perform a sanity check on the return type */ - FFI_ASSERT(ffi_type_test(cif->rtype)); - -#ifndef M68K - /* Make space for the return structure pointer */ - if (cif->rtype->type == FFI_TYPE_STRUCT -#ifdef SPARC - && (cif->abi != FFI_V9 || cif->rtype->size > 32) -#endif - ) - bytes = STACK_ARG_SIZE(sizeof(void*)); -#endif - - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - /* Perform a sanity check on the argument type */ - FFI_ASSERT(ffi_type_test(*ptr)); - - /* Initialize any uninitialized aggregate type definitions */ - if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) - return FFI_BAD_TYPEDEF; - -#ifdef SPARC - if (((*ptr)->type == FFI_TYPE_STRUCT - && ((*ptr)->size > 16 || cif->abi != FFI_V9)) - || ((*ptr)->type == FFI_TYPE_LONGDOUBLE - && cif->abi != FFI_V9)) - bytes += sizeof(void*); - else -#endif - { - /* Add any padding if necessary */ - if (((*ptr)->alignment - 1) & bytes) - bytes = ALIGN(bytes, (*ptr)->alignment); - - bytes += STACK_ARG_SIZE((*ptr)->size); - } - } - - cif->bytes = bytes; - - /* Perform machine dependent cif processing */ - return ffi_prep_cif_machdep(cif); -} diff --git a/libffi/src/raw_api.c b/libffi/src/raw_api.c deleted file mode 100644 index c8a8e3d..0000000 --- a/libffi/src/raw_api.c +++ /dev/null @@ -1,242 +0,0 @@ -/* ----------------------------------------------------------------------- - raw_api.c - Copyright (c) 1999 Cygnus Solutions - - Author: Kresten Krab Thorup - - $Id $ - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -/* This file defines generic functions for use with the raw api. */ - -#include -#include - -#if !FFI_NO_RAW_API - -size_t -ffi_raw_size (ffi_cif *cif) -{ - size_t result = 0; - int i; - - ffi_type **at = cif->arg_types; - - for (i = cif->nargs-1; i >= 0; i--, at++) - { -#if !FFI_NO_STRUCTS - if ((*at)->type == FFI_TYPE_STRUCT) - result += ALIGN (sizeof (void*), SIZEOF_ARG); - else -#endif - result += ALIGN ((*at)->size, SIZEOF_ARG); - } - - return result; -} - - -void -ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args) -{ - unsigned i; - ffi_type **tp = cif->arg_types; - -#if WORDS_BIGENDIAN - - for (i = 0; i < cif->nargs; i++, tp++, args++) - { - switch ((*tp)->type) - { - case FFI_TYPE_UINT8: - case FFI_TYPE_SINT8: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 1); - break; - - case FFI_TYPE_UINT16: - case FFI_TYPE_SINT16: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 2); - break; - -#if SIZEOF_ARG >= 4 - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - *args = (void*) ((char*)(raw++) + SIZEOF_ARG - 4); - break; -#endif - -#if !FFI_NO_STRUCTS - case FFI_TYPE_STRUCT: - *args = (raw++)->ptr; - break; -#endif - - case FFI_TYPE_POINTER: - *args = (void*) &(raw++)->ptr; - break; - - default: - *args = raw; - raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG; - } - } - -#else /* WORDS_BIGENDIAN */ - -#if !PDP - - /* then assume little endian */ - for (i = 0; i < cif->nargs; i++, tp++, args++) - { -#if !FFI_NO_STRUCTS - if ((*tp)->type == FFI_TYPE_STRUCT) - { - *args = (raw++)->ptr; - } - else -#endif - { - *args = (void*) raw; - raw += ALIGN ((*tp)->size, sizeof (void*)) / sizeof (void*); - } - } - -#else -#error "pdp endian not supported" -#endif /* ! PDP */ - -#endif /* WORDS_BIGENDIAN */ -} - -void -ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw) -{ - unsigned i; - ffi_type **tp = cif->arg_types; - - for (i = 0; i < cif->nargs; i++, tp++, args++) - { - switch ((*tp)->type) - { - case FFI_TYPE_UINT8: - (raw++)->uint = *(UINT8*) (*args); - break; - - case FFI_TYPE_SINT8: - (raw++)->sint = *(SINT8*) (*args); - break; - - case FFI_TYPE_UINT16: - (raw++)->uint = *(UINT16*) (*args); - break; - - case FFI_TYPE_SINT16: - (raw++)->sint = *(SINT16*) (*args); - break; - -#if SIZEOF_ARG >= 4 - case FFI_TYPE_UINT32: - (raw++)->uint = *(UINT32*) (*args); - break; - - case FFI_TYPE_SINT32: - (raw++)->sint = *(SINT32*) (*args); - break; -#endif - -#if !FFI_NO_STRUCTS - case FFI_TYPE_STRUCT: - (raw++)->ptr = *args; - break; -#endif - - case FFI_TYPE_POINTER: - (raw++)->ptr = **(void***) args; - break; - - default: - memcpy ((void*) raw->data, (void*)*args, (*tp)->size); - raw += ALIGN ((*tp)->size, SIZEOF_ARG) / SIZEOF_ARG; - } - } -} - -#if !FFI_NATIVE_RAW_API - - -/* This is a generic definition of ffi_raw_call, to be used if the - * native system does not provide a machine-specific implementation. - * Having this, allows code to be written for the raw API, without - * the need for system-specific code to handle input in that format; - * these following couple of functions will handle the translation forth - * and back automatically. */ - -void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *raw) -{ - void **avalue = (void**) alloca (cif->nargs * sizeof (void*)); - ffi_raw_to_ptrarray (cif, raw, avalue); - ffi_call (cif, fn, rvalue, avalue); -} - -#if FFI_CLOSURES /* base system provides closures */ - -static void -ffi_translate_args (ffi_cif *cif, void *rvalue, - void **avalue, void *user_data) -{ - ffi_raw *raw = (ffi_raw*)alloca (ffi_raw_size (cif)); - ffi_raw_closure *cl = (ffi_raw_closure*)user_data; - - ffi_ptrarray_to_raw (cif, avalue, raw); - (*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_prep_raw_closure (ffi_raw_closure* cl, - ffi_cif *cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) -{ - ffi_status status; - - status = ffi_prep_closure ((ffi_closure*) cl, - cif, - &ffi_translate_args, - (void*)cl); - if (status == FFI_OK) - { - cl->fun = fun; - cl->user_data = user_data; - } - - return status; -} - -#endif /* FFI_CLOSURES */ -#endif /* !FFI_NATIVE_RAW_API */ -#endif /* !FFI_NO_RAW_API */ diff --git a/libffi/src/s390/ffi.c b/libffi/src/s390/ffi.c deleted file mode 100644 index 5498883..0000000 --- a/libffi/src/s390/ffi.c +++ /dev/null @@ -1,589 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 2000 Software AG - - S390 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ -/*====================================================================*/ -/* Includes */ -/* -------- */ -/*====================================================================*/ - -#include -#include - -#include -#include - -/*====================== End of Includes =============================*/ - -/*====================================================================*/ -/* Defines */ -/* ------- */ -/*====================================================================*/ - -#define MAX_GPRARGS 5 /* Max. no. of GPR available */ -#define MAX_FPRARGS 2 /* Max. no. of FPR available */ - -#define STR_GPR 1 /* Structure will fit in 1 or 2 GPR */ -#define STR_FPR 2 /* Structure will fit in a FPR */ -#define STR_STACK 3 /* Structure needs to go on stack */ - -/*===================== End of Defines ===============================*/ - -/*====================================================================*/ -/* Types */ -/* ----- */ -/*====================================================================*/ - -typedef struct stackLayout -{ - int *backChain; - int *endOfStack; - int glue[2]; - int scratch[2]; - int gprArgs[MAX_GPRARGS]; - int notUsed; - union - { - float f; - double d; - } fprArgs[MAX_FPRARGS]; - int unUsed[8]; - int outArgs[100]; -} stackLayout; - -/*======================== End of Types ==============================*/ - -/*====================================================================*/ -/* Prototypes */ -/* ---------- */ -/*====================================================================*/ - -void ffi_prep_args(stackLayout *, extended_cif *); -static int ffi_check_struct(ffi_type *, unsigned int *); -static void ffi_insert_int(int, stackLayout *, int *, int *); -static void ffi_insert_int64(long long, stackLayout *, int *, int *); -static void ffi_insert_double(double, stackLayout *, int *, int *); - -/*====================== End of Prototypes ===========================*/ - -/*====================================================================*/ -/* Externals */ -/* --------- */ -/*====================================================================*/ - -extern void ffi_call_SYSV(void (*)(stackLayout *, extended_cif *), - extended_cif *, - unsigned, unsigned, - unsigned *, - void (*fn)()); - -/*====================== End of Externals ============================*/ - -/*====================================================================*/ -/* */ -/* Name - ffi_check_struct. */ -/* */ -/* Function - Determine if a structure can be passed within a */ -/* general or floating point register. */ -/* */ -/*====================================================================*/ - -int -ffi_check_struct(ffi_type *arg, unsigned int *strFlags) -{ - ffi_type *element; - int i_Element; - - for (i_Element = 0; arg->elements[i_Element]; i_Element++) { - element = arg->elements[i_Element]; - switch (element->type) { - case FFI_TYPE_DOUBLE : - *strFlags |= STR_FPR; - break; - - case FFI_TYPE_STRUCT : - *strFlags |= ffi_check_struct(element, strFlags); - break; - - default : - *strFlags |= STR_GPR; - } - } - return (*strFlags); -} - -/*======================== End of Routine ============================*/ - -/*====================================================================*/ -/* */ -/* Name - ffi_insert_int. */ -/* */ -/* Function - Insert an integer parameter in a register if there are */ -/* spares else on the stack. */ -/* */ -/*====================================================================*/ - -void -ffi_insert_int(int gprValue, stackLayout *stack, - int *intArgC, int *outArgC) -{ - if (*intArgC < MAX_GPRARGS) { - stack->gprArgs[*intArgC] = gprValue; - *intArgC += 1; - } - else { - stack->outArgs[*outArgC++] = gprValue; - *outArgC += 1; - } -} - -/*======================== End of Routine ============================*/ - -/*====================================================================*/ -/* */ -/* Name - ffi_insert_int64. */ -/* */ -/* Function - Insert a long long parameter in registers if there are */ -/* spares else on the stack. */ -/* */ -/*====================================================================*/ - -void -ffi_insert_int64(long long llngValue, stackLayout *stack, - int *intArgC, int *outArgC) -{ - - if (*intArgC < (MAX_GPRARGS-1)) { - memcpy(&stack->gprArgs[*intArgC], - &llngValue, sizeof(long long)); - *intArgC += 2; - } - else { - memcpy(&stack->outArgs[*outArgC], - &llngValue, sizeof(long long)); - *outArgC += 2; - } - -} - -/*======================== End of Routine ============================*/ - -/*====================================================================*/ -/* */ -/* Name - ffi_insert_double. */ -/* */ -/* Function - Insert a double parameter in a FP register if there is */ -/* a spare else on the stack. */ -/* */ -/*====================================================================*/ - -void -ffi_insert_double(double dblValue, stackLayout *stack, - int *fprArgC, int *outArgC) -{ - - if (*fprArgC < MAX_FPRARGS) { - stack->fprArgs[*fprArgC].d = dblValue; - *fprArgC += 1; - } - else { - memcpy(&stack->outArgs[*outArgC], - &dblValue,sizeof(double)); - *outArgC += 2; - } - -} - -/*======================== End of Routine ============================*/ - -/*====================================================================*/ -/* */ -/* Name - ffi_prep_args. */ -/* */ -/* Function - Prepare parameters for call to function. */ -/* */ -/* ffi_prep_args is called by the assembly routine once stack space */ -/* has been allocated for the function's arguments. */ -/* */ -/* The stack layout we want looks like this: */ -/* *------------------------------------------------------------* */ -/* | 0 | Back chain (a 0 here signifies end of back chain) | */ -/* +--------+---------------------------------------------------+ */ -/* | 4 | EOS (end of stack, not used on Linux for S390) | */ -/* +--------+---------------------------------------------------+ */ -/* | 8 | Glue used in other linkage formats | */ -/* +--------+---------------------------------------------------+ */ -/* | 12 | Glue used in other linkage formats | */ -/* +--------+---------------------------------------------------+ */ -/* | 16 | Scratch area | */ -/* +--------+---------------------------------------------------+ */ -/* | 20 | Scratch area | */ -/* +--------+---------------------------------------------------+ */ -/* | 24 | GPR parameter register 1 | */ -/* +--------+---------------------------------------------------+ */ -/* | 28 | GPR parameter register 2 | */ -/* +--------+---------------------------------------------------+ */ -/* | 32 | GPR parameter register 3 | */ -/* +--------+---------------------------------------------------+ */ -/* | 36 | GPR parameter register 4 | */ -/* +--------+---------------------------------------------------+ */ -/* | 40 | GPR parameter register 5 | */ -/* +--------+---------------------------------------------------+ */ -/* | 44 | Unused | */ -/* +--------+---------------------------------------------------+ */ -/* | 48 | FPR parameter register 1 | */ -/* +--------+---------------------------------------------------+ */ -/* | 56 | FPR parameter register 2 | */ -/* +--------+---------------------------------------------------+ */ -/* | 64 | Unused | */ -/* +--------+---------------------------------------------------+ */ -/* | 96 | Outgoing args (length x) | */ -/* +--------+---------------------------------------------------+ */ -/* | 96+x | Copy area for structures (length y) | */ -/* +--------+---------------------------------------------------+ */ -/* | 96+x+y | Possible stack alignment | */ -/* *------------------------------------------------------------* */ -/* */ -/*====================================================================*/ - -void -ffi_prep_args(stackLayout *stack, extended_cif *ecif) -{ - const unsigned bytes = ecif->cif->bytes; - const unsigned flags = ecif->cif->flags; - - /*----------------------------------------------------------*/ - /* Pointer to the copy area on stack for structures */ - /*----------------------------------------------------------*/ - char *copySpace = (char *) stack + bytes + sizeof(stackLayout); - - /*----------------------------------------------------------*/ - /* Count of general and floating point register usage */ - /*----------------------------------------------------------*/ - int intArgC = 0, - fprArgC = 0, - outArgC = 0; - - int i; - ffi_type **ptr; - void **p_argv; - size_t structCopySize; - unsigned gprValue, strFlags = 0; - unsigned long long llngValue; - double dblValue; - - /* Now for the arguments. */ - p_argv = ecif->avalue; - - /*----------------------------------------------------------------------*/ - /* If we returning a structure then we set the first parameter register */ - /* to the address of where we are returning this structure */ - /*----------------------------------------------------------------------*/ - if (flags == FFI_TYPE_STRUCT) - stack->gprArgs[intArgC++] = (int) ecif->rvalue; - - for (ptr = ecif->cif->arg_types, i = ecif->cif->nargs; - i > 0; - i--, ptr++, p_argv++) - { - switch ((*ptr)->type) { - - case FFI_TYPE_FLOAT: - if (fprArgC < MAX_FPRARGS) - stack->fprArgs[fprArgC++].f = *(float *) *p_argv; - else - stack->outArgs[outArgC++] = *(int *) *p_argv; - break; - - case FFI_TYPE_DOUBLE: - dblValue = *(double *) *p_argv; - ffi_insert_double(dblValue, stack, &fprArgC, &outArgC); - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - llngValue = *(unsigned long long *) *p_argv; - ffi_insert_int64(llngValue, stack, &intArgC, &outArgC); - break; - - case FFI_TYPE_UINT8: - gprValue = *(unsigned char *)*p_argv; - ffi_insert_int(gprValue, stack, &intArgC, &outArgC); - break; - - case FFI_TYPE_SINT8: - gprValue = *(signed char *)*p_argv; - ffi_insert_int(gprValue, stack, &intArgC, &outArgC); - break; - - case FFI_TYPE_UINT16: - gprValue = *(unsigned short *)*p_argv; - ffi_insert_int(gprValue, stack, &intArgC, &outArgC); - break; - - case FFI_TYPE_SINT16: - gprValue = *(signed short *)*p_argv; - ffi_insert_int(gprValue, stack, &intArgC, &outArgC); - break; - - case FFI_TYPE_STRUCT: - /*--------------------------------------------------*/ - /* If structure > 8 bytes then it goes on the stack */ - /*--------------------------------------------------*/ - if (((*ptr)->size > 8) || - ((*ptr)->size > 4 && - (*ptr)->size < 8)) - strFlags = STR_STACK; - else - strFlags = ffi_check_struct((ffi_type *) *ptr, &strFlags); - - switch (strFlags) { - /*-------------------------------------------*/ - /* Structure that will fit in one or two GPR */ - /*-------------------------------------------*/ - case STR_GPR : - if ((*ptr)->size <= 4) { - gprValue = *(unsigned int *) *p_argv; - gprValue = gprValue >> ((4 - (*ptr)->size) * 8); - ffi_insert_int(gprValue, stack, &intArgC, &outArgC); - } - else { - llngValue = *(unsigned long long *) *p_argv; - ffi_insert_int64(llngValue, stack, &intArgC, &outArgC); - } - break; - - /*-------------------------------------------*/ - /* Structure that will fit in one FPR */ - /*-------------------------------------------*/ - case STR_FPR : - dblValue = *(double *) *p_argv; - ffi_insert_double(dblValue, stack, &fprArgC, &outArgC); - break; - - /*-------------------------------------------*/ - /* Structure that must be copied to stack */ - /*-------------------------------------------*/ - default : - structCopySize = (((*ptr)->size + 15) & ~0xF); - copySpace -= structCopySize; - memcpy(copySpace, (char *)*p_argv, (*ptr)->size); - gprValue = (unsigned) copySpace; - if (intArgC < MAX_GPRARGS) - stack->gprArgs[intArgC++] = gprValue; - else - stack->outArgs[outArgC++] = gprValue; - } - break; - -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: - structCopySize = (((*ptr)->size + 15) & ~0xF); - copySpace -= structCopySize; - memcpy(copySpace, (char *)*p_argv, (*ptr)->size); - gprValue = (unsigned) copySpace; - if (intArgC < MAX_GPRARGS) - stack->gprArgs[intArgC++] = gprValue; - else - stack->outArgs[outArgC++] = gprValue; - break; -#endif - - case FFI_TYPE_INT: - case FFI_TYPE_UINT32: - case FFI_TYPE_SINT32: - case FFI_TYPE_POINTER: - gprValue = *(unsigned *)*p_argv; - if (intArgC < MAX_GPRARGS) - stack->gprArgs[intArgC++] = gprValue; - else - stack->outArgs[outArgC++] = gprValue; - break; - - } - } -} - -/*======================== End of Routine ============================*/ - -/*====================================================================*/ -/* */ -/* Name - ffi_prep_cif_machdep. */ -/* */ -/* Function - Perform machine dependent CIF processing. */ -/* */ -/*====================================================================*/ - -ffi_status -ffi_prep_cif_machdep(ffi_cif *cif) -{ - int i; - ffi_type **ptr; - unsigned bytes; - int fpArgC = 0, - intArgC = 0; - unsigned flags = 0; - unsigned structCopySize = 0; - - /*-----------------------------------------------------------------*/ - /* Extra space required in stack for overflow parameters. */ - /*-----------------------------------------------------------------*/ - bytes = 0; - - /*--------------------------------------------------------*/ - /* Return value handling. The rules are as follows: */ - /* - 32-bit (or less) integer values are returned in gpr2 */ - /* - Structures are returned as pointers in gpr2 */ - /* - 64-bit integer values are returned in gpr2 and 3 */ - /* - Single/double FP values are returned in fpr0 */ - /*--------------------------------------------------------*/ - flags = cif->rtype->type; - - /*------------------------------------------------------------------------*/ - /* The first MAX_GPRARGS words of integer arguments, and the */ - /* first MAX_FPRARGS floating point arguments, go in registers; the rest */ - /* goes on the stack. Structures and long doubles (if not equivalent */ - /* to double) are passed as a pointer to a copy of the structure. */ - /* Stuff on the stack needs to keep proper alignment. */ - /*------------------------------------------------------------------------*/ - for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) - { - switch ((*ptr)->type) - { - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - fpArgC++; - if (fpArgC > MAX_FPRARGS && intArgC%2 != 0) - intArgC++; - break; - - case FFI_TYPE_UINT64: - case FFI_TYPE_SINT64: - /*----------------------------------------------------*/ - /* 'long long' arguments are passed as two words, but */ - /* either both words must fit in registers or both go */ - /* on the stack. If they go on the stack, they must */ - /* be 8-byte-aligned. */ - /*----------------------------------------------------*/ - if ((intArgC == MAX_GPRARGS-1) || - (intArgC >= MAX_GPRARGS) && - (intArgC%2 != 0)) - intArgC++; - intArgC += 2; - break; - - case FFI_TYPE_STRUCT: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - /*----------------------------------------------------*/ - /* We must allocate space for a copy of these to */ - /* enforce pass-by-value. Pad the space up to a */ - /* multiple of 16 bytes (the maximum alignment */ - /* required for anything under the SYSV ABI). */ - /*----------------------------------------------------*/ - structCopySize += ((*ptr)->size + 15) & ~0xF; - /*----------------------------------------------------*/ - /* Fall through (allocate space for the pointer). */ - /*----------------------------------------------------*/ - - default: - /*----------------------------------------------------*/ - /* Everything else is passed as a 4-byte word in a */ - /* GPR either the object itself or a pointer to it. */ - /*----------------------------------------------------*/ - intArgC++; - break; - } - } - - /*-----------------------------------------------------------------*/ - /* Stack space. */ - /*-----------------------------------------------------------------*/ - if (intArgC > MAX_GPRARGS) - bytes += (intArgC - MAX_GPRARGS) * sizeof(int); - if (fpArgC > MAX_FPRARGS) - bytes += (fpArgC - MAX_FPRARGS) * sizeof(double); - - /*-----------------------------------------------------------------*/ - /* The stack space allocated needs to be a multiple of 16 bytes. */ - /*-----------------------------------------------------------------*/ - bytes = (bytes + 15) & ~0xF; - - /*-----------------------------------------------------------------*/ - /* Add in the space for the copied structures. */ - /*-----------------------------------------------------------------*/ - bytes += structCopySize; - - cif->flags = flags; - cif->bytes = bytes; - - return FFI_OK; -} - -/*======================== End of Routine ============================*/ - -/*====================================================================*/ -/* */ -/* Name - ffi_call. */ -/* */ -/* Function - Call the FFI routine. */ -/* */ -/*====================================================================*/ - -void -ffi_call(ffi_cif *cif, - void (*fn)(), - void *rvalue, - void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /*-----------------------------------------------------------------*/ - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - /*-----------------------------------------------------------------*/ - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - ecif.rvalue = alloca(cif->rtype->size); - else - ecif.rvalue = rvalue; - - switch (cif->abi) - { - case FFI_SYSV: - ffi_call_SYSV(ffi_prep_args, - &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - break; - - default: - FFI_ASSERT(0); - break; - } -} - -/*======================== End of Routine ============================*/ diff --git a/libffi/src/s390/sysv.S b/libffi/src/s390/sysv.S deleted file mode 100644 index afaf1ea..0000000 --- a/libffi/src/s390/sysv.S +++ /dev/null @@ -1,161 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 2000 Software AG - - S390 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include -#ifdef HAVE_MACHINE_ASM_H -#include -#endif - -.text - - # r2: ffi_prep_args - # r3: &ecif - # r4: cif->bytes - # r5: fig->flags - # r6: ecif.rvalue - # sp+0: fn - - # This assumes we are using gas. - .globl ffi_call_SYSV - .type ffi_call_SYSV,%function -ffi_call_SYSV: - # Save registers - stm %r7,%r15,28(%r15) - l %r7,96(%r15) # Get A(fn) - lr %r0,%r15 - ahi %r15,-128 # Make room for my args - st %r0,0(%r15) # Set backchain - lr %r11,%r15 # Establish my stack register - sr %r15,%r4 # Make room for fn args - ahi %r15,-96 # Make room for new frame - lr %r10,%r15 # Establish stack build area - ahi %r15,-96 # Stack for next call - lr %r1,%r7 - stm %r2,%r7,96(%r11) # Save args on my stack - -#------------------------------------------------------------------ -# move first 3 parameters in registers -#------------------------------------------------------------------ - lr %r9,%r2 # r9: &ffi_prep_args - lr %r2,%r10 # Parm 1: &stack Parm 2: &ecif - basr %r14,%r9 # call ffi_prep_args - -#------------------------------------------------------------------ -# load first 5 parameter registers -#------------------------------------------------------------------ - lm %r2,%r6,24(%r10) - -#------------------------------------------------------------------ -# load fp parameter registers -#------------------------------------------------------------------ - ld %f0,48(%r10) - ld %f2,56(%r10) - -#------------------------------------------------------------------ -# call function -#------------------------------------------------------------------ - lr %r15,%r10 # Set new stack - l %r9,116(%r11) # Get &fn - basr %r14,%r9 # Call function - -#------------------------------------------------------------------ -# On return: -# r2: Return value (r3: Return value + 4 for long long) -#------------------------------------------------------------------ - -#------------------------------------------------------------------ -# If the return value pointer is NULL, assume no return value. -#------------------------------------------------------------------ - icm %r6,15,112(%r11) - jz .Lepilogue - - l %r5,108(%r11) # Get return type -#------------------------------------------------------------------ -# return INT -#------------------------------------------------------------------ - chi %r5,FFI_TYPE_INT - jne .Lchk64 - - st %r2,0(%r6) - j .Lepilogue - -.Lchk64: -#------------------------------------------------------------------ -# return LONG LONG (signed/unsigned) -#------------------------------------------------------------------ - chi %r5,FFI_TYPE_UINT64 - je .LdoLongLong - - chi %r5,FFI_TYPE_SINT64 - jne .LchkFloat - -.LdoLongLong: - stm %r2,%r3,0(%r6) - j .Lepilogue - -.LchkFloat: -#------------------------------------------------------------------ -# return FLOAT -#------------------------------------------------------------------ - chi %r5,FFI_TYPE_FLOAT - jne .LchkDouble - - std %f0,0(%r6) - j .Lepilogue - -.LchkDouble: -#------------------------------------------------------------------ -# return DOUBLE or LONGDOUBLE -#------------------------------------------------------------------ - chi %r5,FFI_TYPE_DOUBLE - jne .LchkStruct - - std %f0,0(%r6) - std %f2,8(%r6) - j .Lepilogue - -.LchkStruct: -#------------------------------------------------------------------ -# Structure - rvalue already set as sent as 1st parm to routine -#------------------------------------------------------------------ - chi %r5,FFI_TYPE_STRUCT - je .Lepilogue - -.Ldefault: -#------------------------------------------------------------------ -# return a pointer -#------------------------------------------------------------------ - st %r2,0(%r6) - j .Lepilogue - -.Lepilogue: - l %r15,0(%r11) - l %r4,56(%r15) - lm %r7,%r15,28(%r15) - br %r4 - -.ffi_call_SYSV_end: - .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV diff --git a/libffi/src/sparc/ffi.c b/libffi/src/sparc/ffi.c deleted file mode 100644 index f557013..0000000 --- a/libffi/src/sparc/ffi.c +++ /dev/null @@ -1,422 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996 Cygnus Solutions - - Sparc Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -void ffi_prep_args_v8(char *stack, extended_cif *ecif) -{ - int i; - int tmp; - int avn; - void **p_argv; - char *argp; - ffi_type **p_arg; - - tmp = 0; - - /* Skip 16 words for the window save area */ - argp = stack + 16*sizeof(int); - - /* This should only really be done when we are returning a structure, - however, it's faster just to do it all the time... - - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) */ - *(int *) argp = (long)ecif->rvalue; - - /* And 1 word for the structure return value. */ - argp += sizeof(int); - -#ifdef USING_PURIFY - /* Purify will probably complain in our assembly routine, unless we - zero out this memory. */ - - ((int*)argp)[0] = 0; - ((int*)argp)[1] = 0; - ((int*)argp)[2] = 0; - ((int*)argp)[3] = 0; - ((int*)argp)[4] = 0; - ((int*)argp)[5] = 0; -#endif - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - i && avn; - i--, p_arg++) - { - size_t z; - - if (avn) - { - avn--; - if ((*p_arg)->type == FFI_TYPE_STRUCT -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - || (*p_arg)->type == FFI_TYPE_LONGDOUBLE -#endif - ) - { - *(unsigned int *) argp = (unsigned long)(* p_argv); - z = sizeof(int); - } - else - { - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = *(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = *(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = *(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = *(UINT16 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } - else - { - memcpy(argp, *p_argv, z); - } - } - p_argv++; - argp += z; - } - } - - return; -} - -int ffi_prep_args_v9(char *stack, extended_cif *ecif) -{ - int i, ret = 0; - int tmp; - void **p_argv; - char *argp; - ffi_type **p_arg; - - tmp = 0; - - /* Skip 16 words for the window save area */ - argp = stack + 16*sizeof(long long); - -#ifdef USING_PURIFY - /* Purify will probably complain in our assembly routine, unless we - zero out this memory. */ - - ((long long*)argp)[0] = 0; - ((long long*)argp)[1] = 0; - ((long long*)argp)[2] = 0; - ((long long*)argp)[3] = 0; - ((long long*)argp)[4] = 0; - ((long long*)argp)[5] = 0; -#endif - - p_argv = ecif->avalue; - - if (ecif->cif->rtype->type == FFI_TYPE_STRUCT && - ecif->cif->rtype->size > 32) - { - *(unsigned long long *) argp = (unsigned long)ecif->rvalue; - tmp = 1; - } - - for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs; - i++, p_arg++) - { - size_t z; - - z = (*p_arg)->size; - switch ((*p_arg)->type) - { - case FFI_TYPE_STRUCT: - if (z > 16) - { - /* For structures larger than 16 bytes we pass reference. */ - *(unsigned long long *) argp = (unsigned long)* p_argv; - argp += sizeof(long long); - tmp++; - p_argv++; - continue; - } - /* FALLTHROUGH */ - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - ret = 1; /* We should promote into FP regs as well as integer. */ - break; - } - if (z < sizeof(long long)) - { - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed long long *) argp = *(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned long long *) argp = *(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed long long *) argp = *(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned long long *) argp = *(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(signed long long *) argp = *(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(unsigned long long *) argp = *(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_FLOAT: - *(float *) (argp + 4) = *(FLOAT32 *)(* p_argv); /* Right justify */ - break; - - case FFI_TYPE_STRUCT: - memcpy(argp, *p_argv, z); - break; - - default: - FFI_ASSERT(0); - } - z = sizeof(long long); - tmp++; - } - else if (z == sizeof(long long)) - { - memcpy(argp, *p_argv, z); - z = sizeof(long long); - tmp++; - } - else - { - if ((tmp & 1) && (*p_arg)->alignment > 8) - { - tmp++; - argp += sizeof(long long); - } - memcpy(argp, *p_argv, z); - z = 2 * sizeof(long long); - tmp += 2; - } - p_argv++; - argp += z; - } - - return ret; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - int wordsize; - - if (cif->abi != FFI_V9) - { - wordsize = 4; - - /* If we are returning a struct, this will already have been added. - Otherwise we need to add it because it's always got to be there! */ - - if (cif->rtype->type != FFI_TYPE_STRUCT) - cif->bytes += wordsize; - - /* sparc call frames require that space is allocated for 6 args, - even if they aren't used. Make that space if necessary. */ - - if (cif->bytes < 4*6+4) - cif->bytes = 4*6+4; - } - else - { - wordsize = 8; - - /* sparc call frames require that space is allocated for 6 args, - even if they aren't used. Make that space if necessary. */ - - if (cif->bytes < 8*6) - cif->bytes = 8*6; - } - - /* Adjust cif->bytes. to include 16 words for the window save area, - and maybe the struct/union return pointer area, */ - - cif->bytes += 16 * wordsize; - - /* The stack must be 2 word aligned, so round bytes up - appropriately. */ - - cif->bytes = ALIGN(cif->bytes, 2 * wordsize); - - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - cif->flags = cif->rtype->type; - break; - - case FFI_TYPE_STRUCT: - if (cif->abi == FFI_V9 && cif->rtype->size > 32) - cif->flags = FFI_TYPE_VOID; - else - cif->flags = FFI_TYPE_STRUCT; - break; - - case FFI_TYPE_SINT64: - case FFI_TYPE_UINT64: - if (cif->abi != FFI_V9) - { - cif->flags = FFI_TYPE_SINT64; - break; - } - /* FALLTHROUGH */ - default: - cif->flags = FFI_TYPE_INT; - break; - } - return FFI_OK; -} - -int ffi_V9_return_struct(ffi_type *arg, int off, char *ret, char *intg, char *flt) -{ - ffi_type **ptr = &arg->elements[0]; - - while (*ptr != NULL) - { - if (off & ((*ptr)->alignment - 1)) - off = ALIGN(off, (*ptr)->alignment); - - switch ((*ptr)->type) - { - case FFI_TYPE_STRUCT: - off = ffi_V9_return_struct(*ptr, off, ret, intg, flt); - break; - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: -#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE - case FFI_TYPE_LONGDOUBLE: -#endif - memcpy(ret + off, flt + off, (*ptr)->size); - off += (*ptr)->size; - break; - default: - memcpy(ret + off, intg + off, (*ptr)->size); - off += (*ptr)->size; - break; - } - ptr++; - } - return off; -} - -extern int ffi_call_V8(void *, extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); -extern int ffi_call_V9(void *, extended_cif *, unsigned, - unsigned, unsigned *, void (*fn)()); - -void ffi_call(ffi_cif *cif, void (*fn)(), void *rvalue, void **avalue) -{ - extended_cif ecif; - void *rval = rvalue; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - ecif.rvalue = rvalue; - if (cif->rtype->type == FFI_TYPE_STRUCT) - { - if (cif->rtype->size <= 32) - rval = alloca(64); - else - { - rval = NULL; - if (rvalue == NULL) - ecif.rvalue = alloca(cif->rtype->size); - } - } - - switch (cif->abi) - { - case FFI_V8: -#ifdef SPARC64 - /* We don't yet support calling 32bit code from 64bit */ - FFI_ASSERT(0); -#else - ffi_call_V8(ffi_prep_args_v8, &ecif, cif->bytes, - cif->flags, rvalue, fn); -#endif - break; - case FFI_V9: -#ifdef SPARC64 - ffi_call_V9(ffi_prep_args_v9, &ecif, cif->bytes, - cif->flags, rval, fn); - if (rvalue && rval && cif->rtype->type == FFI_TYPE_STRUCT) - ffi_V9_return_struct(cif->rtype, 0, (char *)rvalue, (char *)rval, ((char *)rval)+32); -#else - /* And vice versa */ - FFI_ASSERT(0); -#endif - break; - default: - FFI_ASSERT(0); - break; - } - -} diff --git a/libffi/src/sparc/v8.S b/libffi/src/sparc/v8.S deleted file mode 100644 index 0357f4d..0000000 --- a/libffi/src/sparc/v8.S +++ /dev/null @@ -1,93 +0,0 @@ -/* ----------------------------------------------------------------------- - v8.S - Copyright (c) 1996, 1997 Cygnus Solutions - - Sparc Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include - -#define STACKFRAME 96 /* Minimum stack framesize for SPARC */ -#define ARGS (64+4) /* Offset of register area in frame */ - -.text - .align 8 -.globl ffi_call_V8 -.globl _ffi_call_V8 - -ffi_call_V8: -_ffi_call_V8: - save %sp, -STACKFRAME, %sp - - sub %sp, %i2, %sp ! alloca() space in stack for frame to set up - add %sp, STACKFRAME, %l0 ! %l0 has start of - ! frame to set up - - mov %l0, %o0 ! call routine to set up frame - call %i0 - mov %i1, %o1 ! (delay) - - ld [%l0+ARGS], %o0 ! call foreign function - ld [%l0+ARGS+4], %o1 - ld [%l0+ARGS+8], %o2 - ld [%l0+ARGS+12], %o3 - ld [%l0+ARGS+16], %o4 - ld [%l0+ARGS+20], %o5 - call %i5 - mov %l0, %sp ! (delay) switch to frame - nop ! STRUCT returning functions skip 12 instead of 8 bytes - - ! If the return value pointer is NULL, assume no return value. - tst %i4 - bz done - nop - - cmp %i3, FFI_TYPE_INT - be,a done - st %o0, [%i4] ! (delay) - - cmp %i3, FFI_TYPE_FLOAT - be,a done - st %f0, [%i4+0] ! (delay) - - cmp %i3, FFI_TYPE_SINT64 - be longlong - - cmp %i3, FFI_TYPE_DOUBLE - bne done - nop - st %f0, [%i4+0] - st %f1, [%i4+4] - -done: - ret - restore - -longlong: - st %o0, [%i4+0] - st %o1, [%i4+4] - ret - restore - -.ffi_call_V8_end: - .size ffi_call_V8,.ffi_call_V8_end-ffi_call_V8 - diff --git a/libffi/src/sparc/v9.S b/libffi/src/sparc/v9.S deleted file mode 100644 index c937f43..0000000 --- a/libffi/src/sparc/v9.S +++ /dev/null @@ -1,125 +0,0 @@ -/* ----------------------------------------------------------------------- - v9.S - Copyright (c) 2000 Cygnus Solutions - - Sparc 64bit Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include - -#ifdef SPARC64 -/* Only compile this in for 64bit builds, because otherwise the object file - will have inproper architecture due to used instructions. */ - -#define STACKFRAME 128 /* Minimum stack framesize for SPARC */ -#define STACK_BIAS 2047 -#define ARGS (128) /* Offset of register area in frame */ - -.text - .align 8 -.globl ffi_call_V9 -.globl _ffi_call_V9 - -ffi_call_V9: -_ffi_call_V9: - save %sp, -STACKFRAME, %sp - - sub %sp, %i2, %sp ! alloca() space in stack for frame to set up - add %sp, STACKFRAME+STACK_BIAS, %l0 ! %l0 has start of - ! frame to set up - - mov %l0, %o0 ! call routine to set up frame - call %i0 - mov %i1, %o1 ! (delay) - brz,pt %o0, 1f - ldx [%l0+ARGS], %o0 ! call foreign function - - ldd [%l0+ARGS], %f0 - ldd [%l0+ARGS+8], %f2 - ldd [%l0+ARGS+16], %f4 - ldd [%l0+ARGS+24], %f6 - ldd [%l0+ARGS+32], %f8 - ldd [%l0+ARGS+40], %f10 - ldd [%l0+ARGS+48], %f12 - ldd [%l0+ARGS+56], %f14 - ldd [%l0+ARGS+64], %f16 - ldd [%l0+ARGS+72], %f18 - ldd [%l0+ARGS+80], %f20 - ldd [%l0+ARGS+88], %f22 - ldd [%l0+ARGS+96], %f24 - ldd [%l0+ARGS+104], %f26 - ldd [%l0+ARGS+112], %f28 - ldd [%l0+ARGS+120], %f30 - -1: ldx [%l0+ARGS+8], %o1 - ldx [%l0+ARGS+16], %o2 - ldx [%l0+ARGS+24], %o3 - ldx [%l0+ARGS+32], %o4 - ldx [%l0+ARGS+40], %o5 - call %i5 - sub %l0, STACK_BIAS, %sp ! (delay) switch to frame - - ! If the return value pointer is NULL, assume no return value. - brz,pn %i4, done - nop - - cmp %i3, FFI_TYPE_INT - be,a,pt %icc, done - stx %o0, [%i4] ! (delay) - - cmp %i3, FFI_TYPE_FLOAT - be,a,pn %icc, done - st %f0, [%i4+0] ! (delay) - - cmp %i3, FFI_TYPE_DOUBLE - be,a,pn %icc, done - std %f0, [%i4+0] ! (delay) - - cmp %i3, FFI_TYPE_STRUCT - be,pn %icc, dostruct - - cmp %i3, FFI_TYPE_LONGDOUBLE - bne,pt %icc, done - nop - std %f0, [%i4+0] - std %f2, [%i4+8] - -done: ret - restore - -dostruct: - /* This will not work correctly for unions. */ - stx %o0, [%i4+0] - stx %o1, [%i4+8] - stx %o2, [%i4+16] - stx %o3, [%i4+24] - std %f0, [%i4+32] - std %f2, [%i4+40] - std %f4, [%i4+48] - std %f6, [%i4+56] - ret - restore - -.ffi_call_V9_end: - .size ffi_call_V9,.ffi_call_V9_end-ffi_call_V9 - -#endif diff --git a/libffi/src/types.c b/libffi/src/types.c deleted file mode 100644 index 4120e76..0000000 --- a/libffi/src/types.c +++ /dev/null @@ -1,123 +0,0 @@ -/* ----------------------------------------------------------------------- - types.c - Copyright (c) 1996, 1998 Cygnus Solutions - - Predefined ffi_types needed by libffi. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL RED HAT BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -/* Type definitions */ - -#define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL } -#define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } - -/* Size and alignment are fake here. They must not be 0. */ -FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); - -FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); -FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); -FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); -FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); -FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); -FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); -FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); - -#if defined ALPHA || defined SPARC64 - -FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); - -#else - -FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); - -#endif - -#ifdef X86 - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#elif defined X86_WIN32 - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#elif defined ARM - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#elif defined M68K - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); - -#else - -FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); -FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); - -#endif - - -#ifdef X86 - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined X86_WIN32 - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined ARM - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined M68K - -FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); - -#elif defined SPARC - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); - -#ifdef SPARC64 - -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); - -#else - -FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); - -#endif - -#else - -FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); -FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); - -#endif - diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c deleted file mode 100644 index 162d66f..0000000 --- a/libffi/src/x86/ffi.c +++ /dev/null @@ -1,508 +0,0 @@ -/* ----------------------------------------------------------------------- - ffi.c - Copyright (c) 1996, 1998, 1999 Cygnus Solutions - - x86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#include -#include - -#include - -/* ffi_prep_args is called by the assembly routine once stack space - has been allocated for the function's arguments */ - -/*@-exportheader@*/ -void ffi_prep_args(char *stack, extended_cif *ecif) -/*@=exportheader@*/ -{ - register unsigned int i; - register int tmp; - register unsigned int avn; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - tmp = 0; - argp = stack; - - if ( ecif->cif->rtype->type == FFI_TYPE_STRUCT ) { - *(void **) argp = ecif->rvalue; - argp += 4; - } - - avn = ecif->cif->nargs; - p_argv = ecif->avalue; - - for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; - (i != 0) && (avn != 0); - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, (*p_arg)->alignment); - } - - if (avn != 0) - { - avn--; - z = (*p_arg)->size; - if (z < sizeof(int)) - { - z = sizeof(int); - switch ((*p_arg)->type) - { - case FFI_TYPE_SINT8: - *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); - break; - - case FFI_TYPE_UINT8: - *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); - break; - - case FFI_TYPE_SINT16: - *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); - break; - - case FFI_TYPE_UINT16: - *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); - break; - - case FFI_TYPE_SINT32: - *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); - break; - - case FFI_TYPE_UINT32: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - case FFI_TYPE_STRUCT: - *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); - break; - - default: - FFI_ASSERT(0); - } - } - else - { - memcpy(argp, *p_argv, z); - } - p_argv++; - argp += z; - } - } - - return; -} - -/* Perform machine dependent cif processing */ -ffi_status ffi_prep_cif_machdep(ffi_cif *cif) -{ - /* Set the return type flag */ - switch (cif->rtype->type) - { - case FFI_TYPE_VOID: - case FFI_TYPE_STRUCT: - case FFI_TYPE_SINT64: - case FFI_TYPE_FLOAT: - case FFI_TYPE_DOUBLE: - case FFI_TYPE_LONGDOUBLE: - cif->flags = (unsigned) cif->rtype->type; - break; - - case FFI_TYPE_UINT64: - cif->flags = FFI_TYPE_SINT64; - break; - - default: - cif->flags = FFI_TYPE_INT; - break; - } - - return FFI_OK; -} - -/*@-declundef@*/ -/*@-exportheader@*/ -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 (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ void **avalue) -{ - extended_cif ecif; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - default: - FFI_ASSERT(0); - break; - } -} - - -/** private members **/ - -static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, - void** args, ffi_cif* cif); -static void ffi_closure_SYSV (); -static void ffi_closure_raw_SYSV (); - -/* This function is jumped to by the trampoline, on entry, %ecx (a - * caller-save register) holds the address of the closure. - * Clearly, this requires __GNUC__, so perhaps we should translate this - * into an assembly file if this is to be distributed with ffi. - */ - -static void -ffi_closure_SYSV () -{ - // this is our return value storage - long double res; - - // our various things... - void *args; - ffi_cif *cif; - void **arg_area; - ffi_closure *closure; - unsigned short rtype; - void *resp = (void*)&res; - - /* grab the trampoline context pointer */ - asm ("movl %%ecx,%0" : "=r" (closure)); - - cif = closure->cif; - arg_area = (void**) alloca (cif->nargs * sizeof (void*)); - asm ("leal 8(%%ebp),%0" : "=q" (args)); - - /* 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, (void**)&resp, arg_area, cif); - - (closure->fun) (cif, resp, arg_area, closure->user_data); - - rtype = cif->flags; - - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax;" - "movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } -} - -/*@-exportheader@*/ -static void -ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, - void **avalue, ffi_cif *cif) -/*@=exportheader@*/ -{ - register unsigned int i; - register int tmp; - register unsigned int avn; - register void **p_argv; - register char *argp; - register ffi_type **p_arg; - - tmp = 0; - argp = stack; - - if ( cif->rtype->type == FFI_TYPE_STRUCT ) { - *rvalue = *(void **) argp; - argp += 4; - } - - avn = cif->nargs; - p_argv = avalue; - - for (i = cif->nargs, p_arg = cif->arg_types; - (i != 0) && (avn != 0); - i--, p_arg++) - { - size_t z; - - /* Align if necessary */ - if (((*p_arg)->alignment - 1) & (unsigned) argp) { - argp = (char *) ALIGN(argp, (*p_arg)->alignment); - } - - if (avn != 0) - { - avn--; - 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. Derived from gcc/config/i386/i386.c. */ - -#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 __dis = __fun - ((unsigned int) __tramp + 10); \ - *(unsigned char*) &__tramp[0] = 0xb9; \ - *(unsigned int*) &__tramp[1] = __ctx; \ - *(unsigned char*) &__tramp[5] = 0xe9; \ - *(unsigned int*) &__tramp[6] = __dis; \ - }) - - -/* the cif must already be prep'ed */ - -ffi_status -ffi_prep_closure (ffi_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,void**,void*), - void *user_data) -{ - FFI_ASSERT (cif->abi == FFI_SYSV); - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], \ - &ffi_closure_SYSV, \ - (void*)closure); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - -/* ------- Native raw API support -------------------------------- */ - -#if !FFI_NO_RAW_API - -static void -ffi_closure_raw_SYSV () -{ - // this is our return value storage - long double res; - - // our various things... - void *args; - ffi_raw *raw_args; - ffi_cif *cif; - ffi_raw_closure *closure; - unsigned short rtype; - void *resp = (void*)&res; - - /* grab the trampoline context pointer */ - asm ("movl %%ecx,%0" : "=r" (closure)); - - /* take the argument pointer */ - asm ("leal 8(%%ebp),%0" : "=q" (args)); - - /* get the cif */ - cif = closure->cif; - - /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */ - raw_args = (ffi_raw*) args; - - (closure->fun) (cif, resp, raw_args, closure->user_data); - - rtype = cif->flags; - - /* now, do a generic return based on the value of rtype */ - if (rtype == FFI_TYPE_INT) - { - asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); - } - else if (rtype == FFI_TYPE_FLOAT) - { - asm ("flds (%0)" : : "r" (resp) : "st" ); - } - else if (rtype == FFI_TYPE_DOUBLE) - { - asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_LONGDOUBLE) - { - asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); - } - else if (rtype == FFI_TYPE_SINT64) - { - asm ("movl 0(%0),%%eax; movl 4(%0),%%edx" - : : "r"(resp) - : "eax", "edx"); - } -} - - - - -ffi_status -ffi_prep_raw_closure (ffi_raw_closure* closure, - ffi_cif* cif, - void (*fun)(ffi_cif*,void*,ffi_raw*,void*), - void *user_data) -{ - int i; - - FFI_ASSERT (cif->abi == FFI_SYSV); - - // we currently don't support certain kinds of arguments for raw - // closures. This should be implemented by a seperate assembly language - // routine, since it would require argument processing, something we - // don't do now for performance. - - for (i = cif->nargs-1; i >= 0; i--) - { - FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); - FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); - } - - - FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, - (void*)closure); - - closure->cif = cif; - closure->user_data = user_data; - closure->fun = fun; - - return FFI_OK; -} - -static void -ffi_prep_args_raw(char *stack, extended_cif *ecif) -{ - memcpy (stack, ecif->avalue, ecif->cif->bytes); -} - -/* we borrow this routine from libffi (it must be changed, though, to - * actually call the function passed in the first argument. as of - * libffi-1.20, this is not the case.) - */ - -extern void -ffi_call_SYSV(void (*)(char *, extended_cif *), - /*@out@*/ extended_cif *, - unsigned, unsigned, - /*@out@*/ unsigned *, - void (*fn)()); - -void -ffi_raw_call(/*@dependent@*/ ffi_cif *cif, - void (*fn)(), - /*@out@*/ void *rvalue, - /*@dependent@*/ ffi_raw *fake_avalue) -{ - extended_cif ecif; - void **avalue = (void **)fake_avalue; - - ecif.cif = cif; - ecif.avalue = avalue; - - /* If the return value is a struct and we don't have a return */ - /* value address then we need to make one */ - - if ((rvalue == NULL) && - (cif->rtype->type == FFI_TYPE_STRUCT)) - { - /*@-sysunrecog@*/ - ecif.rvalue = alloca(cif->rtype->size); - /*@=sysunrecog@*/ - } - else - ecif.rvalue = rvalue; - - - switch (cif->abi) - { - case FFI_SYSV: - /*@-usedef@*/ - ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, - cif->flags, ecif.rvalue, fn); - /*@=usedef@*/ - break; - default: - FFI_ASSERT(0); - break; - } -} - -#endif diff --git a/libffi/src/x86/sysv.S b/libffi/src/x86/sysv.S deleted file mode 100644 index d59a164..0000000 --- a/libffi/src/x86/sysv.S +++ /dev/null @@ -1,166 +0,0 @@ -/* ----------------------------------------------------------------------- - sysv.S - Copyright (c) 1996, 1998 Cygnus Solutions - - X86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include - -.text - -.globl ffi_prep_args - - # This assumes we are using gas. - .balign 16 -.globl ffi_call_SYSV - .type ffi_call_SYSV,@function - -ffi_call_SYSV: -.LFB1: - pushl %ebp -.LCFI0: - movl %esp,%ebp -.LCFI1: - # Make room for all of the new args. - movl 16(%ebp),%ecx - subl %ecx,%esp - - movl %esp,%eax - - # Place all of the ffi_prep_args in position - pushl 12(%ebp) - pushl %eax - call *8(%ebp) - - # Return stack to previous state and call the function - addl $8,%esp - - 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 - movl 20(%ebp),%ecx - - # If the return value pointer is NULL, assume no return value. - cmpl $0,24(%ebp) - jne retint - - # Even if there is no space for the return value, we are - # obliged to handle floating-point values. - cmpl $FFI_TYPE_FLOAT,%ecx - jne noretval - fstp %st(0) - - jmp epilogue - -retint: - cmpl $FFI_TYPE_INT,%ecx - jne retfloat - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - jmp epilogue - -retfloat: - cmpl $FFI_TYPE_FLOAT,%ecx - jne retdouble - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstps (%ecx) - jmp epilogue - -retdouble: - cmpl $FFI_TYPE_DOUBLE,%ecx - jne retlongdouble - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstpl (%ecx) - jmp epilogue - -retlongdouble: - cmpl $FFI_TYPE_LONGDOUBLE,%ecx - jne retint64 - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstpt (%ecx) - jmp epilogue - -retint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne retstruct - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - movl %edx,4(%ecx) - -retstruct: - # Nothing to do! - -noretval: -epilogue: - movl %ebp,%esp - popl %ebp - ret -.LFE1: -.ffi_call_SYSV_end: - .size ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV - -.section .eh_frame,"aw",@progbits -__FRAME_BEGIN__: - .4byte .LLCIE1 -.LSCIE1: - .4byte 0x0 - .byte 0x1 - .byte 0x0 - .byte 0x1 - .byte 0x7c - .byte 0x8 - .byte 0xc - .byte 0x4 - .byte 0x4 - .byte 0x88 - .byte 0x1 - .align 4 -.LECIE1: - .set .LLCIE1,.LECIE1-.LSCIE1 - .4byte .LLFDE1 -.LSFDE1: - .4byte .LSFDE1-__FRAME_BEGIN__ - .4byte .LFB1 - .4byte .LFE1-.LFB1 - .byte 0x4 - .4byte .LCFI0-.LFB1 - .byte 0xe - .byte 0x8 - .byte 0x85 - .byte 0x2 - .byte 0x4 - .4byte .LCFI1-.LCFI0 - .byte 0xd - .byte 0x5 - .align 4 -.LEFDE1: - .set .LLFDE1,.LEFDE1-.LSFDE1 diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S deleted file mode 100644 index 520d1fc..0000000 --- a/libffi/src/x86/win32.S +++ /dev/null @@ -1,125 +0,0 @@ -/* ----------------------------------------------------------------------- - win32.S - Copyright (c) 1996, 1998, 2001 Cygnus Solutions - - X86 Foreign Function Interface - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - ``Software''), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - ----------------------------------------------------------------------- */ - -#define LIBFFI_ASM -#include - -.text - -.globl ffi_prep_args - - # This assumes we are using gas. - .balign 16 -.globl _ffi_call_SYSV - -_ffi_call_SYSV: - pushl %ebp - movl %esp,%ebp - - # Make room for all of the new args. - movl 16(%ebp),%ecx - subl %ecx,%esp - - movl %esp,%eax - - # Place all of the ffi_prep_args in position - pushl 12(%ebp) - pushl %eax - call *8(%ebp) - - # Return stack to previous state and call the function - addl $8,%esp - - 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 - movl 20(%ebp),%ecx - - # If the return value pointer is NULL, assume no return value. - cmpl $0,24(%ebp) - jne retint - - # Even if there is no space for the return value, we are - # obliged to handle floating-point values. - cmpl $FFI_TYPE_FLOAT,%ecx - jne noretval - fstp %st(0) - - jmp epilogue - -retint: - cmpl $FFI_TYPE_INT,%ecx - jne retfloat - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - jmp epilogue - -retfloat: - cmpl $FFI_TYPE_FLOAT,%ecx - jne retdouble - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstps (%ecx) - jmp epilogue - -retdouble: - cmpl $FFI_TYPE_DOUBLE,%ecx - jne retlongdouble - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstpl (%ecx) - jmp epilogue - -retlongdouble: - cmpl $FFI_TYPE_LONGDOUBLE,%ecx - jne retint64 - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - fstpt (%ecx) - jmp epilogue - -retint64: - cmpl $FFI_TYPE_SINT64,%ecx - jne retstruct - # Load %ecx with the pointer to storage for the return value - movl 24(%ebp),%ecx - movl %eax,0(%ecx) - movl %edx,4(%ecx) - -retstruct: - # Nothing to do! - -noretval: -epilogue: - movl %ebp,%esp - popl %ebp - ret - -.ffi_call_SYSV_end: