diff options
author | Palmer Dabbelt <palmer@dabbelt.com> | 2015-01-09 17:51:21 -0800 |
---|---|---|
committer | Palmer Dabbelt <palmer@dabbelt.com> | 2015-01-09 17:51:21 -0800 |
commit | df4855d6016d7b6d39cbc0b35e06d49db5eb17fb (patch) | |
tree | 016a7d9b7c81ab8ee677e12b38cb067290c46d21 | |
parent | Update the RISC-V toolchain ports (diff) | |
download | palmer-df4855d6016d7b6d39cbc0b35e06d49db5eb17fb.tar.gz palmer-df4855d6016d7b6d39cbc0b35e06d49db5eb17fb.tar.bz2 palmer-df4855d6016d7b6d39cbc0b35e06d49db5eb17fb.zip |
Update the libffi RISCV port
-rw-r--r-- | dev-libs/libffi/Manifest | 4 | ||||
-rw-r--r-- | dev-libs/libffi/files/libffi-3.1-riscv.patch | 2879 | ||||
-rw-r--r-- | dev-libs/libffi/libffi-3.1-r3.ebuild | 3 |
3 files changed, 2019 insertions, 867 deletions
diff --git a/dev-libs/libffi/Manifest b/dev-libs/libffi/Manifest index 771e13d..3464b58 100644 --- a/dev-libs/libffi/Manifest +++ b/dev-libs/libffi/Manifest @@ -1,10 +1,10 @@ AUX libffi-3.0.13-emutramp_pax_proc.patch 911 SHA256 955aa3d87522cb220133fa853bd3a5a7af1fe7cf5cc6b9eb74ffffb9ac563aba SHA512 402712b21feec0f162758adad630ecc588596eaebd2e79bb86802f313e102b8ef6d08eca0580a1aae25dabec3e018c499e2ce1960edc6af9182f67cd8cc9b0e1 WHIRLPOOL 22f76ca6f909c80228958115a8db37fbe5f12e291cdbc1fad672a0903c54a7918e2cee37fdc263e9c350f3c79a7870cc8f7a05789668a8dc87cb8434a6e20f9c AUX libffi-3.0.13-riscv.patch 53809 SHA256 aedec01c63c1b6de06f8e7e84a02e875e5010fcf7f6bbc7e1ba33e998913a176 SHA512 623adfcb444a35715b8c25a72d4da0453bd089bf446ab86f41145c1573cf37a394ac5512a6761b3cd380a01d4ee9b77302315ee75bb1b2ebf81c583730f311bd WHIRLPOOL 52ae17260e31504734b4628997bed7b0e4e508fbbd8cedc6c6fb9062d959de042dff555d7ac0f66ceb8d7d4797217f9c3045603c8608b6d53bb0a0b6534dcc10 AUX libffi-3.1-execstack.patch 277 SHA256 55e95096d8b2bd82188c62b1316c602738336c0a4b58ccce503936dfc436b1d9 SHA512 1365cb102e6ffacd89b399243cd89ddb29259e373d16fd500d9d98bd40edbd0d79b63df6fb9464247cc2f11628d5c692a25f1c6d9cef19feb857e1232c154d4f WHIRLPOOL 597c3cdb8a28dcc15d724fa4d184956bcd4118803070ba63c1d914eb1a3b4c9720f68404a05ba4ad7ad83714f79ee7856bb8921886511bc7d35b39f33b4b41f0 -AUX libffi-3.1-riscv.patch 54381 SHA256 cad025d4dcb44a1cd77456afecfd7f6122e9eb7ac2b24c50a3cce69189f05015 SHA512 ca9728d0b0181be94f37bd8946a7c2c247054092cceebf5d775ea9a96367aa7461a0f756b9f7f637518b8ac5c491abf7714e625523264263de2e2a32ca45dae3 WHIRLPOOL 2f07b163f5d96f668b4f28068e8268af81317fe97968a8e243c1725de28488800067dac4b3d0832fe78cc7d3a48d550bfc416d1314c7061418c73f4975ba4806 +AUX libffi-3.1-riscv.patch 105494 SHA256 02aa3752799edc56cd964379b6f645fb40a7043468b74839bf957b1862aa6939 SHA512 1f26c2660ccb23c08d679c423c4dd6f98b17301809fc4148956c7edae7659a43080df58e9ee024c719db2fe07bfbf722252076e494f4810a1a6e1f4128358205 WHIRLPOOL 2a46150894d5dd89af7c8c0ea68ca3b5bdd5ace9554612f243b2c5d9e10deb9f2da2fb8206f7cd6ea80b671c5d6a65d969b260ed0ac6cd7c5bcba1a919a539f7 AUX libffi-3.1-typing_error.patch 350 SHA256 2e134e7f347f392499ec9128b220cff467919dfc048922d72689816d9f40ea95 SHA512 6be05ec604da587ded9d50ba57153b7ca24ee52dbed132d08f8653032153d377b2e399b58010e3c84e2106f077696a0cc9507018687af2082aa5ce055ba5fa07 WHIRLPOOL e8613594118774abaa2d79b0cdcbfd57d1c3ca275543423cec70b368e604c78bc7162d582a5b654b378b60a1d765a12b418bd10f8a8693ccbc3e7fdf225be216 AUX libffi-3.2-riscv-closure.patch 742 SHA256 ab4320ddad2377458c1a91409b1db5cd41ce8201e12ee3b13afab2f1bbb7f35c SHA512 159f6de35a5ad63911e905af0f60d41b5f3b8f3a7c8e65c3e83ae7b0780315d99b18de96573c043c4650424069db48f8de321d0c42ec49a7517dc98b8719c6b9 WHIRLPOOL 6a8c8dddb26a0941fa34c1cde59d7e91d2ee5416b5dc4478247b7101df9ead6d065344a14691306df6c944a7c7fafe013056e4bd6a2505a81c27702dd5db1c38 DIST libffi-3.0.13.tar.gz 845747 SHA256 1dddde1400c3bcb7749d398071af88c3e4754058d2d4c0b3696c2f82dc5cf11c SHA512 fc47f5d25197c631754efe05a349edb556d072807ecef19b41f17c1a8f39c95221be64926fbd05b1f8439181df1ddff8fc01462ce3a26005b75159ddc27e6f6a WHIRLPOOL d5b14d48a7b35f7349ec938d0deac62db7022ac4d611ab13bc7a6a2766a47e210fc1663fc8c6d7ee48d421c06b66f558010829ac2c215620c76d0bf7650e1308 DIST libffi-3.1.tar.gz 937214 SHA256 97feeeadca5e21870fa4433bc953d1b3af3f698d5df8a428f68b73cd60aef6eb SHA512 8994973d75facf5ad928c270e17b1a56e24d1543af75b93731a0048e747df27e4190a736b6dc2dca7d43de1d7e88891220304802c10fcccdcebee9c9ffd3d1b9 WHIRLPOOL 19c08cffd39c998fcd762b1e3767b4fd86915427226833411302bebd2d5bcf93d515e6df4a4cab11327595d3966e46442e457fbe09ae986b58bdfb2bb6adb913 EBUILD libffi-3.0.13-r1.ebuild 2404 SHA256 a4236c151f490427e889b47dc030536568f65c6e86613a7ccca669c85f3df5fa SHA512 7af6df8c629152c43afb60ac8ac19220eda34e31b98dfbe1cf0cf7c7eeafb11f062ffe1441a53d48bca936b104e0e2afce3645289feff74f63ecd3c73bb73888 WHIRLPOOL 194c73e539836c429c6b3521db7ee1bc398b1f5637c82dbc6dff04638a65286d00c8876eacb7852f91a306aabf0633108a5972592bf705c732639b73e9eeea0a -EBUILD libffi-3.1-r3.ebuild 2430 SHA256 677bf4e8e100c44ea0d69ec5d97dccf74e8d413bb73d0dd70f8333afeb582561 SHA512 185e115d4c2f9b7c778ad02c97ff8baae84386ddb4ac8cd3d0c4a04442a2df3c60791b7124f05e37e2664917d3008bfd20efd641ba1f7c1aa3b6955257e4afdd WHIRLPOOL 07eb9ab93318b34758fdc83ab5ffce43f4ef027d570d5329443ec65748c4a787a72aaa0274b47c0767d9bd571e31e535665a05ce01a4658791dce4195c94bff9 +EBUILD libffi-3.1-r3.ebuild 2368 SHA256 85afd60cc867dced69158da6021ea5f985af62a31b0b1313da5cfd54fd29e5ba SHA512 0a61eb4ce6f4316ccb13c8889c8f9c97ac5913a1f3bfffa2c0b978046a0d6c2f5666ff8243551d1c3443fd6bff5cb33ac7b8c5044459b7561e86e8380b5dd98e WHIRLPOOL 33b741990f16504df534449159f5f6dde5c77b58bbcc7387b18681990c8215714615d7987e1a821095902612463921fe6c97aed354e0591714125cba1c05d0a6 diff --git a/dev-libs/libffi/files/libffi-3.1-riscv.patch b/dev-libs/libffi/files/libffi-3.1-riscv.patch index f606c65..8286e8c 100644 --- a/dev-libs/libffi/files/libffi-3.1-riscv.patch +++ b/dev-libs/libffi/files/libffi-3.1-riscv.patch @@ -1,7 +1,7 @@ -diff --git a/Makefile.am b/Makefile.am -index 1dcdc81..2a6d164 100644 ---- a/Makefile.am -+++ b/Makefile.am +diff --git a/libffi-3.1/Makefile.am b/libffi-3.1/Makefile.am +index 1dcdc81..d3e737f 100644 +--- a/libffi-3.1/Makefile.am ++++ b/libffi-3.1/Makefile.am @@ -8,7 +8,7 @@ SUBDIRS = include testsuite man EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ @@ -11,29 +11,1105 @@ index 1dcdc81..2a6d164 100644 src/alpha/ffitarget.h src/arc/ffi.c src/arc/arcompact.S \ src/arc/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \ -@@ -31,6 +31,8 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ +@@ -31,6 +31,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \ src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \ src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \ -+ src/riscv/ffi.c src/riscv/rv32.S \ -+ src/riscv/rv64.S src/riscv/ffitarget.h \ ++ src/riscv/ffi.c src/riscv/ffitarget.h src/riscv/sysv.S \ src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \ src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c \ src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S \ -@@ -121,6 +123,9 @@ endif +@@ -121,6 +122,9 @@ endif if MIPS nodist_libffi_la_SOURCES += src/mips/ffi.c src/mips/o32.S src/mips/n32.S endif +if RISCV -+nodist_libffi_la_SOURCES += src/riscv/ffi.c src/riscv/rv32.S src/riscv/rv64.S ++nodist_libffi_la_SOURCES += src/riscv/ffi.c src/riscv/sysv.S +endif if BFIN nodist_libffi_la_SOURCES += src/bfin/ffi.c src/bfin/sysv.S endif -diff --git a/configure.ac b/configure.ac +diff --git a/libffi-3.1/Makefile.in b/libffi-3.1/Makefile.in +index 4a57abd..7f4f4fe 100644 +--- a/libffi-3.1/Makefile.in ++++ b/libffi-3.1/Makefile.in +@@ -82,53 +82,54 @@ host_triplet = @host@ + target_triplet = @target@ + @FFI_DEBUG_TRUE@am__append_1 = src/debug.c + @MIPS_TRUE@am__append_2 = src/mips/ffi.c src/mips/o32.S src/mips/n32.S +-@BFIN_TRUE@am__append_3 = src/bfin/ffi.c src/bfin/sysv.S +-@X86_TRUE@am__append_4 = src/x86/ffi.c src/x86/sysv.S src/x86/win32.S +-@X86_FREEBSD_TRUE@am__append_5 = src/x86/ffi.c src/x86/freebsd.S src/x86/win32.S +-@X86_WIN32_TRUE@am__append_6 = src/x86/ffi.c src/x86/win32.S +-@X86_WIN64_TRUE@am__append_7 = src/x86/ffi.c src/x86/win64.S +-@X86_DARWIN_TRUE@am__append_8 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S +-@X86_DARWIN32_TRUE@@X86_DARWIN_TRUE@am__append_9 = src/x86/win32.S +-@SPARC_TRUE@am__append_10 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S +-@ALPHA_TRUE@am__append_11 = src/alpha/ffi.c src/alpha/osf.S +-@IA64_TRUE@am__append_12 = src/ia64/ffi.c src/ia64/unix.S +-@M32R_TRUE@am__append_13 = src/m32r/sysv.S src/m32r/ffi.c +-@M68K_TRUE@am__append_14 = src/m68k/ffi.c src/m68k/sysv.S +-@M88K_TRUE@am__append_15 = src/m88k/ffi.c src/m88k/obsd.S +-@MOXIE_TRUE@am__append_16 = src/moxie/ffi.c src/moxie/eabi.S +-@MICROBLAZE_TRUE@am__append_17 = src/microblaze/ffi.c src/microblaze/sysv.S +-@NIOS2_TRUE@am__append_18 = src/nios2/sysv.S src/nios2/ffi.c +-@POWERPC_TRUE@am__append_19 = src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S +-@POWERPC_AIX_TRUE@am__append_20 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S +-@POWERPC_DARWIN_TRUE@am__append_21 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S +-@POWERPC_FREEBSD_TRUE@am__append_22 = src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/sysv.S src/powerpc/ppc_closure.S +-@AARCH64_TRUE@am__append_23 = src/aarch64/sysv.S src/aarch64/ffi.c +-@ARC_TRUE@am__append_24 = src/arc/arcompact.S src/arc/ffi.c +-@ARM_TRUE@am__append_25 = src/arm/sysv.S src/arm/ffi.c +-@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_26 = src/arm/trampoline.S +-@AVR32_TRUE@am__append_27 = src/avr32/sysv.S src/avr32/ffi.c +-@LIBFFI_CRIS_TRUE@am__append_28 = src/cris/sysv.S src/cris/ffi.c +-@FRV_TRUE@am__append_29 = src/frv/eabi.S src/frv/ffi.c +-@S390_TRUE@am__append_30 = src/s390/sysv.S src/s390/ffi.c +-@X86_64_TRUE@am__append_31 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S +-@SH_TRUE@am__append_32 = src/sh/sysv.S src/sh/ffi.c +-@SH64_TRUE@am__append_33 = src/sh64/sysv.S src/sh64/ffi.c +-@PA_LINUX_TRUE@am__append_34 = src/pa/linux.S src/pa/ffi.c +-@PA_HPUX_TRUE@am__append_35 = src/pa/hpux32.S src/pa/ffi.c +-@TILE_TRUE@am__append_36 = src/tile/tile.S src/tile/ffi.c +-@XTENSA_TRUE@am__append_37 = src/xtensa/sysv.S src/xtensa/ffi.c +-@METAG_TRUE@am__append_38 = src/metag/sysv.S src/metag/ffi.c +-@VAX_TRUE@am__append_39 = src/vax/elfbsd.S src/vax/ffi.c ++@RISCV_TRUE@am__append_3 = src/riscv/ffi.c src/riscv/sysv.S ++@BFIN_TRUE@am__append_4 = src/bfin/ffi.c src/bfin/sysv.S ++@X86_TRUE@am__append_5 = src/x86/ffi.c src/x86/sysv.S src/x86/win32.S ++@X86_FREEBSD_TRUE@am__append_6 = src/x86/ffi.c src/x86/freebsd.S src/x86/win32.S ++@X86_WIN32_TRUE@am__append_7 = src/x86/ffi.c src/x86/win32.S ++@X86_WIN64_TRUE@am__append_8 = src/x86/ffi.c src/x86/win64.S ++@X86_DARWIN_TRUE@am__append_9 = src/x86/ffi.c src/x86/darwin.S src/x86/ffi64.c src/x86/darwin64.S ++@X86_DARWIN32_TRUE@@X86_DARWIN_TRUE@am__append_10 = src/x86/win32.S ++@SPARC_TRUE@am__append_11 = src/sparc/ffi.c src/sparc/v8.S src/sparc/v9.S ++@ALPHA_TRUE@am__append_12 = src/alpha/ffi.c src/alpha/osf.S ++@IA64_TRUE@am__append_13 = src/ia64/ffi.c src/ia64/unix.S ++@M32R_TRUE@am__append_14 = src/m32r/sysv.S src/m32r/ffi.c ++@M68K_TRUE@am__append_15 = src/m68k/ffi.c src/m68k/sysv.S ++@M88K_TRUE@am__append_16 = src/m88k/ffi.c src/m88k/obsd.S ++@MOXIE_TRUE@am__append_17 = src/moxie/ffi.c src/moxie/eabi.S ++@MICROBLAZE_TRUE@am__append_18 = src/microblaze/ffi.c src/microblaze/sysv.S ++@NIOS2_TRUE@am__append_19 = src/nios2/sysv.S src/nios2/ffi.c ++@POWERPC_TRUE@am__append_20 = src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/ffi_linux64.c src/powerpc/sysv.S src/powerpc/ppc_closure.S src/powerpc/linux64.S src/powerpc/linux64_closure.S ++@POWERPC_AIX_TRUE@am__append_21 = src/powerpc/ffi_darwin.c src/powerpc/aix.S src/powerpc/aix_closure.S ++@POWERPC_DARWIN_TRUE@am__append_22 = src/powerpc/ffi_darwin.c src/powerpc/darwin.S src/powerpc/darwin_closure.S ++@POWERPC_FREEBSD_TRUE@am__append_23 = src/powerpc/ffi.c src/powerpc/ffi_sysv.c src/powerpc/sysv.S src/powerpc/ppc_closure.S ++@AARCH64_TRUE@am__append_24 = src/aarch64/sysv.S src/aarch64/ffi.c ++@ARC_TRUE@am__append_25 = src/arc/arcompact.S src/arc/ffi.c ++@ARM_TRUE@am__append_26 = src/arm/sysv.S src/arm/ffi.c ++@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__append_27 = src/arm/trampoline.S ++@AVR32_TRUE@am__append_28 = src/avr32/sysv.S src/avr32/ffi.c ++@LIBFFI_CRIS_TRUE@am__append_29 = src/cris/sysv.S src/cris/ffi.c ++@FRV_TRUE@am__append_30 = src/frv/eabi.S src/frv/ffi.c ++@S390_TRUE@am__append_31 = src/s390/sysv.S src/s390/ffi.c ++@X86_64_TRUE@am__append_32 = src/x86/ffi64.c src/x86/unix64.S src/x86/ffi.c src/x86/sysv.S ++@SH_TRUE@am__append_33 = src/sh/sysv.S src/sh/ffi.c ++@SH64_TRUE@am__append_34 = src/sh64/sysv.S src/sh64/ffi.c ++@PA_LINUX_TRUE@am__append_35 = src/pa/linux.S src/pa/ffi.c ++@PA_HPUX_TRUE@am__append_36 = src/pa/hpux32.S src/pa/ffi.c ++@TILE_TRUE@am__append_37 = src/tile/tile.S src/tile/ffi.c ++@XTENSA_TRUE@am__append_38 = src/xtensa/sysv.S src/xtensa/ffi.c ++@METAG_TRUE@am__append_39 = src/metag/sysv.S src/metag/ffi.c ++@VAX_TRUE@am__append_40 = src/vax/elfbsd.S src/vax/ffi.c + # Build debug. Define FFI_DEBUG on the commandline so that, when building with + # MSVC, it can link against the debug CRT. +-@FFI_DEBUG_TRUE@am__append_40 = -DFFI_DEBUG ++@FFI_DEBUG_TRUE@am__append_41 = -DFFI_DEBUG + subdir = . + DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ + $(top_srcdir)/configure $(am__configure_deps) \ + $(srcdir)/fficonfig.h.in $(srcdir)/libffi.pc.in depcomp \ + mdate-sh $(srcdir)/doc/version.texi $(srcdir)/doc/stamp-vti \ +- texinfo.tex README compile config.guess config.sub install-sh \ +- missing ltmain.sh ++ texinfo.tex ChangeLog README compile config.guess config.sub \ ++ install-sh missing ltmain.sh + ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 + am__aclocal_m4_deps = $(top_srcdir)/m4/asmcfi.m4 \ + $(top_srcdir)/m4/ax_append_flag.m4 \ +@@ -189,61 +190,62 @@ am_libffi_la_OBJECTS = src/prep_cif.lo src/types.lo src/raw_api.lo \ + @FFI_DEBUG_TRUE@am__objects_1 = src/debug.lo + @MIPS_TRUE@am__objects_2 = src/mips/ffi.lo src/mips/o32.lo \ + @MIPS_TRUE@ src/mips/n32.lo +-@BFIN_TRUE@am__objects_3 = src/bfin/ffi.lo src/bfin/sysv.lo +-@X86_TRUE@am__objects_4 = src/x86/ffi.lo src/x86/sysv.lo \ ++@RISCV_TRUE@am__objects_3 = src/riscv/ffi.lo src/riscv/sysv.lo ++@BFIN_TRUE@am__objects_4 = src/bfin/ffi.lo src/bfin/sysv.lo ++@X86_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/sysv.lo \ + @X86_TRUE@ src/x86/win32.lo +-@X86_FREEBSD_TRUE@am__objects_5 = src/x86/ffi.lo src/x86/freebsd.lo \ ++@X86_FREEBSD_TRUE@am__objects_6 = src/x86/ffi.lo src/x86/freebsd.lo \ + @X86_FREEBSD_TRUE@ src/x86/win32.lo +-@X86_WIN32_TRUE@am__objects_6 = src/x86/ffi.lo src/x86/win32.lo +-@X86_WIN64_TRUE@am__objects_7 = src/x86/ffi.lo src/x86/win64.lo +-@X86_DARWIN_TRUE@am__objects_8 = src/x86/ffi.lo src/x86/darwin.lo \ ++@X86_WIN32_TRUE@am__objects_7 = src/x86/ffi.lo src/x86/win32.lo ++@X86_WIN64_TRUE@am__objects_8 = src/x86/ffi.lo src/x86/win64.lo ++@X86_DARWIN_TRUE@am__objects_9 = src/x86/ffi.lo src/x86/darwin.lo \ + @X86_DARWIN_TRUE@ src/x86/ffi64.lo src/x86/darwin64.lo +-@X86_DARWIN32_TRUE@@X86_DARWIN_TRUE@am__objects_9 = src/x86/win32.lo +-@SPARC_TRUE@am__objects_10 = src/sparc/ffi.lo src/sparc/v8.lo \ ++@X86_DARWIN32_TRUE@@X86_DARWIN_TRUE@am__objects_10 = src/x86/win32.lo ++@SPARC_TRUE@am__objects_11 = src/sparc/ffi.lo src/sparc/v8.lo \ + @SPARC_TRUE@ src/sparc/v9.lo +-@ALPHA_TRUE@am__objects_11 = src/alpha/ffi.lo src/alpha/osf.lo +-@IA64_TRUE@am__objects_12 = src/ia64/ffi.lo src/ia64/unix.lo +-@M32R_TRUE@am__objects_13 = src/m32r/sysv.lo src/m32r/ffi.lo +-@M68K_TRUE@am__objects_14 = src/m68k/ffi.lo src/m68k/sysv.lo +-@M88K_TRUE@am__objects_15 = src/m88k/ffi.lo src/m88k/obsd.lo +-@MOXIE_TRUE@am__objects_16 = src/moxie/ffi.lo src/moxie/eabi.lo +-@MICROBLAZE_TRUE@am__objects_17 = src/microblaze/ffi.lo \ ++@ALPHA_TRUE@am__objects_12 = src/alpha/ffi.lo src/alpha/osf.lo ++@IA64_TRUE@am__objects_13 = src/ia64/ffi.lo src/ia64/unix.lo ++@M32R_TRUE@am__objects_14 = src/m32r/sysv.lo src/m32r/ffi.lo ++@M68K_TRUE@am__objects_15 = src/m68k/ffi.lo src/m68k/sysv.lo ++@M88K_TRUE@am__objects_16 = src/m88k/ffi.lo src/m88k/obsd.lo ++@MOXIE_TRUE@am__objects_17 = src/moxie/ffi.lo src/moxie/eabi.lo ++@MICROBLAZE_TRUE@am__objects_18 = src/microblaze/ffi.lo \ + @MICROBLAZE_TRUE@ src/microblaze/sysv.lo +-@NIOS2_TRUE@am__objects_18 = src/nios2/sysv.lo src/nios2/ffi.lo +-@POWERPC_TRUE@am__objects_19 = src/powerpc/ffi.lo \ ++@NIOS2_TRUE@am__objects_19 = src/nios2/sysv.lo src/nios2/ffi.lo ++@POWERPC_TRUE@am__objects_20 = src/powerpc/ffi.lo \ + @POWERPC_TRUE@ src/powerpc/ffi_sysv.lo \ + @POWERPC_TRUE@ src/powerpc/ffi_linux64.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_20 = src/powerpc/ffi_darwin.lo \ ++@POWERPC_AIX_TRUE@am__objects_21 = 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_21 = src/powerpc/ffi_darwin.lo \ ++@POWERPC_DARWIN_TRUE@am__objects_22 = 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_22 = src/powerpc/ffi.lo \ ++@POWERPC_FREEBSD_TRUE@am__objects_23 = src/powerpc/ffi.lo \ + @POWERPC_FREEBSD_TRUE@ src/powerpc/ffi_sysv.lo \ + @POWERPC_FREEBSD_TRUE@ src/powerpc/sysv.lo \ + @POWERPC_FREEBSD_TRUE@ src/powerpc/ppc_closure.lo +-@AARCH64_TRUE@am__objects_23 = src/aarch64/sysv.lo src/aarch64/ffi.lo +-@ARC_TRUE@am__objects_24 = src/arc/arcompact.lo src/arc/ffi.lo +-@ARM_TRUE@am__objects_25 = src/arm/sysv.lo src/arm/ffi.lo +-@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_26 = src/arm/trampoline.lo +-@AVR32_TRUE@am__objects_27 = src/avr32/sysv.lo src/avr32/ffi.lo +-@LIBFFI_CRIS_TRUE@am__objects_28 = src/cris/sysv.lo src/cris/ffi.lo +-@FRV_TRUE@am__objects_29 = src/frv/eabi.lo src/frv/ffi.lo +-@S390_TRUE@am__objects_30 = src/s390/sysv.lo src/s390/ffi.lo +-@X86_64_TRUE@am__objects_31 = src/x86/ffi64.lo src/x86/unix64.lo \ ++@AARCH64_TRUE@am__objects_24 = src/aarch64/sysv.lo src/aarch64/ffi.lo ++@ARC_TRUE@am__objects_25 = src/arc/arcompact.lo src/arc/ffi.lo ++@ARM_TRUE@am__objects_26 = src/arm/sysv.lo src/arm/ffi.lo ++@ARM_TRUE@@FFI_EXEC_TRAMPOLINE_TABLE_TRUE@am__objects_27 = src/arm/trampoline.lo ++@AVR32_TRUE@am__objects_28 = src/avr32/sysv.lo src/avr32/ffi.lo ++@LIBFFI_CRIS_TRUE@am__objects_29 = src/cris/sysv.lo src/cris/ffi.lo ++@FRV_TRUE@am__objects_30 = src/frv/eabi.lo src/frv/ffi.lo ++@S390_TRUE@am__objects_31 = src/s390/sysv.lo src/s390/ffi.lo ++@X86_64_TRUE@am__objects_32 = src/x86/ffi64.lo src/x86/unix64.lo \ + @X86_64_TRUE@ src/x86/ffi.lo src/x86/sysv.lo +-@SH_TRUE@am__objects_32 = src/sh/sysv.lo src/sh/ffi.lo +-@SH64_TRUE@am__objects_33 = src/sh64/sysv.lo src/sh64/ffi.lo +-@PA_LINUX_TRUE@am__objects_34 = src/pa/linux.lo src/pa/ffi.lo +-@PA_HPUX_TRUE@am__objects_35 = src/pa/hpux32.lo src/pa/ffi.lo +-@TILE_TRUE@am__objects_36 = src/tile/tile.lo src/tile/ffi.lo +-@XTENSA_TRUE@am__objects_37 = src/xtensa/sysv.lo src/xtensa/ffi.lo +-@METAG_TRUE@am__objects_38 = src/metag/sysv.lo src/metag/ffi.lo +-@VAX_TRUE@am__objects_39 = src/vax/elfbsd.lo src/vax/ffi.lo ++@SH_TRUE@am__objects_33 = src/sh/sysv.lo src/sh/ffi.lo ++@SH64_TRUE@am__objects_34 = src/sh64/sysv.lo src/sh64/ffi.lo ++@PA_LINUX_TRUE@am__objects_35 = src/pa/linux.lo src/pa/ffi.lo ++@PA_HPUX_TRUE@am__objects_36 = src/pa/hpux32.lo src/pa/ffi.lo ++@TILE_TRUE@am__objects_37 = src/tile/tile.lo src/tile/ffi.lo ++@XTENSA_TRUE@am__objects_38 = src/xtensa/sysv.lo src/xtensa/ffi.lo ++@METAG_TRUE@am__objects_39 = src/metag/sysv.lo src/metag/ffi.lo ++@VAX_TRUE@am__objects_40 = 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) \ +@@ -257,7 +259,7 @@ nodist_libffi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \ + $(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_38) \ +- $(am__objects_39) ++ $(am__objects_39) $(am__objects_40) + libffi_la_OBJECTS = $(am_libffi_la_OBJECTS) \ + $(nodist_libffi_la_OBJECTS) + AM_V_lt = $(am__v_lt_@AM_V@) +@@ -268,10 +270,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_40 = src/prep_cif.lo src/types.lo src/raw_api.lo \ ++am__objects_41 = 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_40) +-am__objects_41 = $(am__objects_1) $(am__objects_2) $(am__objects_3) \ ++am_libffi_convenience_la_OBJECTS = $(am__objects_41) ++am__objects_42 = $(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) \ +@@ -283,8 +285,9 @@ am__objects_41 = $(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) $(am__objects_38) $(am__objects_39) +-nodist_libffi_convenience_la_OBJECTS = $(am__objects_41) ++ $(am__objects_37) $(am__objects_38) $(am__objects_39) \ ++ $(am__objects_40) ++nodist_libffi_convenience_la_OBJECTS = $(am__objects_42) + libffi_convenience_la_OBJECTS = $(am_libffi_convenience_la_OBJECTS) \ + $(nodist_libffi_convenience_la_OBJECTS) + AM_V_P = $(am__v_P_@AM_V@) +@@ -606,7 +609,7 @@ ACLOCAL_AMFLAGS = -I m4 + SUBDIRS = include testsuite man + EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ + src/aarch64/ffi.c src/aarch64/ffitarget.h src/aarch64/sysv.S \ +- src/alpha/ffi.c src/alpha/osf.S \ ++ src/alpha/ffi.c src/alpha/osf.S \ + src/alpha/ffitarget.h src/arc/ffi.c src/arc/arcompact.S \ + src/arc/ffitarget.h src/arm/ffi.c src/arm/sysv.S \ + src/arm/ffitarget.h src/avr32/ffi.c src/avr32/sysv.S \ +@@ -629,6 +632,7 @@ EXTRA_DIST = LICENSE ChangeLog.v1 ChangeLog.libgcj \ + src/powerpc/asm.h src/powerpc/aix.S src/powerpc/darwin.S \ + src/powerpc/aix_closure.S src/powerpc/darwin_closure.S \ + src/powerpc/ffi_darwin.c src/powerpc/ffitarget.h \ ++ src/riscv/ffi.c src/riscv/ffitarget.h src/riscv/sysv.S \ + src/s390/ffi.c src/s390/sysv.S src/s390/ffitarget.h \ + src/sh/ffi.c src/sh/sysv.S src/sh/ffitarget.h src/sh64/ffi.c \ + src/sh64/sysv.S src/sh64/ffitarget.h src/sparc/v8.S \ +@@ -714,11 +718,11 @@ nodist_libffi_la_SOURCES = $(am__append_1) $(am__append_2) \ + $(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_38) \ +- $(am__append_39) ++ $(am__append_39) $(am__append_40) + libffi_convenience_la_SOURCES = $(libffi_la_SOURCES) + nodist_libffi_convenience_la_SOURCES = $(nodist_libffi_la_SOURCES) + LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/libtool-ldflags $(LDFLAGS)) +-AM_CFLAGS = $(am__append_40) ++AM_CFLAGS = $(am__append_41) + libffi_la_LDFLAGS = -no-undefined -version-info `grep -v '^\#' $(srcdir)/libtool-version` $(LTLDFLAGS) $(AM_LTLDFLAGS) + AM_CPPFLAGS = -I. -I$(top_srcdir)/include -Iinclude -I$(top_srcdir)/src + AM_CCASFLAGS = $(AM_CPPFLAGS) +@@ -848,6 +852,16 @@ src/mips/o32.lo: src/mips/$(am__dirstamp) \ + src/mips/$(DEPDIR)/$(am__dirstamp) + src/mips/n32.lo: src/mips/$(am__dirstamp) \ + src/mips/$(DEPDIR)/$(am__dirstamp) ++src/riscv/$(am__dirstamp): ++ @$(MKDIR_P) src/riscv ++ @: > src/riscv/$(am__dirstamp) ++src/riscv/$(DEPDIR)/$(am__dirstamp): ++ @$(MKDIR_P) src/riscv/$(DEPDIR) ++ @: > src/riscv/$(DEPDIR)/$(am__dirstamp) ++src/riscv/ffi.lo: src/riscv/$(am__dirstamp) \ ++ src/riscv/$(DEPDIR)/$(am__dirstamp) ++src/riscv/sysv.lo: src/riscv/$(am__dirstamp) \ ++ src/riscv/$(DEPDIR)/$(am__dirstamp) + src/bfin/$(am__dirstamp): + @$(MKDIR_P) src/bfin + @: > src/bfin/$(am__dirstamp) +@@ -1195,6 +1209,8 @@ mostlyclean-compile: + -rm -f src/pa/*.lo + -rm -f src/powerpc/*.$(OBJEXT) + -rm -f src/powerpc/*.lo ++ -rm -f src/riscv/*.$(OBJEXT) ++ -rm -f src/riscv/*.lo + -rm -f src/s390/*.$(OBJEXT) + -rm -f src/s390/*.lo + -rm -f src/sh/*.$(OBJEXT) +@@ -1272,6 +1288,8 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/linux64_closure.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/ppc_closure.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/powerpc/$(DEPDIR)/sysv.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@src/riscv/$(DEPDIR)/ffi.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@src/riscv/$(DEPDIR)/sysv.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/s390/$(DEPDIR)/ffi.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/s390/$(DEPDIR)/sysv.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@src/sh/$(DEPDIR)/ffi.Plo@am__quote@ +@@ -1370,6 +1388,7 @@ clean-libtool: + -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/riscv/.libs src/riscv/_libs + -rm -rf src/s390/.libs src/s390/_libs + -rm -rf src/sh/.libs src/sh/_libs + -rm -rf src/sh64/.libs src/sh64/_libs +@@ -1932,6 +1951,8 @@ distclean-generic: + -rm -f src/pa/$(am__dirstamp) + -rm -f src/powerpc/$(DEPDIR)/$(am__dirstamp) + -rm -f src/powerpc/$(am__dirstamp) ++ -rm -f src/riscv/$(DEPDIR)/$(am__dirstamp) ++ -rm -f src/riscv/$(am__dirstamp) + -rm -f src/s390/$(DEPDIR)/$(am__dirstamp) + -rm -f src/s390/$(am__dirstamp) + -rm -f src/sh/$(DEPDIR)/$(am__dirstamp) +@@ -1960,7 +1981,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/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 -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/riscv/$(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 +@@ -2099,7 +2120,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/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 -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/riscv/$(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/libffi-3.1/README.md b/libffi-3.1/README.md +new file mode 100644 +index 0000000..d1a0b77 +--- /dev/null ++++ b/libffi-3.1/README.md +@@ -0,0 +1,23 @@ ++RISC-V Port of libffi ++===================== ++ ++Compile and run: ++ ++``` ++./configure --host=riscv64-unknown-elf ++make ++``` ++ ++Run tests in Spike: ++ ++``` ++make check RUNTESTFLAGS="--target_board=riscv-sim --all" ++``` ++ ++Run an individual test: ++ ++Go to `testsuite/libffi.call` directory and run: ++ ++``` ++../../misc/run_test.sh <test_name.c> ++``` +diff --git a/libffi-3.1/aclocal.m4 b/libffi-3.1/aclocal.m4 +index 6292fba..db932a6 100644 +--- a/libffi-3.1/aclocal.m4 ++++ b/libffi-3.1/aclocal.m4 +@@ -1,4 +1,4 @@ +-# generated automatically by aclocal 1.13.4 -*- Autoconf -*- ++# generated automatically by aclocal 1.14.1 -*- Autoconf -*- + + # Copyright (C) 1996-2013 Free Software Foundation, Inc. + +@@ -515,7 +515,7 @@ AC_CACHE_CHECK([whether deplibs are loaded by dlopen], + # at 6.2 and later dlopen does load deplibs. + lt_cv_sys_dlopen_deplibs=yes + ;; +- netbsd*) ++ netbsd* | netbsdelf*-gnu) + lt_cv_sys_dlopen_deplibs=yes + ;; + openbsd*) +@@ -850,10 +850,10 @@ dnl AC_DEFUN([AC_LTDL_DLSYM_USCORE], []) + # generated from the m4 files accompanying Automake X.Y. + # (This private macro should not be called outside this file.) + AC_DEFUN([AM_AUTOMAKE_VERSION], +-[am__api_version='1.13' ++[am__api_version='1.14' + dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to + dnl require some minimum version. Point them to the right macro. +-m4_if([$1], [1.13.4], [], ++m4_if([$1], [1.14.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl + ]) + +@@ -869,7 +869,7 @@ m4_define([_AM_AUTOCONF_VERSION], []) + # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. + # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. + AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +-[AM_AUTOMAKE_VERSION([1.13.4])dnl ++[AM_AUTOMAKE_VERSION([1.14.1])dnl + m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl + _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) +@@ -1256,6 +1256,12 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], + # This macro actually does too much. Some checks are only needed if + # your package does certain things. But this isn't really a big deal. + ++dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. ++m4_define([AC_PROG_CC], ++m4_defn([AC_PROG_CC]) ++[_AM_PROG_CC_C_O ++]) ++ + # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) + # AM_INIT_AUTOMAKE([OPTIONS]) + # ----------------------------------------------- +@@ -1364,7 +1370,48 @@ dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. + AC_CONFIG_COMMANDS_PRE(dnl + [m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +-]) ++ ++# POSIX will say in a future version that running "rm -f" with no argument ++# is OK; and we want to be able to make that assumption in our Makefile ++# recipes. So use an aggressive probe to check that the usage we want is ++# actually supported "in the wild" to an acceptable degree. ++# See automake bug#10828. ++# To make any issue more visible, cause the running configure to be aborted ++# by default if the 'rm' program in use doesn't match our expectations; the ++# user can still override this though. ++if rm -f && rm -fr && rm -rf; then : OK; else ++ cat >&2 <<'END' ++Oops! ++ ++Your 'rm' program seems unable to run without file operands specified ++on the command line, even when the '-f' option is present. This is contrary ++to the behaviour of most rm programs out there, and not conforming with ++the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> ++ ++Please tell bug-automake@gnu.org about your system, including the value ++of your $PATH and any error possibly output before this message. This ++can help us improve future automake versions. ++ ++END ++ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then ++ echo 'Configuration will proceed anyway, since you have set the' >&2 ++ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 ++ echo >&2 ++ else ++ cat >&2 <<'END' ++Aborting the configuration process, to ensure you take notice of the issue. ++ ++You can download and install GNU coreutils to get an 'rm' implementation ++that behaves properly: <http://www.gnu.org/software/coreutils/>. ++ ++If you want to complete the configuration process using your problematic ++'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM ++to "yes", and re-run configure. ++ ++END ++ AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) ++ fi ++fi]) + + dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not + dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +@@ -1372,7 +1419,6 @@ dnl mangled by Autoconf and run in a shell conditional statement. + m4_define([_AC_COMPILER_EXEEXT], + m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +- + # When config.status generates a header, we must update the stamp-h file. + # This file resides in the same directory as the config header + # that is generated. The stamp files are numbered to have different names. +@@ -1520,38 +1566,6 @@ AC_MSG_RESULT([$_am_result]) + rm -f confinc confmf + ]) + +-# Copyright (C) 1999-2013 Free Software Foundation, Inc. +-# +-# This file 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. +- +-# AM_PROG_CC_C_O +-# -------------- +-# Like AC_PROG_CC_C_O, but changed for automake. +-AC_DEFUN([AM_PROG_CC_C_O], +-[AC_REQUIRE([AC_PROG_CC_C_O])dnl +-AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +-AC_REQUIRE_AUX_FILE([compile])dnl +-# FIXME: we rely on the cache variable name because +-# there is no other way. +-set dummy $CC +-am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']` +-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +-if test "$am_t" != yes; then +- # Losing compiler, so override with the script. +- # FIXME: It is wrong to rewrite CC. +- # But if we don't then we get into trouble of one sort or another. +- # A longer-term fix would be to have automake use am__CC in this case, +- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" +- CC="$am_aux_dir/compile $CC" +-fi +-dnl Make sure AC_PROG_CC is never called again, or it will override our +-dnl setting of CC. +-m4_define([AC_PROG_CC], +- [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])]) +-]) +- + # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + + # Copyright (C) 1997-2013 Free Software Foundation, Inc. +@@ -1622,6 +1636,70 @@ AC_DEFUN([_AM_SET_OPTIONS], + AC_DEFUN([_AM_IF_OPTION], + [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + ++# Copyright (C) 1999-2013 Free Software Foundation, Inc. ++# ++# This file 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. ++ ++# _AM_PROG_CC_C_O ++# --------------- ++# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC ++# to automatically call this. ++AC_DEFUN([_AM_PROG_CC_C_O], ++[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl ++AC_REQUIRE_AUX_FILE([compile])dnl ++AC_LANG_PUSH([C])dnl ++AC_CACHE_CHECK( ++ [whether $CC understands -c and -o together], ++ [am_cv_prog_cc_c_o], ++ [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) ++ # Make sure it works both with $CC and with simple cc. ++ # Following AC_PROG_CC_C_O, we do the test twice because some ++ # compilers refuse to overwrite an existing .o file with -o, ++ # though they will create one. ++ am_cv_prog_cc_c_o=yes ++ for am_i in 1 2; do ++ if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ ++ && test -f conftest2.$ac_objext; then ++ : OK ++ else ++ am_cv_prog_cc_c_o=no ++ break ++ fi ++ done ++ rm -f core conftest* ++ unset am_i]) ++if test "$am_cv_prog_cc_c_o" != yes; then ++ # Losing compiler, so override with the script. ++ # FIXME: It is wrong to rewrite CC. ++ # But if we don't then we get into trouble of one sort or another. ++ # A longer-term fix would be to have automake use am__CC in this case, ++ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" ++ CC="$am_aux_dir/compile $CC" ++fi ++AC_LANG_POP([C])]) ++ ++# For backward compatibility. ++AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) ++ ++# Copyright (C) 2001-2013 Free Software Foundation, Inc. ++# ++# This file 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. ++ ++# AM_RUN_LOG(COMMAND) ++# ------------------- ++# Run COMMAND, save the exit status in ac_status, and log it. ++# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) ++AC_DEFUN([AM_RUN_LOG], ++[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ++ ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD ++ (exit $ac_status); }]) ++ + # Check to make sure that the build environment is sane. -*- Autoconf -*- + + # Copyright (C) 1996-2013 Free Software Foundation, Inc. +diff --git a/libffi-3.1/config.sub b/libffi-3.1/config.sub +index c765b34..5d14ffc 100755 +--- a/libffi-3.1/config.sub ++++ b/libffi-3.1/config.sub +@@ -1,8 +1,8 @@ + #! /bin/sh + # Configuration validation subroutine script. +-# Copyright 1992-2013 Free Software Foundation, Inc. ++# Copyright 1992-2014 Free Software Foundation, Inc. + +-timestamp='2013-04-24' ++timestamp='2014-05-01' + + # This file is free software; you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by +@@ -68,7 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>." + version="\ + GNU config.sub ($timestamp) + +-Copyright 1992-2013 Free Software Foundation, Inc. ++Copyright 1992-2014 Free Software Foundation, Inc. + + This is free software; see the source for copying conditions. There is NO + warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." +@@ -257,7 +257,7 @@ case $basic_machine in + | avr | avr32 \ + | be32 | be64 \ + | bfin \ +- | c4x | clipper \ ++ | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | epiphany \ + | fido | fr30 | frv \ +@@ -265,6 +265,7 @@ case $basic_machine in + | hexagon \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ ++ | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ +@@ -282,8 +283,10 @@ case $basic_machine in + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ ++ | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ ++ | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ +@@ -295,11 +298,11 @@ case $basic_machine in + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ +- | open8 \ +- | or1k | or32 \ ++ | open8 | or1k | or1knd | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pyramid \ ++ | riscv \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ +@@ -324,7 +327,7 @@ case $basic_machine in + c6x) + basic_machine=tic6x-unknown + ;; +- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) ++ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; +@@ -372,7 +375,7 @@ case $basic_machine in + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ +- | clipper-* | craynv-* | cydra-* \ ++ | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ +@@ -381,6 +384,7 @@ case $basic_machine in + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ ++ | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ +@@ -400,8 +404,10 @@ case $basic_machine in + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ ++ | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ ++ | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ +@@ -413,6 +419,7 @@ case $basic_machine in + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ ++ | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ +@@ -794,7 +801,7 @@ case $basic_machine in + os=-mingw64 + ;; + mingw32) +- basic_machine=i386-pc ++ basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) +@@ -830,7 +837,7 @@ case $basic_machine in + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + msys) +- basic_machine=i386-pc ++ basic_machine=i686-pc + os=-msys + ;; + mvs) +@@ -1006,7 +1013,7 @@ case $basic_machine in + ;; + ppc64) basic_machine=powerpc64-unknown + ;; +- ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown +@@ -1374,7 +1381,7 @@ case $os in + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ +- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) ++ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) +@@ -1546,6 +1553,9 @@ case $basic_machine in + c4x-* | tic4x-*) + os=-coff + ;; ++ c8051-*) ++ os=-elf ++ ;; + hexagon-*) + os=-elf + ;; +@@ -1589,9 +1599,6 @@ case $basic_machine in + mips*-*) + os=-elf + ;; +- or1k-*) +- os=-elf +- ;; + or32-*) + os=-coff + ;; +diff --git a/libffi-3.1/configure b/libffi-3.1/configure +index a05785e..d9fee55 100755 +--- a/libffi-3.1/configure ++++ b/libffi-3.1/configure +@@ -726,6 +726,8 @@ BFIN_FALSE + BFIN_TRUE + MIPS_FALSE + MIPS_TRUE ++RISCV_FALSE ++RISCV_TRUE + AM_LTLDFLAGS + AM_RUNTESTFLAGS + TESTSUBDIR_FALSE +@@ -2959,7 +2961,7 @@ ax_enable_builddir_auxdir="$am_aux_dir" + ac_config_commands="$ac_config_commands buildir" + + +-am__api_version='1.13' ++am__api_version='1.14' + + # Find a good install program. We prefer a C program (faster), + # so one script is as good as another. But avoid the broken or +@@ -3493,6 +3495,47 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + ++# POSIX will say in a future version that running "rm -f" with no argument ++# is OK; and we want to be able to make that assumption in our Makefile ++# recipes. So use an aggressive probe to check that the usage we want is ++# actually supported "in the wild" to an acceptable degree. ++# See automake bug#10828. ++# To make any issue more visible, cause the running configure to be aborted ++# by default if the 'rm' program in use doesn't match our expectations; the ++# user can still override this though. ++if rm -f && rm -fr && rm -rf; then : OK; else ++ cat >&2 <<'END' ++Oops! ++ ++Your 'rm' program seems unable to run without file operands specified ++on the command line, even when the '-f' option is present. This is contrary ++to the behaviour of most rm programs out there, and not conforming with ++the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> ++ ++Please tell bug-automake@gnu.org about your system, including the value ++of your $PATH and any error possibly output before this message. This ++can help us improve future automake versions. ++ ++END ++ if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then ++ echo 'Configuration will proceed anyway, since you have set the' >&2 ++ echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 ++ echo >&2 ++ else ++ cat >&2 <<'END' ++Aborting the configuration process, to ensure you take notice of the issue. ++ ++You can download and install GNU coreutils to get an 'rm' implementation ++that behaves properly: <http://www.gnu.org/software/coreutils/>. ++ ++If you want to complete the configuration process using your problematic ++'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM ++to "yes", and re-run configure. ++ ++END ++ as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 ++ fi ++fi + + # The same as in boehm-gc and libstdc++. Have to borrow it from there. + # We must force CC to /not/ be precious variables; otherwise +@@ -4292,6 +4335,65 @@ ac_cpp='$CPP $CPPFLAGS' + ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' + ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' + ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 ++$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } ++if ${am_cv_prog_cc_c_o+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++int ++main () ++{ ++ ++ ; ++ return 0; ++} ++_ACEOF ++ # Make sure it works both with $CC and with simple cc. ++ # Following AC_PROG_CC_C_O, we do the test twice because some ++ # compilers refuse to overwrite an existing .o file with -o, ++ # though they will create one. ++ am_cv_prog_cc_c_o=yes ++ for am_i in 1 2; do ++ if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ++ ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ++ ac_status=$? ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 ++ (exit $ac_status); } \ ++ && test -f conftest2.$ac_objext; then ++ : OK ++ else ++ am_cv_prog_cc_c_o=no ++ break ++ fi ++ done ++ rm -f core conftest* ++ unset am_i ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 ++$as_echo "$am_cv_prog_cc_c_o" >&6; } ++if test "$am_cv_prog_cc_c_o" != yes; then ++ # Losing compiler, so override with the script. ++ # FIXME: It is wrong to rewrite CC. ++ # But if we don't then we get into trouble of one sort or another. ++ # A longer-term fix would be to have automake use am__CC in this case, ++ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" ++ CC="$am_aux_dir/compile $CC" ++fi ++ac_ext=c ++ac_cpp='$CPP $CPPFLAGS' ++ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ++ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ++ac_compiler_gnu=$ac_cv_c_compiler_gnu ++ + DEPDIR="${am__leading_dot}deps" + + ac_config_commands="$ac_config_commands depfiles" +@@ -5008,131 +5110,6 @@ else + fi + + +-if test "x$CC" != xcc; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5 +-$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5 +-$as_echo_n "checking whether cc understands -c and -o together... " >&6; } +-fi +-set dummy $CC; ac_cc=`$as_echo "$2" | +- sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +-if eval \${ac_cv_prog_cc_${ac_cc}_c_o+:} false; then : +- $as_echo_n "(cached) " >&6 +-else +- cat confdefs.h - <<_ACEOF >conftest.$ac_ext +-/* end confdefs.h. */ +- +-int +-main () +-{ +- +- ; +- return 0; +-} +-_ACEOF +-# Make sure it works both with $CC and with simple cc. +-# We do the test twice because some compilers refuse to overwrite an +-# existing .o file with -o, though they will create one. +-ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +-rm -f conftest2.* +-if { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && +- test -f conftest2.$ac_objext && { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; +-then +- eval ac_cv_prog_cc_${ac_cc}_c_o=yes +- if test "x$CC" != xcc; then +- # Test first that cc exists at all. +- if { ac_try='cc -c conftest.$ac_ext >&5' +- { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; }; then +- ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5' +- rm -f conftest2.* +- if { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; } && +- test -f conftest2.$ac_objext && { { case "(($ac_try" in +- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; +- *) ac_try_echo=$ac_try;; +-esac +-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +-$as_echo "$ac_try_echo"; } >&5 +- (eval "$ac_try") 2>&5 +- ac_status=$? +- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 +- test $ac_status = 0; }; +- then +- # cc works too. +- : +- else +- # cc exists but doesn't like -o. +- eval ac_cv_prog_cc_${ac_cc}_c_o=no +- fi +- fi +- fi +-else +- eval ac_cv_prog_cc_${ac_cc}_c_o=no +-fi +-rm -f core conftest* +- +-fi +-if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +-$as_echo "yes" >&6; } +-else +- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +-$as_echo "no" >&6; } +- +-$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h +- +-fi +- +-# FIXME: we rely on the cache variable name because +-# there is no other way. +-set dummy $CC +-am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'` +-eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o +-if test "$am_t" != yes; then +- # Losing compiler, so override with the script. +- # FIXME: It is wrong to rewrite CC. +- # But if we don't then we get into trouble of one sort or another. +- # A longer-term fix would be to have automake use am__CC in this case, +- # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" +- CC="$am_aux_dir/compile $CC" +-fi +- + + case `pwd` in + *\ * | *\ *) +@@ -16950,6 +16927,7 @@ fi + cat > local.exp <<EOF + set CC_FOR_TARGET "$CC" + set CXX_FOR_TARGET "$CXX" ++lappend boards_dir "$srcdir/../misc" + EOF + + +@@ -17337,6 +17315,10 @@ case "$host" in + TARGET=POWERPC; TARGETDIR=powerpc + ;; + ++ riscv | riscv-* | riscv64-*) ++ TARGET=RISCV; TARGETDIR=riscv; ++ ;; ++ + s390-*-* | s390x-*-*) + TARGET=S390; TARGETDIR=s390 + ;; +@@ -17353,8 +17335,8 @@ case "$host" in + ;; + + tile*-*) +- TARGET=TILE; TARGETDIR=tile +- ;; ++ TARGET=TILE; TARGETDIR=tile ++ ;; + + vax-*-*) + TARGET=VAX; TARGETDIR=vax +@@ -17373,6 +17355,14 @@ if test $TARGETDIR = unknown; then + as_fn_error $? "\"libffi has not been ported to $host.\"" "$LINENO" 5 + fi + ++ if test x$TARGET = xRISCV; then ++ RISCV_TRUE= ++ RISCV_FALSE='#' ++else ++ RISCV_TRUE='#' ++ RISCV_FALSE= ++fi ++ + if test x$TARGET = xMIPS; then + MIPS_TRUE= + MIPS_FALSE='#' +@@ -18963,6 +18953,10 @@ if test -z "${TESTSUBDIR_TRUE}" && test -z "${TESTSUBDIR_FALSE}"; then + as_fn_error $? "conditional \"TESTSUBDIR\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 + fi ++if test -z "${RISCV_TRUE}" && test -z "${RISCV_FALSE}"; then ++ as_fn_error $? "conditional \"RISCV\" was never defined. ++Usually this means the macro was only invoked conditionally." "$LINENO" 5 ++fi + if test -z "${MIPS_TRUE}" && test -z "${MIPS_FALSE}"; then + as_fn_error $? "conditional \"MIPS\" was never defined. + Usually this means the macro was only invoked conditionally." "$LINENO" 5 +diff --git a/libffi-3.1/configure.ac b/libffi-3.1/configure.ac index d3b8b99..9e4049c 100644 ---- a/configure.ac -+++ b/configure.ac +--- a/libffi-3.1/configure.ac ++++ b/libffi-3.1/configure.ac @@ -59,6 +59,7 @@ fi cat > local.exp <<EOF set CC_FOR_TARGET "$CC" @@ -72,11 +1148,234 @@ index d3b8b99..9e4049c 100644 AM_CONDITIONAL(MIPS, test x$TARGET = xMIPS) AM_CONDITIONAL(BFIN, test x$TARGET = xBFIN) AM_CONDITIONAL(SPARC, test x$TARGET = xSPARC) -diff --git a/src/riscv/asm.py b/src/riscv/asm.py +diff --git a/libffi-3.1/fficonfig.h.in b/libffi-3.1/fficonfig.h.in +index cdef91b..c5a784f 100644 +--- a/libffi-3.1/fficonfig.h.in ++++ b/libffi-3.1/fficonfig.h.in +@@ -124,9 +124,6 @@ + /* Define to the sub-directory where libtool stores uninstalled libraries. */ + #undef LT_OBJDIR + +-/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +-#undef NO_MINUS_C_MINUS_O +- + /* Name of package */ + #undef PACKAGE + +diff --git a/libffi-3.1/include/Makefile.in b/libffi-3.1/include/Makefile.in +index 9d747e8..61e41a7 100644 +--- a/libffi-3.1/include/Makefile.in ++++ b/libffi-3.1/include/Makefile.in +@@ -1,4 +1,4 @@ +-# Makefile.in generated by automake 1.13.4 from Makefile.am. ++# Makefile.in generated by automake 1.14.1 from Makefile.am. + # @configure_input@ + + # Copyright (C) 1994-2013 Free Software Foundation, Inc. +diff --git a/libffi-3.1/man/Makefile.in b/libffi-3.1/man/Makefile.in +index d92af74..47d6d8c 100644 +--- a/libffi-3.1/man/Makefile.in ++++ b/libffi-3.1/man/Makefile.in +@@ -1,4 +1,4 @@ +-# Makefile.in generated by automake 1.13.4 from Makefile.am. ++# Makefile.in generated by automake 1.14.1 from Makefile.am. + # @configure_input@ + + # Copyright (C) 1994-2013 Free Software Foundation, Inc. +diff --git a/libffi-3.1/misc/riscv-sim.exp b/libffi-3.1/misc/riscv-sim.exp new file mode 100644 -index 0000000..55c3c33 +index 0000000..03177d2 --- /dev/null -+++ b/src/riscv/asm.py ++++ b/libffi-3.1/misc/riscv-sim.exp +@@ -0,0 +1,6 @@ ++load_generic_config "sim" ++set_board_info sim "spike pk" ++set_board_info compiler "[find_gcc]" ++set_board_info ldflags "-static" ++set_board_info gdb,nosignals 1 ++set_board_info is_simulator 1 +diff --git a/libffi-3.1/misc/run_test.sh b/libffi-3.1/misc/run_test.sh +new file mode 100755 +index 0000000..dcc0191 +--- /dev/null ++++ b/libffi-3.1/misc/run_test.sh +@@ -0,0 +1,3 @@ ++#/bin/bash ++riscv64-unknown-elf-gcc -I../../riscv64-unknown-elf/include -I../../riscv64-unknown-elf -L../../riscv64-unknown-elf/.libs/ $1 -lffi ++spike pk a.out +diff --git a/libffi-3.1/src/riscv/.deps/.dirstamp b/libffi-3.1/src/riscv/.deps/.dirstamp +new file mode 100644 +index 0000000..e69de29 +diff --git a/libffi-3.1/src/riscv/.deps/ffi.Plo b/libffi-3.1/src/riscv/.deps/ffi.Plo +new file mode 100644 +index 0000000..eb18c9b +--- /dev/null ++++ b/libffi-3.1/src/riscv/.deps/ffi.Plo +@@ -0,0 +1,61 @@ ++src/riscv/ffi.lo: src/riscv/ffi.c include/ffi.h include/ffitarget.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/include/stddef.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/include-fixed/limits.h \ ++ include/ffi_common.h fficonfig.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/alloca.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/_ansi.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/newlib.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/config.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/ieeefp.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/reent.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/_ansi.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/_types.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/_types.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/_default_types.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/lock.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/string.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/string.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/stdlib.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/stdlib.h ++ ++include/ffi.h: ++ ++include/ffitarget.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/include/stddef.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/include-fixed/limits.h: ++ ++include/ffi_common.h: ++ ++fficonfig.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/alloca.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/_ansi.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/newlib.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/config.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/ieeefp.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/reent.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/_ansi.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/_types.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/_types.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/_default_types.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/lock.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/string.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/string.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/stdlib.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/stdlib.h: +diff --git a/libffi-3.1/src/riscv/.deps/ffi64.Plo b/libffi-3.1/src/riscv/.deps/ffi64.Plo +new file mode 100644 +index 0000000..e765ffb +--- /dev/null ++++ b/libffi-3.1/src/riscv/.deps/ffi64.Plo +@@ -0,0 +1,61 @@ ++src/riscv/ffi64.lo: src/riscv/ffi64.c include/ffi.h include/ffitarget.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/include/stddef.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/include-fixed/limits.h \ ++ include/ffi_common.h fficonfig.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/alloca.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/_ansi.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/newlib.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/config.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/ieeefp.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/reent.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/_ansi.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/_types.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/_types.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/_default_types.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/lock.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/string.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/string.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/stdlib.h \ ++ /home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/stdlib.h ++ ++include/ffi.h: ++ ++include/ffitarget.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/include/stddef.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/include-fixed/limits.h: ++ ++include/ffi_common.h: ++ ++fficonfig.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/alloca.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/_ansi.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/newlib.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/config.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/ieeefp.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/reent.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/_ansi.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/_types.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/_types.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/_default_types.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/lock.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/string.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/sys/string.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/stdlib.h: ++ ++/home/risc-v/riscv/lib64/gcc/riscv-elf/4.6.1/../../../../riscv-elf/include/machine/stdlib.h: +diff --git a/libffi-3.1/src/riscv/.deps/rv32.Plo b/libffi-3.1/src/riscv/.deps/rv32.Plo +new file mode 100644 +index 0000000..ffad3c5 +--- /dev/null ++++ b/libffi-3.1/src/riscv/.deps/rv32.Plo +@@ -0,0 +1,8 @@ ++src/riscv/rv32.lo: src/riscv/rv32.S fficonfig.h include/ffi.h \ ++ include/ffitarget.h ++ ++fficonfig.h: ++ ++include/ffi.h: ++ ++include/ffitarget.h: +diff --git a/libffi-3.1/src/riscv/.deps/rv64.Plo b/libffi-3.1/src/riscv/.deps/rv64.Plo +new file mode 100644 +index 0000000..439907d +--- /dev/null ++++ b/libffi-3.1/src/riscv/.deps/rv64.Plo +@@ -0,0 +1,8 @@ ++src/riscv/rv64.lo: src/riscv/rv64.S fficonfig.h include/ffi.h \ ++ include/ffitarget.h ++ ++fficonfig.h: ++ ++include/ffi.h: ++ ++include/ffitarget.h: +diff --git a/libffi-3.1/src/riscv/.dirstamp b/libffi-3.1/src/riscv/.dirstamp +new file mode 100644 +index 0000000..e69de29 +diff --git a/libffi-3.1/src/riscv/asm.py b/libffi-3.1/src/riscv/asm.py +new file mode 100644 +index 0000000..0d6ab2c +--- /dev/null ++++ b/libffi-3.1/src/riscv/asm.py @@ -0,0 +1,37 @@ +#!/bin/python + @@ -92,7 +1391,7 @@ index 0000000..55c3c33 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg""" + str(i) + """_float -+ ld a""" + str(i) + """, FFI_SIZEOF_ARG_X""" + str(i) + """(sp) # load argument ++ REG_L a""" + str(i) + """, FFI_SIZEOF_ARG_X""" + str(i) + """(sp) # load argument + j set_arg""" + str(i+1) + """ + +set_arg""" + str(i) + """_float: @@ -115,13 +1414,12 @@ index 0000000..55c3c33 + return setargs + +print gen64_setargs_string() -\ No newline at end of file -diff --git a/src/riscv/ffi.c b/src/riscv/ffi.c +diff --git a/libffi-3.1/src/riscv/ffi.c b/libffi-3.1/src/riscv/ffi.c new file mode 100644 -index 0000000..9e130a2 +index 0000000..54961ad --- /dev/null -+++ b/src/riscv/ffi.c -@@ -0,0 +1,327 @@ ++++ b/libffi-3.1/src/riscv/ffi.c +@@ -0,0 +1,654 @@ +/* ----------------------------------------------------------------------- + ffi.c - 2014 Michael Knyszek + @@ -152,6 +1450,7 @@ index 0000000..9e130a2 +#include <ffi_common.h> + +#include <stdlib.h> ++#include <stdint.h> + +/* ffi_prep_args is called by the assembly routine once stack space + has been allocated for the function's arguments */ @@ -162,7 +1461,11 @@ index 0000000..9e130a2 + void **p_argv; + char *argp; + ffi_type **p_arg; -+ argp = stack; ++ ++ if (bytes > 8 * sizeof(ffi_arg)) ++ argp = &stack[bytes - (8 * sizeof(ffi_arg))]; ++ else ++ argp = stack; + + memset(stack, 0, bytes); + @@ -252,15 +1555,12 @@ index 0000000..9e130a2 + *(ffi_arg *)argp = *(UINT64 *)(* p_argv); + break; + ++ /* This can only happen with 64bit slots. */ + case FFI_TYPE_FLOAT: + *(float *) argp = *(float *)(* p_argv); + break; -+ -+ case FFI_TYPE_DOUBLE: -+ *(double *) argp = *(double *)(* p_argv); -+ break; + -+ /* Handle structures. */ ++ /* Handle structures. */ + default: + memcpy(argp, *p_argv, (*p_arg)->size); + break; @@ -268,7 +1568,23 @@ index 0000000..9e130a2 + } + else + { -+ memcpy(argp, *p_argv, z); ++ unsigned long end = (unsigned long) argp + z; ++ unsigned long cap = (unsigned long) 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 long portion = cap - (unsigned long)argp; ++ ++ memcpy(argp, *p_argv, portion); ++ argp = stack; ++ z -= portion; ++ memcpy(argp, (void*)((unsigned long)(*p_argv) + portion), z); ++ } + } + + p_argv++; @@ -276,19 +1592,133 @@ index 0000000..9e130a2 + } +} + ++/* This code traverses structure definitions ++ and generates the appropriate flags. */ ++ ++static unsigned calc_riscv_struct_flags(int soft_float, ffi_type *arg, unsigned *loc, unsigned *arg_reg) ++{ ++ unsigned flags = 0; ++ unsigned index = 0; ++ ffi_type *e; ++ ++ if (soft_float) ++ return 0; ++ ++ while ((e = arg->elements[index])) ++ { ++ /* Align this object. */ ++ *loc = ALIGN(*loc, e->alignment); ++ ++ if (e->type == FFI_TYPE_DOUBLE) ++ { ++ /* Already aligned to FFI_SIZEOF_ARG. */ ++ *arg_reg = *loc / FFI_SIZEOF_ARG; ++ ++ if (*arg_reg > 7) ++ break; ++ ++ flags += (FFI_TYPE_DOUBLE << (*arg_reg * FFI_FLAG_BITS)); ++ *loc += e->size; ++ } ++ else ++ *loc += e->size; ++ ++ index++; ++ } ++ ++ /* Next Argument register at alignment of FFI_SIZEOF_ARG. */ ++ *arg_reg = ALIGN(*loc, FFI_SIZEOF_ARG) / FFI_SIZEOF_ARG; ++ ++ return flags; ++} ++ ++static unsigned calc_riscv_return_struct_flags(int soft_float, ffi_type *arg) ++{ ++ unsigned flags = 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 > 2 * FFI_SIZEOF_ARG) ++ return 0; ++ ++ if (arg->size > 8) ++ small = FFI_TYPE_SMALLSTRUCT2; ++ ++ e = arg->elements[0]; ++ if (e->type == FFI_TYPE_DOUBLE) ++ flags = FFI_TYPE_DOUBLE; ++ else if (e->type == FFI_TYPE_FLOAT) ++ flags = FFI_TYPE_FLOAT; ++ ++ if (flags && (e = arg->elements[1])) ++ { ++ 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; ++ 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; ++ } ++ ++ if (soft_float) ++ flags += FFI_TYPE_STRUCT_SOFT; ++ } ++ else if (!flags) ++ return small; ++ ++ return flags; ++} ++ +/* Perform machine dependent cif processing */ + +ffi_status ffi_prep_cif_machdep(ffi_cif *cif) +{ -+ int i; -+ unsigned int prev_dbl_size = 0; ++ int type; ++ unsigned arg_reg = 0; ++ unsigned loc = 0; ++ unsigned count = (cif->nargs < 8) ? cif->nargs : 8; ++ unsigned index = 0; ++ ++ unsigned int struct_flags = 0; ++ int soft_float = cif->abi == FFI_RV64_SOFT_FLOAT || cif->abi == FFI_RV32_SOFT_FLOAT;; ++ + cif->flags = 0; + ++ if (cif->rtype->type == FFI_TYPE_STRUCT) ++ { ++ struct_flags = calc_riscv_return_struct_flags(soft_float, cif->rtype); ++ if (struct_flags == 0) ++ { ++ /* This means that the structure is being passed as ++ a hidden argument */ ++ arg_reg = 1; ++ count = (cif->nargs < 7) ? cif->nargs : 7; ++ cif->rstruct_flag = !0; ++ } ++ else ++ cif->rstruct_flag = 0; ++ } ++ else ++ cif->rstruct_flag = 0; ++ + /* Set the first 8 existing argument types in the flag bit string + * + * We only describe the two argument types we care about: -+ * - Whether or not its a float -+ * - Whether or not its a 64 bit type ++ * - Whether or not its a float/double ++ * - Whether or not its a struct + * + * This is is two bits per argument accounting for the first 16 bits + * of cif->flags. @@ -298,126 +1728,101 @@ index 0000000..9e130a2 + * FFI_FLAG_BITS = 2 + */ + -+ for(i = 0; i < cif->nargs && i < 8; ++i) ++ while (count-- > 0 && arg_reg < 8) + { -+ #ifdef __riscv64 -+ switch ((cif->arg_types)[i]->type) ++ type = (cif->arg_types)[index]->type; ++ ++ /* Handle float argument types for soft float case */ ++ if (soft_float) + { -+ case FFI_TYPE_FLOAT: -+ cif->flags += 1 << (FFI_FLAG_BITS * i); -+ -+ prev_dbl_size = 0; -+ break; -+ -+ case FFI_TYPE_DOUBLE: -+ cif->flags += 2 << (FFI_FLAG_BITS * i); -+ -+ prev_dbl_size = 0; -+ break; -+ -+ /*case FFI_TYPE_LONG_DOUBLE: -+ if (i == 7) break; -+ if (!prev_dbl_size && i % 2 != 0) ++i; -+ -+ cif->flags += 3 << (FFI_FLAG_BITS * i); -+ -+ ++i; -+ prev_dbl_size = 1; -+ break; -+ */ -+ default: -+ prev_dbl_size = 0; -+ break; ++ switch (type) ++ { ++ case FFI_TYPE_FLOAT: ++ type = FFI_TYPE_UINT32; ++ break; ++ case FFI_TYPE_DOUBLE: ++ type = FFI_TYPE_UINT64; ++ break; ++ default: ++ break; ++ } + } -+ #else -+ switch ((cif->arg_types)[i]->type) ++ switch (type) + { + case FFI_TYPE_FLOAT: -+ cif->flags += 1 << (FFI_FLAG_BITS * i); -+ -+ prev_dbl_size = 0; -+ break; -+ + case FFI_TYPE_DOUBLE: -+ if (i == 7) break; -+ if (!prev_dbl_size && i % 2 != 0) ++i; -+ -+ cif->flags += 3 << (FFI_FLAG_BITS * i); -+ ++i; -+ -+ prev_dbl_size = 1; ++ cif->flags += ((cif->arg_types)[index]->type << (arg_reg * FFI_FLAG_BITS)); ++ arg_reg++; + break; -+ -+ case FFI_TYPE_SINT64: -+ case FFI_TYPE_UINT64: -+ if (i == 7) break; -+ if (!prev_dbl_size && i % 2 != 0) ++i; -+ -+ cif->flags += 2 << (FFI_FLAG_BITS * i); -+ ++i; -+ -+ prev_dbl_size = 1; ++ case FFI_TYPE_STRUCT: ++ loc = arg_reg * FFI_SIZEOF_ARG; ++ cif->flags += calc_riscv_struct_flags(soft_float, (cif->arg_types)[index], &loc, &arg_reg); + break; -+ + default: -+ prev_dbl_size = 0; ++ arg_reg++; + break; + } -+ #endif ++ index++; + } -+ ++ + /* Set the return type flag */ -+ -+ if (cif->abi == FFI_RV32_SOFT_FLOAT || cif->abi == FFI_RV64_SOFT_FLOAT) ++ ++ type = cif->rtype->type; ++ ++ /* Handle float return types for soft float case */ ++ if (soft_float) + { -+ switch (cif->rtype->type) ++ switch (type) + { -+ // long long is the same size as a word in riscv64 -+ #ifndef __riscv64 -+ case FFI_TYPE_SINT64: -+ case FFI_TYPE_UINT64: ++ case FFI_TYPE_FLOAT: ++ type = FFI_TYPE_UINT32; ++ break; + case FFI_TYPE_DOUBLE: -+ cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 8); ++ type = FFI_TYPE_UINT64; + break; -+ #endif + default: -+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); + break; + } + } -+ else -+ { -+ switch (cif->rtype->type) -+ { -+ case FFI_TYPE_FLOAT: -+ case FFI_TYPE_DOUBLE: -+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); -+ break; -+ // long long is the same size as a word in riscv64 ++ ++ switch (type) ++ { ++ case FFI_TYPE_STRUCT: ++ if (struct_flags != 0) ++ { ++ /* 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)); ++ } ++ /* else the structure is returned through a hidden ++ first argument. Do nothing, 'cause FFI_TYPE_VOID is 0 */ ++ 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; + #ifndef __riscv64 -+ case FFI_TYPE_SINT64: -+ case FFI_TYPE_UINT64: -+ cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 8); -+ break; ++ case FFI_TYPE_SINT64: ++ case FFI_TYPE_UINT64: ++ cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 8); ++ break; + #endif -+ default: -+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); -+ break; -+ } ++ default: ++ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); ++ break; + } + + return FFI_OK; +} + -+/* Low level routine for calling RV32 functions */ -+extern int ffi_call_rv32(void (*)(char *, extended_cif *, int, int), -+ extended_cif *, unsigned, unsigned, -+ unsigned *, void (*)(void)); -+ +/* Low level routine for calling RV64 functions */ -+extern int ffi_call_rv64(void (*)(char *, extended_cif *, int, int), ++extern int ffi_call_asm(void (*)(char *, extended_cif *, int, int), + extended_cif *, unsigned, unsigned, -+ unsigned *, void (*)(void)); ++ unsigned *, void (*)(void)) ++ __attribute__((visibility("hidden"))); + +void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) +{ @@ -427,145 +1832,254 @@ index 0000000..9e130a2 + 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 */ ++ /* 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) ++ int copy_rvalue = 0; ++ char *rvalue_copy = ecif.rvalue; ++ if (cif->rtype->type == FFI_TYPE_STRUCT && cif->rtype->size < 2 * FFI_SIZEOF_ARG) + { -+ case FFI_RV32: -+ case FFI_RV32_SOFT_FLOAT: -+ ffi_call_rv32(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); -+ break; -+ case FFI_RV64: -+ case FFI_RV64_SOFT_FLOAT: -+ ffi_call_rv64(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); -+ break; -+ default: -+ FFI_ASSERT(0); -+ break; ++ /* For structures smaller than 16 bytes we clobber memory ++ in 8 byte increments. Make a copy so we don't clobber ++ the callers memory outside of the struct bounds. */ ++ rvalue_copy = alloca(2 * FFI_SIZEOF_ARG); ++ copy_rvalue = 1; + } ++ else if (cif->rtype->type == FFI_TYPE_FLOAT && (cif->abi == FFI_RV64_SOFT_FLOAT || cif->abi == FFI_RV32_SOFT_FLOAT)) ++ { ++ rvalue_copy = alloca(FFI_SIZEOF_ARG); ++ copy_rvalue = 1; ++ } ++ ++ ffi_call_asm(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); ++ ++ if (copy_rvalue) ++ memcpy(ecif.rvalue, rvalue_copy, cif->rtype->size); +} -diff --git a/src/riscv/ffi64.c b/src/riscv/ffi64.c -new file mode 100644 -index 0000000..f0d45eb ---- /dev/null -+++ b/src/riscv/ffi64.c -@@ -0,0 +1,105 @@ -+/* ----------------------------------------------------------------------- -+ ffi64.c - 2014 Michael Knyszek -+ -+ RISC-V 64-bit 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> ++#if FFI_CLOSURES + -+#include <stdlib.h> ++extern void ffi_closure_asm(void) __attribute__((visibility("hidden"))); + -+/* Perform machine dependent cif processing */ -+ -+ffi_status ffi_prep_cif_machdep(ffi_cif *cif) ++ffi_status ffi_prep_closure_loc(ffi_closure *closure, ffi_cif *cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data, void *codeloc) +{ -+ int i; -+ unsigned int prev_dbl_size = 0; -+ cif->flags = 0; ++ unsigned int *tramp = (unsigned int *) &closure->tramp[0]; + -+ /* Set the first 8 existing argument types in the flag bit string -+ * -+ * We only describe the two argument types we care about: -+ * - Whether or not its a float -+ * - Whether or not its a 128 bit type (only long double) -+ * -+ * This is is two bits per argument accounting for the first 16 bits -+ * of cif->flags. -+ * -+ * The last 16 bits are just used to describe the return type -+ * -+ * FFI_FLAG_BITS = 2 -+ */ ++ uintptr_t fn = (uintptr_t) ffi_closure_asm; ++ FFI_ASSERT(tramp == codeloc); ++ ++ /* Remove when more than just rv64 is supported */ ++ if (cif->abi != FFI_RV64) ++ return FFI_BAD_ABI; + -+ for(i = 0; i < cif->nargs && i < 8; ++i) ++ if (cif->abi == FFI_RV32 || cif->abi == FFI_RV32_SOFT_FLOAT || fn < 0x7ffff000U) + { -+ ++ /* auipc t0, 0 (i.e. t0 <- codeloc) */ ++ tramp[0] = 0x00000297; ++ /* lui t1, %hi(fn) */ ++ tramp[1] = 0x00000337 | ((fn + 0x800) & 0xFFFFF000); ++ /* jalr x0, t1, %lo(fn) */ ++ tramp[2] = 0x00030067 | ((fn & 0xFFF) << 20); ++ /* nops */ ++ tramp[3] = 0x00000013; ++ tramp[4] = 0x00000013; ++ tramp[5] = 0x00000013; + } ++ else ++ { ++ /* auipc t0, 0 (i.e. t0 <- codeloc) */ ++ tramp[0] = 0x00000297; ++ /* ld t1, 16(t0) */ ++ tramp[1] = 0x0102b303; ++ /* jalr x0, t1, %lo(fn) */ ++ tramp[2] = 0x00030067; ++ /* nop */ ++ tramp[3] = 0x00000013; ++ /* fn */ ++ tramp[4] = fn; ++ tramp[5] = fn >> 32; ++ } ++ ++ closure->cif = cif; ++ closure->fun = fun; ++ closure->user_data = user_data; ++ __builtin___clear_cache(codeloc, codeloc + FFI_TRAMPOLINE_SIZE); ++ ++ return FFI_OK; ++} + -+ /* Set the return type flag */ ++static void copy_struct(char *target, unsigned offset, ffi_abi abi, ffi_type *type, int argn, unsigned arg_offset, ffi_arg *ar, ffi_arg *fpr, int soft_float) ++{ ++ ffi_type **elt_typep = type->elements; ++ ++ while(*elt_typep) ++ { ++ ffi_type *elt_type = *elt_typep; ++ unsigned o; ++ char *tp; ++ char *argp; ++ char *fpp; ++ ++ o = ALIGN(offset, elt_type->alignment); ++ arg_offset += o - offset; ++ offset = o; ++ argn += arg_offset / sizeof(ffi_arg); ++ arg_offset = arg_offset % sizeof(ffi_arg); ++ argp = (char *)(ar + argn); ++ fpp = (char *)(argn >= 8 ? ar + argn : fpr + argn); ++ tp = target + offset; ++ ++ if (elt_type->type == FFI_TYPE_DOUBLE && !soft_float) ++ *(double *)tp = *(double *)fpp; ++ else ++ memcpy(tp, argp + arg_offset, elt_type->size); ++ ++ offset += elt_type->size; ++ arg_offset += elt_type->size; ++ elt_typep++; ++ argn += arg_offset / sizeof(ffi_arg); ++ arg_offset = arg_offset % sizeof(ffi_arg); ++ } ++} + -+ if (cif->abi == FFI_RV64_SOFT_FLOAT) ++/* ++* Decodes the arguments to a function, which will be stored on the ++* stack. AR is the pointer to the beginning of the integer ++* arguments. FPR is a pointer to the area where floating point ++* registers have been saved. ++* ++* RVALUE is the location where the function return value will be ++* stored. CLOSURE is the prepared closure to invoke. ++* ++* This function should only be called from assembly, which is in ++* turn called from a trampoline. ++* ++* Returns the function return flags. ++* ++*/ ++int ffi_closure_riscv_inner(ffi_closure *closure, void *rvalue, ffi_arg *ar, ffi_arg *fpr) ++{ ++ ffi_cif *cif; ++ void **avaluep; ++ ffi_arg *avalue; ++ ffi_type **arg_types; ++ int i, avn, argn; ++ int soft_float; ++ ffi_arg *argp; ++ ++ cif = closure->cif; ++ soft_float = cif->abi == FFI_RV64_SOFT_FLOAT || cif->abi == FFI_RV32_SOFT_FLOAT; ++ avalue = alloca(cif->nargs * sizeof (ffi_arg)); ++ avaluep = alloca(cif->nargs * sizeof (ffi_arg)); ++ argn = 0; ++ ++ if (cif->rstruct_flag) ++ { ++ rvalue = (void *)ar[0]; ++ argn = 1; ++ } ++ ++ i = 0; ++ avn = cif->nargs; ++ arg_types = cif->arg_types; ++ ++ while (i < avn) + { -+ switch (cif->rtype->type) ++ if (arg_types[i]->type == FFI_TYPE_FLOAT || arg_types[i]->type == FFI_TYPE_DOUBLE || arg_types[i]->type == FFI_TYPE_LONGDOUBLE) + { -+ case FFI_TYPE_VOID: -+ case FFI_TYPE_POINTER: -+ case FFI_TYPE_STRUCT: -+ //case FFI_TYPE_LONG_DOUBLE: -+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); -+ break; -+ case FFI_TYPE_SINT64: -+ case FFI_TYPE_UINT64: -+ case FFI_TYPE_DOUBLE: -+ cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 8); -+ break; -+ case FFI_TYPE_FLOAT: -+ default: -+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); -+ break; ++ argp = (argn >= 8 || soft_float) ? ar + argn : fpr + argn; ++ if ((arg_types[i]->type == FFI_TYPE_LONGDOUBLE) && ((uintptr_t)argp & (arg_types[i]->alignment-1))) ++ { ++ argp=(ffi_arg*)ALIGN(argp,arg_types[i]->alignment); ++ argn++; ++ } ++ avaluep[i] = (char *) argp; + } -+ } -+ else -+ { -+ switch (cif->rtype->type) ++ else + { -+ case FFI_TYPE_VOID: -+ case FFI_TYPE_POINTER: -+ case FFI_TYPE_STRUCT: -+ case FFI_TYPE_FLOAT: -+ case FFI_TYPE_DOUBLE: -+ //case FFI_TYPE_LONG_DOUBLE: -+ cif->flags += cif->rtype->type << (FFI_FLAG_BITS * 8); -+ break; -+ case FFI_TYPE_SINT64: -+ case FFI_TYPE_UINT64: -+ cif->flags += FFI_TYPE_UINT64 << (FFI_FLAG_BITS * 8); -+ break; -+ default: -+ cif->flags += FFI_TYPE_INT << (FFI_FLAG_BITS * 8); -+ break; ++ unsigned type = arg_types[i]->type; ++ ++ if (arg_types[i]->alignment > sizeof(ffi_arg)) ++ argn = ALIGN(argn, arg_types[i]->alignment / sizeof(ffi_arg)); ++ ++ argp = ar + argn; ++ ++ /* The size of a pointer depends on the ABI */ ++ if (type == FFI_TYPE_POINTER) ++ type = (cif->abi == FFI_RV64 || cif->abi == FFI_RV64_SOFT_FLOAT) ? FFI_TYPE_SINT64 : FFI_TYPE_SINT32; ++ if (soft_float && type == FFI_TYPE_FLOAT) ++ type = FFI_TYPE_UINT32; ++ ++ switch (type) ++ { ++ case FFI_TYPE_SINT8: ++ avaluep[i] = &avalue[i]; ++ *(SINT8 *) &avalue[i] = (SINT8) *argp; ++ break; ++ ++ case FFI_TYPE_UINT8: ++ avaluep[i] = &avalue[i]; ++ *(UINT8 *) &avalue[i] = (UINT8) *argp; ++ break; ++ ++ case FFI_TYPE_SINT16: ++ avaluep[i] = &avalue[i]; ++ *(SINT16 *) &avalue[i] = (SINT16) *argp; ++ break; ++ ++ case FFI_TYPE_UINT16: ++ avaluep[i] = &avalue[i]; ++ *(UINT16 *) &avalue[i] = (UINT16) *argp; ++ break; ++ ++ case FFI_TYPE_SINT32: ++ avaluep[i] = &avalue[i]; ++ *(SINT32 *) &avalue[i] = (SINT32) *argp; ++ break; ++ ++ case FFI_TYPE_UINT32: ++ avaluep[i] = &avalue[i]; ++ *(UINT32 *) &avalue[i] = (UINT32) *argp; ++ break; ++ ++ case FFI_TYPE_STRUCT: ++ if (argn < 8) ++ { ++ /* Allocate space for the struct as at least part of ++ it was passed in registers. */ ++ avaluep[i] = alloca(arg_types[i]->size); ++ copy_struct(avaluep[i], 0, cif->abi, arg_types[i], ++ argn, 0, ar, fpr, soft_float); ++ break; ++ } ++ ++ /* Else fall through. */ ++ default: ++ avaluep[i] = (char *) argp; ++ break; ++ } + } ++ ++ argn += ALIGN(arg_types[i]->size, sizeof(ffi_arg)) / sizeof(ffi_arg); ++ i++; + } -+ -+ return FFI_OK; ++ ++ /* Invoke the closure. */ ++ (closure->fun) (cif, rvalue, avaluep, closure->user_data); ++ return cif->flags >> (FFI_FLAG_BITS * 8); +} -diff --git a/src/riscv/ffitarget.h b/src/riscv/ffitarget.h ++ ++#endif /* FFI_CLOSURES */ +diff --git a/libffi-3.1/src/riscv/ffitarget.h b/libffi-3.1/src/riscv/ffitarget.h new file mode 100644 -index 0000000..d56eb59 +index 0000000..b2b773b --- /dev/null -+++ b/src/riscv/ffitarget.h -@@ -0,0 +1,74 @@ ++++ b/libffi-3.1/src/riscv/ffitarget.h +@@ -0,0 +1,119 @@ +/* -----------------------------------------------------------------*-C-*- + ffitarget.h - 2014 Michael Knyszek + @@ -600,10 +2114,20 @@ index 0000000..d56eb59 +#error "Please do not include ffitarget.h directly into your source. Use ffi.h instead." +#endif + -+#ifndef LIBFFI_ASM ++#ifndef __riscv64 ++# error We currently only support RV64. ++#endif ++ ++#ifdef __LP64__ ++# define FFI_SIZEOF_ARG 8 ++#else ++# define FFI_SIZEOF_ARG 4 ++#endif + +#define FFI_FLAG_BITS 2 + ++#ifndef LIBFFI_ASM ++ +typedef unsigned long ffi_arg; +typedef signed long ffi_sarg; + @@ -630,582 +2154,57 @@ index 0000000..d56eb59 +#endif /* __riscv_soft_float */ +} ffi_abi; + -+#endif /* LIBFFI_ASM */ -+ -+/* ---- Definitions for closures ----------------------------------------- */ -+ -+#define FFI_CLOSURES 0 -+#define FFI_TRAMPOLINE_SIZE 48 -+#define FFI_NATIVE_RAW_API 0 -+ -+#endif -+ -diff --git a/src/riscv/rv32.S b/src/riscv/rv32.S -new file mode 100644 -index 0000000..c31c439 ---- /dev/null -+++ b/src/riscv/rv32.S -@@ -0,0 +1,554 @@ -+/* ----------------------------------------------------------------------- -+ rv32.S - Michael Knyszek 2014 -+ -+ RISC-V 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> -+ -+#define callback a0 -+#define ecif a1 -+#define bytes a2 -+#define flags a3 -+#define rvalue a4 -+#define fn a5 -+#define fp s0 -+ -+# The RISCV GCC compiler can't handle expressions in assembly, so -+# the workaround is this: -+ -+#define FFI_SIZEOF_ARG_X0 0 -+#define FFI_SIZEOF_ARG_X1 4 -+#define FFI_SIZEOF_ARG_X2 8 -+#define FFI_SIZEOF_ARG_X3 12 -+#define FFI_SIZEOF_ARG_X4 16 -+#define FFI_SIZEOF_ARG_X5 20 -+#define FFI_SIZEOF_ARG_X6 24 -+#define FFI_SIZEOF_ARG_X7 28 -+#define FFI_SIZEOF_ARG_X8 32 -+ -+#define ARG_MASK 65535 -+ -+#define FFI_FLAG_BITS_X0 0 -+#define FFI_FLAG_BITS_X1 2 -+#define FFI_FLAG_BITS_X2 4 -+#define FFI_FLAG_BITS_X3 6 -+#define FFI_FLAG_BITS_X4 8 -+#define FFI_FLAG_BITS_X5 10 -+#define FFI_FLAG_BITS_X6 12 -+#define FFI_FLAG_BITS_X7 14 -+ -+# Stack pointer needs to be 16-byte aligned, so frame size is rounded up -+# FFI_SIZEOF_ARG should be 4 in the 32-bit case -+ -+ .text -+ .align 2 -+ .globl ffi_call_rv32 -+ .type ffi_call_rv32, @function -+ffi_call_rv32: -+ ### Prologue -+ -+ # a0 - ffi_prep_args pointer -+ # a1 - extended_cif pointer -+ # a2 - bytes -+ # a3 - flags -+ # a4 - rvalue -+ # a5 - function ptr -+ -+ add sp, sp, -FFI_SIZEOF_ARG_X8 # move stack pointer by frame size -+ # must be 16-byte aligned -+ -+ # stack ptr points to first argument on stack, -+ # but there should be no arguments on the stack -+ -+ sw flags, FFI_SIZEOF_ARG_X0(sp) # save flags -+ sw rvalue, FFI_SIZEOF_ARG_X1(sp) # save return value pointer -+ sw fn, FFI_SIZEOF_ARG_X2(sp) # save function pointer -+ sw fp, FFI_SIZEOF_ARG_X3(sp) # save frame pointer -+ sw ra, FFI_SIZEOF_ARG_X4(sp) # save return address -+ -+ add fp, sp, zero # new frame pointer is updated stack pointer -+ add t4, callback, zero # function ptr to prep_args -+ -+ # Allocate at least 8 words on the argstack -+ ori t0, zero, FFI_SIZEOF_ARG_X8 -+ bltu bytes, t0, thirtytwo -+ -+ # Here it turns out that our total arg space is bigger than our -+ # argument register space, so we set it according to bytes -+ # and makes sure its aligned to 16 bytes -+ -+ add t0, bytes, 15 # make sure it is aligned -+ andi t0, t0, -16 # to a 16 byte boundry -+ -+thirtytwo: -+ sub sp, sp, t0 # move the stack pointer to reflect the arg space -+ -+ # a0 is the stack with proper arg space allocated -+ add a0, sp, zero -+ -+ # a1 is ecif -+ # a2 is bytes -+ # a3 is flags -+ -+ jalr t4 # call ffi_prep_args -+ -+ lw t0, 0(fp) # load the flags word -+ srli t2, t0, 16 # shift our return type into t4 -+ -+ li t1, ARG_MASK -+ and t0, t0, t1 # mask out the arg types into t0 -+ -+ # time to load the arguments for the call -+ -+#ifndef __riscv_soft_float -+ -+#################### -+## SET ARGUMENT 0 ## -+#################### -+ -+set_arg0: -+ srli t1, t0, FFI_FLAG_BITS_X0 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg0_float -+ lw a0, FFI_SIZEOF_ARG_X0(sp) # load argument -+ j set_arg1 -+ -+set_arg0_float: -+ addi t1, t1, -1 -+ -+ # when its zero, it means its just a word-sized float -+ bne t1, zero, set_arg0_longlong -+ flw fa0, FFI_SIZEOF_ARG_X0(sp) # load argument -+ j set_arg1 -+ -+set_arg0_longlong: -+ addi t1, t1, -1 -+ -+ # when its zero, it means its just a double-word-sized int/struct -+ bne t1, zero, set_arg0_double -+ lw a0, FFI_SIZEOF_ARG_X0(sp) # load low order bits into even -+ lw a1, FFI_SIZEOF_ARG_X1(sp) # load high order bits into odd -+ j set_arg2 -+ -+set_arg0_double: -+ # otherwise it must be a double we're dealing with -+ flw fa0, FFI_SIZEOF_ARG_X0(sp) # load low order bits into even -+ flw fa1, FFI_SIZEOF_ARG_X1(sp) # load high order bits into odd -+ j set_arg2 -+ -+#################### -+## SET ARGUMENT 1 ## -+#################### -+ -+set_arg1: -+ srli t1, t0, FFI_FLAG_BITS_X1 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg1_float -+ lw a1, FFI_SIZEOF_ARG_X1(sp) # load argument -+ j set_arg2 -+ -+set_arg1_float: -+ # this is an odd register, so that means we cannot have a double-sized type -+ # here anyway. we just assume its a float, in this case. -+ flw fa1, FFI_SIZEOF_ARG_X1(sp) # load argument -+ j set_arg2 -+ -+#################### -+## SET ARGUMENT 2 ## -+#################### -+ -+set_arg2: -+ srli t1, t0, FFI_FLAG_BITS_X2 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg2_float -+ lw a2, FFI_SIZEOF_ARG_X2(sp) # load argument -+ j set_arg3 -+ -+set_arg2_float: -+ addi t1, t1, -1 -+ -+ # when its zero, it means its just a word-sized float -+ bne t1, zero, set_arg2_longlong -+ flw fa2, FFI_SIZEOF_ARG_X2(sp) # load argument -+ j set_arg3 -+ -+set_arg2_longlong: -+ addi t1, t1, -1 -+ -+ # when its zero, it means its just a double-word-sized int/struct -+ bne t1, zero, set_arg2_double -+ lw a2, FFI_SIZEOF_ARG_X2(sp) # load low order bits into even -+ lw a3, FFI_SIZEOF_ARG_X3(sp) # load high order bits into odd -+ j set_arg4 -+ -+set_arg2_double: -+ # otherwise it must be a double we're dealing with -+ flw fa2, FFI_SIZEOF_ARG_X2(sp) # load low order bits into even -+ flw fa3, FFI_SIZEOF_ARG_X3(sp) # load high order bits into odd -+ j set_arg4 -+ -+#################### -+## SET ARGUMENT 3 ## -+#################### -+ -+set_arg3: -+ srli t1, t0, FFI_FLAG_BITS_X3 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg3_float -+ lw a3, FFI_SIZEOF_ARG_X3(sp) # load argument -+ j set_arg4 -+ -+set_arg3_float: -+ # this is an odd register, so that means we cannot have a double-sized type -+ # here anyway. we just assume its a float, in this case. -+ flw fa3, FFI_SIZEOF_ARG_X3(sp) # load argument -+ j set_arg4 -+ -+#################### -+## SET ARGUMENT 4 ## -+#################### -+ -+set_arg4: -+ srli t1, t0, FFI_FLAG_BITS_X4 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg4_float -+ lw a4, FFI_SIZEOF_ARG_X4(sp) # load argument -+ j set_arg5 -+ -+set_arg4_float: -+ addi t1, t1, -1 -+ -+ # when its zero, it means its just a word-sized float -+ bne t1, zero, set_arg4_longlong -+ flw fa4, FFI_SIZEOF_ARG_X4(sp) # load argument -+ j set_arg5 -+ -+set_arg4_longlong: -+ addi t1, t1, -1 -+ -+ # when its zero, it means its just a double-word-sized int/struct -+ bne t1, zero, set_arg4_double -+ lw a4, FFI_SIZEOF_ARG_X4(sp) # load low order bits into even -+ lw a5, FFI_SIZEOF_ARG_X5(sp) # load high order bits into odd -+ j set_arg6 -+ -+set_arg4_double: -+ # otherwise it must be a double we're dealing with -+ flw fa4, FFI_SIZEOF_ARG_X4(sp) # load low order bits into even -+ flw fa5, FFI_SIZEOF_ARG_X5(sp) # load high order bits into odd -+ j set_arg6 -+ -+#################### -+## SET ARGUMENT 5 ## -+#################### -+ -+set_arg5: -+ srli t1, t0, FFI_FLAG_BITS_X5 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg5_float -+ lw a5, FFI_SIZEOF_ARG_X5(sp) # load argument -+ j set_arg6 -+ -+set_arg5_float: -+ # this is an odd register, so that means we cannot have a double-sized type -+ # here anyway. we just assume its a float, in this case. -+ flw fa5, FFI_SIZEOF_ARG_X5(sp) # load argument -+ j set_arg6 -+ -+#################### -+## SET ARGUMENT 6 ## -+#################### -+ -+set_arg6: -+ srli t1, t0, FFI_FLAG_BITS_X6 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg6_float -+ lw a6, FFI_SIZEOF_ARG_X6(sp) # load argument -+ j set_arg7 -+ -+set_arg6_float: -+ addi t1, t1, -1 -+ -+ # when its zero, it means its just a word-sized float -+ bne t1, zero, set_arg6_longlong -+ flw fa6, FFI_SIZEOF_ARG_X6(sp) # load argument -+ j set_arg7 -+ -+set_arg6_longlong: -+ addi t1, t1, -1 -+ -+ # when its zero, it means its just a double-word-sized int/struct -+ bne t1, zero, set_arg6_double -+ lw a6, FFI_SIZEOF_ARG_X6(sp) # load low order bits into even -+ lw a7, FFI_SIZEOF_ARG_X7(sp) # load high order bits into odd -+ j call_it -+ -+set_arg6_double: -+ # otherwise it must be a double we're dealing with -+ flw fa6, FFI_SIZEOF_ARG_X6(sp) # load low order bits into even -+ flw fa7, FFI_SIZEOF_ARG_X7(sp) # load high order bits into odd -+ j call_it -+ -+#################### -+## SET ARGUMENT 7 ## -+#################### -+ -+set_arg7: -+ srli t1, t0, FFI_FLAG_BITS_X7 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg7_float -+ lw a7, FFI_SIZEOF_ARG_X7(sp) # load argument -+ j call_it -+ -+set_arg7_float: -+ # this is an odd register, so that means we cannot have a double-sized type -+ # here anyway. we just assume its a float, in this case. -+ flw fa7, FFI_SIZEOF_ARG_X7(sp) # load argument -+ j call_it -+ +#else + -+## START RISCV SOFT-FLOAT LOADING ## -+ -+#################### -+## SET ARGUMENT 0 ## -+#################### -+ -+set_arg0: -+ srli t1, t0, FFI_FLAG_BITS_X0 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg0_longlong -+ lw a0, FFI_SIZEOF_ARG_X0(sp) # load argument -+ j set_arg1 -+ -+set_arg0_longlong: -+ # must be a double-word-sized argument -+ lw a0, FFI_SIZEOF_ARG_X0(sp) # load low order bits into even -+ lw a1, FFI_SIZEOF_ARG_X1(sp) # load high order bits into odd -+ j set_arg2 -+ -+#################### -+## SET ARGUMENT 1 ## -+#################### -+ -+set_arg1: -+ srli t1, t0, FFI_FLAG_BITS_X1 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # in this case, the argument must be just word-sized -+ lw a1, FFI_SIZEOF_ARG_X1(sp) # load argument -+ -+#################### -+## SET ARGUMENT 2 ## -+#################### -+ -+set_arg2: -+ srli t1, t0, FFI_FLAG_BITS_X2 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg2_longlong -+ lw a2, FFI_SIZEOF_ARG_X2(sp) # load argument -+ j set_arg3 -+ -+set_arg2_longlong: -+ # must be a double-word-sized argument -+ lw a2, FFI_SIZEOF_ARG_X2(sp) # load low order bits into even -+ lw a3, FFI_SIZEOF_ARG_X3(sp) # load high order bits into odd -+ j set_arg4 -+ -+#################### -+## SET ARGUMENT 3 ## -+#################### -+ -+set_arg3: -+ srli t1, t0, FFI_FLAG_BITS_X3 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # in this case, the argument must be just word-sized -+ lw a3, FFI_SIZEOF_ARG_X3(sp) # load argument -+ -+#################### -+## SET ARGUMENT 4 ## -+#################### -+ -+set_arg4: -+ srli t1, t0, FFI_FLAG_BITS_X4 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg4_longlong -+ lw a4, FFI_SIZEOF_ARG_X4(sp) # load argument -+ j set_arg5 -+ -+set_arg4_longlong: -+ # must be a double-word-sized argument -+ lw a4, FFI_SIZEOF_ARG_X4(sp) # load low order bits into even -+ lw a5, FFI_SIZEOF_ARG_X5(sp) # load high order bits into odd -+ j set_arg6 -+ -+#################### -+## SET ARGUMENT 5 ## -+#################### -+ -+set_arg5: -+ srli t1, t0, FFI_FLAG_BITS_X5 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # in this case, the argument must be just word-sized -+ lw a5, FFI_SIZEOF_ARG_X5(sp) # load argument -+ -+#################### -+## SET ARGUMENT 6 ## -+#################### -+ -+set_arg6: -+ srli t1, t0, FFI_FLAG_BITS_X6 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # when its zero, it means its just a word-sized int/ptr -+ bne t1, zero, set_arg6_longlong -+ lw a6, FFI_SIZEOF_ARG_X6(sp) # load argument -+ j set_arg7 -+ -+set_arg6_longlong: -+ addi t1, t1, -1 -+ -+ # must be a double-word-sized argument -+ lw a6, FFI_SIZEOF_ARG_X6(sp) # load low order bits into even -+ lw a7, FFI_SIZEOF_ARG_X7(sp) # load high order bits into odd -+ j call_it -+ -+#################### -+## SET ARGUMENT 7 ## -+#################### -+ -+set_arg7: -+ srli t1, t0, FFI_FLAG_BITS_X7 # Shift to get the bits for this argument -+ andi t1, t1, 3 # Mask out the bits for this argument -+ -+ # in this case, the argument must be just word-sized -+ lw a7, FFI_SIZEOF_ARG_X7(sp) # load argument -+ j call_it -+ ++#ifdef __riscv64 ++ #define REG_S sd ++ #define REG_L ld ++#else ++ #define REG_S sw ++ #define REG_L lw +#endif + -+call_it: -+ # Load the function pointer -+ lw t4, FFI_SIZEOF_ARG_X2(fp) -+ -+ # When the return value pointer is NULL, assume no return value. -+ lw t1, FFI_SIZEOF_ARG_X1(fp) -+ beq t1, zero, return_void -+ -+ # is the return type word-sized? if not, jump ahead -+ ori t3, zero, FFI_TYPE_INT -+ bne t2, t3, return_longlong -+ -+ jalr t4 # call the function -+ -+ # We reload the return value because it was in a temp reg and -+ # there was just a function call. -+ lw t0, FFI_SIZEOF_ARG_X1(fp) -+ sw a0, 0(t0) -+ j epilogue ++#endif /* LIBFFI_ASM */ + -+return_longlong: -+ # is the return type double-word-sized? if not, jump ahead -+ ori t3, zero, FFI_TYPE_UINT64 -+#ifndef __riscv_soft_float -+ bne t2, t3, return_float -+#else -+ bne t2, t3s, return_void -+#endif ++#define FFI_ARGS_D FFI_TYPE_DOUBLE ++#define FFI_ARGS_F FFI_TYPE_FLOAT ++#define FFI_ARGS_DD ((FFI_TYPE_DOUBLE << FFI_FLAG_BITS) + FFI_TYPE_DOUBLE) ++#define FFI_ARGS_FF ((FFI_TYPE_FLOAT << FFI_FLAG_BITS) + FFI_TYPE_FLOAT) ++#define FFI_ARGS_FD ((FFI_TYPE_DOUBLE << FFI_FLAG_BITS) + FFI_TYPE_FLOAT) ++#define FFI_ARGS_DF ((FFI_TYPE_FLOAT << FFI_FLAG_BITS) + FFI_TYPE_DOUBLE) ++#define FFI_TYPE_SMALLSTRUCT FFI_TYPE_UINT8 ++#define FFI_TYPE_SMALLSTRUCT2 FFI_TYPE_SINT8 ++#define FFI_TYPE_STRUCT_D (FFI_TYPE_STRUCT + (FFI_ARGS_D << 4)) ++#define FFI_TYPE_STRUCT_F (FFI_TYPE_STRUCT + (FFI_ARGS_F << 4)) ++#define FFI_TYPE_STRUCT_DD (FFI_TYPE_STRUCT + (FFI_ARGS_DD << 4)) ++#define FFI_TYPE_STRUCT_FF (FFI_TYPE_STRUCT + (FFI_ARGS_FF << 4)) ++#define FFI_TYPE_STRUCT_FD (FFI_TYPE_STRUCT + (FFI_ARGS_FD << 4)) ++#define FFI_TYPE_STRUCT_DF (FFI_TYPE_STRUCT + (FFI_ARGS_DF << 4)) ++#define FFI_TYPE_STRUCT_SMALL (FFI_TYPE_STRUCT + (5 << 4)) ++#define FFI_TYPE_STRUCT_SMALL2 (FFI_TYPE_STRUCT + (6 << 4)) ++#define FFI_TYPE_STRUCT_D_SOFT (FFI_TYPE_STRUCT_D + 256) ++#define FFI_TYPE_STRUCT_F_SOFT (FFI_TYPE_STRUCT_F + 256) ++#define FFI_TYPE_STRUCT_DD_SOFT (FFI_TYPE_STRUCT_DD + 256) ++#define FFI_TYPE_STRUCT_FF_SOFT (FFI_TYPE_STRUCT_FF + 256) ++#define FFI_TYPE_STRUCT_FD_SOFT (FFI_TYPE_STRUCT_FD + 256) ++#define FFI_TYPE_STRUCT_DF_SOFT (FFI_TYPE_STRUCT_DF + 256) ++#define FFI_TYPE_STRUCT_SOFT 16 + -+ jalr t4 -+ -+ # We reload the return value because it was in a temp reg and -+ # there was just a function call. -+ lw t0, FFI_SIZEOF_ARG_X1(fp) -+ sw a1, FFI_SIZEOF_ARG_X1(t0) -+ sw a0, FFI_SIZEOF_ARG_X0(t0) -+ j epilogue ++/* ---- Definitions for closures ----------------------------------------- */ + -+#ifndef __riscv_soft_float -+return_float: -+ # is the return type a float? if not, jump ahead -+ ori t3, zero, FFI_TYPE_FLOAT -+ bne t2, t3, return_double -+ -+ jalr t4 -+ -+ # We reload the return value because it was in a temp reg and -+ # there was just a function call. -+ lw t0, FFI_SIZEOF_ARG_X1(fp) -+ fsw fa0, FFI_SIZEOF_ARG_X0(t0) -+ j epilogue ++#define FFI_CLOSURES 1 ++#define FFI_TRAMPOLINE_SIZE 24 ++#define FFI_NATIVE_RAW_API 0 ++#define FFI_EXTRA_CIF_FIELDS unsigned rstruct_flag + -+return_double: -+ # is the return type a double? if not, give up -+ ori t3, zero, FFI_TYPE_DOUBLE -+ bne t2, t3, return_void -+ -+ jalr t4 -+ -+ # We reload the return value because it was in a temp reg and -+ # there was just a function call. -+ lw t0, FFI_SIZEOF_ARG_X1(fp) -+ fsw fa1, FFI_SIZEOF_ARG_X1(t0) -+ fsw fa0, FFI_SIZEOF_ARG_X0(t0) -+ j epilogue +#endif -+ -+return_void: -+ jalr t4 -+ -+epilogue: -+ add sp, fp, zero -+ lw fp, FFI_SIZEOF_ARG_X3(sp) # Restore frame pointer -+ lw ra, FFI_SIZEOF_ARG_X4(sp) # Restore return address -+ add sp, sp, FFI_SIZEOF_ARG_X8 # Fix stack pointer -+ jr ra -+ -+ .size ffi_call_rv32, .-ffi_call_rv32 -diff --git a/src/riscv/rv64.S b/src/riscv/rv64.S ++ +diff --git a/libffi-3.1/src/riscv/sysv.S b/libffi-3.1/src/riscv/sysv.S new file mode 100644 -index 0000000..b315607 +index 0000000..ed3471f --- /dev/null -+++ b/src/riscv/rv64.S -@@ -0,0 +1,410 @@ ++++ b/libffi-3.1/src/riscv/sysv.S +@@ -0,0 +1,545 @@ +/* ----------------------------------------------------------------------- + rv64.S - Michael Knyszek 2014 + @@ -1244,40 +2243,39 @@ index 0000000..b315607 +#define fn a5 +#define fp s0 + -+# Can't resolve expressions, workaround is -+# explicit enumeration of values -+ -+# FFI_SIZEOF_ARG = 8 in this case -+ -+#define FFI_SIZEOF_ARG_X0 0 -+#define FFI_SIZEOF_ARG_X1 8 -+#define FFI_SIZEOF_ARG_X2 16 -+#define FFI_SIZEOF_ARG_X3 24 -+#define FFI_SIZEOF_ARG_X4 32 -+#define FFI_SIZEOF_ARG_X5 40 -+#define FFI_SIZEOF_ARG_X6 48 -+#define FFI_SIZEOF_ARG_X7 56 -+#define FFI_SIZEOF_ARG_X8 64 ++#define FFI_SIZEOF_ARG_X0 (0 * FFI_SIZEOF_ARG) ++#define FFI_SIZEOF_ARG_X1 (1 * FFI_SIZEOF_ARG) ++#define FFI_SIZEOF_ARG_X2 (2 * FFI_SIZEOF_ARG) ++#define FFI_SIZEOF_ARG_X3 (3 * FFI_SIZEOF_ARG) ++#define FFI_SIZEOF_ARG_X4 (4 * FFI_SIZEOF_ARG) ++#define FFI_SIZEOF_ARG_X5 (5 * FFI_SIZEOF_ARG) ++#define FFI_SIZEOF_ARG_X6 (6 * FFI_SIZEOF_ARG) ++#define FFI_SIZEOF_ARG_X7 (7 * FFI_SIZEOF_ARG) ++#define FFI_SIZEOF_ARG_X8 (8 * FFI_SIZEOF_ARG) + +#define ARG_MASK 65535 + -+#define FFI_FLAG_BITS_X0 0 -+#define FFI_FLAG_BITS_X1 2 -+#define FFI_FLAG_BITS_X2 4 -+#define FFI_FLAG_BITS_X3 6 -+#define FFI_FLAG_BITS_X4 8 -+#define FFI_FLAG_BITS_X5 10 -+#define FFI_FLAG_BITS_X6 12 -+#define FFI_FLAG_BITS_X7 14 ++#define FFI_FLAG_BITS_X0 (0 * FFI_FLAG_BITS) ++#define FFI_FLAG_BITS_X1 (1 * FFI_FLAG_BITS) ++#define FFI_FLAG_BITS_X2 (2 * FFI_FLAG_BITS) ++#define FFI_FLAG_BITS_X3 (3 * FFI_FLAG_BITS) ++#define FFI_FLAG_BITS_X4 (4 * FFI_FLAG_BITS) ++#define FFI_FLAG_BITS_X5 (5 * FFI_FLAG_BITS) ++#define FFI_FLAG_BITS_X6 (6 * FFI_FLAG_BITS) ++#define FFI_FLAG_BITS_X7 (7 * FFI_FLAG_BITS) + +# Stack pointer needs to be 16-byte aligned, so frame size is rounded up -+# FFI_SIZEOF_ARG should be 4 in the 32-bit case ++#ifdef __riscv64 ++# define SIZEOF_FRAME (6 * FFI_SIZEOF_ARG) ++#else ++# define SIZEOF_FRAME (8 * FFI_SIZEOF_ARG) ++#endif + + .text + .align 2 -+ .globl ffi_call_rv64 -+ .type ffi_call_rv64, @function -+ffi_call_rv64: ++ .globl ffi_call_asm ++ .type ffi_call_asm, @function ++ffi_call_asm: + ### Prologue + + # a0 - ffi_prep_args pointer @@ -1287,17 +2285,17 @@ index 0000000..b315607 + # a4 - rvalue + # a5 - function ptr + -+ add sp, sp, -FFI_SIZEOF_ARG_X6 # move stack pointer by frame size -+ # must be 16-byte aligned ++ add sp, sp, -SIZEOF_FRAME # move stack pointer by frame size ++ # must be 16-byte aligned + + # stack ptr points to first argument on stack, + # but there should be no arguments on the stack + -+ sd flags, FFI_SIZEOF_ARG_X0(sp) # save flags -+ sd rvalue, FFI_SIZEOF_ARG_X1(sp) # save return value pointer -+ sd fn, FFI_SIZEOF_ARG_X2(sp) # save function pointer -+ sd fp, FFI_SIZEOF_ARG_X3(sp) # save frame pointer -+ sd ra, FFI_SIZEOF_ARG_X4(sp) # save return address ++ REG_S flags, FFI_SIZEOF_ARG_X0(sp) # save flags ++ REG_S rvalue, FFI_SIZEOF_ARG_X1(sp) # save return value pointer ++ REG_S fn, FFI_SIZEOF_ARG_X2(sp) # save function pointer ++ REG_S fp, FFI_SIZEOF_ARG_X3(sp) # save frame pointer ++ REG_S ra, FFI_SIZEOF_ARG_X4(sp) # save return address + + add fp, sp, zero # new frame pointer is updated stack pointer + add t4, callback, zero # function ptr to prep_args @@ -1325,7 +2323,7 @@ index 0000000..b315607 + + jalr t4 # call ffi_prep_args + -+ ld t0, 0(fp) # load the flags word ++ REG_L t0, 0(fp) # load the flags word + srli t2, t0, 16 # shift our return type into t4 + + li t1, ARG_MASK @@ -1345,7 +2343,7 @@ index 0000000..b315607 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg0_float -+ ld a0, FFI_SIZEOF_ARG_X0(sp) # load argument ++ REG_L a0, FFI_SIZEOF_ARG_X0(sp) # load argument + j set_arg1 + +set_arg0_float: @@ -1370,7 +2368,7 @@ index 0000000..b315607 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg1_float -+ ld a1, FFI_SIZEOF_ARG_X1(sp) # load argument ++ REG_L a1, FFI_SIZEOF_ARG_X1(sp) # load argument + j set_arg2 + +set_arg1_float: @@ -1395,7 +2393,7 @@ index 0000000..b315607 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg2_float -+ ld a2, FFI_SIZEOF_ARG_X2(sp) # load argument ++ REG_L a2, FFI_SIZEOF_ARG_X2(sp) # load argument + j set_arg3 + +set_arg2_float: @@ -1420,7 +2418,7 @@ index 0000000..b315607 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg3_float -+ ld a3, FFI_SIZEOF_ARG_X3(sp) # load argument ++ REG_L a3, FFI_SIZEOF_ARG_X3(sp) # load argument + j set_arg4 + +set_arg3_float: @@ -1445,7 +2443,7 @@ index 0000000..b315607 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg4_float -+ ld a4, FFI_SIZEOF_ARG_X4(sp) # load argument ++ REG_L a4, FFI_SIZEOF_ARG_X4(sp) # load argument + j set_arg5 + +set_arg4_float: @@ -1470,7 +2468,7 @@ index 0000000..b315607 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg5_float -+ ld a5, FFI_SIZEOF_ARG_X5(sp) # load argument ++ REG_L a5, FFI_SIZEOF_ARG_X5(sp) # load argument + j set_arg6 + +set_arg5_float: @@ -1495,7 +2493,7 @@ index 0000000..b315607 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg6_float -+ ld a6, FFI_SIZEOF_ARG_X6(sp) # load argument ++ REG_L a6, FFI_SIZEOF_ARG_X6(sp) # load argument + j set_arg7 + +set_arg6_float: @@ -1520,7 +2518,7 @@ index 0000000..b315607 + + # when its zero, it means its just a word-sized int/ptr + bne t1, zero, set_arg7_float -+ ld a7, FFI_SIZEOF_ARG_X7(sp) # load argument ++ REG_L a7, FFI_SIZEOF_ARG_X7(sp) # load argument + j call_it + +set_arg7_float: @@ -1543,23 +2541,23 @@ index 0000000..b315607 + # that has a size of >8 bytes. Therefore, we can + # just load everything quite easily and nicely. + -+ ld a0, FFI_SIZEOF_ARG_X0(sp) # load argument -+ ld a1, FFI_SIZEOF_ARG_X1(sp) # load argument -+ ld a2, FFI_SIZEOF_ARG_X2(sp) # load argument -+ ld a3, FFI_SIZEOF_ARG_X3(sp) # load argument -+ ld a4, FFI_SIZEOF_ARG_X4(sp) # load argument -+ ld a5, FFI_SIZEOF_ARG_X5(sp) # load argument -+ ld a6, FFI_SIZEOF_ARG_X6(sp) # load argument -+ ld a7, FFI_SIZEOF_ARG_X7(sp) # load argument ++ REG_L a0, FFI_SIZEOF_ARG_X0(sp) # load argument ++ REG_L a1, FFI_SIZEOF_ARG_X1(sp) # load argument ++ REG_L a2, FFI_SIZEOF_ARG_X2(sp) # load argument ++ REG_L a3, FFI_SIZEOF_ARG_X3(sp) # load argument ++ REG_L a4, FFI_SIZEOF_ARG_X4(sp) # load argument ++ REG_L a5, FFI_SIZEOF_ARG_X5(sp) # load argument ++ REG_L a6, FFI_SIZEOF_ARG_X6(sp) # load argument ++ REG_L a7, FFI_SIZEOF_ARG_X7(sp) # load argument + +#endif + +call_it: + # Load the function pointer -+ ld t4, FFI_SIZEOF_ARG_X2(fp) ++ REG_L t4, FFI_SIZEOF_ARG_X2(fp) + + # When the return value pointer is NULL, assume no return value. -+ ld t1, FFI_SIZEOF_ARG_X1(fp) ++ REG_L t1, FFI_SIZEOF_ARG_X1(fp) + beq t1, zero, return_void + + # is the return type an int? if not, and if we have an FPU, @@ -1573,8 +2571,8 @@ index 0000000..b315607 + + # We reload the return value because it was in a temp reg and + # there was just a function call. -+ ld t0, FFI_SIZEOF_ARG_X1(fp) -+ sd a0, 0(t0) ++ REG_L t0, FFI_SIZEOF_ARG_X1(fp) ++ REG_S a0, 0(t0) + j epilogue + +#ifndef __riscv_soft_float @@ -1587,7 +2585,7 @@ index 0000000..b315607 + + # We reload the return value because it was in a temp reg and + # there was just a function call. -+ ld t0, FFI_SIZEOF_ARG_X1(fp) ++ REG_L t0, FFI_SIZEOF_ARG_X1(fp) + fsw fa0, FFI_SIZEOF_ARG_X0(t0) + j epilogue + @@ -1600,7 +2598,7 @@ index 0000000..b315607 + + # We reload the return value because it was in a temp reg and + # there was just a function call. -+ ld t0, FFI_SIZEOF_ARG_X1(fp) ++ REG_L t0, FFI_SIZEOF_ARG_X1(fp) + fsd fa0, FFI_SIZEOF_ARG_X0(t0) + j epilogue +#endif @@ -1610,16 +2608,152 @@ index 0000000..b315607 + +epilogue: + add sp, fp, zero -+ ld fp, FFI_SIZEOF_ARG_X3(sp) # Restore frame pointer -+ ld ra, FFI_SIZEOF_ARG_X4(sp) # Restore return address ++ REG_L fp, FFI_SIZEOF_ARG_X3(sp) # Restore frame pointer ++ REG_L ra, FFI_SIZEOF_ARG_X4(sp) # Restore return address + add sp, sp, FFI_SIZEOF_ARG_X8 # Fix stack pointer + jr ra + -+ .size ffi_call_rv64, .-ffi_call_rv64 -diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am ++ .size ffi_call_asm, .-ffi_call_asm ++ ++ ++/* ffi_closure_asm. Expects address of the passed-in ffi_closure in t0. */ ++ ++#define SIZEOF_FRAME2 (20 * FFI_SIZEOF_ARG) ++#define A7_OFF2 (19 * FFI_SIZEOF_ARG) ++#define A6_OFF2 (18 * FFI_SIZEOF_ARG) ++#define A5_OFF2 (17 * FFI_SIZEOF_ARG) ++#define A4_OFF2 (16 * FFI_SIZEOF_ARG) ++#define A3_OFF2 (15 * FFI_SIZEOF_ARG) ++#define A2_OFF2 (14 * FFI_SIZEOF_ARG) ++#define A1_OFF2 (13 * FFI_SIZEOF_ARG) ++#define A0_OFF2 (12 * FFI_SIZEOF_ARG) ++#define FA7_OFF2 (11 * FFI_SIZEOF_ARG) ++#define FA6_OFF2 (10 * FFI_SIZEOF_ARG) ++#define FA5_OFF2 (9 * FFI_SIZEOF_ARG) ++#define FA4_OFF2 (8 * FFI_SIZEOF_ARG) ++#define FA3_OFF2 (7 * FFI_SIZEOF_ARG) ++#define FA2_OFF2 (6 * FFI_SIZEOF_ARG) ++#define FA1_OFF2 (5 * FFI_SIZEOF_ARG) ++#define FA0_OFF2 (4 * FFI_SIZEOF_ARG) ++#define V1_OFF2 (3 * FFI_SIZEOF_ARG) ++#define V0_OFF2 (2 * FFI_SIZEOF_ARG) ++#define RA_OFF2 (1 * FFI_SIZEOF_ARG) ++ ++ .align 2 ++ .globl ffi_closure_asm ++ .type ffi_closure_asm, @function ++ffi_closure_asm: ++ ++ addi sp, sp, -SIZEOF_FRAME2 ++ REG_S ra, RA_OFF2(sp) # Save return address ++ ++ # Store all possible argument registers. If there are more than ++ # fit in registers, then they were stored on the stack. ++ REG_S a0, A0_OFF2(sp) ++ REG_S a1, A1_OFF2(sp) ++ REG_S a2, A2_OFF2(sp) ++ REG_S a3, A3_OFF2(sp) ++ REG_S a4, A4_OFF2(sp) ++ REG_S a5, A5_OFF2(sp) ++ REG_S a6, A6_OFF2(sp) ++ REG_S a7, A7_OFF2(sp) ++ ++ # Store all possible float/double registers. ++ fsd fa0, FA0_OFF2(sp) ++ fsd fa1, FA1_OFF2(sp) ++ fsd fa2, FA2_OFF2(sp) ++ fsd fa3, FA3_OFF2(sp) ++ fsd fa4, FA4_OFF2(sp) ++ fsd fa5, FA5_OFF2(sp) ++ fsd fa6, FA6_OFF2(sp) ++ fsd fa7, FA7_OFF2(sp) ++ ++ # Call ffi_closure_riscv_inner to do the real work. ++ move a0, t0 # Pointer to the ffi_closure ++ addi a1, sp, V0_OFF2 ++ addi a2, sp, A0_OFF2 ++ addi a3, sp, FA0_OFF2 ++ call ffi_closure_riscv_inner ++ ++ # Return flags are in a0 ++ li t0, FFI_TYPE_SINT32 ++ bne a0, t0, cls_retint ++ lw a0, V0_OFF2(sp) ++ j cls_epilogue ++ ++cls_retint: ++ li t0, FFI_TYPE_INT ++ bne a0, t0, cls_retfloat ++ REG_L a0, V0_OFF2(sp) ++ j cls_epilogue ++ ++cls_retfloat: ++ li t0, FFI_TYPE_FLOAT ++ bne a0, t0, cls_retdouble ++ flw fa0, V0_OFF2(sp) ++ j cls_epilogue ++ ++cls_retdouble: ++ li t0, FFI_TYPE_DOUBLE ++ bne a0, t0, cls_retstruct_d ++ fld fa0, V0_OFF2(sp) ++ j cls_epilogue ++ ++cls_retstruct_d: ++ li t0, FFI_TYPE_STRUCT_D ++ bne a0, t0, cls_retstruct_f ++ fld fa0, V0_OFF2(sp) ++ j cls_epilogue ++ ++cls_retstruct_f: ++ li t0, FFI_TYPE_STRUCT_F ++ bne a0, t0, cls_retstruct_d_d ++ flw fa0, V0_OFF2(sp) ++ j cls_epilogue ++ ++cls_retstruct_d_d: ++ li t0, FFI_TYPE_STRUCT_DD ++ bne a0, t0, cls_retstruct_f_f ++ fld fa0, V0_OFF2(sp) ++ fld fa1, V1_OFF2(sp) ++ j cls_epilogue ++ ++cls_retstruct_f_f: ++ li t0, FFI_TYPE_STRUCT_FF ++ bne a0, t0, cls_retstruct_d_f ++ flw fa0, V0_OFF2(sp) ++ flw fa1, V1_OFF2(sp) ++ j cls_epilogue ++ ++cls_retstruct_d_f: ++ li t0, FFI_TYPE_STRUCT_DF ++ bne a0, t0, cls_retstruct_f_d ++ fld fa0, V0_OFF2(sp) ++ flw fa1, V1_OFF2(sp) ++ j cls_epilogue ++ ++cls_retstruct_f_d: ++ li t0, FFI_TYPE_STRUCT_FD ++ bne a0, t0, cls_retstruct_small2 ++ flw fa0, V0_OFF2(sp) ++ fld fa1, V1_OFF2(sp) ++ j cls_epilogue ++ ++cls_retstruct_small2: ++ REG_L a0, V0_OFF2(sp) ++ REG_L a1, V1_OFF2(sp) ++ ++# Epilogue ++cls_epilogue: ++ REG_L ra, RA_OFF2(sp) # Restore return address ++ addi sp, sp, SIZEOF_FRAME2 ++ ret ++ ++ .size ffi_closure_asm, .-ffi_closure_asm +diff --git a/libffi-3.1/testsuite/Makefile.am b/libffi-3.1/testsuite/Makefile.am index da10465..d72f122 100644 ---- a/testsuite/Makefile.am -+++ b/testsuite/Makefile.am +--- a/libffi-3.1/testsuite/Makefile.am ++++ b/libffi-3.1/testsuite/Makefile.am @@ -34,7 +34,7 @@ libffi.call/cls_12byte.c libffi.call/cls_multi_sshortchar.c \ libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ libffi.call/return_fl3.c libffi.call/stret_medium.c \ @@ -1629,11 +2763,30 @@ index da10465..d72f122 100644 libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ -diff --git a/testsuite/libffi.call/many3.c b/testsuite/libffi.call/many3.c +diff --git a/libffi-3.1/testsuite/Makefile.in b/libffi-3.1/testsuite/Makefile.in +index 99e226c..5bbedb9 100644 +--- a/libffi-3.1/testsuite/Makefile.in ++++ b/libffi-3.1/testsuite/Makefile.in +@@ -1,4 +1,4 @@ +-# Makefile.in generated by automake 1.13.4 from Makefile.am. ++# Makefile.in generated by automake 1.14.1 from Makefile.am. + # @configure_input@ + + # Copyright (C) 1994-2013 Free Software Foundation, Inc. +@@ -297,7 +297,7 @@ libffi.call/cls_12byte.c libffi.call/cls_multi_sshortchar.c \ + libffi.call/cls_align_longdouble_split2.c libffi.call/return_dbl2.c \ + libffi.call/return_fl3.c libffi.call/stret_medium.c \ + libffi.call/nested_struct6.c libffi.call/closure_fn3.c \ +-libffi.call/float3.c libffi.call/many2.c \ ++libffi.call/float3.c libffi.call/many2.c libffi.call/many3.c \ + libffi.call/closure_simple.c libffi.call/cls_align_uint16.c \ + libffi.call/cls_9byte1.c libffi.call/closure_fn6.c \ + libffi.call/cls_double_va.c libffi.call/cls_align_pointer.c \ +diff --git a/libffi-3.1/testsuite/libffi.call/many3.c b/libffi-3.1/testsuite/libffi.call/many3.c new file mode 100644 index 0000000..d7396da --- /dev/null -+++ b/testsuite/libffi.call/many3.c ++++ b/libffi-3.1/testsuite/libffi.call/many3.c @@ -0,0 +1,59 @@ +/* Area: ffi_call + Purpose: Check return value int, with many arguments diff --git a/dev-libs/libffi/libffi-3.1-r3.ebuild b/dev-libs/libffi/libffi-3.1-r3.ebuild index c68d046..a3a1480 100644 --- a/dev-libs/libffi/libffi-3.1-r3.ebuild +++ b/dev-libs/libffi/libffi-3.1-r3.ebuild @@ -40,8 +40,7 @@ src_prepare() { epatch \ "${FILESDIR}"/${P}-execstack.patch \ "${FILESDIR}"/${P}-typing_error.patch \ - "${FILESDIR}"/${P}-riscv.patch \ - "${FILESDIR}"/${PN}-3.2-riscv-closure.patch + "${FILESDIR}"/${P}-riscv.patch sed -i -e 's:@toolexeclibdir@:$(libdir):g' Makefile.in || die #462814 # http://sourceware.org/ml/libffi-discuss/2014/msg00060.html |