New microblaze support
authorAnthony Green <green@moxielogic.com>
Mon, 21 Jan 2013 12:37:30 +0000 (07:37 -0500)
committerAnthony Green <green@moxielogic.com>
Mon, 21 Jan 2013 12:37:30 +0000 (07:37 -0500)
Makefile.am
Makefile.in
README
configure
configure.ac
src/microblaze/ffi.c [new file with mode: 0644]
src/microblaze/ffitarget.h [new file with mode: 0644]
src/microblaze/sysv.S [new file with mode: 0644]
testsuite/libffi.call/return_uc.c

index 571e677..cf35c83 100644 (file)
@@ -14,7 +14,9 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host     \
         src/ia64/unix.S src/mips/ffi.c src/mips/n32.S src/mips/o32.S   \
         src/mips/ffitarget.h src/m32r/ffi.c src/m32r/sysv.S            \
         src/m32r/ffitarget.h src/m68k/ffi.c src/m68k/sysv.S            \
-        src/m68k/ffitarget.h src/powerpc/ffi.c src/powerpc/sysv.S      \
+        src/m68k/ffitarget.h src/microblaze/ffi.c                      \
+        src/microblaze/sysv.S src/microblaze/ffitarget.h               \
+        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                          \
@@ -139,6 +141,9 @@ endif
 if M68K
 nodist_libffi_la_SOURCES += src/m68k/ffi.c src/m68k/sysv.S
 endif
+if MICROBLAZE
+nodist_libffi_la_SOURCES += src/microblaze/ffi.c src/microblaze/sysv.S
+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 d457e1e..44ecdeb 100644 (file)
@@ -64,24 +64,25 @@ target_triplet = @target@
 @IA64_TRUE@am__append_11 = src/ia64/ffi.c src/ia64/unix.S
 @M32R_TRUE@am__append_12 = src/m32r/sysv.S src/m32r/ffi.c
 @M68K_TRUE@am__append_13 = src/m68k/ffi.c src/m68k/sysv.S
