Add nios2 port.
authorSandra Loosemore <sandra@codesourcery.com>
Tue, 15 Oct 2013 19:33:59 +0000 (15:33 -0400)
committerAnthony Green <green@moxielogic.com>
Tue, 15 Oct 2013 19:33:59 +0000 (15:33 -0400)
ChangeLog
Makefile.am
Makefile.in
README
configure
configure.ac
src/nios2/ffi.c [new file with mode: 0644]
src/nios2/ffitarget.h [new file with mode: 0644]
src/nios2/sysv.S [new file with mode: 0644]
src/prep_cif.c

index c20ea9b..eceef84 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2013-10-13  Sandra Loosemore  <sandra@codesourcery.com>
+
+       * README: Add Nios II to table of supported platforms.
+       * Makefile.am (EXTRA_DIST): Add nios2 files.
+       (nodist_libffi_la_SOURCES): Likewise.
+       * Makefile.in: Regenerated.
+       * configure.ac (nios2*-linux*): New host.
+       (NIOS2): Add AM_CONDITIONAL.
+       * configure: Regenerated.
+       * src/nios2/ffi.c: New.
+       * src/nios2/ffitarget.h: New.
+       * src/nios2/sysv.S: New.
+       * src/prep_cif.c (initialize_aggregate): Handle extra structure
+       alignment via FFI_AGGREGATE_ALIGNMENT.
+       (ffi_prep_cif_core): Conditionalize structure return for NIOS2.
+
 2013-10-10  Sandra Loosemore  <sandra@codesourcery.com>
 
        * testsuite/libffi.call/cls_many_mixed_args.c (cls_ret_double_fn):
index d747ffa..cb078ed 100644 (file)
@@ -22,7 +22,9 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host     \
         src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h            \
         src/m88k/ffi.c src/m88k/obsd.S src/m88k/ffitarget.h            \
         src/microblaze/ffi.c src/microblaze/sysv.S                     \
-        src/microblaze/ffitarget.h src/powerpc/ffi.c                   \
+        src/microblaze/ffitarget.h                                     \
+        src/nios2/ffi.c src/nios2/ffitarget.h src/nios2/sysv.S         \
+        src/powerpc/ffi.c                                              \
         src/powerpc/sysv.S src/powerpc/linux64.S                       \
         src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S        \
         src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S       \
@@ -161,6 +163,9 @@ endif
 if MICROBLAZE
 nodist_libffi_la_SOURCES += src/microblaze/ffi.c src/microblaze/sysv.S
 endif
+if NIOS2
+nodist_libffi_la_SOURCES += src/nios2/sysv.S src/nios2/ffi.c
+endif
 if POWERPC
 nodist_libffi_la_SOURCES += src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
 endif
index ce0c6ff..348c4d8 100644 (file)
@@ -96,27 +96,28 @@ target_triplet = @target@
 @M88K_TRUE@am__append_14 = src/m88k/ffi.c src/m88k/obsd.S
 @MOXIE_TRUE@am__append_15 = src/moxie/ffi.c src/moxie/eabi.S
 @MICROBLAZE_TRUE@am__append_16 = src/microblaze/ffi.c src/microblaze/sysv.S