-@POWERPC_TRUE@am__append_14 = 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_15 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
-@POWERPC_DARWIN_TRUE@am__append_16 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
-@POWERPC_FREEBSD_TRUE@am__append_17 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
-@AARCH64_TRUE@am__append_18 = src/aarch64/sysv.S src/aarch64/ffi.c
-@ARM_TRUE@am__append_19 = src/arm/sysv.S src/arm/ffi.c
-@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_20 = src/arm/trampoline.S
-@AVR32_TRUE@am__append_21 = src/avr32/sysv.S src/avr32/ffi.c
-@LIBFFI_CRIS_TRUE@am__append_22 = src/cris/sysv.S src/cris/ffi.c
-@FRV_TRUE@am__append_23 = src/frv/eabi.S src/frv/ffi.c
-@S390_TRUE@am__append_24 = src/s390/sysv.S src/s390/ffi.c
-@X86_64_TRUE@am__append_25 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
-@SH_TRUE@am__append_26 = src/sh/sysv.S src/sh/ffi.c
-@SH64_TRUE@am__append_27 = src/sh64/sysv.S src/sh64/ffi.c
-@PA_LINUX_TRUE@am__append_28 = src/pa/linux.S src/pa/ffi.c
-@PA_HPUX_TRUE@am__append_29 = src/pa/hpux32.S src/pa/ffi.c
-@TILE_TRUE@am__append_30 = src/tile/tile.S src/tile/ffi.c
-@XTENSA_TRUE@am__append_31 = src/xtensa/sysv.S src/xtensa/ffi.c
+@MICROBLAZE_TRUE@am__append_14 = src/microblaze/ffi.c src/microblaze/sysv.S
+@POWERPC_TRUE@am__append_15 = 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_16 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S
+@POWERPC_DARWIN_TRUE@am__append_17 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S
+@POWERPC_FREEBSD_TRUE@am__append_18 = src/powerpc/ffi.c src/powerpc/sysv.S src/powerpc/ppc_closure.S
+@AARCH64_TRUE@am__append_19 = src/aarch64/sysv.S src/aarch64/ffi.c
+@ARM_TRUE@am__append_20 = src/arm/sysv.S src/arm/ffi.c
+@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_21 = src/arm/trampoline.S
+@AVR32_TRUE@am__append_22 = src/avr32/sysv.S src/avr32/ffi.c
+@LIBFFI_CRIS_TRUE@am__append_23 = src/cris/sysv.S src/cris/ffi.c
+@FRV_TRUE@am__append_24 = src/frv/eabi.S src/frv/ffi.c
+@S390_TRUE@am__append_25 = src/s390/sysv.S src/s390/ffi.c
+@X86_64_TRUE@am__append_26 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S
+@SH_TRUE@am__append_27 = src/sh/sysv.S src/sh/ffi.c
+@SH64_TRUE@am__append_28 = src/sh64/sysv.S src/sh64/ffi.c
+@PA_LINUX_TRUE@am__append_29 = src/pa/linux.S src/pa/ffi.c
+@PA_HPUX_TRUE@am__append_30 = src/pa/hpux32.S src/pa/ffi.c
+@TILE_TRUE@am__append_31 = src/tile/tile.S src/tile/ffi.c
+@XTENSA_TRUE@am__append_32 = src/xtensa/sysv.S src/xtensa/ffi.c
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
        $(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \
@@ -161,34 +162,36 @@ am_libffi_la_OBJECTS = src/prep_cif.lo src/types.lo src/raw_api.lo \
 @IA64_TRUE@am__objects_11 = src/ia64/ffi.lo src/ia64/unix.lo
 @M32R_TRUE@am__objects_12 = src/m32r/sysv.lo src/m32r/ffi.lo
 @M68K_TRUE@am__objects_13 = src/m68k/ffi.lo src/m68k/sysv.lo
-@POWERPC_TRUE@am__objects_14 = src/powerpc/ffi.lo src/powerpc/sysv.lo \
+@MICROBLAZE_TRUE@am__objects_14 = src/microblaze/ffi.lo \
+@MICROBLAZE_TRUE@      src/microblaze/sysv.lo
+@POWERPC_TRUE@am__objects_15 = 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_15 = src/powerpc/ffi_darwin.lo \
+@POWERPC_AIX_TRUE@am__objects_16 = 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_16 = src/powerpc/ffi_darwin.lo \
+@POWERPC_DARWIN_TRUE@am__objects_17 = 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_17 = src/powerpc/ffi.lo \
+@POWERPC_FREEBSD_TRUE@am__objects_18 = src/powerpc/ffi.lo \
 @POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \
 @POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo
-@AARCH64_TRUE@am__objects_18 = src/aarch64/sysv.lo src/aarch64/ffi.lo
-@ARM_TRUE@am__objects_19 = src/arm/sysv.lo src/arm/ffi.lo
-@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_20 = src/arm/trampoline.lo
-@AVR32_TRUE@am__objects_21 = src/avr32/sysv.lo src/avr32/ffi.lo
-@LIBFFI_CRIS_TRUE@am__objects_22 = src/cris/sysv.lo src/cris/ffi.lo
-@FRV_TRUE@am__objects_23 = src/frv/eabi.lo src/frv/ffi.lo
-@S390_TRUE@am__objects_24 = src/s390/sysv.lo src/s390/ffi.lo
-@X86_64_TRUE@am__objects_25 = src/x86/ffi64.lo src/x86/unix64.lo \
+@AARCH64_TRUE@am__objects_19 = src/aarch64/sysv.lo src/aarch64/ffi.lo
+@ARM_TRUE@am__objects_20 = src/arm/sysv.lo src/arm/ffi.lo
+@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_21 = src/arm/trampoline.lo
+@AVR32_TRUE@am__objects_22 = src/avr32/sysv.lo src/avr32/ffi.lo
+@LIBFFI_CRIS_TRUE@am__objects_23 = src/cris/sysv.lo src/cris/ffi.lo
+@FRV_TRUE@am__objects_24 = src/frv/eabi.lo src/frv/ffi.lo
+@S390_TRUE@am__objects_25 = src/s390/sysv.lo src/s390/ffi.lo
+@X86_64_TRUE@am__objects_26 = src/x86/ffi64.lo src/x86/unix64.lo \
 @X86_64_TRUE@  src/x86/ffi.lo src/x86/sysv.lo
-@SH_TRUE@am__objects_26 = src/sh/sysv.lo src/sh/ffi.lo
-@SH64_TRUE@am__objects_27 = src/sh64/sysv.lo src/sh64/ffi.lo
-@PA_LINUX_TRUE@am__objects_28 = src/pa/linux.lo src/pa/ffi.lo
-@PA_HPUX_TRUE@am__objects_29 = src/pa/hpux32.lo src/pa/ffi.lo
-@TILE_TRUE@am__objects_30 = src/tile/tile.lo src/tile/ffi.lo
-@XTENSA_TRUE@am__objects_31 = src/xtensa/sysv.lo src/xtensa/ffi.lo
+@SH_TRUE@am__objects_27 = src/sh/sysv.lo src/sh/ffi.lo
+@SH64_TRUE@am__objects_28 = src/sh64/sysv.lo src/sh64/ffi.lo
+@PA_LINUX_TRUE@am__objects_29 = src/pa/linux.lo src/pa/ffi.lo
+@PA_HPUX_TRUE@am__objects_30 = src/pa/hpux32.lo src/pa/ffi.lo
+@TILE_TRUE@am__objects_31 = src/tile/tile.lo src/tile/ffi.lo
+@XTENSA_TRUE@am__objects_32 = src/xtensa/sysv.lo src/xtensa/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) \
@@ -199,17 +202,17 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
        $(am__objects_21) $(am__objects_22) $(am__objects_23) \
        $(am__objects_24) $(am__objects_25) $(am__objects_26) \
        $(am__objects_27) $(am__objects_28) $(am__objects_29) \
-       $(am__objects_30) $(am__objects_31)
+       $(am__objects_30) $(am__objects_31) $(am__objects_32)
 libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \
        $(nodist_libffi_la_OBJECTS)
 libffi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(libffi_la_LDFLAGS) $(LDFLAGS) -o $@
 libffi_convenience_la_LIBADD =
-am__objects_32 = src/prep_cif.lo src/types.lo src/raw_api.lo \
+am__objects_33 = 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_32)
-am__objects_33 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
+am_libffi_convenience_la_OBJECTS = $(am__objects_33)
+am__objects_34 = $(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) \
@@ -219,8 +222,8 @@ am__objects_33 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \
        $(am__objects_22) $(am__objects_23) $(am__objects_24) \
        $(am__objects_25) $(am__objects_26) $(am__objects_27) \
        $(am__objects_28) $(am__objects_29) $(am__objects_30) \