-@POWERPC_TRUE@am__append_17 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
-@POWERPC_AIX_TRUE@am__append_18 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
-@POWERPC_DARWIN_TRUE@am__append_19 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
-@POWERPC_FREEBSD_TRUE@am__append_20 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
-@AARCH64_TRUE@am__append_21 = src/aarch64/sysv.S src/aarch64/ffi.c
-@ARC_TRUE@am__append_22 = src/arc/sysv.S src/arc/ffi.c
-@ARM_TRUE@am__append_23 = src/arm/sysv.S src/arm/ffi.c
-@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_24 = src/arm/trampoline.S
-@AVR32_TRUE@am__append_25 = src/avr32/sysv.S src/avr32/ffi.c
-@LIBFFI_CRIS_TRUE@am__append_26 = src/cris/sysv.S src/cris/ffi.c
-@FRV_TRUE@am__append_27 = src/frv/eabi.S src/frv/ffi.c
-@S390_TRUE@am__append_28 = src/s390/sysv.S src/s390/ffi.c
-@X86_64_TRUE@am__append_29 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
-@SH_TRUE@am__append_30 = src/sh/sysv.S src/sh/ffi.c
-@SH64_TRUE@am__append_31 = src/sh64/sysv.S src/sh64/ffi.c
-@PA_LINUX_TRUE@am__append_32 = src/pa/linux.S src/pa/ffi.c
-@PA_HPUX_TRUE@am__append_33 = src/pa/hpux32.S src/pa/ffi.c
-@TILE_TRUE@am__append_34 = src/tile/tile.S src/tile/ffi.c
-@XTENSA_TRUE@am__append_35 = src/xtensa/sysv.S src/xtensa/ffi.c
-@METAG_TRUE@am__append_36 = src/metag/sysv.S src/metag/ffi.c
-@VAX_TRUE@am__append_37 = src/vax/elfbsd.S src/vax/ffi.c
+@NIOS2_TRUE@am__append_17 = src/nios2/sysv.S src/nios2/ffi.c
+@POWERPC_TRUE@am__append_18 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S
+@POWERPC_AIX_TRUE@am__append_19 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
+@POWERPC_DARWIN_TRUE@am__append_20 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
+@POWERPC_FREEBSD_TRUE@am__append_21 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+@AARCH64_TRUE@am__append_22 = src/aarch64/sysv.S src/aarch64/ffi.c
+@ARC_TRUE@am__append_23 = src/arc/sysv.S src/arc/ffi.c
+@ARM_TRUE@am__append_24 = src/arm/sysv.S src/arm/ffi.c
+@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_25 = src/arm/trampoline.S
+@AVR32_TRUE@am__append_26 = src/avr32/sysv.S src/avr32/ffi.c
+@LIBFFI_CRIS_TRUE@am__append_27 = src/cris/sysv.S src/cris/ffi.c
+@FRV_TRUE@am__append_28 = src/frv/eabi.S src/frv/ffi.c
+@S390_TRUE@am__append_29 = src/s390/sysv.S src/s390/ffi.c
+@X86_64_TRUE@am__append_30 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+@SH_TRUE@am__append_31 = src/sh/sysv.S src/sh/ffi.c
+@SH64_TRUE@am__append_32 = src/sh64/sysv.S src/sh64/ffi.c
+@PA_LINUX_TRUE@am__append_33 = src/pa/linux.S src/pa/ffi.c
+@PA_HPUX_TRUE@am__append_34 = src/pa/hpux32.S src/pa/ffi.c
+@TILE_TRUE@am__append_35 = src/tile/tile.S src/tile/ffi.c
+@XTENSA_TRUE@am__append_36 = src/xtensa/sysv.S src/xtensa/ffi.c
+@METAG_TRUE@am__append_37 = src/metag/sysv.S src/metag/ffi.c
+@VAX_TRUE@am__append_38 = src/vax/elfbsd.S src/vax/ffi.c
 subdir = .
 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
        $(top_srcdir)/configure $(am__configure_deps) \
@@ -201,37 +202,38 @@ am_libffi_la_OBJECTS = src/prep_cif.lo src/types.lo src/raw_api.lo \
 @MOXIE_TRUE@am__objects_15 = src/moxie/ffi.lo src/moxie/eabi.lo
 @MICROBLAZE_TRUE@am__objects_16 = src/microblaze/ffi.lo \
 @MICROBLAZE_TRUE@      src/microblaze/sysv.lo
-@POWERPC_TRUE@am__objects_17 = src/powerpc/ffi.lo src/powerpc/sysv.lo \
+@NIOS2_TRUE@am__objects_17 = src/nios2/sysv.lo src/nios2/ffi.lo
+@POWERPC_TRUE@am__objects_18 = src/powerpc/ffi.lo src/powerpc/sysv.lo \
 @POWERPC_TRUE@ src/powerpc/ppc_closure.lo \
 @POWERPC_TRUE@ src/powerpc/linux64.lo \
 @POWERPC_TRUE@ src/powerpc/linux64_closure.lo
-@POWERPC_AIX_TRUE@am__objects_18 = src/powerpc/ffi_darwin.lo \
+@POWERPC_AIX_TRUE@am__objects_19 = src/powerpc/ffi_darwin.lo \
 @POWERPC_AIX_TRUE@     src/powerpc/aix.lo \
 @POWERPC_AIX_TRUE@     src/powerpc/aix_closure.lo
-@POWERPC_DARWIN_TRUE@am__objects_19 = src/powerpc/ffi_darwin.lo \
+@POWERPC_DARWIN_TRUE@am__objects_20 = src/powerpc/ffi_darwin.lo \
 @POWERPC_DARWIN_TRUE@  src/powerpc/darwin.lo \
 @POWERPC_DARWIN_TRUE@  src/powerpc/darwin_closure.lo
-@POWERPC_FREEBSD_TRUE@am__objects_20 = src/powerpc/ffi.lo \
+@POWERPC_FREEBSD_TRUE@am__objects_21 = src/powerpc/ffi.lo \
 @POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \
 @POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo
-@AARCH64_TRUE@am__objects_21 = src/aarch64/sysv.lo src/aarch64/ffi.lo
-@ARC_TRUE@am__objects_22 = src/arc/sysv.lo src/arc/ffi.lo
-@ARM_TRUE@am__objects_23 = src/arm/sysv.lo src/arm/ffi.lo
-@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_24 = src/arm/trampoline.lo
-@AVR32_TRUE@am__objects_25 = src/avr32/sysv.lo src/avr32/ffi.lo
-@LIBFFI_CRIS_TRUE@am__objects_26 = src/cris/sysv.lo src/cris/ffi.lo
-@FRV_TRUE@am__objects_27 = src/frv/eabi.lo src/frv/ffi.lo
-@S390_TRUE@am__objects_28 = src/s390/sysv.lo src/s390/ffi.lo
-@X86_64_TRUE@am__objects_29 = src/x86/ffi64.lo src/x86/unix64.lo \
+@AARCH64_TRUE@am__objects_22 = src/aarch64/sysv.lo src/aarch64/ffi.lo
+@ARC_TRUE@am__objects_23 = src/arc/sysv.lo src/arc/ffi.lo
+@ARM_TRUE@am__objects_24 = src/arm/sysv.lo src/arm/ffi.lo
+@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_25 = src/arm/trampoline.lo
+@AVR32_TRUE@am__objects_26 = src/avr32/sysv.lo src/avr32/ffi.lo
+@LIBFFI_CRIS_TRUE@am__objects_27 = src/cris/sysv.lo src/cris/ffi.lo
+@FRV_TRUE@am__objects_28 = src/frv/eabi.lo src/frv/ffi.lo
+@S390_TRUE@am__objects_29 = src/s390/sysv.lo src/s390/ffi.lo
+@X86_64_TRUE@am__objects_30 = src/x86/ffi64.lo src/x86/unix64.lo \
 @X86_64_TRUE@  src/x86/ffi.lo src/x86/sysv.lo
-@SH_TRUE@am__objects_30 = src/sh/sysv.lo src/sh/ffi.lo
-@SH64_TRUE@am__objects_31 = src/sh64/sysv.lo src/sh64/ffi.lo
-@PA_LINUX_TRUE@am__objects_32 = src/pa/linux.lo src/pa/ffi.lo
-@PA_HPUX_TRUE@am__objects_33 = src/pa/hpux32.lo src/pa/ffi.lo
-@TILE_TRUE@am__objects_34 = src/tile/tile.lo src/tile/ffi.lo
-@XTENSA_TRUE@am__objects_35 = src/xtensa/sysv.lo src/xtensa/ffi.lo
-@METAG_TRUE@am__objects_36 = src/metag/sysv.lo src/metag/ffi.lo
-@VAX_TRUE@am__objects_37 = src/vax/elfbsd.lo src/vax/ffi.lo
+@SH_TRUE@am__objects_31 = src/sh/sysv.lo src/sh/ffi.lo
+@SH64_TRUE@am__objects_32 = src/sh64/sysv.lo src/sh64/ffi.lo
+@PA_LINUX_TRUE@am__objects_33 = src/pa/linux.lo src/pa/ffi.lo
+@PA_HPUX_TRUE@am__objects_34 = src/pa/hpux32.lo src/pa/ffi.lo
+@TILE_TRUE@am__objects_35 = src/tile/tile.lo src/tile/ffi.lo
+@XTENSA_TRUE@am__objects_36 = src/xtensa/sysv.lo src/xtensa/ffi.lo
+@METAG_TRUE@am__objects_37 = src/metag/sysv.lo src/metag/ffi.lo
+@VAX_TRUE@am__objects_38 = src/vax/elfbsd.lo src/vax/ffi.lo
 nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
        $(am__objects_3) $(am__objects_4) $(am__objects_5) \
        $(am__objects_6) $(am__objects_7) $(am__objects_8) \
@@ -244,7 +246,7 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
        $(am__objects_27) $(am__objects_28) $(am__objects_29) \
        $(am__objects_30) $(am__objects_31) $(am__objects_32) \
        $(am__objects_33) $(am__objects_34) $(am__objects_35) \
-       $(am__objects_36) $(am__objects_37)
+       $(am__objects_36) $(am__objects_37) $(am__objects_38)
 libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
        $(nodist_libffi_la_OBJECTS)
 AM_V_lt = $(am__v_lt_@AM_V@)
@@ -255,10 +257,10 @@ libffi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(libffi_la_LDFLAGS) $(LDFLAGS) -o $@
 libffi_convenience_la_LIBADD =
-am__objects_38 = src/prep_cif.lo src/types.lo src/raw_api.lo \
+am__objects_39 = src/prep_cif.lo src/types.lo src/raw_api.lo \
        src/java_raw_api.lo src/closures.lo
-am_libffi_convenience_la_OBJECTS = $(am__objects_38)
-am__objects_39 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
+am_libffi_convenience_la_OBJECTS = $(am__objects_39)
+am__objects_40 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
        $(am__objects_4) $(am__objects_5) $(am__objects_6) \
        $(am__objects_7) $(am__objects_8) $(am__objects_9) \
        $(am__objects_10) $(am__objects_11) $(am__objects_12) \
@@ -270,8 +272,8 @@ am__objects_39 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
        $(am__objects_28) $(am__objects_29) $(am__objects_30) \
        $(am__objects_31) $(am__objects_32) $(am__objects_33) \
        $(am__objects_34) $(am__objects_35) $(am__objects_36) \
-       $(am__objects_37)
-nodist_libffi_convenience_la_OBJECTS = $(am__objects_39)
+       $(am__objects_37) $(am__objects_38)
+nodist_libffi_convenience_la_OBJECTS = $(am__objects_40)
 libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
        $(nodist_libffi_convenience_la_OBJECTS)
 AM_V_P = $(am__v_P_@AM_V@)
@@ -601,7 +603,9 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host   \
         src/m68k/ffi.c src/m68k/sysv.S src/m68k/ffitarget.h            \
         src/m88k/ffi.c src/m88k/obsd.S src/m88k/ffitarget.h            \
         src/microblaze/ffi.c src/microblaze/sysv.S                     \