-       $(am__objects_31)
-nodist_libffi_convenience_la_OBJECTS = $(am__objects_33)
+       $(am__objects_31) $(am__objects_32)
+nodist_libffi_convenience_la_OBJECTS = $(am__objects_34)
 libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \
        $(nodist_libffi_convenience_la_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@
@@ -465,7 +468,9 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj configure.host   \
         src/ia64/unix.S src/mips/ffi.c src/mips/n32.S src/mips/o32.S   \
         src/mips/ffitarget.h src/m32r/ffi.c src/m32r/sysv.S            \
         src/m32r/ffitarget.h src/m68k/ffi.c src/m68k/sysv.S            \
-        src/m68k/ffitarget.h src/powerpc/ffi.c src/powerpc/sysv.S      \
+        src/m68k/ffitarget.h src/microblaze/ffi.c                      \
+        src/microblaze/sysv.S src/microblaze/ffitarget.h               \
+        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                          \
@@ -550,7 +555,7 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \
        $(am__append_21) $(am__append_22) $(am__append_23) \
        $(am__append_24) $(am__append_25) $(am__append_26) \
        $(am__append_27) $(am__append_28) $(am__append_29) \
-       $(am__append_30) $(am__append_31)
+       $(am__append_30) $(am__append_31) $(am__append_32)
 libffi_convenience_la_SOURCES = $(libffi_la_SOURCES)
 nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES)
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
@@ -766,6 +771,16 @@ src/m68k/ffi.lo: src/m68k/$(am__dirstamp) \
        src/m68k/$(DEPDIR)/$(am__dirstamp)
 src/m68k/sysv.lo: src/m68k/$(am__dirstamp) \
        src/m68k/$(DEPDIR)/$(am__dirstamp)
+src/microblaze/$(am__dirstamp):
+       @$(MKDIR_P) src/microblaze
+       @: > src/microblaze/$(am__dirstamp)
+src/microblaze/$(DEPDIR)/$(am__dirstamp):
+       @$(MKDIR_P) src/microblaze/$(DEPDIR)
+       @: > src/microblaze/$(DEPDIR)/$(am__dirstamp)
+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/powerpc/$(am__dirstamp):
        @$(MKDIR_P) src/powerpc
        @: > src/powerpc/$(am__dirstamp)