-        src/microblaze/ffitarget.h src/powerpc/ffi.c                   \
+        src/microblaze/ffitarget.h                                     \
+        src/nios2/ffi.c src/nios2/ffitarget.h src/nios2/sysv.S         \
+        src/powerpc/ffi.c                                              \
         src/powerpc/sysv.S src/powerpc/linux64.S                       \
         src/powerpc/linux64_closure.S src/powerpc/ppc_closure.S        \
         src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S       \
@@ -692,7 +696,7 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
        $(am__append_27) $(am__append_28) $(am__append_29) \
        $(am__append_30) $(am__append_31) $(am__append_32) \
        $(am__append_33) $(am__append_34) $(am__append_35) \
-       $(am__append_36) $(am__append_37)
+       $(am__append_36) $(am__append_37) $(am__append_38)
 libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
 nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS))
@@ -939,6 +943,16 @@ src/microblaze/ffi.lo: src/microblaze/$(am__dirstamp) \
        src/microblaze/$(DEPDIR)/$(am__dirstamp)
 src/microblaze/sysv.lo: src/microblaze/$(am__dirstamp) \
        src/microblaze/$(DEPDIR)/$(am__dirstamp)
+src/nios2/$(am__dirstamp):
+       @$(MKDIR_P) src/nios2
+       @: > src/nios2/$(am__dirstamp)
+src/nios2/$(DEPDIR)/$(am__dirstamp):
+       @$(MKDIR_P) src/nios2/$(DEPDIR)
+       @: > src/nios2/$(DEPDIR)/$(am__dirstamp)
+src/nios2/sysv.lo: src/nios2/$(am__dirstamp) \
+       src/nios2/$(DEPDIR)/$(am__dirstamp)
+src/nios2/ffi.lo: src/nios2/$(am__dirstamp) \
+       src/nios2/$(DEPDIR)/$(am__dirstamp)
 src/powerpc/$(am__dirstamp):
        @$(MKDIR_P) src/powerpc
        @: > src/powerpc/$(am__dirstamp)
@@ -1152,6 +1166,8 @@ mostlyclean-compile:
        -rm -f src/mips/*.lo
        -rm -f src/moxie/*.$(OBJEXT)
        -rm -f src/moxie/*.lo
+       -rm -f src/nios2/*.$(OBJEXT)
+       -rm -f src/nios2/*.lo
        -rm -f src/pa/*.$(OBJEXT)
        -rm -f src/pa/*.lo
        -rm -f src/powerpc/*.$(OBJEXT)
@@ -1216,6 +1232,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/eabi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/moxie/$(DEPDIR)/ffi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/nios2/$(DEPDIR)/ffi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/nios2/$(DEPDIR)/sysv.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/ffi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/hpux32.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/pa/$(DEPDIR)/linux.Plo@am__quote@
@@ -1324,6 +1342,7 @@ clean-libtool:
        -rm -rf src/microblaze/.libs src/microblaze/_libs
        -rm -rf src/mips/.libs src/mips/_libs
        -rm -rf src/moxie/.libs src/moxie/_libs
+       -rm -rf src/nios2/.libs src/nios2/_libs
        -rm -rf src/pa/.libs src/pa/_libs
        -rm -rf src/powerpc/.libs src/powerpc/_libs
        -rm -rf src/s390/.libs src/s390/_libs
@@ -1882,6 +1901,8 @@ distclean-generic:
        -rm -f src/mips/$(am__dirstamp)
        -rm -f src/moxie/$(DEPDIR)/$(am__dirstamp)
        -rm -f src/moxie/$(am__dirstamp)
+       -rm -f src/nios2/$(DEPDIR)/$(am__dirstamp)
+       -rm -f src/nios2/$(am__dirstamp)
        -rm -f src/pa/$(DEPDIR)/$(am__dirstamp)
        -rm -f src/pa/$(am__dirstamp)
        -rm -f src/powerpc/$(DEPDIR)/$(am__dirstamp)
@@ -1914,7 +1935,7 @@ clean-am: clean-aminfo clean-generic clean-libtool \
 
 distclean: distclean-recursive
        -rm -f $(am__CONFIG_DISTCLEAN_FILES)
-       -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
+       -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-hdr distclean-libtool distclean-tags
@@ -2053,7 +2074,7 @@ installcheck-am:
 maintainer-clean: maintainer-clean-recursive
        -rm -f $(am__CONFIG_DISTCLEAN_FILES)
        -rm -rf $(top_srcdir)/autom4te.cache
-       -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
+       -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(DEPDIR) src/arc/$(DEPDIR) src/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/m88k/$(DEPDIR) src/metag/$(DEPDIR) src/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/moxie/$(DEPDIR) src/nios2/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/vax/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
        -rm -f Makefile
 maintainer-clean-am: distclean-am maintainer-clean-aminfo \
        maintainer-clean-generic maintainer-clean-vti
diff --git a/README b/README
index b8aa963..fdee468 100644 (file)
--- a/README
+++ b/README
@@ -72,6 +72,7 @@ tested:
 | MIPS            | RTEMS            | GCC                     |
 | MIPS64          | Linux            | GCC                     |
 | Moxie           | Bare metal       | GCC                     |
+| Nios II         | Linux            | GCC                     |
 | PowerPC 32-bit  | AIX              | IBM XL C                |
 | PowerPC 64-bit  | AIX              | IBM XL C                |
 | PowerPC         | AMIGA            | GCC                     |
index a419c97..02066ce 100755 (executable)
--- a/configure
+++ b/configure
@@ -687,6 +687,8 @@ POWERPC_AIX_FALSE
 POWERPC_AIX_TRUE
 POWERPC_FALSE
 POWERPC_TRUE
+NIOS2_FALSE
+NIOS2_TRUE
 MOXIE_FALSE
 MOXIE_TRUE
 METAG_FALSE
@@ -13499,6 +13501,10 @@ case "$host" in
        TARGET=MIPS; TARGETDIR=mips
        ;;
 
+  nios2*-linux*)
+       TARGET=NIOS2; TARGETDIR=nios2
+       ;;
+
   powerpc*-*-linux* | powerpc-*-sysv*)
        TARGET=POWERPC; TARGETDIR=powerpc
        ;;
@@ -13688,6 +13694,14 @@ else
   MOXIE_FALSE=
 fi
 
+ if test x$TARGET = xNIOS2; then
+  NIOS2_TRUE=
+  NIOS2_FALSE='#'
+else
+  NIOS2_TRUE='#'
+  NIOS2_FALSE=
+fi
+
  if test x$TARGET = xPOWERPC; then
   POWERPC_TRUE=
   POWERPC_FALSE='#'
@@ -15164,6 +15178,10 @@ if test -z "${MOXIE_TRUE}" && test -z "${MOXIE_FALSE}"; then
   as_fn_error $? "conditional \"MOXIE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${NIOS2_TRUE}" && test -z "${NIOS2_FALSE}"; then
+  as_fn_error $? "conditional \"NIOS2\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 if test -z "${POWERPC_TRUE}" && test -z "${POWERPC_FALSE}"; then
   as_fn_error $? "conditional \"POWERPC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
index 339dce0..8246ee9 100644 (file)
@@ -220,6 +220,10 @@ case "$host" in
        TARGET=MIPS; TARGETDIR=mips
        ;;
 
+  nios2*-linux*)
+       TARGET=NIOS2; TARGETDIR=nios2
+       ;;
+
   powerpc*-*-linux* | powerpc-*-sysv*)
        TARGET=POWERPC; TARGETDIR=powerpc
        ;;
@@ -297,6 +301,7 @@ AM_CONDITIONAL(M88K, test x$TARGET = xM88K)
 AM_CONDITIONAL(MICROBLAZE, test x$TARGET = xMICROBLAZE)
 AM_CONDITIONAL(METAG, test x$TARGET = xMETAG)
 AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
+AM_CONDITIONAL(NIOS2, test x$TARGET = xNIOS2)
 AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
 AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
 AM_CONDITIONAL(POWERPC_DARWIN, test x$TARGET = xPOWERPC_DARWIN)
diff --git a/src/nios2/ffi.c b/src/nios2/ffi.c
new file mode 100644 (file)
index 0000000..2efa033
--- /dev/null
@@ -0,0 +1,304 @@
+/* libffi support for Altera Nios II.
+
+   Copyright (c) 2013 Mentor Graphics.
+
+   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 AUTHORS OR COPYRIGHT HOLDERS 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 <ffi.h>
+#include <ffi_common.h>
+
+#include <stdlib.h>
+
+/* The Nios II Processor Reference Handbook defines the procedure call
+   ABI as follows.
+
+   Arguments are passed as if a structure containing the types of
+   the arguments were constructed.  The first 16 bytes are passed in r4
+   through r7, the remainder on the stack.  The first 16 bytes of a function
+   taking variable arguments are passed in r4-r7 in the same way.
+
+   Return values of types up to 8 bytes are returned in r2 and r3.  For
+   return values greater than 8 bytes, the caller must allocate memory for
+   the result and pass the address as if it were argument 0.  
+
+   While this isn't specified explicitly in the ABI documentation, GCC
+   promotes integral arguments smaller than int size to 32 bits.
+
+   Also of note, the ABI specifies that all structure objects are
+   aligned to 32 bits even if all their fields have a smaller natural
+   alignment.  See FFI_AGGREGATE_ALIGNMENT.  */
+
+
+/* Declare the assembly language hooks.  */
+
+extern UINT64 ffi_call_sysv (void (*) (char *, extended_cif *),
+                            extended_cif *,
+                            unsigned, 
+                            void (*fn) (void));
+extern void ffi_closure_sysv (void);
+
+/* Perform machine-dependent cif processing.  */
+
+ffi_status ffi_prep_cif_machdep (ffi_cif *cif)
+{
+  /* We always want at least 16 bytes in the parameter block since it
+     simplifies the low-level call function.  Also round the parameter
+     block size up to a multiple of 4 bytes to preserve
+     32-bit alignment of the stack pointer.  */
+  if (cif->bytes < 16)
+    cif->bytes = 16;
+  else
+    cif->bytes = (cif->bytes + 3) & ~3;
+
+  return FFI_OK;
+}
+
+
+/* ffi_prep_args is called by the assembly routine to transfer arguments
+   to the stack using the pointers in the ecif array.
+   Note that the stack buffer is big enough to fit all the arguments,
+   but the first 16 bytes will be copied to registers for the actual
+   call.  */
+
+void ffi_prep_args (char *stack, extended_cif *ecif)
+{
+  char *argp = stack;
+  unsigned int i;
+
+  /* The implicit return value pointer is passed as if it were a hidden
+     first argument.  */
+  if (ecif->cif->rtype->type == FFI_TYPE_STRUCT
+      && ecif->cif->rtype->size > 8)
+    {
+      (*(void **) argp) = ecif->rvalue;
+      argp += 4;
+    }
+
+  for (i = 0; i < ecif->cif->nargs; i++)
+    {
+      void *avalue = ecif->avalue[i];
+      ffi_type *atype = ecif->cif->arg_types[i];
+      size_t size = atype->size;
+      size_t alignment = atype->alignment;
+
+      /* Align argp as appropriate for the argument type.  */
+      if ((alignment - 1) & (unsigned) argp)
+       argp = (char *) ALIGN (argp, alignment);
+
+      /* Copy the argument, promoting integral types smaller than a
+        word to word size.  */
+      if (size < sizeof (int))
+       {
+         size = sizeof (int);
+         switch (atype->type)
+           {
+           case FFI_TYPE_SINT8:
+             *(signed int *) argp = (signed int) *(SINT8 *) avalue;
+             break;
+                 
+           case FFI_TYPE_UINT8:
+             *(unsigned int *) argp = (unsigned int) *(UINT8 *) avalue;
+             break;
+                 
+           case FFI_TYPE_SINT16:
+             *(signed int *) argp = (signed int) *(SINT16 *) avalue;
+             break;
+                 
+           case FFI_TYPE_UINT16:
+             *(unsigned int *) argp = (unsigned int) *(UINT16 *) avalue;
+             break;
+
+           case FFI_TYPE_STRUCT:
+             memcpy (argp, avalue, atype->size);
+             break;
+
+           default:
+             FFI_ASSERT(0);
+           }
+       }
+      else if (size == sizeof (int))
+       *(unsigned int *) argp = (unsigned int) *(UINT32 *) avalue;
+      else
+       memcpy (argp, avalue, size);
+      argp += size;
+    }
+}
+
+
+/* Call FN using the prepared CIF.  RVALUE points to space allocated by
+   the caller for the return value, and AVALUE is an array of argument
+   pointers.  */
+
+void ffi_call (ffi_cif *cif, void (*fn) (void), void *rvalue, void **avalue)
+{
+
+  extended_cif ecif;
+  UINT64 result;
+
+  /* If bigret is true, this is the case where a return value of larger
+     than 8 bytes is handled by being passed by reference as an implicit
+     argument.  */
+  int bigret = (cif->rtype->type == FFI_TYPE_STRUCT
+               && cif->rtype->size > 8);
+
+  ecif.cif = cif;
+  ecif.avalue = avalue;
+
+  /* Allocate space for return value if this is the pass-by-reference case
+     and the caller did not provide a buffer.  */
+  if (rvalue == NULL && bigret)
+    ecif.rvalue = alloca (cif->rtype->size);
+  else
+    ecif.rvalue = rvalue;
+
+  result = ffi_call_sysv (ffi_prep_args, &ecif, cif->bytes, fn);
+
+  /* Now result contains the 64 bit contents returned from fn in
+     r2 and r3.  Copy the value of the appropriate size to the user-provided
+     rvalue buffer.  */
+  if (rvalue && !bigret)
+    switch (cif->rtype->size)
+      {
+      case 1:
+       *(UINT8 *)rvalue = (UINT8) result;
+       break;
+      case 2:
+       *(UINT16 *)rvalue = (UINT16) result;
+       break;
+      case 4:
+       *(UINT32 *)rvalue = (UINT32) result;
+       break;
+      case 8:
+       *(UINT64 *)rvalue = (UINT64) result;
+       break;
+      default:
+       memcpy (rvalue, (void *)&result, cif->rtype->size);
+       break;
+      }
+}
+
+/* This function is invoked from the closure trampoline to invoke
+   CLOSURE with argument block ARGS.  Parse ARGS according to
+   CLOSURE->cfi and invoke CLOSURE->fun.  */
+
+static UINT64
+ffi_closure_helper (unsigned char *args,
+                   ffi_closure *closure)
+{
+  ffi_cif *cif = closure->cif;
+  unsigned char *argp = args;
+  void **parsed_args = alloca (cif->nargs * sizeof (void *));
+  UINT64 result;
+  void *retptr;
+  unsigned int i;
+
+  /* First figure out what to do about the return type.  If this is the
+     big-structure-return case, the first arg is the hidden return buffer
+     allocated by the caller.  */
+  if (cif->rtype->type == FFI_TYPE_STRUCT
+      && cif->rtype->size > 8)
+    {
+      retptr = *((void **) argp);
+      argp += 4;
+    }
+  else
+    retptr = (void *) &result;
+
+  /* Fill in the array of argument pointers.  */
+  for (i = 0; i < cif->nargs; i++)
+    {
+      size_t size = cif->arg_types[i]->size;
+      size_t alignment = cif->arg_types[i]->alignment;
+
+      /* Align argp as appropriate for the argument type.  */
+      if ((alignment - 1) & (unsigned) argp)
+       argp = (char *) ALIGN (argp, alignment);
+
+      /* Arguments smaller than an int are promoted to int.  */
+      if (size < sizeof (int))
+       size = sizeof (int);
+
+      /* Store the pointer.  */
+      parsed_args[i] = argp;
+      argp += size;
+    }
+
+  /* Call the user-supplied function.  */
+  (closure->fun) (cif, retptr, parsed_args, closure->user_data);
+  return result;
+}
+
+
+/* Initialize CLOSURE with a trampoline to call FUN with
+   CIF and USER_DATA.  */
+ffi_status
+ffi_prep_closure_loc (ffi_closure* closure,
+                     ffi_cif* cif,
+                     void (*fun) (ffi_cif*, void*, void**, void*),
+                     void *user_data,
+                     void *codeloc)
+{
+  unsigned int *tramp = (unsigned int *) &closure->tramp[0];
+  int i;
+
+  if (cif->abi != FFI_SYSV)
+    return FFI_BAD_ABI;
+
+  /* The trampoline looks like:
+       movhi r8, %hi(ffi_closure_sysv)
+       ori r8, r8, %lo(ffi_closure_sysv)
+       movhi r9, %hi(ffi_closure_helper)
+       ori r0, r9, %lo(ffi_closure_helper)
+       movhi r10, %hi(closure)
+       ori r10, r10, %lo(closure)
+       jmp r8
+     and then ffi_closure_sysv retrieves the closure pointer out of r10
+     in addition to the arguments passed in the normal way for the call,
+     and invokes ffi_closure_helper.  We encode the pointer to
+     ffi_closure_helper in the trampoline because making a PIC call
+     to it in ffi_closure_sysv would be messy (it would have to indirect
+     through the GOT).  */
+
+#define HI(x) ((((unsigned int) (x)) >> 16) & 0xffff)
+#define LO(x) (((unsigned int) (x)) & 0xffff)
+  tramp[0] = (0 << 27) | (8 << 22) | (HI (ffi_closure_sysv) << 6) | 0x34;
+  tramp[1] = (8 << 27) | (8 << 22) | (LO (ffi_closure_sysv) << 6) | 0x14;
+  tramp[2] = (0 << 27) | (9 << 22) | (HI (ffi_closure_helper) << 6) | 0x34;
+  tramp[3] = (9 << 27) | (9 << 22) | (LO (ffi_closure_helper) << 6) | 0x14;
+  tramp[4] = (0 << 27) | (10 << 22) | (HI (closure) << 6) | 0x34;
+  tramp[5] = (10 << 27) | (10 << 22) | (LO (closure) << 6) | 0x14;
+  tramp[6] = (8 << 27) | (0x0d << 11) | 0x3a;
+#undef HI
+#undef LO
+
+  /* Flush the caches.
+     See Example 9-4 in the Nios II Software Developer's Handbook.  */
+  for (i = 0; i < 7; i++)
+    asm volatile ("flushd 0(%0); flushi %0" :: "r"(tramp + i) : "memory");
+  asm volatile ("flushp" ::: "memory");
+
+  closure->cif = cif;
+  closure->fun = fun;
+  closure->user_data = user_data;
+
+  return FFI_OK;
+}
+
diff --git a/src/nios2/ffitarget.h b/src/nios2/ffitarget.h
new file mode 100644 (file)
index 0000000..134d118
--- /dev/null
@@ -0,0 +1,52 @@
+/* libffi target includes for Altera Nios II.
+
+   Copyright (c) 2013 Mentor Graphics.
+
+   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 AUTHORS OR COPYRIGHT HOLDERS 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.  */
+
+
+#ifndef LIBFFI_TARGET_H
+#define LIBFFI_TARGET_H
+
+#ifndef LIBFFI_H
+#error "Please do not include ffitarget.h directly into your source.  Use ffi.h instead."
+#endif
+
+#ifndef LIBFFI_ASM
+typedef unsigned long          ffi_arg;
+typedef signed long            ffi_sarg;
+
+typedef enum ffi_abi {
+  FFI_FIRST_ABI = 0,
+  FFI_SYSV,
+  FFI_LAST_ABI,
+  FFI_DEFAULT_ABI = FFI_SYSV
+} ffi_abi;
+#endif
+
+/* Structures have a 4-byte alignment even if all the fields have lesser
+   alignment requirements.  */
+#define FFI_AGGREGATE_ALIGNMENT 4
+
+#define FFI_CLOSURES 1
+#define FFI_TRAMPOLINE_SIZE 28   /* 7 instructions */
+#define FFI_NATIVE_RAW_API 0
+
+#endif
diff --git a/src/nios2/sysv.S b/src/nios2/sysv.S
new file mode 100644 (file)
index 0000000..75f442b
--- /dev/null
@@ -0,0 +1,136 @@
+/* Low-level libffi support for Altera Nios II.
+
+   Copyright (c) 2013 Mentor Graphics.
+
+   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 AUTHORS OR COPYRIGHT HOLDERS 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 function is declared on the C side as 
+
+   extern UINT64 ffi_call_sysv (void (*arghook) (char *, extended_cif *),
+                               extended_cif *ecif,
+                               unsigned nbytes, 
+                               void (*fn) (void));
+       
+   On input, the arguments appear as
+       r4 = arghook
+       r5 = ecif
+       r6 = nbytes
+       r7 = fn
+*/
+
+       .section        .text
+       .align  2
+       .global ffi_call_sysv
+       .type   ffi_call_sysv, @function
+
+ffi_call_sysv:
+       .cfi_startproc
+
+       /* Create the stack frame, saving r16 so we can use it locally.  */
+       addi    sp, sp, -12
+       .cfi_def_cfa_offset 12
+       stw     ra, 8(sp)
+       stw     fp, 4(sp)
+       stw     r16, 0(sp)
+       .cfi_offset 31, -4
+       .cfi_offset 28, -8
+       .cfi_offset 16, -12
+       mov     fp, sp
+       .cfi_def_cfa_register 28
+       mov     r16, r7
+
+       /* Adjust the stack pointer to create the argument buffer
+          nbytes long.  */
+       sub     sp, sp, r6
+
+       /* Call the arghook function.  */
+       mov     r2, r4          /* fn */
+       mov     r4, sp          /* argbuffer */
+       callr   r2              /* r5 already contains ecif */
+
+       /* Pop off the first 16 bytes of the argument buffer on the stack,
+          transferring the contents to the argument registers.  */
+       ldw     r4, 0(sp)
+       ldw     r5, 4(sp)
+       ldw     r6, 8(sp)
+       ldw     r7, 12(sp)
+       addi    sp, sp, 16
+
+       /* Call the user function, which leaves its result in r2 and r3.  */
+       callr   r16
+
+       /* Pop off the stack frame.  */
+       mov     sp, fp
+       ldw     ra, 8(sp)
+       ldw     fp, 4(sp)
+       ldw     r16, 0(sp)
+       addi    sp, sp, 12
+       ret
+       .cfi_endproc
+       .size   ffi_call_sysv, .-ffi_call_sysv
+
+
+/* Closure trampolines jump here after putting the C helper address
+   in r9 and the closure pointer in r10.  The user-supplied arguments
+   to the closure are in the normal places, in r4-r7 and on the
+   stack.  Push the register arguments on the stack too and then call the
+   C helper function to deal with them.  */
+   
+       .section        .text
+       .align  2
+       .global ffi_closure_sysv
+       .type   ffi_closure_sysv, @function
+
+ffi_closure_sysv:
+       .cfi_startproc
+
+       /* Create the stack frame, pushing the register args on the stack
+          just below the stack args.  This is the same trick illustrated
+          in Figure 7-3 in the Nios II Processor Reference Handbook, used
+          for variable arguments and structures passed by value.  */
+       addi    sp, sp, -20
+       .cfi_def_cfa_offset 20
+       stw     ra, 0(sp)
+       .cfi_offset 31, -20
+       stw     r4, 4(sp)
+       .cfi_offset 4, -16
+       stw     r5, 8(sp)
+       .cfi_offset 5, -12
+       stw     r6, 12(sp)
+       .cfi_offset 6, -8
+       stw     r7, 16(sp)
+       .cfi_offset 7, -4
+
+       /* Call the helper.
+          r4 = pointer to arguments on stack
+          r5 = closure pointer (loaded in r10 by the trampoline)
+          r9 = address of helper function (loaded by trampoline) */
+       addi    r4, sp, 4
+       mov     r5, r10
+       callr   r9
+       
+       /* Pop the stack and return.  */
+       ldw     ra, 0(sp)
+       addi    sp, sp, 20
+       .cfi_def_cfa_offset -20
+       ret
+       .cfi_endproc
+       .size   ffi_closure_sysv, .-ffi_closure_sysv
+
index e8ec5cf..e373cbd 100644 (file)
@@ -76,6 +76,13 @@ static ffi_status initialize_aggregate(ffi_type *arg)
      total size of 3*sizeof(long).  */
   arg->size = ALIGN (arg->size, arg->alignment);
 
+  /* On some targets, the ABI defines that structures have an additional
+     alignment beyond the "natural" one based on their elements.  */
+#ifdef FFI_AGGREGATE_ALIGNMENT
+  if (FFI_AGGREGATE_ALIGNMENT > arg->alignment)
+    arg->alignment = FFI_AGGREGATE_ALIGNMENT;
+#endif
+
   if (arg->size == 0)
     return FFI_BAD_TYPEDEF;
   else
@@ -146,7 +153,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
 #ifdef XTENSA
       && (cif->rtype->size > 16)
 #endif
-
+#ifdef NIOS2
+      && (cif->rtype->size > 8)
+#endif
      )
     bytes = STACK_ARG_SIZE(sizeof(void*));
 #endif