@@ -935,6 +950,8 @@ mostlyclean-compile:
        -rm -f src/m32r/*.lo
        -rm -f src/m68k/*.$(OBJEXT)
        -rm -f src/m68k/*.lo
+       -rm -f src/microblaze/*.$(OBJEXT)
+       -rm -f src/microblaze/*.lo
        -rm -f src/mips/*.$(OBJEXT)
        -rm -f src/mips/*.lo
        -rm -f src/pa/*.$(OBJEXT)
@@ -986,6 +1003,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@src/m32r/$(DEPDIR)/sysv.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/m68k/$(DEPDIR)/ffi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/m68k/$(DEPDIR)/sysv.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/microblaze/$(DEPDIR)/ffi.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/microblaze/$(DEPDIR)/sysv.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/ffi.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/n32.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@src/mips/$(DEPDIR)/o32.Plo@am__quote@
@@ -1089,6 +1108,7 @@ clean-libtool:
        -rm -rf src/ia64/.libs src/ia64/_libs
        -rm -rf src/m32r/.libs src/m32r/_libs
        -rm -rf src/m68k/.libs src/m68k/_libs
+       -rm -rf src/microblaze/.libs src/microblaze/_libs
        -rm -rf src/mips/.libs src/mips/_libs
        -rm -rf src/pa/.libs src/pa/_libs
        -rm -rf src/powerpc/.libs src/powerpc/_libs
@@ -1643,6 +1663,8 @@ distclean-generic:
        -rm -f src/m32r/$(am__dirstamp)
        -rm -f src/m68k/$(DEPDIR)/$(am__dirstamp)
        -rm -f src/m68k/$(am__dirstamp)
+       -rm -f src/microblaze/$(DEPDIR)/$(am__dirstamp)
+       -rm -f src/microblaze/$(am__dirstamp)
        -rm -f src/mips/$(DEPDIR)/$(am__dirstamp)
        -rm -f src/mips/$(am__dirstamp)
        -rm -f src/pa/$(DEPDIR)/$(am__dirstamp)
@@ -1675,7 +1697,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/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
+       -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(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/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
        -rm -f Makefile
 distclean-am: clean-am distclean-compile distclean-generic \
        distclean-hdr distclean-libtool distclean-tags
@@ -1814,7 +1836,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/arm/$(DEPDIR) src/avr32/$(DEPDIR) src/bfin/$(DEPDIR) src/cris/$(DEPDIR) src/frv/$(DEPDIR) src/ia64/$(DEPDIR) src/m32r/$(DEPDIR) src/m68k/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(DEPDIR) src/x86/$(DEPDIR) src/xtensa/$(DEPDIR)
+       -rm -rf src/$(DEPDIR) src/aarch64/$(DEPDIR) src/alpha/$(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/microblaze/$(DEPDIR) src/mips/$(DEPDIR) src/pa/$(DEPDIR) src/powerpc/$(DEPDIR) src/s390/$(DEPDIR) src/sh/$(DEPDIR) src/sh64/$(DEPDIR) src/sparc/$(DEPDIR) src/tile/$(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 3684ed6..9645a07 100644 (file)
--- a/README
+++ b/README
@@ -62,6 +62,7 @@ tested:
 | IA-64           | Linux            | GCC                     |
 | M68K            | FreeMiNT         | GCC                     |
 | M68K            | RTEMS            | GCC                     |
+| MicroBlaze      | Linux            | GCC                     |
 | MIPS            | IRIX             | GCC                     |
 | MIPS            | Linux            | GCC                     |
 | MIPS            | RTEMS            | GCC                     |
@@ -344,6 +345,7 @@ frv         Anthony Green
 ia64           Hans Boehm
 m32r           Kazuhiro Inaoka
 m68k           Andreas Schwab
+microblaze     Nathan Rossi
 mips           Anthony Green, Casey Marshall
 mips64         David Daney
 pa             Randolph Chung, Dave Anglin, Andreas Tobler
index 2af0ff1..a1f5235 100755 (executable)
--- a/configure
+++ b/configure
@@ -685,6 +685,8 @@ POWERPC_FALSE
 POWERPC_TRUE
 MOXIE_FALSE
 MOXIE_TRUE
+MICROBLAZE_FALSE
+MICROBLAZE_TRUE
 M68K_FALSE
 M68K_TRUE
 M32R_FALSE
@@ -13384,6 +13386,10 @@ case "$host" in
        TARGET=M68K; TARGETDIR=m68k
        ;;
 
+  microblaze*-*-*)
+       TARGET=MICROBLAZE; TARGETDIR=microblaze
+       ;;
+
   mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
        TARGET=MIPS; TARGETDIR=mips
        ;;
@@ -13563,6 +13569,14 @@ else
   M68K_FALSE=
 fi
 
+ if test x$TARGET = xMICROBLAZE; then
+  MICROBLAZE_TRUE=
+  MICROBLAZE_FALSE='#'
+else
+  MICROBLAZE_TRUE='#'
+  MICROBLAZE_FALSE=
+fi
+
  if test x$TARGET = xMOXIE; then
   MOXIE_TRUE=
   MOXIE_FALSE='#'
@@ -15013,6 +15027,10 @@ if test -z "${M68K_TRUE}" && test -z "${M68K_FALSE}"; then
   as_fn_error $? "conditional \"M68K\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
+if test -z "${MICROBLAZE_TRUE}" && test -z "${MICROBLAZE_FALSE}"; then
+  as_fn_error $? "conditional \"MICROBLAZE\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 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
index db91985..5d61007 100644 (file)
@@ -167,6 +167,10 @@ case "$host" in
        TARGET=M68K; TARGETDIR=m68k
        ;;
 
+  microblaze*-*-*)
+       TARGET=MICROBLAZE; TARGETDIR=microblaze
+       ;;
+
   mips-sgi-irix5.* | mips-sgi-irix6.* | mips*-*-rtems*)
        TARGET=MIPS; TARGETDIR=mips
        ;;
@@ -262,6 +266,7 @@ AM_CONDITIONAL(ALPHA, test x$TARGET = xALPHA)
 AM_CONDITIONAL(IA64, test x$TARGET = xIA64)
 AM_CONDITIONAL(M32R, test x$TARGET = xM32R)
 AM_CONDITIONAL(M68K, test x$TARGET = xM68K)
+AM_CONDITIONAL(MICROBLAZE, test x$TARGET = xMICROBLAZE)
 AM_CONDITIONAL(MOXIE, test x$TARGET = xMOXIE)
 AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
 AM_CONDITIONAL(POWERPC_AIX, test x$TARGET = xPOWERPC_AIX)
diff --git a/src/microblaze/ffi.c b/src/microblaze/ffi.c
new file mode 100644 (file)
index 0000000..86ea37d
--- /dev/null
@@ -0,0 +1,339 @@
+/* -----------------------------------------------------------------------
+   ffi.c - Copyright (c) 2012, 2013 Xilinx, Inc
+
+   MicroBlaze 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 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>
+
+extern void ffi_call_SYSV(void (*)(void*, extended_cif*), extended_cif*,
+               unsigned int, unsigned int, unsigned int*, void (*fn)(void),
+               unsigned int, unsigned int);
+
+extern void ffi_closure_SYSV(void);
+
+#define WORD_SIZE                      sizeof(unsigned int)
+#define ARGS_REGISTER_SIZE     (WORD_SIZE * 6)
+#define WORD_ALIGN(x)          ALIGN(x, WORD_SIZE)
+
+/* ffi_prep_args is called by the assembly routine once stack space
+   has been allocated for the function's arguments */
+void ffi_prep_args(void* stack, extended_cif* ecif)
+{
+       unsigned int i;
+       ffi_type** p_arg;
+       void** p_argv;
+       void* stack_args_p = stack;
+
+       p_argv = ecif->avalue;
+
+       if (ecif == NULL || ecif->cif == NULL) {
+               return; /* no description to prepare */
+       }
+
+       if ((ecif->cif->rtype != NULL) &&
+                       (ecif->cif->rtype->type == FFI_TYPE_STRUCT))
+       {
+               /* if return type is a struct which is referenced on the stack/reg5,
+                * by a pointer. Stored the return value pointer in r5.
+                */
+               char* addr = stack_args_p;
+               memcpy(addr, &(ecif->rvalue), WORD_SIZE);
+               stack_args_p += WORD_SIZE;
+       }
+
+       if (ecif->avalue == NULL) {
+               return; /* no arguments to prepare */
+       }
+
+       for (i = 0, p_arg = ecif->cif->arg_types; i < ecif->cif->nargs;
+                       i++, p_arg++)
+       {
+               size_t size = (*p_arg)->size;
+               int type = (*p_arg)->type;
+               void* value = p_argv[i];
+               char* addr = stack_args_p;
+               int aligned_size = WORD_ALIGN(size);
+
+               /* force word alignment on the stack */
+               stack_args_p += aligned_size;
+               
+               switch (type)
+               {
+                       case FFI_TYPE_UINT8:
+                               *(unsigned int *)addr = (unsigned int)*(UINT8*)(value);
+                               break;
+                       case FFI_TYPE_SINT8:
+                               *(signed int *)addr = (signed int)*(SINT8*)(value);
+                               break;
+                       case FFI_TYPE_UINT16:
+                               *(unsigned int *)addr = (unsigned int)*(UINT16*)(value);
+                               break;
+                       case FFI_TYPE_SINT16:
+                               *(signed int *)addr = (signed int)*(SINT16*)(value);
+                               break;
+                       case FFI_TYPE_STRUCT:
+#if __BIG_ENDIAN__
+                               /*
+                                * MicroBlaze toolchain appears to emit:
+                                * bsrli r5, r5, 8 (caller)
+                                * ...
+                                * <branch to callee>
+                                * ...
+                                * bslli r5, r5, 8 (callee)
+                                * 
+                                * For structs like "struct a { uint8_t a[3]; };", when passed
+                                * by value.
+                                *
+                                * Structs like "struct b { uint16_t a; };" are also expected
+                                * to be packed strangely in registers.
+                                *
+                                * This appears to be because the microblaze toolchain expects
+                                * "struct b == uint16_t", which is only any issue for big
+                                * endian.
+                                *
+                                * The following is a work around for big-endian only, for the
+                                * above mentioned case, it will re-align the contents of a
+                                * <= 3-byte struct value.
+                                */
+                               if (size < WORD_SIZE)
+                               {
+                                       if (size == 1) {
+                                               *(unsigned int *)addr =
+                                                               (unsigned int)*(UINT8*)(value);
+                                       } else if (size == 2) {
+                                               *(unsigned int *)addr =
+                                                               (unsigned int)*(UINT16*)(value);
+                                       } else {
+                                               *(unsigned int *)addr =
+                                                               ((unsigned int)*(UINT32*)(value)) >> 8;
+                                       }
+                                       break;
+                               }
+#endif
+                       case FFI_TYPE_SINT32:
+                       case FFI_TYPE_UINT32:
+                       case FFI_TYPE_FLOAT:
+                       case FFI_TYPE_SINT64:
+                       case FFI_TYPE_UINT64:
+                       case FFI_TYPE_DOUBLE:
+                       default:
+                               memcpy(addr, value, aligned_size);
+               }
+       }
+}
+
+ffi_status ffi_prep_cif_machdep(ffi_cif* cif)
+{
+       /* check ABI */
+       switch (cif->abi)
+       {
+               case FFI_SYSV:
+                       break;
+               default:
+                       return FFI_BAD_ABI;
+       }
+       return FFI_OK;
+}
+
+void ffi_call(ffi_cif* cif, void (*fn)(void), 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, cif->rtype->type, cif->rtype->size);
+               break;
+       default:
+               FFI_ASSERT(0);
+               break;
+       }
+}
+
+void ffi_closure_call_SYSV(void* register_args, void* stack_args,
+                       ffi_closure* closure, void* rvalue,
+                       unsigned int* rtype, unsigned int* rsize)
+{
+       /* prepare arguments for closure call */
+       ffi_cif* cif = closure->cif;
+       ffi_type** arg_types = cif->arg_types;
+
+       /* re-allocate data for the args. This needs to be done in order to keep
+        * multi-word objects (e.g. structs) in contigious memory. Callers are not
+        * required to store the value of args in the lower 6 words in the stack
+        * (although they are allocated in the stack).
+        */
+       char* stackclone = alloca(cif->bytes);
+       void** avalue = alloca(cif->nargs * sizeof(void*));
+       void* struct_rvalue = NULL;
+       char* ptr = stackclone;
+       int i;
+
+       /* copy registers into stack clone */
+       int registers_used = cif->bytes;
+       if (registers_used > ARGS_REGISTER_SIZE) {
+               registers_used = ARGS_REGISTER_SIZE;
+       }
+       memcpy(stackclone, register_args, registers_used);
+
+       /* copy stack allocated args into stack clone */
+       if (cif->bytes > ARGS_REGISTER_SIZE) {
+               int stack_used = cif->bytes - ARGS_REGISTER_SIZE;
+               memcpy(stackclone + ARGS_REGISTER_SIZE, stack_args, stack_used);
+       }
+
+       /* preserve struct type return pointer passing */
+       if ((cif->rtype != NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) {
+               struct_rvalue = *((void**)ptr);
+               ptr += WORD_SIZE;
+       }
+
+       /* populate arg pointer list */
+       for (i = 0; i < cif->nargs; i++)
+       {
+               switch (arg_types[i]->type)
+               {
+                       case FFI_TYPE_SINT8:
+                       case FFI_TYPE_UINT8:
+#ifdef __BIG_ENDIAN__
+                               avalue[i] = ptr + 3;
+#else
+                               avalue[i] = ptr;
+#endif
+                               break;
+                       case FFI_TYPE_SINT16:
+                       case FFI_TYPE_UINT16:
+#ifdef __BIG_ENDIAN__
+                               avalue[i] = ptr + 2;
+#else
+                               avalue[i] = ptr;
+#endif
+                               break;
+                       case FFI_TYPE_STRUCT:
+#if __BIG_ENDIAN__
+                               /*
+                                * Work around strange ABI behaviour.
+                                * (see info in ffi_prep_args)
+                                */
+                               if (arg_types[i]->size < WORD_SIZE)
+                               {
+                                       if (arg_types[i]->size == 1) {
+                                               *(unsigned int *)ptr =
+                                                               ((unsigned int)*(UINT32*)(ptr)) << 24;
+                                       } else if (arg_types[i]->size == 2) {
+                                               *(unsigned int *)ptr =
+                                                               ((unsigned int)*(UINT32*)(ptr)) << 16;
+                                       } else {
+                                               *(unsigned int *)ptr =
+                                                               ((unsigned int)*(UINT32*)(ptr)) << 8;
+                                       }
+                               }
+#endif
+                               avalue[i] = (void*)ptr;
+                               break;
+                       case FFI_TYPE_UINT64:
+                       case FFI_TYPE_SINT64:
+                       case FFI_TYPE_DOUBLE:
+                               avalue[i] = ptr;
+                               break;
+                       case FFI_TYPE_SINT32:
+                       case FFI_TYPE_UINT32:
+                       case FFI_TYPE_FLOAT:
+                       default:
+                               /* default 4-byte argument */
+                               avalue[i] = ptr;
+                               break;
+               }
+               ptr += WORD_ALIGN(arg_types[i]->size);
+       }
+
+       /* set the return type info passed back to the wrapper */
+       *rsize = cif->rtype->size;
+       *rtype = cif->rtype->type;
+       if (struct_rvalue != NULL) {
+               closure->fun(cif, struct_rvalue, avalue, closure->user_data);
+               /* copy struct return pointer value into function return value */
+               *((void**)rvalue) = struct_rvalue;
+       } else {
+               closure->fun(cif, rvalue, avalue, closure->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 long* tramp = (unsigned long*)&(closure->tramp[0]);
+       unsigned long cls = (unsigned long)codeloc;
+       unsigned long fn = 0;
+       unsigned long fn_closure_call_sysv = (unsigned long)ffi_closure_call_SYSV;
+
+       closure->cif = cif;
+       closure->fun = fun;
+       closure->user_data = user_data;
+
+       switch (cif->abi)
+       {
+       case FFI_SYSV:
+               fn = (unsigned long)ffi_closure_SYSV;
+
+               /* load r11 (temp) with fn */
+               /* imm fn(upper) */
+               tramp[0] = 0xb0000000 | ((fn >> 16) & 0xffff);
+               /* addik r11, r0, fn(lower) */
+               tramp[1] = 0x31600000 | (fn & 0xffff);
+
+               /* load r12 (temp) with cls */
+               /* imm cls(upper) */
+               tramp[2] = 0xb0000000 | ((cls >> 16) & 0xffff);
+               /* addik r12, r0, cls(lower) */
+               tramp[3] = 0x31800000 | (cls & 0xffff);
+
+               /* load r3 (temp) with ffi_closure_call_SYSV */
+               /* imm fn_closure_call_sysv(upper) */
+               tramp[4] = 0xb0000000 | ((fn_closure_call_sysv >> 16) & 0xffff);
+               /* addik r3, r0, fn_closure_call_sysv(lower) */
+               tramp[5] = 0x30600000 | (fn_closure_call_sysv & 0xffff);
+               /* branch/jump to address stored in r11 (fn) */
+               tramp[6] = 0x98085800; /* bra r11 */
+
+               break;
+       default:
+               return FFI_BAD_ABI;
+       }
+       return FFI_OK;
+}
diff --git a/src/microblaze/ffitarget.h b/src/microblaze/ffitarget.h
new file mode 100644 (file)
index 0000000..c6fa5a4
--- /dev/null
@@ -0,0 +1,53 @@
+/* -----------------------------------------------------------------------
+   ffitarget.h - Copyright (c) 2012, 2013 Xilinx, Inc
+
+   Target configuration macros for MicroBlaze.
+
+   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
+
+/* Definitions for closures */
+
+#define FFI_CLOSURES 1
+#define FFI_NATIVE_RAW_API 0
+
+#define FFI_TRAMPOLINE_SIZE (4*8)
+
+#endif
diff --git a/src/microblaze/sysv.S b/src/microblaze/sysv.S
new file mode 100644 (file)
index 0000000..7a195a6
--- /dev/null
@@ -0,0 +1,302 @@
+/* -----------------------------------------------------------------------
+   sysv.S - Copyright (c) 2012, 2013 Xilinx, Inc
+
+   MicroBlaze 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 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.
+   ----------------------------------------------------------------------- */
+
+#define LIBFFI_ASM
+#include <fficonfig.h>
+#include <ffi.h>
+
+       /*
+        * arg[0] (r5)  = ffi_prep_args,
+        * arg[1] (r6)  = &ecif,
+        * arg[2] (r7)  = cif->bytes,
+        * arg[3] (r8)  = cif->flags,
+        * arg[4] (r9)  = ecif.rvalue,
+        * arg[5] (r10) = fn
+        * arg[6] (sp[0]) = cif->rtype->type
+        * arg[7] (sp[4]) = cif->rtype->size
+        */
+       .text
+       .globl ffi_call_SYSV
+       .type ffi_call_SYSV, @function
+ffi_call_SYSV:
+       /* push callee saves */
+       addik r1, r1, -20
+       swi r19, r1, 0 /* Frame Pointer */
+       swi r20, r1, 4 /* PIC register */
+       swi r21, r1, 8 /* PIC register */
+       swi r22, r1, 12 /* save for locals */
+       swi r23, r1, 16 /* save for locals */
+       
+       /* save the r5-r10 registers in the stack */
+       addik r1, r1, -24 /* increment sp to store 6x 32-bit words */
+       swi r5, r1, 0
+       swi r6, r1, 4
+       swi r7, r1, 8
+       swi r8, r1, 12
+       swi r9, r1, 16
+       swi r10, r1, 20
+
+       /* save function pointer */
+       addik r3, r5, 0 /* copy ffi_prep_args into r3 */
+       addik r22, r1, 0 /* save sp for unallocated args into r22 (callee-saved) */
+       addik r23, r10, 0 /* save function address into r23 (callee-saved) */
+
+       /* prepare stack with allocation for n (bytes = r7) args */
+       rsub r1, r7, r1 /* subtract bytes from sp */
+
+       /* prep args for ffi_prep_args call */
+       addik r5, r1, 0 /* store stack pointer into arg[0] */
+       /* r6 still holds ecif for arg[1] */
+
+       /* Call ffi_prep_args(stack, &ecif). */
+       addik r1, r1, -4
+       swi r15, r1, 0 /* store the link register in the frame */
+       brald r15, r3
+       nop /* branch has delay slot */
+       lwi r15, r1, 0
+       addik r1, r1, 4 /* restore the link register from the frame */
+       /* returns calling stack pointer location */
+
+       /* prepare args for fn call, prep_args populates them onto the stack */
+       lwi r5, r1, 0 /* arg[0] */
+       lwi r6, r1, 4 /* arg[1] */
+       lwi r7, r1, 8 /* arg[2] */
+       lwi r8, r1, 12 /* arg[3] */
+       lwi r9, r1, 16 /* arg[4] */
+       lwi r10, r1, 20 /* arg[5] */
+
+       /* call (fn) (...). */
+       addik r1, r1, -4
+       swi r15, r1, 0 /* store the link register in the frame */
+       brald r15, r23
+       nop /* branch has delay slot */
+       lwi r15, r1, 0
+       addik r1, r1, 4 /* restore the link register from the frame */
+
+       /* Remove the space we pushed for the args. */
+       addik r1, r22, 0 /* restore old SP */
+
+       /* restore this functions parameters */
+       lwi r5, r1, 0 /* arg[0] */
+       lwi r6, r1, 4 /* arg[1] */
+       lwi r7, r1, 8 /* arg[2] */
+       lwi r8, r1, 12 /* arg[3] */
+       lwi r9, r1, 16 /* arg[4] */
+       lwi r10, r1, 20 /* arg[5] */
+       addik r1, r1, 24 /* decrement sp to de-allocate 6x 32-bit words */
+
+       /* If the return value pointer is NULL, assume no return value. */
+       beqi r9, ffi_call_SYSV_end
+
+       lwi r22, r1, 48 /* get return type (20 for locals + 28 for arg[6]) */
+       lwi r23, r1, 52 /* get return size (20 for locals + 32 for arg[7])  */
+       
+       /* Check if return type is actually a struct, do nothing */
+       rsubi r11, r22, FFI_TYPE_STRUCT
+       beqi r11, ffi_call_SYSV_end
+
+       /* Return 8bit */
+       rsubi r11, r23, 1
+       beqi r11, ffi_call_SYSV_store8
+
+       /* Return 16bit */
+       rsubi r11, r23, 2
+       beqi r11, ffi_call_SYSV_store16
+
+       /* Return 32bit */
+       rsubi r11, r23, 4
+       beqi r11, ffi_call_SYSV_store32
+
+       /* Return 64bit */
+       rsubi r11, r23, 8
+       beqi r11, ffi_call_SYSV_store64
+
+       /* Didnt match anything */
+       bri ffi_call_SYSV_end
+
+ffi_call_SYSV_store64:
+       swi r3, r9, 0 /* store word r3 into return value */
+       swi r4, r9, 4 /* store word r4 into return value */
+       bri ffi_call_SYSV_end
+
+ffi_call_SYSV_store32:
+       swi r3, r9, 0 /* store word r3 into return value */
+       bri ffi_call_SYSV_end
+
+ffi_call_SYSV_store16:
+#ifdef __BIG_ENDIAN__
+       shi r3, r9, 2 /* store half-word r3 into return value */
+#else
+       shi r3, r9, 0 /* store half-word r3 into return value */
+#endif
+       bri ffi_call_SYSV_end
+
+ffi_call_SYSV_store8:
+#ifdef __BIG_ENDIAN__
+       sbi r3, r9, 3 /* store byte r3 into return value */
+#else
+       sbi r3, r9, 0 /* store byte r3 into return value */
+#endif
+       bri ffi_call_SYSV_end
+
+ffi_call_SYSV_end:
+       /* callee restores */
+       lwi r19, r1, 0 /* frame pointer */
+       lwi r20, r1, 4 /* PIC register */
+       lwi r21, r1, 8 /* PIC register */
+       lwi r22, r1, 12
+       lwi r23, r1, 16
+       addik r1, r1, 20
+
+       /* return from sub-routine (with delay slot) */
+       rtsd r15, 8
+       nop
+
+       .size ffi_call_SYSV, . - ffi_call_SYSV
+
+/* ------------------------------------------------------------------------- */
+
+       /*
+        * args passed into this function, are passed down to the callee.
+        * this function is the target of the closure trampoline, as such r12 is 
+        * a pointer to the closure object.
+        */
+       .text
+       .globl ffi_closure_SYSV
+       .type ffi_closure_SYSV, @function
+ffi_closure_SYSV:
+       /* push callee saves */
+       addik r11, r1, 28 /* save stack args start location (excluding regs/link) */
+       addik r1, r1, -12
+       swi r19, r1, 0 /* Frame Pointer */
+       swi r20, r1, 4 /* PIC register */
+       swi r21, r1, 8 /* PIC register */
+
+       /* store register args on stack */
+       addik r1, r1, -24
+       swi r5, r1, 0
+       swi r6, r1, 4
+       swi r7, r1, 8
+       swi r8, r1, 12
+       swi r9, r1, 16
+       swi r10, r1, 20
+
+       /* setup args */
+       addik r5, r1, 0 /* register_args */
+       addik r6, r11, 0 /* stack_args */
+       addik r7, r12, 0 /* closure object */
+       addik r1, r1, -8 /* allocate return value */
+       addik r8, r1, 0 /* void* rvalue */
+       addik r1, r1, -8 /* allocate for reutrn type/size values */
+       addik r9, r1, 0 /* void* rtype */
+       addik r10, r1, 4 /* void* rsize */
+
+       /* call the wrap_call function */
+       addik r1, r1, -28 /* allocate args + link reg */
+       swi r15, r1, 0 /* store the link register in the frame */
+       brald r15, r3
+       nop /* branch has delay slot */
+       lwi r15, r1, 0
+       addik r1, r1, 28 /* restore the link register from the frame */
+
+ffi_closure_SYSV_prepare_return:
+       lwi r9, r1, 0 /* rtype */
+       lwi r10, r1, 4 /* rsize */
+       addik r1, r1, 8 /* de-allocate return info values */
+
+       /* Check if return type is actually a struct, store 4 bytes */
+       rsubi r11, r9, FFI_TYPE_STRUCT
+       beqi r11, ffi_closure_SYSV_store32
+
+       /* Return 8bit */
+       rsubi r11, r10, 1
+       beqi r11, ffi_closure_SYSV_store8
+
+       /* Return 16bit */
+       rsubi r11, r10, 2
+       beqi r11, ffi_closure_SYSV_store16
+
+       /* Return 32bit */
+       rsubi r11, r10, 4
+       beqi r11, ffi_closure_SYSV_store32
+
+       /* Return 64bit */
+       rsubi r11, r10, 8
+       beqi r11, ffi_closure_SYSV_store64
+
+       /* Didnt match anything */
+       bri ffi_closure_SYSV_end
+
+ffi_closure_SYSV_store64:
+       lwi r3, r1, 0 /* store word r3 into return value */
+       lwi r4, r1, 4 /* store word r4 into return value */
+       /* 64 bits == 2 words, no sign extend occurs */
+       bri ffi_closure_SYSV_end
+
+ffi_closure_SYSV_store32:
+       lwi r3, r1, 0 /* store word r3 into return value */
+       /* 32 bits == 1 word, no sign extend occurs */
+       bri ffi_closure_SYSV_end
+
+ffi_closure_SYSV_store16:
+#ifdef __BIG_ENDIAN__
+       lhui r3, r1, 2 /* store half-word r3 into return value */
+#else
+       lhui r3, r1, 0 /* store half-word r3 into return value */
+#endif
+       rsubi r11, r9, FFI_TYPE_SINT16
+       bnei r11, ffi_closure_SYSV_end
+       sext16 r3, r3 /* fix sign extend of sint8 */
+       bri ffi_closure_SYSV_end
+
+ffi_closure_SYSV_store8:
+#ifdef __BIG_ENDIAN__
+       lbui r3, r1, 3 /* store byte r3 into return value */
+#else
+       lbui r3, r1, 0 /* store byte r3 into return value */
+#endif
+       rsubi r11, r9, FFI_TYPE_SINT8
+       bnei r11, ffi_closure_SYSV_end
+       sext8 r3, r3 /* fix sign extend of sint8 */
+       bri ffi_closure_SYSV_end
+
+ffi_closure_SYSV_end:
+       addik r1, r1, 8 /* de-allocate return value */
+
+       /* de-allocate stored args */
+       addik r1, r1, 24
+
+       /* callee restores */
+       lwi r19, r1, 0 /* frame pointer */
+       lwi r20, r1, 4 /* PIC register */
+       lwi r21, r1, 8 /* PIC register */
+       addik r1, r1, 12
+
+       /* return from sub-routine (with delay slot) */
+       rtsd r15, 8
+       nop
+
+       .size ffi_closure_SYSV, . - ffi_closure_SYSV
index 07c45de..6fe5546 100644 (file)
@@ -32,7 +32,7 @@ int main (void)
        uc < (unsigned char) '\xff'; uc++)
     {
       ffi_call(&cif, FFI_FN(return_uc), &rint, values);
-      CHECK(rint == (signed int) uc);
+      CHECK((unsigned char)rint == uc);
     }
   exit(0);
 }