Compare commits
5 Commits
libffi-3.3
...
libffi-3.3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35a5081d07 | ||
|
|
82244f9715 | ||
|
|
d160812995 | ||
|
|
68f488bcf4 | ||
|
|
ed22026f39 |
@@ -8,9 +8,12 @@ shallow_clone: true
|
||||
# 32- and 64-bit clang/mingw
|
||||
# and perhaps more.
|
||||
|
||||
image: Visual Studio 2013
|
||||
image: Visual Studio 2017
|
||||
platform:
|
||||
- x64
|
||||
- x86
|
||||
- arm
|
||||
- arm64
|
||||
|
||||
environment:
|
||||
global:
|
||||
@@ -18,30 +21,48 @@ environment:
|
||||
CYG_CACHE: C:/cygwin/var/cache/setup
|
||||
CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/
|
||||
matrix:
|
||||
- VSVER: 12
|
||||
- VSVER: 15
|
||||
|
||||
install:
|
||||
- ps: >-
|
||||
If ($env:Platform -Match "x86") {
|
||||
$env:VCVARS_PLATFORM="x86"
|
||||
$env:BUILD="x86-pc-cygwin"
|
||||
$env:HOST="x86-pc-windows"
|
||||
$env:BUILD="i686-pc-cygwin"
|
||||
$env:HOST="i686-pc-cygwin"
|
||||
$env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh"
|
||||
$env:SRC_ARCHITECTURE="x86"
|
||||
} ElseIf ($env:Platform -Match "arm64") {
|
||||
$env:VCVARS_PLATFORM="x86_arm64"
|
||||
$env:BUILD="i686-pc-cygwin"
|
||||
$env:HOST="aarch64-w64-cygwin"
|
||||
$env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -marm64"
|
||||
$env:SRC_ARCHITECTURE="aarch64"
|
||||
} ElseIf ($env:Platform -Match "arm") {
|
||||
$env:VCVARS_PLATFORM="x86_arm"
|
||||
$env:BUILD="i686-pc-cygwin"
|
||||
$env:HOST="arm-w32-cygwin"
|
||||
$env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -marm"
|
||||
$env:SRC_ARCHITECTURE="arm"
|
||||
} Else {
|
||||
$env:VCVARS_PLATFORM="amd64"
|
||||
$env:BUILD="x86_64-w64-cygwin"
|
||||
$env:HOST="x86_64-w64-cygwin"
|
||||
$env:MSVCC="/cygdrive/c/projects/libffi/msvcc.sh -m64"
|
||||
$env:SRC_ARCHITECTURE="x86"
|
||||
}
|
||||
- 'appveyor DownloadFile https://cygwin.com/setup-x86.exe -FileName setup.exe'
|
||||
- 'setup.exe -qnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P dejagnu >NUL'
|
||||
- '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin"'
|
||||
- echo call VsDevCmd to set VS150COMNTOOLS
|
||||
- call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat"
|
||||
- ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
|
||||
- echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%"
|
||||
- call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM%
|
||||
- call "%VSCOMNTOOLS%..\..\vc\Auxiliary\Build\vcvarsall.bat" %VCVARS_PLATFORM%
|
||||
|
||||
build_script:
|
||||
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./autogen.sh;)"
|
||||
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./configure CC='/cygdrive/c/projects/libffi/msvcc.sh -m64' CXX='/cygdrive/c/projects/libffi/msvcc.sh -m64' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)"
|
||||
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp src/x86/ffitarget.h include; make; find .;)"
|
||||
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; ./configure CC='%MSVCC%' CXX='%MSVCC%' LD='link' CPP='cl -nologo -EP' CXXCPP='cl -nologo -EP' CPPFLAGS='-DFFI_BUILDING_DLL' AR='/cygdrive/c/projects/libffi/.travis/ar-lib lib' NM='dumpbin -symbols' STRIP=':' --build=$BUILD --host=$HOST;)"
|
||||
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp src/%SRC_ARCHITECTURE%/ffitarget.h include; make; find .;)"
|
||||
- c:\cygwin\bin\sh -lc "(cd $OLDPWD; cp `find . -name 'libffi-?.dll'` $HOST/testsuite/; make check; cat `find ./ -name libffi.log`)"
|
||||
|
||||
# FIXME: "make check" currently fails. It just looks like msvcc needs
|
||||
|
||||
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
* text=auto
|
||||
|
||||
*.sln text eol=crlf
|
||||
*.vcxproj* text eol=crlf
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -36,3 +36,7 @@ build_*/
|
||||
darwin_*/
|
||||
src/arm/trampoline.S
|
||||
**/texinfo.tex
|
||||
|
||||
x86_64-w64-cygwin
|
||||
i686-pc-cygwin
|
||||
arm-w32-cygwin
|
||||
@@ -10,7 +10,16 @@ function build_linux()
|
||||
make
|
||||
make dist
|
||||
make check RUNTESTFLAGS="-a $RUNTESTFLAGS"
|
||||
cat */testsuite/libffi.log
|
||||
|
||||
gzip -c -9 */testsuite/libffi.log > libffi.log.gz
|
||||
echo ================================================================
|
||||
echo The logs are too long for travis to handle, so we compress and
|
||||
echo uuencode them. Download, decode and uncompress if you need to
|
||||
echo read them.
|
||||
echo ================================================================
|
||||
uuencode libffi.log.gz -
|
||||
echo ================================================================
|
||||
echo ================================================================
|
||||
}
|
||||
|
||||
function build_ios()
|
||||
|
||||
@@ -8,14 +8,17 @@ if [[ $TRAVIS_OS_NAME != 'linux' ]]; then
|
||||
brew install libtool dejagnu;
|
||||
else
|
||||
sudo apt-get update
|
||||
sudo apt-get install dejagnu texinfo
|
||||
sudo apt-get install dejagnu texinfo sharutils
|
||||
case "$HOST" in
|
||||
i386-pc-linux-gnu)
|
||||
sudo apt-get install gcc-multilib g++-multilib
|
||||
;;
|
||||
moxie-elf)
|
||||
echo 'deb http://repos.moxielogic.org:7114/MoxieLogic moxiedev main' | sudo tee -a /etc/apt/sources.list
|
||||
sudo apt-get update -qq
|
||||
echo 'deb https://repos.moxielogic.org:7114/MoxieLogic moxiedev main' | sudo tee -a /etc/apt/sources.list
|
||||
sudo apt-get clean # clear the cache
|
||||
sudo apt-get update ## -qq
|
||||
# debug...
|
||||
curl https://repos.moxielogic.org:7114/MoxieLogic/dists/moxiedev/main/binary-amd64/Packages
|
||||
sudo apt-get install -y --allow-unauthenticated moxielogic-moxie-elf-gcc moxielogic-moxie-elf-gcc-c++ moxielogic-moxie-elf-gcc-libstdc++ moxielogic-moxie-elf-gdb-sim
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -79,9 +79,11 @@ noinst_HEADERS = \
|
||||
|
||||
EXTRA_libffi_la_SOURCES = \
|
||||
src/aarch64/ffi.c src/aarch64/sysv.S \
|
||||
src/aarch64/win64_armasm.S \
|
||||
src/alpha/ffi.c src/alpha/osf.S \
|
||||
src/arc/ffi.c src/arc/arcompact.S \
|
||||
src/arm/ffi.c src/arm/sysv.S \
|
||||
src/arm/ffi.c src/arm/sysv_msvc_arm32.S \
|
||||
src/avr32/ffi.c src/avr32/sysv.S \
|
||||
src/bfin/ffi.c src/bfin/sysv.S \
|
||||
src/cris/ffi.c src/cris/sysv.S \
|
||||
|
||||
15
README.md
15
README.md
@@ -51,11 +51,13 @@ tested:
|
||||
| --------------- | ---------------- | ----------------------- |
|
||||
| AArch64 (ARM64) | iOS | Clang |
|
||||
| AArch64 | Linux | GCC |
|
||||
| AArch64 | Windows | MSVC |
|
||||
| Alpha | Linux | GCC |
|
||||
| Alpha | Tru64 | GCC |
|
||||
| ARC | Linux | GCC |
|
||||
| ARM | Linux | GCC |
|
||||
| ARM | iOS | GCC |
|
||||
| ARM | Windows | MSVC |
|
||||
| AVR32 | Linux | GCC |
|
||||
| Blackfin | uClinux | GCC |
|
||||
| HPPA | HPUX | GCC |
|
||||
@@ -168,6 +170,11 @@ remove the line in configure that sets 'fix_srcfile_path' to a 'cygpath'
|
||||
command. ('cygpath' is not present in MingW, and is not required when
|
||||
using MingW-style paths.)
|
||||
|
||||
To build static library for ARM64 with MSVC using visual studio solution, msvc_build folder have
|
||||
aarch64/Ffi_staticLib.sln
|
||||
required header files in aarch64/aarch64_include/
|
||||
|
||||
|
||||
SPARC Solaris builds require the use of the GNU assembler and linker.
|
||||
Point ``AS`` and ``LD`` environment variables at those tool prior to
|
||||
configuration.
|
||||
@@ -194,9 +201,11 @@ See the git log for details at http://github.com/libffi/libffi.
|
||||
Add RISC-V support.
|
||||
New API in support of GO closures.
|
||||
Default to Microsoft's 64 bit long double ABI with Visual C++.
|
||||
GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI.
|
||||
Many new tests cases and bug fixes.
|
||||
|
||||
GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI.
|
||||
Many new tests cases and bug fixes.
|
||||
Add windows on arm64 (WOA) support.
|
||||
Add Windows 32-bit arm support.
|
||||
|
||||
3.2.1 Nov-12-14
|
||||
Build fix for non-iOS AArch64 targets.
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
# THIS TABLE IS SORTED. KEEP IT THAT WAY.
|
||||
# Most of the time we can define all the variables all at once...
|
||||
case "${host}" in
|
||||
aarch64*-*-cygwin* | aarch64*-*-mingw* | aarch64*-*-win* )
|
||||
TARGET=ARM_WIN64; TARGETDIR=aarch64
|
||||
MSVC=1
|
||||
;;
|
||||
|
||||
aarch64*-*-*)
|
||||
TARGET=AARCH64; TARGETDIR=aarch64
|
||||
SOURCES="ffi.c sysv.S"
|
||||
@@ -23,6 +28,11 @@ case "${host}" in
|
||||
SOURCES="ffi.c arcompact.S"
|
||||
;;
|
||||
|
||||
arm*-*-cygwin* | arm*-*-mingw* | arm*-*-win* )
|
||||
TARGET=ARM_WIN32; TARGETDIR=arm
|
||||
MSVC=1
|
||||
;;
|
||||
|
||||
arm*-*-*)
|
||||
TARGET=ARM; TARGETDIR=arm
|
||||
SOURCES="ffi.c sysv.S"
|
||||
@@ -74,12 +84,6 @@ case "${host}" in
|
||||
fi
|
||||
if test "${ax_cv_c_compiler_vendor}" = "microsoft"; then
|
||||
MSVC=1
|
||||
if test $ac_cv_sizeof_size_t = 4; then
|
||||
# libffi does not support microsoft tools for 32-bit windows
|
||||
# hosts. Try porting src/x86/sysv.S to intel assembly
|
||||
# format.
|
||||
UNSUPPORTED=1
|
||||
fi
|
||||
fi
|
||||
# All mingw/cygwin/win32 builds require -no-undefined for sharedlib.
|
||||
# We must also check with_cross_host to decide if this is a native
|
||||
@@ -248,6 +252,12 @@ esac
|
||||
|
||||
# ... but some of the cases above share configury.
|
||||
case "${TARGET}" in
|
||||
ARM_WIN32)
|
||||
SOURCES="ffi.c sysv_msvc_arm32.S"
|
||||
;;
|
||||
ARM_WIN64)
|
||||
SOURCES="ffi.c win64_armasm.S"
|
||||
;;
|
||||
MIPS)
|
||||
SOURCES="ffi.c o32.S n32.S"
|
||||
;;
|
||||
@@ -265,7 +275,11 @@ case "${TARGET}" in
|
||||
SOURCES="ffi.c ffi_sysv.c sysv.S ppc_closure.S"
|
||||
;;
|
||||
X86 | X86_DARWIN | X86_FREEBSD | X86_WIN32)
|
||||
SOURCES="ffi.c sysv.S"
|
||||
if test "$MSVC" = 1; then
|
||||
SOURCES="ffi.c sysv_intel.S"
|
||||
else
|
||||
SOURCES="ffi.c sysv.S"
|
||||
fi
|
||||
;;
|
||||
X86_64)
|
||||
if test x"$TARGET_X32" = xyes; then
|
||||
|
||||
@@ -283,11 +283,13 @@ FFI_API size_t ffi_raw_size (ffi_cif *cif);
|
||||
packing, even on 64-bit machines. I.e. on 64-bit machines longs
|
||||
and doubles are followed by an empty 64-bit word. */
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
FFI_API
|
||||
void ffi_java_raw_call (ffi_cif *cif,
|
||||
void (*fn)(void),
|
||||
void *rvalue,
|
||||
ffi_java_raw *avalue);
|
||||
#endif
|
||||
|
||||
FFI_API
|
||||
void ffi_java_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_java_raw *raw);
|
||||
@@ -414,6 +416,7 @@ ffi_prep_raw_closure_loc (ffi_raw_closure*,
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
|
||||
#if !FFI_NATIVE_RAW_API
|
||||
FFI_API ffi_status
|
||||
ffi_prep_java_raw_closure (ffi_java_raw_closure*,
|
||||
ffi_cif *cif,
|
||||
@@ -426,6 +429,7 @@ ffi_prep_java_raw_closure_loc (ffi_java_raw_closure*,
|
||||
void (*fun)(ffi_cif*,void*,ffi_java_raw*,void*),
|
||||
void *user_data,
|
||||
void *codeloc);
|
||||
#endif
|
||||
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
|
||||
@@ -99,6 +99,10 @@ ffi_status ffi_prep_cif_core(ffi_cif *cif,
|
||||
ffi_type *rtype,
|
||||
ffi_type **atypes);
|
||||
|
||||
/* Translate a data pointer to a code pointer. Needed for closures on
|
||||
some targets. */
|
||||
void *ffi_data_to_code_pointer (void *data) FFI_HIDDEN;
|
||||
|
||||
/* Extended cif, used in callback from assembly routine */
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@ AC_DEFUN([GCC_AS_CFI_PSEUDO_OP],
|
||||
[AC_CACHE_CHECK([assembler .cfi pseudo-op support],
|
||||
gcc_cv_as_cfi_pseudo_op, [
|
||||
gcc_cv_as_cfi_pseudo_op=unknown
|
||||
AC_TRY_COMPILE([asm (".cfi_startproc\n\t.cfi_endproc");],,
|
||||
AC_TRY_COMPILE([asm (".cfi_sections\n\t.cfi_startproc\n\t.cfi_endproc");],,
|
||||
[gcc_cv_as_cfi_pseudo_op=yes],
|
||||
[gcc_cv_as_cfi_pseudo_op=no])
|
||||
])
|
||||
|
||||
33
msvc_build/aarch64/Ffi_staticLib.sln
Normal file
33
msvc_build/aarch64/Ffi_staticLib.sln
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.28302.56
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Ffi_staticLib_arm64", "Ffi_staticLib.vcxproj", "{115502C0-BE05-4767-BF19-5C87D805FAD6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM64 = Debug|ARM64
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|ARM64 = Release|ARM64
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x64.ActiveCfg = Debug|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Debug|x86.ActiveCfg = Debug|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|ARM64.Build.0 = Release|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x64.ActiveCfg = Release|ARM64
|
||||
{115502C0-BE05-4767-BF19-5C87D805FAD6}.Release|x86.ActiveCfg = Release|ARM64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {241C54C7-20DD-4897-9376-E6B6D1B43BD5}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
130
msvc_build/aarch64/Ffi_staticLib.vcxproj
Normal file
130
msvc_build/aarch64/Ffi_staticLib.vcxproj
Normal file
@@ -0,0 +1,130 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|ARM64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|ARM64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>ARM64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{115502C0-BE05-4767-BF19-5C87D805FAD6}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>FfistaticLib</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<ProjectName>Ffi_staticLib_arm64</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>FFI_BUILDING_DLL;_DEBUG;_LIB;USE_DL_PREFIX;ARM64;_M_ARM64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\include;.\aarch64_include;..\..\src\aarch64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<IgnoreStandardIncludePath>false</IgnoreStandardIncludePath>
|
||||
<BrowseInformation>true</BrowseInformation>
|
||||
<OmitFramePointers>
|
||||
</OmitFramePointers>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>FFI_BUILDING_DLL;USE_DL_PREFIX;ARM64;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<AdditionalIncludeDirectories>..\..\include;.\aarch64_include;..\..\src\aarch64;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OmitFramePointers>true</OmitFramePointers>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
|
||||
<AdditionalUsingDirectories>..\..\src;..\..\src\aarch64;%(AdditionalUsingDirectories)</AdditionalUsingDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>true</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include=".\aarch64_include\ffi.h" />
|
||||
<ClInclude Include=".\aarch64_include\fficonfig.h" />
|
||||
<ClInclude Include="..\..\src\aarch64\ffitarget.h" />
|
||||
<ClInclude Include="..\include\ffi_cfi.h" />
|
||||
<ClInclude Include="..\include\ffi_common.h" />
|
||||
<ClInclude Include="..\..\src\aarch64\internal.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\closures.c" />
|
||||
<ClCompile Include="..\..\src\dlmalloc.c" />
|
||||
<ClCompile Include="..\..\src\aarch64\ffi.c" />
|
||||
<ClCompile Include="..\..\src\prep_cif.c" />
|
||||
<ClCompile Include="..\..\src\types.c" />
|
||||
</ItemGroup>
|
||||
<!--ItemGroup>
|
||||
<Object Include="..\..\..\..\Downloads\libffi-master-win64\src\aarch64\win64_armasm.obj" />
|
||||
</ItemGroup-->
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="..\..\src\aarch64\win64_armasm.S">
|
||||
<!--ExcludedFromBuild Condition="'$(Platform)'!='ARM64'">true</ExcludedFromBuild -->
|
||||
<Command>
|
||||
cl /FA /EP /nologo /I"..\..\include" /I".\aarch64_include" /I"..\..\src\aarch64" "%(FullPath)" > $(IntDir)win64_armasm.i
|
||||
armasm64 $(IntDir)win64_armasm.i /I"src\" /I"..\..\include" /I"..\..\src\aarch64" -o "$(IntDir)win64_armasm.obj"
|
||||
</Command>
|
||||
<Outputs>win64_armasm.obj;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
57
msvc_build/aarch64/Ffi_staticLib.vcxproj.filters
Normal file
57
msvc_build/aarch64/Ffi_staticLib.vcxproj.filters
Normal file
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\include\ffi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\ffi_cfi.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\ffi_common.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\fficonfig.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\ffitarget.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\include\internal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\closures.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\dlmalloc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\ffi.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\prep_cif.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\types.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="src\win64_armasm.S" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
4
msvc_build/aarch64/Ffi_staticLib.vcxproj.user
Normal file
4
msvc_build/aarch64/Ffi_staticLib.vcxproj.user
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -49,26 +49,9 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* Specify which architecture libffi is configured for. */
|
||||
/* --- Begin CPython patch ---
|
||||
ZCW: This is patched by us to avoid having to keep two mostly-identical files.
|
||||
#ifndef X86_WIN32
|
||||
#define X86_WIN32
|
||||
#ifndef AARCH64
|
||||
#define AARCH64
|
||||
#endif
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef _WIN64
|
||||
# ifndef X86_WIN64
|
||||
# define X86_WIN64
|
||||
# endif
|
||||
#else
|
||||
# ifndef X86_WIN32
|
||||
# define X86_WIN32
|
||||
# endif
|
||||
#endif
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
/* --- End CPython patch --- */
|
||||
|
||||
/* ---- System configuration information --------------------------------- */
|
||||
|
||||
@@ -134,10 +117,8 @@ typedef struct _ffi_type
|
||||
#if defined _MSC_VER
|
||||
# if defined FFI_BUILDING_DLL /* Building libffi.DLL with msvcc.sh */
|
||||
# define FFI_API __declspec(dllexport)
|
||||
#error FFI_BUILDING_DLL should not be defined
|
||||
# elif !defined FFI_BUILDING /* Importing libffi.DLL */
|
||||
# define FFI_API __declspec(dllimport)
|
||||
#error FFI_BUILDING should be defined
|
||||
# else /* Building/linking static library */
|
||||
# define FFI_API
|
||||
# endif
|
||||
@@ -216,7 +197,7 @@ FFI_EXTERN ffi_type ffi_type_float;
|
||||
FFI_EXTERN ffi_type ffi_type_double;
|
||||
FFI_EXTERN ffi_type ffi_type_pointer;
|
||||
|
||||
#if 1
|
||||
#ifndef _M_ARM64
|
||||
FFI_EXTERN ffi_type ffi_type_longdouble;
|
||||
#else
|
||||
#define ffi_type_longdouble ffi_type_double
|
||||
@@ -503,7 +484,7 @@ ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
|
||||
#define FFI_TYPE_INT 1
|
||||
#define FFI_TYPE_FLOAT 2
|
||||
#define FFI_TYPE_DOUBLE 3
|
||||
#if 1
|
||||
#ifndef _M_ARM64
|
||||
#define FFI_TYPE_LONGDOUBLE 4
|
||||
#else
|
||||
#define FFI_TYPE_LONGDOUBLE FFI_TYPE_DOUBLE
|
||||
@@ -519,9 +500,9 @@ ffi_status ffi_get_struct_offsets (ffi_abi abi, ffi_type *struct_type,
|
||||
#define FFI_TYPE_STRUCT 13
|
||||
#define FFI_TYPE_POINTER 14
|
||||
#define FFI_TYPE_COMPLEX 15
|
||||
|
||||
/* This should always refer to the last type code (for sanity checks). */
|
||||
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
|
||||
#define FFI_TYPE_LAST FFI_TYPE_COMPLEX
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@@ -1,14 +1,6 @@
|
||||
/* fficonfig.h. Originally created by configure, now hand_maintained for MSVC. */
|
||||
|
||||
/* fficonfig.h. Generated from fficonfig.h.in by configure. */
|
||||
/* fficonfig.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define this for MSVC, but not for mingw32! */
|
||||
#ifdef _MSC_VER
|
||||
#define __attribute__(x) /* */
|
||||
#endif
|
||||
#define alloca _alloca
|
||||
|
||||
/* Define if building universal (internal helper macro) */
|
||||
/* #undef AC_APPLE_UNIVERSAL_BUILD */
|
||||
|
||||
@@ -21,10 +13,7 @@
|
||||
/* #undef C_ALLOCA */
|
||||
|
||||
/* Define to the flags needed for the .section .eh_frame directive. */
|
||||
/* #undef EH_FRAME_FLAGS */
|
||||
|
||||
/* using static library */
|
||||
#define FFI_BUILDING 1
|
||||
#define EH_FRAME_FLAGS "a"
|
||||
|
||||
/* Define this if you want extra debugging. */
|
||||
/* #undef FFI_DEBUG */
|
||||
@@ -49,10 +38,10 @@
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||
*/
|
||||
/* #undef HAVE_ALLOCA_H */
|
||||
/*#define HAVE_ALLOCA_H 1 */
|
||||
|
||||
/* Define if your assembler supports .cfi_* directives. */
|
||||
/* #undef HAVE_AS_CFI_PSEUDO_OP */
|
||||
#define HAVE_AS_CFI_PSEUDO_OP 1
|
||||
|
||||
/* Define if your assembler supports .register. */
|
||||
/* #undef HAVE_AS_REGISTER_PSEUDO_OP */
|
||||
@@ -68,26 +57,23 @@
|
||||
/* #undef HAVE_AS_X86_64_UNWIND_SECTION_TYPE */
|
||||
|
||||
/* Define if your assembler supports PC relative relocs. */
|
||||
#define HAVE_AS_X86_PCREL 1
|
||||
/* #undef HAVE_AS_X86_PCREL */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
/* #undef HAVE_DLFCN_H */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define if __attribute__((visibility("hidden"))) is supported. */
|
||||
/* #undef HAVE_HIDDEN_VISIBILITY_ATTRIBUTE */
|
||||
#define HAVE_HIDDEN_VISIBILITY_ATTRIBUTE 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define if you have the long double type and it is bigger than a double */
|
||||
/* #undef HAVE_LONG_DOUBLE */
|
||||
#define HAVE_LONG_DOUBLE 1
|
||||
|
||||
/* Define if you support more than one size of the long double type */
|
||||
/* #undef HAVE_LONG_DOUBLE_VARIANT */
|
||||
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define to 1 if you have the `memcpy' function. */
|
||||
#define HAVE_MEMCPY 1
|
||||
|
||||
@@ -95,37 +81,37 @@
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the `mkostemp' function. */
|
||||
/* #undef HAVE_MKOSTEMP */
|
||||
#define HAVE_MKOSTEMP 1
|
||||
|
||||
/* Define to 1 if you have the `mmap' function. */
|
||||
/* #undef HAVE_MMAP */
|
||||
#define HAVE_MMAP 1
|
||||
|
||||
/* Define if mmap with MAP_ANON(YMOUS) works. */
|
||||
/* #undef HAVE_MMAP_ANON */
|
||||
#define HAVE_MMAP_ANON 1
|
||||
|
||||
/* Define if mmap of /dev/zero works. */
|
||||
/* #undef HAVE_MMAP_DEV_ZERO */
|
||||
#define HAVE_MMAP_DEV_ZERO 1
|
||||
|
||||
/* Define if read-only mmap of a plain file works. */
|
||||
/* #undef HAVE_MMAP_FILE */
|
||||
#define HAVE_MMAP_FILE 1
|
||||
|
||||
/* Define if .eh_frame sections should be read-only. */
|
||||
/* #undef HAVE_RO_EH_FRAME */
|
||||
#define HAVE_RO_EH_FRAME 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
//#define HAVE_STDLIB_H 0
|
||||
#define LACKS_STDLIB_H 1
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
/* #undef HAVE_SYS_MMAN_H */
|
||||
#define HAVE_SYS_MMAN_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
@@ -134,14 +120,18 @@
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if GNU symbol versioning is used for libatomic. */
|
||||
/* #undef LIBFFI_GNU_SYMBOL_VERSIONING */
|
||||
#define LIBFFI_GNU_SYMBOL_VERSIONING 1
|
||||
|
||||
/* Define to the sub-directory where libtool stores uninstalled libraries. */
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#define LT_OBJDIR ".libs/"
|
||||
|
||||
/* Define to 1 if your C compiler doesn't accept -c and -o together. */
|
||||
/* #undef NO_MINUS_C_MINUS_O */
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "libffi"
|
||||
|
||||
@@ -167,10 +157,7 @@
|
||||
#define SIZEOF_DOUBLE 8
|
||||
|
||||
/* The size of `long double', as computed by sizeof. */
|
||||
#define SIZEOF_LONG_DOUBLE 12
|
||||
|
||||
/* Define if you have the long double type and it is bigger than a double */
|
||||
#define HAVE_LONG_DOUBLE 1
|
||||
#define SIZEOF_LONG_DOUBLE 8
|
||||
|
||||
/* The size of `size_t', as computed by sizeof. */
|
||||
#define SIZEOF_SIZE_T 8
|
||||
29
msvcc.sh
29
msvcc.sh
@@ -60,7 +60,7 @@ do
|
||||
case $1
|
||||
in
|
||||
--verbose)
|
||||
$verbose=1
|
||||
verbose=1
|
||||
shift 1
|
||||
;;
|
||||
--version)
|
||||
@@ -80,6 +80,16 @@ do
|
||||
safeseh=
|
||||
shift 1
|
||||
;;
|
||||
-marm)
|
||||
ml='armasm'
|
||||
safeseh=
|
||||
shift 1
|
||||
;;
|
||||
-marm64)
|
||||
ml='armasm64'
|
||||
safeseh=
|
||||
shift 1
|
||||
;;
|
||||
-clang-cl)
|
||||
cl="clang-cl"
|
||||
shift 1
|
||||
@@ -237,6 +247,7 @@ do
|
||||
else
|
||||
output="-Fe$2"
|
||||
fi
|
||||
armasm_output="-o $2"
|
||||
if [ -n "$assembly" ]; then
|
||||
args="$args $output"
|
||||
else
|
||||
@@ -289,13 +300,27 @@ if [ -n "$assembly" ]; then
|
||||
fi
|
||||
ppsrc="$outdir/$(basename $src|sed 's/.S$/.asm/g')"
|
||||
|
||||
if [ $ml = "armasm" ]; then
|
||||
defines="$defines -D_M_ARM"
|
||||
fi
|
||||
|
||||
if [ $ml = "armasm64" ]; then
|
||||
defines="$defines -D_M_ARM64"
|
||||
fi
|
||||
|
||||
if test -n "$verbose"; then
|
||||
echo "$cl -nologo -EP $includes $defines $src > $ppsrc"
|
||||
fi
|
||||
|
||||
"$cl" -nologo -EP $includes $defines $src > $ppsrc || exit $?
|
||||
output="$(echo $output | sed 's%/F[dpa][^ ]*%%g')"
|
||||
args="-nologo $safeseh $single $output $ppsrc"
|
||||
if [ $ml = "armasm" ]; then
|
||||
args="-nologo -g -oldit $armasm_output $ppsrc -errorReport:prompt"
|
||||
elif [ $ml = "armasm64" ]; then
|
||||
args="-nologo -g $armasm_output $ppsrc -errorReport:prompt"
|
||||
else
|
||||
args="-nologo $safeseh $single $output $ppsrc"
|
||||
fi
|
||||
|
||||
if test -n "$verbose"; then
|
||||
echo "$ml $args"
|
||||
|
||||
@@ -19,6 +19,7 @@ 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. */
|
||||
|
||||
#if defined(__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@@ -26,6 +27,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include "internal.h"
|
||||
#ifdef _M_ARM64
|
||||
#include <windows.h> /* FlushInstructionCache */
|
||||
#endif
|
||||
|
||||
/* Force FFI_TYPE_LONGDOUBLE to be different than FFI_TYPE_DOUBLE;
|
||||
all further uses in this file will refer to the 128-bit type. */
|
||||
@@ -74,6 +78,8 @@ ffi_clear_cache (void *start, void *end)
|
||||
sys_icache_invalidate (start, (char *)end - (char *)start);
|
||||
#elif defined (__GNUC__)
|
||||
__builtin___clear_cache (start, end);
|
||||
#elif defined (_M_ARM64)
|
||||
FlushInstructionCache(GetCurrentProcess(), start, (char*)end - (char*)start);
|
||||
#else
|
||||
#error "Missing builtin to flush instruction cache"
|
||||
#endif
|
||||
@@ -315,6 +321,9 @@ extend_integer_type (void *source, int type)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
void extend_hfa_type (void *dest, void *src, int h);
|
||||
#else
|
||||
static void
|
||||
extend_hfa_type (void *dest, void *src, int h)
|
||||
{
|
||||
@@ -368,7 +377,11 @@ extend_hfa_type (void *dest, void *src, int h)
|
||||
: "r"(f * 12), "r"(dest), "r"(src)
|
||||
: "memory", "v16", "v17", "v18", "v19");
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
void* compress_hfa_type (void *dest, void *src, int h);
|
||||
#else
|
||||
static void *
|
||||
compress_hfa_type (void *dest, void *reg, int h)
|
||||
{
|
||||
@@ -437,6 +450,7 @@ compress_hfa_type (void *dest, void *reg, int h)
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Either allocate an appropriate register for the argument type, or if
|
||||
none are available, allocate a stack slot and return a pointer
|
||||
@@ -454,7 +468,7 @@ allocate_int_to_reg_or_stack (struct call_context *context,
|
||||
return allocate_to_stack (state, stack, size, size);
|
||||
}
|
||||
|
||||
ffi_status
|
||||
ffi_status FFI_HIDDEN
|
||||
ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
{
|
||||
ffi_type *rtype = cif->rtype;
|
||||
@@ -539,9 +553,9 @@ ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
|
||||
#if defined (__APPLE__)
|
||||
/* Perform Apple-specific cif processing for variadic calls */
|
||||
ffi_status ffi_prep_cif_machdep_var(ffi_cif *cif,
|
||||
unsigned int nfixedargs,
|
||||
unsigned int ntotalargs)
|
||||
ffi_status FFI_HIDDEN
|
||||
ffi_prep_cif_machdep_var(ffi_cif *cif, unsigned int nfixedargs,
|
||||
unsigned int ntotalargs)
|
||||
{
|
||||
ffi_status status = ffi_prep_cif_machdep (cif);
|
||||
cif->aarch64_nfixedargs = nfixedargs;
|
||||
@@ -588,8 +602,8 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
|
||||
/* Allocate consectutive stack for everything we'll need. */
|
||||
context = alloca (sizeof(struct call_context) + stack_bytes + 32 + rsize);
|
||||
stack = context + 1;
|
||||
frame = stack + stack_bytes;
|
||||
rvalue = (rsize ? frame + 32 : orig_rvalue);
|
||||
frame = (void*)((uintptr_t)stack + (uintptr_t)stack_bytes);
|
||||
rvalue = (rsize ? (void*)((uintptr_t)frame + 32) : orig_rvalue);
|
||||
|
||||
arg_init (&state);
|
||||
for (i = 0, nargs = cif->nargs; i < nargs; i++)
|
||||
@@ -651,6 +665,22 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
|
||||
if (h)
|
||||
{
|
||||
int elems = 4 - (h & 3);
|
||||
#ifdef _M_ARM64 /* for handling armasm calling convention */
|
||||
if (cif->is_variadic)
|
||||
{
|
||||
if (state.ngrn + elems <= N_X_ARG_REG)
|
||||
{
|
||||
dest = &context->x[state.ngrn];
|
||||
state.ngrn += elems;
|
||||
extend_hfa_type(dest, a, h);
|
||||
break;
|
||||
}
|
||||
state.nsrn = N_X_ARG_REG;
|
||||
dest = allocate_to_stack(&state, stack, ty->alignment, s);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* for handling armasm calling convention */
|
||||
if (state.nsrn + elems <= N_V_ARG_REG)
|
||||
{
|
||||
dest = &context->v[state.nsrn];
|
||||
@@ -660,6 +690,9 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
|
||||
}
|
||||
state.nsrn = N_V_ARG_REG;
|
||||
dest = allocate_to_stack (&state, stack, ty->alignment, s);
|
||||
#ifdef _M_ARM64 /* for handling armasm calling convention */
|
||||
}
|
||||
#endif /* for handling armasm calling convention */
|
||||
}
|
||||
else if (s > 16)
|
||||
{
|
||||
@@ -681,7 +714,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *orig_rvalue,
|
||||
X registers, then the argument is copied into
|
||||
consecutive X registers. */
|
||||
dest = &context->x[state.ngrn];
|
||||
state.ngrn += n;
|
||||
state.ngrn += (unsigned int)n;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -773,6 +806,16 @@ ffi_prep_closure_loc (ffi_closure *closure,
|
||||
*(UINT64 *)(tramp + 16) = (uintptr_t)start;
|
||||
|
||||
ffi_clear_cache(tramp, tramp + FFI_TRAMPOLINE_SIZE);
|
||||
|
||||
/* Also flush the cache for code mapping. */
|
||||
#ifdef _M_ARM64
|
||||
// Not using dlmalloc.c for Windows ARM64 builds
|
||||
// so calling ffi_data_to_code_pointer() isn't necessary
|
||||
unsigned char *tramp_code = tramp;
|
||||
#else
|
||||
unsigned char *tramp_code = ffi_data_to_code_pointer (tramp);
|
||||
#endif
|
||||
ffi_clear_cache (tramp_code, tramp_code + FFI_TRAMPOLINE_SIZE);
|
||||
#endif
|
||||
|
||||
closure->cif = cif;
|
||||
@@ -871,55 +914,78 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
|
||||
if (h)
|
||||
{
|
||||
n = 4 - (h & 3);
|
||||
if (state.nsrn + n <= N_V_ARG_REG)
|
||||
{
|
||||
void *reg = &context->v[state.nsrn];
|
||||
state.nsrn += n;
|
||||
#ifdef _M_ARM64 /* for handling armasm calling convention */
|
||||
if (cif->is_variadic)
|
||||
{
|
||||
if (state.ngrn + n <= N_X_ARG_REG)
|
||||
{
|
||||
void *reg = &context->x[state.ngrn];
|
||||
state.ngrn += (unsigned int)n;
|
||||
|
||||
/* Eeek! We need a pointer to the structure, however the
|
||||
homogeneous float elements are being passed in individual
|
||||
registers, therefore for float and double the structure
|
||||
is not represented as a contiguous sequence of bytes in
|
||||
our saved register context. We don't need the original
|
||||
contents of the register storage, so we reformat the
|
||||
structure into the same memory. */
|
||||
avalue[i] = compress_hfa_type(reg, reg, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.ngrn = N_X_ARG_REG;
|
||||
state.nsrn = N_V_ARG_REG;
|
||||
avalue[i] = allocate_to_stack(&state, stack,
|
||||
ty->alignment, s);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* for handling armasm calling convention */
|
||||
if (state.nsrn + n <= N_V_ARG_REG)
|
||||
{
|
||||
void *reg = &context->v[state.nsrn];
|
||||
state.nsrn += (unsigned int)n;
|
||||
avalue[i] = compress_hfa_type(reg, reg, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.nsrn = N_V_ARG_REG;
|
||||
avalue[i] = allocate_to_stack(&state, stack,
|
||||
ty->alignment, s);
|
||||
}
|
||||
#ifdef _M_ARM64 /* for handling armasm calling convention */
|
||||
}
|
||||
#endif /* for handling armasm calling convention */
|
||||
}
|
||||
else if (s > 16)
|
||||
{
|
||||
/* Replace Composite type of size greater than 16 with a
|
||||
pointer. */
|
||||
avalue[i] = *(void **)
|
||||
allocate_int_to_reg_or_stack (context, &state, stack,
|
||||
sizeof (void *));
|
||||
}
|
||||
else
|
||||
{
|
||||
n = (s + 7) / 8;
|
||||
if (state.ngrn + n <= N_X_ARG_REG)
|
||||
{
|
||||
avalue[i] = &context->x[state.ngrn];
|
||||
state.ngrn += (unsigned int)n;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.ngrn = N_X_ARG_REG;
|
||||
avalue[i] = allocate_to_stack(&state, stack,
|
||||
ty->alignment, s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* Eeek! We need a pointer to the structure, however the
|
||||
homogeneous float elements are being passed in individual
|
||||
registers, therefore for float and double the structure
|
||||
is not represented as a contiguous sequence of bytes in
|
||||
our saved register context. We don't need the original
|
||||
contents of the register storage, so we reformat the
|
||||
structure into the same memory. */
|
||||
avalue[i] = compress_hfa_type (reg, reg, h);
|
||||
}
|
||||
else
|
||||
{
|
||||
state.nsrn = N_V_ARG_REG;
|
||||
avalue[i] = allocate_to_stack (&state, stack,
|
||||
ty->alignment, s);
|
||||
}
|
||||
}
|
||||
else if (s > 16)
|
||||
{
|
||||
/* Replace Composite type of size greater than 16 with a
|
||||
pointer. */
|
||||
avalue[i] = *(void **)
|
||||
allocate_int_to_reg_or_stack (context, &state, stack,
|
||||
sizeof (void *));
|
||||
}
|
||||
else
|
||||
{
|
||||
n = (s + 7) / 8;
|
||||
if (state.ngrn + n <= N_X_ARG_REG)
|
||||
{
|
||||
avalue[i] = &context->x[state.ngrn];
|
||||
state.ngrn += n;
|
||||
}
|
||||
else
|
||||
{
|
||||
state.ngrn = N_X_ARG_REG;
|
||||
avalue[i] = allocate_to_stack (&state, stack,
|
||||
ty->alignment, s);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
#if defined (__APPLE__)
|
||||
if (i + 1 == cif->aarch64_nfixedargs)
|
||||
@@ -939,3 +1005,5 @@ ffi_closure_SYSV_inner (ffi_cif *cif,
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#endif /* (__aarch64__) || defined(__arm64__)|| defined (_M_ARM64)*/
|
||||
|
||||
@@ -32,6 +32,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
#define FFI_SIZEOF_JAVA_RAW 4
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef signed long long ffi_sarg;
|
||||
#elif defined(_M_ARM64)
|
||||
#define FFI_SIZEOF_ARG 8
|
||||
typedef unsigned long long ffi_arg;
|
||||
typedef signed long long ffi_sarg;
|
||||
#else
|
||||
typedef unsigned long ffi_arg;
|
||||
typedef signed long ffi_sarg;
|
||||
@@ -65,17 +69,24 @@ typedef enum ffi_abi
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
|
||||
#endif
|
||||
|
||||
#ifdef _M_ARM64
|
||||
#define FFI_EXTRA_CIF_FIELDS unsigned is_variadic
|
||||
#endif
|
||||
|
||||
/* ---- Internal ---- */
|
||||
|
||||
#if defined (__APPLE__)
|
||||
#define FFI_TARGET_SPECIFIC_VARIADIC
|
||||
#define FFI_EXTRA_CIF_FIELDS unsigned aarch64_nfixedargs
|
||||
#else
|
||||
/* iOS reserves x18 for the system. Disable Go closures until
|
||||
#elif !defined(_M_ARM64)
|
||||
/* iOS and Windows reserve x18 for the system. Disable Go closures until
|
||||
a new static chain is chosen. */
|
||||
#define FFI_GO_CLOSURES 1
|
||||
#endif
|
||||
|
||||
#ifndef _M_ARM64
|
||||
/* No complex type on Windows */
|
||||
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,6 +19,7 @@ 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. */
|
||||
|
||||
#if defined(__aarch64__) || defined(__arm64__)
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
@@ -198,9 +199,9 @@ CNAME(ffi_call_SYSV):
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_call_SYSV)
|
||||
FFI_HIDDEN(CNAME(ffi_call_SYSV))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_call_SYSV), #function
|
||||
.hidden CNAME(ffi_call_SYSV)
|
||||
.size CNAME(ffi_call_SYSV), .-CNAME(ffi_call_SYSV)
|
||||
#endif
|
||||
|
||||
@@ -237,9 +238,9 @@ CNAME(ffi_closure_SYSV_V):
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_closure_SYSV_V)
|
||||
FFI_HIDDEN(CNAME(ffi_closure_SYSV_V))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_closure_SYSV_V), #function
|
||||
.hidden CNAME(ffi_closure_SYSV_V)
|
||||
.size CNAME(ffi_closure_SYSV_V), . - CNAME(ffi_closure_SYSV_V)
|
||||
#endif
|
||||
|
||||
@@ -349,9 +350,9 @@ CNAME(ffi_closure_SYSV):
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_closure_SYSV)
|
||||
FFI_HIDDEN(CNAME(ffi_closure_SYSV))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_closure_SYSV), #function
|
||||
.hidden CNAME(ffi_closure_SYSV)
|
||||
.size CNAME(ffi_closure_SYSV), . - CNAME(ffi_closure_SYSV)
|
||||
#endif
|
||||
|
||||
@@ -369,9 +370,9 @@ CNAME(ffi_closure_trampoline_table_page):
|
||||
.endr
|
||||
|
||||
.globl CNAME(ffi_closure_trampoline_table_page)
|
||||
FFI_HIDDEN(CNAME(ffi_closure_trampoline_table_page))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_closure_trampoline_table_page), #function
|
||||
.hidden CNAME(ffi_closure_trampoline_table_page)
|
||||
.size CNAME(ffi_closure_trampoline_table_page), . - CNAME(ffi_closure_trampoline_table_page)
|
||||
#endif
|
||||
#endif
|
||||
@@ -396,9 +397,9 @@ CNAME(ffi_go_closure_SYSV_V):
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_go_closure_SYSV_V)
|
||||
FFI_HIDDEN(CNAME(ffi_go_closure_SYSV_V))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_go_closure_SYSV_V), #function
|
||||
.hidden CNAME(ffi_go_closure_SYSV_V)
|
||||
.size CNAME(ffi_go_closure_SYSV_V), . - CNAME(ffi_go_closure_SYSV_V)
|
||||
#endif
|
||||
|
||||
@@ -425,12 +426,13 @@ CNAME(ffi_go_closure_SYSV):
|
||||
cfi_endproc
|
||||
|
||||
.globl CNAME(ffi_go_closure_SYSV)
|
||||
FFI_HIDDEN(CNAME(ffi_go_closure_SYSV))
|
||||
#ifdef __ELF__
|
||||
.type CNAME(ffi_go_closure_SYSV), #function
|
||||
.hidden CNAME(ffi_go_closure_SYSV)
|
||||
.size CNAME(ffi_go_closure_SYSV), . - CNAME(ffi_go_closure_SYSV)
|
||||
#endif
|
||||
#endif /* FFI_GO_CLOSURES */
|
||||
#endif /* __arm64__ */
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
|
||||
506
src/aarch64/win64_armasm.S
Normal file
506
src/aarch64/win64_armasm.S
Normal file
@@ -0,0 +1,506 @@
|
||||
/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.
|
||||
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>
|
||||
#include <ffi_cfi.h>
|
||||
#include "internal.h"
|
||||
|
||||
OPT 2 /*disable listing */
|
||||
/* For some macros to add unwind information */
|
||||
#include "ksarm64.h"
|
||||
OPT 1 /*re-enable listing */
|
||||
|
||||
#define BE(X) 0
|
||||
#define PTR_REG(n) x##n
|
||||
#define PTR_SIZE 8
|
||||
|
||||
IMPORT ffi_closure_SYSV_inner
|
||||
EXPORT ffi_call_SYSV
|
||||
EXPORT ffi_closure_SYSV_V
|
||||
EXPORT ffi_closure_SYSV
|
||||
EXPORT extend_hfa_type
|
||||
EXPORT compress_hfa_type
|
||||
#ifdef FFI_GO_CLOSURES
|
||||
EXPORT ffi_go_closure_SYSV_V
|
||||
EXPORT ffi_go_closure_SYSV
|
||||
#endif
|
||||
|
||||
TEXTAREA, ALLIGN=8
|
||||
|
||||
/* ffi_call_SYSV
|
||||
extern void ffi_call_SYSV (void *stack, void *frame,
|
||||
void (*fn)(void), void *rvalue,
|
||||
int flags, void *closure);
|
||||
Therefore on entry we have:
|
||||
x0 stack
|
||||
x1 frame
|
||||
x2 fn
|
||||
x3 rvalue
|
||||
x4 flags
|
||||
x5 closure
|
||||
*/
|
||||
|
||||
NESTED_ENTRY ffi_call_SYSV_fake
|
||||
|
||||
/* For unwind information, Windows has to store fp and lr */
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-32!
|
||||
|
||||
ALTERNATE_ENTRY ffi_call_SYSV
|
||||
/* Use a stack frame allocated by our caller. */
|
||||
stp x29, x30, [x1]
|
||||
mov x29, x1
|
||||
mov sp, x0
|
||||
|
||||
mov x9, x2 /* save fn */
|
||||
mov x8, x3 /* install structure return */
|
||||
#ifdef FFI_GO_CLOSURES
|
||||
/*mov x18, x5 install static chain */
|
||||
#endif
|
||||
stp x3, x4, [x29, #16] /* save rvalue and flags */
|
||||
|
||||
/* Load the vector argument passing registers, if necessary. */
|
||||
tbz x4, #AARCH64_FLAG_ARG_V_BIT, ffi_call_SYSV_L1
|
||||
ldp q0, q1, [sp, #0]
|
||||
ldp q2, q3, [sp, #32]
|
||||
ldp q4, q5, [sp, #64]
|
||||
ldp q6, q7, [sp, #96]
|
||||
|
||||
ffi_call_SYSV_L1
|
||||
/* Load the core argument passing registers, including
|
||||
the structure return pointer. */
|
||||
ldp x0, x1, [sp, #16*N_V_ARG_REG + 0]
|
||||
ldp x2, x3, [sp, #16*N_V_ARG_REG + 16]
|
||||
ldp x4, x5, [sp, #16*N_V_ARG_REG + 32]
|
||||
ldp x6, x7, [sp, #16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Deallocate the context, leaving the stacked arguments. */
|
||||
add sp, sp, #CALL_CONTEXT_SIZE
|
||||
|
||||
blr x9 /* call fn */
|
||||
|
||||
ldp x3, x4, [x29, #16] /* reload rvalue and flags */
|
||||
|
||||
/* Partially deconstruct the stack frame. */
|
||||
mov sp, x29
|
||||
ldp x29, x30, [x29]
|
||||
|
||||
/* Save the return value as directed. */
|
||||
adr x5, ffi_call_SYSV_return
|
||||
and w4, w4, #AARCH64_RET_MASK
|
||||
add x5, x5, x4, lsl #3
|
||||
br x5
|
||||
|
||||
/* Note that each table entry is 2 insns, and thus 8 bytes.
|
||||
For integer data, note that we're storing into ffi_arg
|
||||
and therefore we want to extend to 64 bits; these types
|
||||
have two consecutive entries allocated for them. */
|
||||
ALIGN 4
|
||||
ffi_call_SYSV_return
|
||||
ret /* VOID */
|
||||
nop
|
||||
str x0, [x3] /* INT64 */
|
||||
ret
|
||||
stp x0, x1, [x3] /* INT128 */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
brk #1000 /* UNUSED */
|
||||
ret
|
||||
st4 { v0.s, v1.s, v2.s, v3.s }[0], [x3] /* S4 */
|
||||
ret
|
||||
st3 { v0.s, v1.s, v2.s }[0], [x3] /* S3 */
|
||||
ret
|
||||
stp s0, s1, [x3] /* S2 */
|
||||
ret
|
||||
str s0, [x3] /* S1 */
|
||||
ret
|
||||
st4 { v0.d, v1.d, v2.d, v3.d }[0], [x3] /* D4 */
|
||||
ret
|
||||
st3 { v0.d, v1.d, v2.d }[0], [x3] /* D3 */
|
||||
ret
|
||||
stp d0, d1, [x3] /* D2 */
|
||||
ret
|
||||
str d0, [x3] /* D1 */
|
||||
ret
|
||||
str q3, [x3, #48] /* Q4 */
|
||||
nop
|
||||
str q2, [x3, #32] /* Q3 */
|
||||
nop
|
||||
stp q0, q1, [x3] /* Q2 */
|
||||
ret
|
||||
str q0, [x3] /* Q1 */
|
||||
ret
|
||||
uxtb w0, w0 /* UINT8 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
uxth w0, w0 /* UINT16 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
mov w0, w0 /* UINT32 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
sxtb x0, w0 /* SINT8 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
sxth x0, w0 /* SINT16 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
sxtw x0, w0 /* SINT32 */
|
||||
str x0, [x3]
|
||||
ret /* reserved */
|
||||
nop
|
||||
|
||||
|
||||
NESTED_END ffi_call_SYSV_fake
|
||||
|
||||
|
||||
/* ffi_closure_SYSV
|
||||
Closure invocation glue. This is the low level code invoked directly by
|
||||
the closure trampoline to setup and call a closure.
|
||||
On entry x17 points to a struct ffi_closure, x16 has been clobbered
|
||||
all other registers are preserved.
|
||||
We allocate a call context and save the argument passing registers,
|
||||
then invoked the generic C ffi_closure_SYSV_inner() function to do all
|
||||
the real work, on return we load the result passing registers back from
|
||||
the call context.
|
||||
*/
|
||||
|
||||
#define ffi_closure_SYSV_FS (8*2 + CALL_CONTEXT_SIZE + 64)
|
||||
|
||||
NESTED_ENTRY ffi_closure_SYSV_V
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS!
|
||||
|
||||
/* Save the argument passing vector registers. */
|
||||
stp q0, q1, [sp, #16 + 0]
|
||||
stp q2, q3, [sp, #16 + 32]
|
||||
stp q4, q5, [sp, #16 + 64]
|
||||
stp q6, q7, [sp, #16 + 96]
|
||||
|
||||
b ffi_closure_SYSV_save_argument
|
||||
NESTED_END ffi_closure_SYSV_V
|
||||
|
||||
NESTED_ENTRY ffi_closure_SYSV
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS!
|
||||
|
||||
ffi_closure_SYSV_save_argument
|
||||
/* Save the argument passing core registers. */
|
||||
stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
|
||||
stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
|
||||
stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
|
||||
stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Load ffi_closure_inner arguments. */
|
||||
ldp PTR_REG(0), PTR_REG(1), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET] /* load cif, fn */
|
||||
ldr PTR_REG(2), [x17, #FFI_TRAMPOLINE_CLOSURE_OFFSET+PTR_SIZE*2] /* load user_data */
|
||||
|
||||
do_closure
|
||||
add x3, sp, #16 /* load context */
|
||||
add x4, sp, #ffi_closure_SYSV_FS /* load stack */
|
||||
add x5, sp, #16+CALL_CONTEXT_SIZE /* load rvalue */
|
||||
mov x6, x8 /* load struct_rval */
|
||||
|
||||
bl ffi_closure_SYSV_inner
|
||||
|
||||
/* Load the return value as directed. */
|
||||
adr x1, ffi_closure_SYSV_return_base
|
||||
and w0, w0, #AARCH64_RET_MASK
|
||||
add x1, x1, x0, lsl #3
|
||||
add x3, sp, #16+CALL_CONTEXT_SIZE
|
||||
br x1
|
||||
|
||||
/* Note that each table entry is 2 insns, and thus 8 bytes. */
|
||||
ALIGN 8
|
||||
ffi_closure_SYSV_return_base
|
||||
b ffi_closure_SYSV_epilog /* VOID */
|
||||
nop
|
||||
ldr x0, [x3] /* INT64 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldp x0, x1, [x3] /* INT128 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
brk #1000 /* UNUSED */
|
||||
nop
|
||||
ldr s3, [x3, #12] /* S4 */
|
||||
nop
|
||||
ldr s2, [x3, #8] /* S3 */
|
||||
nop
|
||||
ldp s0, s1, [x3] /* S2 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr s0, [x3] /* S1 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr d3, [x3, #24] /* D4 */
|
||||
nop
|
||||
ldr d2, [x3, #16] /* D3 */
|
||||
nop
|
||||
ldp d0, d1, [x3] /* D2 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr d0, [x3] /* D1 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr q3, [x3, #48] /* Q4 */
|
||||
nop
|
||||
ldr q2, [x3, #32] /* Q3 */
|
||||
nop
|
||||
ldp q0, q1, [x3] /* Q2 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldr q0, [x3] /* Q1 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
ldrb w0, [x3, #BE(7)] /* UINT8 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldrh w0, [x3, #BE(6)] /* UINT16 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldr w0, [x3, #BE(4)] /* UINT32 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldrsb x0, [x3, #BE(7)] /* SINT8 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldrsh x0, [x3, #BE(6)] /* SINT16 */
|
||||
b ffi_closure_SYSV_epilog
|
||||
brk #1000 /* reserved */
|
||||
nop
|
||||
ldrsw x0, [x3, #BE(4)] /* SINT32 */
|
||||
nop
|
||||
/* reserved */
|
||||
|
||||
ffi_closure_SYSV_epilog
|
||||
EPILOG_RESTORE_REG_PAIR x29, x30, #ffi_closure_SYSV_FS!
|
||||
EPILOG_RETURN
|
||||
NESTED_END ffi_closure_SYSV
|
||||
|
||||
|
||||
#ifdef FFI_GO_CLOSURES
|
||||
NESTED_ENTRY ffi_go_closure_SYSV_V
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS!
|
||||
|
||||
/* Save the argument passing vector registers. */
|
||||
stp q0, q1, [sp, #16 + 0]
|
||||
stp q2, q3, [sp, #16 + 32]
|
||||
stp q4, q5, [sp, #16 + 64]
|
||||
stp q6, q7, [sp, #16 + 96]
|
||||
b ffi_go_closure_SYSV_save_argument
|
||||
NESTED_END ffi_go_closure_SYSV_V
|
||||
|
||||
NESTED_ENTRY ffi_go_closure_SYSV
|
||||
PROLOG_SAVE_REG_PAIR x29, x30, #-ffi_closure_SYSV_FS!
|
||||
|
||||
ffi_go_closure_SYSV_save_argument
|
||||
/* Save the argument passing core registers. */
|
||||
stp x0, x1, [sp, #16 + 16*N_V_ARG_REG + 0]
|
||||
stp x2, x3, [sp, #16 + 16*N_V_ARG_REG + 16]
|
||||
stp x4, x5, [sp, #16 + 16*N_V_ARG_REG + 32]
|
||||
stp x6, x7, [sp, #16 + 16*N_V_ARG_REG + 48]
|
||||
|
||||
/* Load ffi_closure_inner arguments. */
|
||||
ldp PTR_REG(0), PTR_REG(1), [x18, #PTR_SIZE]/* load cif, fn */
|
||||
mov x2, x18 /* load user_data */
|
||||
b do_closure
|
||||
NESTED_END ffi_go_closure_SYSV
|
||||
|
||||
#endif /* FFI_GO_CLOSURES */
|
||||
|
||||
|
||||
/* void extend_hfa_type (void *dest, void *src, int h) */
|
||||
|
||||
LEAF_ENTRY extend_hfa_type
|
||||
|
||||
adr x3, extend_hfa_type_jump_base
|
||||
and w2, w2, #AARCH64_RET_MASK
|
||||
sub x2, x2, #AARCH64_RET_S4
|
||||
add x3, x3, x2, lsl #4
|
||||
br x3
|
||||
|
||||
ALIGN 4
|
||||
extend_hfa_type_jump_base
|
||||
ldp s16, s17, [x1] /* S4 */
|
||||
ldp s18, s19, [x1, #8]
|
||||
b extend_hfa_type_store_4
|
||||
nop
|
||||
|
||||
ldp s16, s17, [x1] /* S3 */
|
||||
ldr s18, [x1, #8]
|
||||
b extend_hfa_type_store_3
|
||||
nop
|
||||
|
||||
ldp s16, s17, [x1] /* S2 */
|
||||
b extend_hfa_type_store_2
|
||||
nop
|
||||
nop
|
||||
|
||||
ldr s16, [x1] /* S1 */
|
||||
b extend_hfa_type_store_1
|
||||
nop
|
||||
nop
|
||||
|
||||
ldp d16, d17, [x1] /* D4 */
|
||||
ldp d18, d19, [x1, #16]
|
||||
b extend_hfa_type_store_4
|
||||
nop
|
||||
|
||||
ldp d16, d17, [x1] /* D3 */
|
||||
ldr d18, [x1, #16]
|
||||
b extend_hfa_type_store_3
|
||||
nop
|
||||
|
||||
ldp d16, d17, [x1] /* D2 */
|
||||
b extend_hfa_type_store_2
|
||||
nop
|
||||
nop
|
||||
|
||||
ldr d16, [x1] /* D1 */
|
||||
b extend_hfa_type_store_1
|
||||
nop
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q4 */
|
||||
ldp q18, q19, [x1, #16]
|
||||
b extend_hfa_type_store_4
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q3 */
|
||||
ldr q18, [x1, #16]
|
||||
b extend_hfa_type_store_3
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q2 */
|
||||
b extend_hfa_type_store_2
|
||||
nop
|
||||
nop
|
||||
|
||||
ldr q16, [x1] /* Q1 */
|
||||
b extend_hfa_type_store_1
|
||||
|
||||
extend_hfa_type_store_4
|
||||
str q19, [x0, #48]
|
||||
extend_hfa_type_store_3
|
||||
str q18, [x0, #32]
|
||||
extend_hfa_type_store_2
|
||||
str q17, [x0, #16]
|
||||
extend_hfa_type_store_1
|
||||
str q16, [x0]
|
||||
ret
|
||||
|
||||
LEAF_END extend_hfa_type
|
||||
|
||||
|
||||
/* void compress_hfa_type (void *dest, void *reg, int h) */
|
||||
|
||||
LEAF_ENTRY compress_hfa_type
|
||||
|
||||
adr x3, compress_hfa_type_jump_base
|
||||
and w2, w2, #AARCH64_RET_MASK
|
||||
sub x2, x2, #AARCH64_RET_S4
|
||||
add x3, x3, x2, lsl #4
|
||||
br x3
|
||||
|
||||
ALIGN 4
|
||||
compress_hfa_type_jump_base
|
||||
ldp q16, q17, [x1] /* S4 */
|
||||
ldp q18, q19, [x1, #32]
|
||||
st4 { v16.s, v17.s, v18.s, v19.s }[0], [x0]
|
||||
ret
|
||||
|
||||
ldp q16, q17, [x1] /* S3 */
|
||||
ldr q18, [x1, #32]
|
||||
st3 { v16.s, v17.s, v18.s }[0], [x0]
|
||||
ret
|
||||
|
||||
ldp q16, q17, [x1] /* S2 */
|
||||
st2 { v16.s, v17.s }[0], [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldr q16, [x1] /* S1 */
|
||||
st1 { v16.s }[0], [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* D4 */
|
||||
ldp q18, q19, [x1, #32]
|
||||
st4 { v16.d, v17.d, v18.d, v19.d }[0], [x0]
|
||||
ret
|
||||
|
||||
ldp q16, q17, [x1] /* D3 */
|
||||
ldr q18, [x1, #32]
|
||||
st3 { v16.d, v17.d, v18.d }[0], [x0]
|
||||
ret
|
||||
|
||||
ldp q16, q17, [x1] /* D2 */
|
||||
st2 { v16.d, v17.d }[0], [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldr q16, [x1] /* D1 */
|
||||
st1 { v16.d }[0], [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q4 */
|
||||
ldp q18, q19, [x1, #32]
|
||||
b compress_hfa_type_store_q4
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q3 */
|
||||
ldr q18, [x1, #32]
|
||||
b compress_hfa_type_store_q3
|
||||
nop
|
||||
|
||||
ldp q16, q17, [x1] /* Q2 */
|
||||
stp q16, q17, [x0]
|
||||
ret
|
||||
nop
|
||||
|
||||
ldr q16, [x1] /* Q1 */
|
||||
str q16, [x0]
|
||||
ret
|
||||
|
||||
compress_hfa_type_store_q4
|
||||
str q19, [x0, #48]
|
||||
compress_hfa_type_store_q3
|
||||
str q18, [x0, #32]
|
||||
stp q16, q17, [x0]
|
||||
ret
|
||||
|
||||
LEAF_END compress_hfa_type
|
||||
|
||||
END
|
||||
@@ -28,6 +28,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#if defined(__arm__) || defined(_M_ARM)
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
@@ -35,6 +36,11 @@
|
||||
#include <stdlib.h>
|
||||
#include "internal.h"
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_ARM)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if FFI_EXEC_TRAMPOLINE_TABLE
|
||||
|
||||
#ifdef __MACH__
|
||||
@@ -42,7 +48,11 @@
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifndef _M_ARM
|
||||
extern unsigned int ffi_arm_trampoline[2] FFI_HIDDEN;
|
||||
#else
|
||||
extern unsigned int ffi_arm_trampoline[3] FFI_HIDDEN;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Forward declares. */
|
||||
@@ -88,10 +98,20 @@ ffi_put_arg (ffi_type *ty, void *src, void *dst)
|
||||
case FFI_TYPE_SINT32:
|
||||
case FFI_TYPE_UINT32:
|
||||
case FFI_TYPE_POINTER:
|
||||
#ifndef _MSC_VER
|
||||
case FFI_TYPE_FLOAT:
|
||||
#endif
|
||||
*(UINT32 *)dst = *(UINT32 *)src;
|
||||
break;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// casting a float* to a UINT32* doesn't work on Windows
|
||||
case FFI_TYPE_FLOAT:
|
||||
*(uintptr_t *)dst = 0;
|
||||
*(float *)dst = *(float *)src;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FFI_TYPE_SINT64:
|
||||
case FFI_TYPE_UINT64:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
@@ -210,7 +230,7 @@ ffi_prep_args_VFP (ffi_cif *cif, int flags, void *rvalue,
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing */
|
||||
ffi_status
|
||||
ffi_status FFI_HIDDEN
|
||||
ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
{
|
||||
int flags = 0, cabi = cif->abi;
|
||||
@@ -301,7 +321,7 @@ ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
}
|
||||
|
||||
/* Perform machine dependent cif processing for variadic calls */
|
||||
ffi_status
|
||||
ffi_status FFI_HIDDEN
|
||||
ffi_prep_cif_machdep_var (ffi_cif * cif,
|
||||
unsigned int nfixedargs, unsigned int ntotalargs)
|
||||
{
|
||||
@@ -571,15 +591,28 @@ ffi_prep_closure_loc (ffi_closure * closure,
|
||||
config[0] = closure;
|
||||
config[1] = closure_func;
|
||||
#else
|
||||
memcpy (closure->tramp, ffi_arm_trampoline, 8);
|
||||
|
||||
#ifndef _M_ARM
|
||||
memcpy(closure->tramp, ffi_arm_trampoline, 8);
|
||||
#else
|
||||
// cast away function type so MSVC doesn't set the lower bit of the function pointer
|
||||
memcpy(closure->tramp, (void*)((uintptr_t)ffi_arm_trampoline & 0xFFFFFFFE), FFI_TRAMPOLINE_CLOSURE_OFFSET);
|
||||
#endif
|
||||
|
||||
#if defined (__QNX__)
|
||||
msync(closure->tramp, 8, 0x1000000); /* clear data map */
|
||||
msync(codeloc, 8, 0x1000000); /* clear insn map */
|
||||
#elif defined(_MSC_VER)
|
||||
FlushInstructionCache(GetCurrentProcess(), closure->tramp, FFI_TRAMPOLINE_SIZE);
|
||||
#else
|
||||
__clear_cache(closure->tramp, closure->tramp + 8); /* clear data map */
|
||||
__clear_cache(codeloc, codeloc + 8); /* clear insn map */
|
||||
#endif
|
||||
#ifdef _M_ARM
|
||||
*(void(**)(void))(closure->tramp + FFI_TRAMPOLINE_CLOSURE_FUNCTION) = closure_func;
|
||||
#else
|
||||
*(void (**)(void))(closure->tramp + 8) = closure_func;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
closure->cif = cif;
|
||||
@@ -781,7 +814,7 @@ place_vfp_arg (ffi_cif *cif, int h)
|
||||
}
|
||||
/* Found regs to allocate. */
|
||||
cif->vfp_used |= new_used;
|
||||
cif->vfp_args[cif->vfp_nargs++] = reg;
|
||||
cif->vfp_args[cif->vfp_nargs++] = (signed char)reg;
|
||||
|
||||
/* Update vfp_reg_free. */
|
||||
if (cif->vfp_used & (1 << cif->vfp_reg_free))
|
||||
@@ -803,7 +836,7 @@ place_vfp_arg (ffi_cif *cif, int h)
|
||||
static void
|
||||
layout_vfp_args (ffi_cif * cif)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
/* Init VFP fields */
|
||||
cif->vfp_used = 0;
|
||||
cif->vfp_nargs = 0;
|
||||
@@ -817,3 +850,5 @@ layout_vfp_args (ffi_cif * cif)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __arm__ or _M_ARM */
|
||||
|
||||
@@ -43,7 +43,7 @@ typedef enum ffi_abi {
|
||||
FFI_SYSV,
|
||||
FFI_VFP,
|
||||
FFI_LAST_ABI,
|
||||
#ifdef __ARM_PCS_VFP
|
||||
#if defined(__ARM_PCS_VFP) || defined(_M_ARM)
|
||||
FFI_DEFAULT_ABI = FFI_VFP,
|
||||
#else
|
||||
FFI_DEFAULT_ABI = FFI_SYSV,
|
||||
@@ -57,7 +57,9 @@ typedef enum ffi_abi {
|
||||
signed char vfp_args[16] \
|
||||
|
||||
#define FFI_TARGET_SPECIFIC_VARIADIC
|
||||
#ifndef _M_ARM
|
||||
#define FFI_TARGET_HAS_COMPLEX_TYPE
|
||||
#endif
|
||||
|
||||
/* ---- Definitions for closures ----------------------------------------- */
|
||||
|
||||
@@ -74,8 +76,13 @@ typedef enum ffi_abi {
|
||||
#error "No trampoline table implementation"
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#define FFI_TRAMPOLINE_SIZE 16
|
||||
#define FFI_TRAMPOLINE_CLOSURE_FUNCTION 12
|
||||
#else
|
||||
#define FFI_TRAMPOLINE_SIZE 12
|
||||
#endif
|
||||
#define FFI_TRAMPOLINE_CLOSURE_OFFSET FFI_TRAMPOLINE_SIZE
|
||||
#endif
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifdef __arm__
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
@@ -377,6 +378,7 @@ ARM_FUNC_START(ffi_arm_trampoline)
|
||||
ARM_FUNC_END(ffi_arm_trampoline)
|
||||
|
||||
#endif /* FFI_EXEC_TRAMPOLINE_TABLE */
|
||||
#endif /* __arm__ */
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
|
||||
311
src/arm/sysv_msvc_arm32.S
Normal file
311
src/arm/sysv_msvc_arm32.S
Normal file
@@ -0,0 +1,311 @@
|
||||
/* -----------------------------------------------------------------------
|
||||
sysv.S - Copyright (c) 1998, 2008, 2011 Red Hat, Inc.
|
||||
Copyright (c) 2011 Plausible Labs Cooperative, Inc.
|
||||
Copyright (c) 2019 Microsoft Corporation.
|
||||
|
||||
ARM Foreign Function Interface
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
``Software''), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL 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>
|
||||
#include <ffi_cfi.h>
|
||||
#include "internal.h"
|
||||
#include "ksarm.h"
|
||||
|
||||
|
||||
; 8 byte aligned AREA to support 8 byte aligned jump tables
|
||||
MACRO
|
||||
NESTED_ENTRY_FFI $FuncName, $AreaName, $ExceptHandler
|
||||
|
||||
; compute the function's labels
|
||||
__DeriveFunctionLabels $FuncName
|
||||
|
||||
; determine the area we will put the function into
|
||||
__FuncArea SETS "|.text|"
|
||||
IF "$AreaName" != ""
|
||||
__FuncArea SETS "$AreaName"
|
||||
ENDIF
|
||||
|
||||
; set up the exception handler itself
|
||||
__FuncExceptionHandler SETS ""
|
||||
IF "$ExceptHandler" != ""
|
||||
__FuncExceptionHandler SETS "|$ExceptHandler|"
|
||||
ENDIF
|
||||
|
||||
; switch to the specified area, jump tables require 8 byte alignment
|
||||
AREA $__FuncArea,CODE,CODEALIGN,ALIGN=3,READONLY
|
||||
|
||||
; export the function name
|
||||
__ExportProc $FuncName
|
||||
|
||||
; flush any pending literal pool stuff
|
||||
ROUT
|
||||
|
||||
; reset the state of the unwind code tracking
|
||||
__ResetUnwindState
|
||||
|
||||
MEND
|
||||
|
||||
; MACRO
|
||||
; TABLE_ENTRY $Type, $Table
|
||||
;$Type_$Table
|
||||
; MEND
|
||||
|
||||
#define E(index,table) return_##index##_##table
|
||||
|
||||
; r0: stack
|
||||
; r1: frame
|
||||
; r2: fn
|
||||
; r3: vfp_used
|
||||
|
||||
; fake entry point exists only to generate exists only to
|
||||
; generate .pdata for exception unwinding
|
||||
NESTED_ENTRY_FFI ffi_call_VFP_fake
|
||||
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
|
||||
|
||||
ALTERNATE_ENTRY ffi_call_VFP
|
||||
cmp r3, #3 ; load only d0 if possible
|
||||
vldrle d0, [r0]
|
||||
vldmgt r0, {d0-d7}
|
||||
add r0, r0, #64 ; discard the vfp register args
|
||||
b ffi_call_SYSV
|
||||
NESTED_END ffi_call_VFP_fake
|
||||
|
||||
; fake entry point exists only to generate exists only to
|
||||
; generate .pdata for exception unwinding
|
||||
NESTED_ENTRY_FFI ffi_call_SYSV_fake
|
||||
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
|
||||
|
||||
ALTERNATE_ENTRY ffi_call_SYSV
|
||||
stm r1, {fp, lr}
|
||||
mov fp, r1
|
||||
|
||||
mov sp, r0 ; install the stack pointer
|
||||
mov lr, r2 ; move the fn pointer out of the way
|
||||
ldr ip, [fp, #16] ; install the static chain
|
||||
ldmia sp!, {r0-r3} ; move first 4 parameters in registers.
|
||||
blx lr ; call fn
|
||||
|
||||
; Load r2 with the pointer to storage for the return value
|
||||
; Load r3 with the return type code
|
||||
ldr r2, [fp, #8]
|
||||
ldr r3, [fp, #12]
|
||||
|
||||
; Deallocate the stack with the arguments.
|
||||
mov sp, fp
|
||||
|
||||
; Store values stored in registers.
|
||||
ALIGN 8
|
||||
lsl r3, #3
|
||||
add r3, r3, pc
|
||||
add r3, #8
|
||||
mov pc, r3
|
||||
|
||||
|
||||
E(ARM_TYPE_VFP_S, ffi_call)
|
||||
ALIGN 8
|
||||
vstr s0, [r2]
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VFP_D, ffi_call)
|
||||
ALIGN 8
|
||||
vstr d0, [r2]
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VFP_N, ffi_call)
|
||||
ALIGN 8
|
||||
vstm r2, {d0-d3}
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_INT64, ffi_call)
|
||||
ALIGN 8
|
||||
str r1, [r2, #4]
|
||||
nop
|
||||
E(ARM_TYPE_INT, ffi_call)
|
||||
ALIGN 8
|
||||
str r0, [r2]
|
||||
pop {fp,pc}
|
||||
E(ARM_TYPE_VOID, ffi_call)
|
||||
ALIGN 8
|
||||
pop {fp,pc}
|
||||
nop
|
||||
E(ARM_TYPE_STRUCT, ffi_call)
|
||||
ALIGN 8
|
||||
cmp r3, #ARM_TYPE_STRUCT
|
||||
pop {fp,pc}
|
||||
NESTED_END ffi_call_SYSV_fake
|
||||
|
||||
IMPORT |ffi_closure_inner_SYSV|
|
||||
/*
|
||||
int ffi_closure_inner_SYSV
|
||||
(
|
||||
cif, ; r0
|
||||
fun, ; r1
|
||||
user_data, ; r2
|
||||
frame ; r3
|
||||
)
|
||||
*/
|
||||
|
||||
NESTED_ENTRY_FFI ffi_go_closure_SYSV
|
||||
stmdb sp!, {r0-r3} ; save argument regs
|
||||
ldr r0, [ip, #4] ; load cif
|
||||
ldr r1, [ip, #8] ; load fun
|
||||
mov r2, ip ; load user_data
|
||||
b ffi_go_closure_SYSV_0
|
||||
NESTED_END ffi_go_closure_SYSV
|
||||
|
||||
; r3: ffi_closure
|
||||
|
||||
; fake entry point exists only to generate exists only to
|
||||
; generate .pdata for exception unwinding
|
||||
NESTED_ENTRY_FFI ffi_closure_SYSV_fake
|
||||
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
|
||||
ALTERNATE_ENTRY ffi_closure_SYSV
|
||||
ldmfd sp!, {ip,r0} ; restore fp (r0 is used for stack alignment)
|
||||
stmdb sp!, {r0-r3} ; save argument regs
|
||||
|
||||
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] ; ffi_closure->cif
|
||||
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] ; ffi_closure->fun
|
||||
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] ; ffi_closure->user_data
|
||||
|
||||
ALTERNATE_ENTRY ffi_go_closure_SYSV_0
|
||||
add ip, sp, #16 ; compute entry sp
|
||||
|
||||
sub sp, sp, #64+32 ; allocate frame parameter (sizeof(vfp_space) = 64, sizeof(result) = 32)
|
||||
mov r3, sp ; set frame parameter
|
||||
stmdb sp!, {ip,lr}
|
||||
|
||||
bl ffi_closure_inner_SYSV ; call the Python closure
|
||||
|
||||
; Load values returned in registers.
|
||||
add r2, sp, #64+8 ; address of closure_frame->result
|
||||
bl ffi_closure_ret ; move result to correct register or memory for type
|
||||
|
||||
ldmfd sp!, {ip,lr}
|
||||
mov sp, ip ; restore stack pointer
|
||||
mov pc, lr
|
||||
NESTED_END ffi_closure_SYSV_fake
|
||||
|
||||
IMPORT |ffi_closure_inner_VFP|
|
||||
/*
|
||||
int ffi_closure_inner_VFP
|
||||
(
|
||||
cif, ; r0
|
||||
fun, ; r1
|
||||
user_data, ; r2
|
||||
frame ; r3
|
||||
)
|
||||
*/
|
||||
|
||||
NESTED_ENTRY_FFI ffi_go_closure_VFP
|
||||
stmdb sp!, {r0-r3} ; save argument regs
|
||||
ldr r0, [ip, #4] ; load cif
|
||||
ldr r1, [ip, #8] ; load fun
|
||||
mov r2, ip ; load user_data
|
||||
b ffi_go_closure_VFP_0
|
||||
NESTED_END ffi_go_closure_VFP
|
||||
|
||||
; fake entry point exists only to generate exists only to
|
||||
; generate .pdata for exception unwinding
|
||||
; r3: closure
|
||||
NESTED_ENTRY_FFI ffi_closure_VFP_fake
|
||||
PROLOG_PUSH {r11, lr} ; save fp and lr for unwind
|
||||
|
||||
ALTERNATE_ENTRY ffi_closure_VFP
|
||||
ldmfd sp!, {ip,r0} ; restore fp (r0 is used for stack alignment)
|
||||
stmdb sp!, {r0-r3} ; save argument regs
|
||||
|
||||
ldr r0, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET] ; load cif
|
||||
ldr r1, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+4] ; load fun
|
||||
ldr r2, [ip, #FFI_TRAMPOLINE_CLOSURE_OFFSET+8] ; load user_data
|
||||
|
||||
ALTERNATE_ENTRY ffi_go_closure_VFP_0
|
||||
add ip, sp, #16 ; compute entry sp
|
||||
sub sp, sp, #32 ; save space for closure_frame->result
|
||||
vstmdb sp!, {d0-d7} ; push closure_frame->vfp_space
|
||||
|
||||
mov r3, sp ; save closure_frame
|
||||
stmdb sp!, {ip,lr}
|
||||
|
||||
bl ffi_closure_inner_VFP
|
||||
|
||||
; Load values returned in registers.
|
||||
add r2, sp, #64+8 ; load result
|
||||
bl ffi_closure_ret
|
||||
ldmfd sp!, {ip,lr}
|
||||
mov sp, ip ; restore stack pointer
|
||||
mov pc, lr
|
||||
NESTED_END ffi_closure_VFP_fake
|
||||
|
||||
/* Load values returned in registers for both closure entry points.
|
||||
Note that we use LDM with SP in the register set. This is deprecated
|
||||
by ARM, but not yet unpredictable. */
|
||||
|
||||
NESTED_ENTRY_FFI ffi_closure_ret
|
||||
stmdb sp!, {fp,lr}
|
||||
|
||||
ALIGN 8
|
||||
lsl r0, #3
|
||||
add r0, r0, pc
|
||||
add r0, #8
|
||||
mov pc, r0
|
||||
|
||||
E(ARM_TYPE_VFP_S, ffi_closure)
|
||||
ALIGN 8
|
||||
vldr s0, [r2]
|
||||
b call_epilogue
|
||||
E(ARM_TYPE_VFP_D, ffi_closure)
|
||||
ALIGN 8
|
||||
vldr d0, [r2]
|
||||
b call_epilogue
|
||||
E(ARM_TYPE_VFP_N, ffi_closure)
|
||||
ALIGN 8
|
||||
vldm r2, {d0-d3}
|
||||
b call_epilogue
|
||||
E(ARM_TYPE_INT64, ffi_closure)
|
||||
ALIGN 8
|
||||
ldr r1, [r2, #4]
|
||||
nop
|
||||
E(ARM_TYPE_INT, ffi_closure)
|
||||
ALIGN 8
|
||||
ldr r0, [r2]
|
||||
b call_epilogue
|
||||
E(ARM_TYPE_VOID, ffi_closure)
|
||||
ALIGN 8
|
||||
b call_epilogue
|
||||
nop
|
||||
E(ARM_TYPE_STRUCT, ffi_closure)
|
||||
ALIGN 8
|
||||
b call_epilogue
|
||||
call_epilogue
|
||||
ldmfd sp!, {fp,pc}
|
||||
NESTED_END ffi_closure_ret
|
||||
|
||||
AREA |.trampoline|, DATA, THUMB, READONLY
|
||||
EXPORT |ffi_arm_trampoline|
|
||||
|ffi_arm_trampoline| DATA
|
||||
thisproc adr ip, thisproc
|
||||
stmdb sp!, {ip, r0}
|
||||
ldr pc, [pc, #0]
|
||||
DCD 0
|
||||
;ENDP
|
||||
|
||||
END
|
||||
@@ -122,7 +122,7 @@ ffi_closure_free (void *ptr)
|
||||
# define FFI_MMAP_EXEC_WRIT 1
|
||||
# define HAVE_MNTENT 1
|
||||
# endif
|
||||
# if defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)
|
||||
# if defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)
|
||||
/* Windows systems may have Data Execution Protection (DEP) enabled,
|
||||
which requires the use of VirtualMalloc/VirtualFree to alloc/free
|
||||
executable memory. */
|
||||
@@ -172,7 +172,7 @@ struct ffi_trampoline_table
|
||||
|
||||
struct ffi_trampoline_table_entry
|
||||
{
|
||||
void *(*trampoline) ();
|
||||
void *(*trampoline) (void);
|
||||
ffi_trampoline_table_entry *next;
|
||||
};
|
||||
|
||||
@@ -385,7 +385,7 @@ ffi_closure_free (void *ptr)
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#if !defined(X86_WIN32) && !defined(X86_WIN64)
|
||||
#if !defined(X86_WIN32) && !defined(X86_WIN64) && !defined(_M_ARM64)
|
||||
#ifdef HAVE_MNTENT
|
||||
#include <mntent.h>
|
||||
#endif /* HAVE_MNTENT */
|
||||
@@ -511,7 +511,7 @@ static int dlmalloc_trim(size_t) MAYBE_UNUSED;
|
||||
static size_t dlmalloc_usable_size(void*) MAYBE_UNUSED;
|
||||
static void dlmalloc_stats(void) MAYBE_UNUSED;
|
||||
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
|
||||
/* Use these for mmap and munmap within dlmalloc.c. */
|
||||
static void *dlmmap(void *, size_t, int, int, int, off_t);
|
||||
static int dlmunmap(void *, size_t);
|
||||
@@ -525,7 +525,7 @@ static int dlmunmap(void *, size_t);
|
||||
#undef mmap
|
||||
#undef munmap
|
||||
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
|
||||
#if !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX)
|
||||
|
||||
/* A mutex used to synchronize access to *exec* variables in this file. */
|
||||
static pthread_mutex_t open_temp_exec_file_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -789,7 +789,13 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
|
||||
close (execfd);
|
||||
goto retry_open;
|
||||
}
|
||||
ftruncate (execfd, offset);
|
||||
if (ftruncate (execfd, offset) != 0)
|
||||
{
|
||||
/* Fixme : Error logs can be added here. Returning an error for
|
||||
* ftruncte() will not add any advantage as it is being
|
||||
* validating in the error case. */
|
||||
}
|
||||
|
||||
return MFAIL;
|
||||
}
|
||||
else if (!offset
|
||||
@@ -801,7 +807,12 @@ dlmmap_locked (void *start, size_t length, int prot, int flags, off_t offset)
|
||||
if (start == MFAIL)
|
||||
{
|
||||
munmap (ptr, length);
|
||||
ftruncate (execfd, offset);
|
||||
if (ftruncate (execfd, offset) != 0)
|
||||
{
|
||||
/* Fixme : Error logs can be added here. Returning an error for
|
||||
* ftruncte() will not add any advantage as it is being
|
||||
* validating in the error case. */
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
@@ -896,7 +907,7 @@ segment_holding_code (mstate m, char* addr)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
|
||||
#endif /* !(defined(X86_WIN32) || defined(X86_WIN64) || defined(_M_ARM64) || defined(__OS2__)) || defined (__CYGWIN__) || defined(__INTERIX) */
|
||||
|
||||
/* Allocate a chunk of memory with the given size. Returns a pointer
|
||||
to the writable address, and sets *CODE to the executable
|
||||
@@ -921,6 +932,13 @@ ffi_closure_alloc (size_t size, void **code)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *
|
||||
ffi_data_to_code_pointer (void *data)
|
||||
{
|
||||
msegmentptr seg = segment_holding (gm, data);
|
||||
return add_segment_exec_offset (data, seg);
|
||||
}
|
||||
|
||||
/* Release a chunk of memory allocated with ffi_closure_alloc. If
|
||||
FFI_CLOSURE_FREE_CODE is nonzero, the given address can be the
|
||||
writable or the executable address given. Otherwise, only the
|
||||
@@ -960,6 +978,12 @@ ffi_closure_free (void *ptr)
|
||||
free (ptr);
|
||||
}
|
||||
|
||||
void *
|
||||
ffi_data_to_code_pointer (void *data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
# endif /* ! FFI_MMAP_EXEC_WRIT */
|
||||
#endif /* FFI_CLOSURES */
|
||||
|
||||
|
||||
@@ -297,10 +297,18 @@ ffi_closure_pa32:
|
||||
.LSCIE1:
|
||||
.word 0x0 ;# CIE Identifier Tag
|
||||
.byte 0x1 ;# CIE Version
|
||||
#ifdef __PIC__
|
||||
.ascii "zR\0" ;# CIE Augmentation: 'z' - data, 'R' - DW_EH_PE_... data
|
||||
#else
|
||||
.ascii "\0" ;# CIE Augmentation
|
||||
#endif
|
||||
.uleb128 0x1 ;# CIE Code Alignment Factor
|
||||
.sleb128 4 ;# CIE Data Alignment Factor
|
||||
.byte 0x2 ;# CIE RA Column
|
||||
#ifdef __PIC__
|
||||
.uleb128 0x1 ;# Augmentation size
|
||||
.byte 0x1b ;# FDE Encoding (DW_EH_PE_pcrel|DW_EH_PE_sdata4)
|
||||
#endif
|
||||
.byte 0xc ;# DW_CFA_def_cfa
|
||||
.uleb128 0x1e
|
||||
.uleb128 0x0
|
||||
@@ -310,9 +318,15 @@ ffi_closure_pa32:
|
||||
.word .LEFDE1-.LASFDE1 ;# FDE Length
|
||||
.LASFDE1:
|
||||
.word .LASFDE1-.Lframe1 ;# FDE CIE offset
|
||||
.word .LFB1 ;# FDE initial location
|
||||
#ifdef __PIC__
|
||||
.word .LFB1-. ;# FDE initial location
|
||||
#else
|
||||
.word .LFB1 ;# FDE initial location
|
||||
#endif
|
||||
.word .LFE1-.LFB1 ;# FDE address range
|
||||
|
||||
#ifdef __PIC__
|
||||
.uleb128 0x0 ;# Augmentation size: no data
|
||||
#endif
|
||||
.byte 0x4 ;# DW_CFA_advance_loc4
|
||||
.word .LCFI11-.LFB1
|
||||
.byte 0x83 ;# DW_CFA_offset, column 0x3
|
||||
@@ -338,8 +352,15 @@ ffi_closure_pa32:
|
||||
.word .LEFDE2-.LASFDE2 ;# FDE Length
|
||||
.LASFDE2:
|
||||
.word .LASFDE2-.Lframe1 ;# FDE CIE offset
|
||||
#ifdef __PIC__
|
||||
.word .LFB2-. ;# FDE initial location
|
||||
#else
|
||||
.word .LFB2 ;# FDE initial location
|
||||
#endif
|
||||
.word .LFE2-.LFB2 ;# FDE address range
|
||||
#ifdef __PIC__
|
||||
.uleb128 0x0 ;# Augmentation size: no data
|
||||
#endif
|
||||
.byte 0x4 ;# DW_CFA_advance_loc4
|
||||
.word .LCFI21-.LFB2
|
||||
.byte 0x83 ;# DW_CFA_offset, column 0x3
|
||||
|
||||
@@ -121,8 +121,9 @@ ffi_call_int (ffi_cif *cif,
|
||||
# endif
|
||||
/* The SYSV ABI returns a structure of up to 8 bytes in size
|
||||
left-padded in r3/r4, and the ELFv2 ABI similarly returns a
|
||||
structure of up to 8 bytes in size left-padded in r3. */
|
||||
if (rsize <= 8)
|
||||
structure of up to 8 bytes in size left-padded in r3. But
|
||||
note that a structure of a single float is not paddded. */
|
||||
if (rsize <= 8 && (cif->flags & FLAG_RETURNS_FP) == 0)
|
||||
memcpy (rvalue, (char *) smst_buffer + 8 - rsize, rsize);
|
||||
else
|
||||
#endif
|
||||
|
||||
@@ -63,10 +63,30 @@ ffi_prep_types_linux64 (ffi_abi abi)
|
||||
|
||||
|
||||
static unsigned int
|
||||
discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
|
||||
discover_homogeneous_aggregate (ffi_abi abi,
|
||||
const ffi_type *t,
|
||||
unsigned int *elnum)
|
||||
{
|
||||
switch (t->type)
|
||||
{
|
||||
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
/* 64-bit long doubles are equivalent to doubles. */
|
||||
if ((abi & FFI_LINUX_LONG_DOUBLE_128) == 0)
|
||||
{
|
||||
*elnum = 1;
|
||||
return FFI_TYPE_DOUBLE;
|
||||
}
|
||||
/* IBM extended precision values use unaligned pairs
|
||||
of FPRs, but according to the ABI must be considered
|
||||
distinct from doubles. They are also limited to a
|
||||
maximum of four members in a homogeneous aggregate. */
|
||||
else
|
||||
{
|
||||
*elnum = 2;
|
||||
return FFI_TYPE_LONGDOUBLE;
|
||||
}
|
||||
#endif
|
||||
case FFI_TYPE_FLOAT:
|
||||
case FFI_TYPE_DOUBLE:
|
||||
*elnum = 1;
|
||||
@@ -79,7 +99,7 @@ discover_homogeneous_aggregate (const ffi_type *t, unsigned int *elnum)
|
||||
while (*el)
|
||||
{
|
||||
unsigned int el_elt, el_elnum = 0;
|
||||
el_elt = discover_homogeneous_aggregate (*el, &el_elnum);
|
||||
el_elt = discover_homogeneous_aggregate (abi, *el, &el_elnum);
|
||||
if (el_elt == 0
|
||||
|| (base_elt && base_elt != el_elt))
|
||||
return 0;
|
||||
@@ -112,7 +132,7 @@ ffi_prep_cif_linux64_core (ffi_cif *cif)
|
||||
unsigned bytes;
|
||||
unsigned i, fparg_count = 0, intarg_count = 0;
|
||||
unsigned flags = cif->flags;
|
||||
unsigned int elt, elnum;
|
||||
unsigned elt, elnum, rtype;
|
||||
|
||||
#if FFI_TYPE_LONGDOUBLE == FFI_TYPE_DOUBLE
|
||||
/* If compiled without long double support.. */
|
||||
@@ -138,7 +158,11 @@ ffi_prep_cif_linux64_core (ffi_cif *cif)
|
||||
#endif
|
||||
|
||||
/* Return value handling. */
|
||||
switch (cif->rtype->type)
|
||||
rtype = cif->rtype->type;
|
||||
#if _CALL_ELF == 2
|
||||
homogeneous:
|
||||
#endif
|
||||
switch (rtype)
|
||||
{
|
||||
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
@@ -164,19 +188,18 @@ ffi_prep_cif_linux64_core (ffi_cif *cif)
|
||||
|
||||
case FFI_TYPE_STRUCT:
|
||||
#if _CALL_ELF == 2
|
||||
elt = discover_homogeneous_aggregate (cif->rtype, &elnum);
|
||||
elt = discover_homogeneous_aggregate (cif->abi, cif->rtype, &elnum);
|
||||
if (elt)
|
||||
{
|
||||
if (elt == FFI_TYPE_DOUBLE)
|
||||
flags |= FLAG_RETURNS_64BITS;
|
||||
flags |= FLAG_RETURNS_FP | FLAG_RETURNS_SMST;
|
||||
break;
|
||||
}
|
||||
{
|
||||
flags |= FLAG_RETURNS_SMST;
|
||||
rtype = elt;
|
||||
goto homogeneous;
|
||||
}
|
||||
if (cif->rtype->size <= 16)
|
||||
{
|
||||
flags |= FLAG_RETURNS_SMST;
|
||||
break;
|
||||
}
|
||||
{
|
||||
flags |= FLAG_RETURNS_SMST;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
intarg_count++;
|
||||
flags |= FLAG_RETVAL_REFERENCE;
|
||||
@@ -224,7 +247,7 @@ ffi_prep_cif_linux64_core (ffi_cif *cif)
|
||||
intarg_count = FFI_ALIGN (intarg_count, align);
|
||||
}
|
||||
intarg_count += ((*ptr)->size + 7) / 8;
|
||||
elt = discover_homogeneous_aggregate (*ptr, &elnum);
|
||||
elt = discover_homogeneous_aggregate (cif->abi, *ptr, &elnum);
|
||||
if (elt)
|
||||
{
|
||||
fparg_count += elnum;
|
||||
@@ -391,7 +414,7 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
|
||||
valp rest;
|
||||
valp next_arg;
|
||||
|
||||
/* 'fpr_base' points at the space for fpr3, and grows upwards as
|
||||
/* 'fpr_base' points at the space for f1, and grows upwards as
|
||||
we use FPR registers. */
|
||||
valp fpr_base;
|
||||
unsigned int fparg_count;
|
||||
@@ -492,7 +515,9 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
|
||||
/* Fall through. */
|
||||
#endif
|
||||
case FFI_TYPE_DOUBLE:
|
||||
#if _CALL_ELF != 2
|
||||
do_double:
|
||||
#endif
|
||||
double_tmp = **p_argv.d;
|
||||
if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
|
||||
{
|
||||
@@ -511,7 +536,9 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
#if _CALL_ELF != 2
|
||||
do_float:
|
||||
#endif
|
||||
double_tmp = **p_argv.f;
|
||||
if (fparg_count < NUM_FPR_ARG_REGISTERS64 && i < nfixedargs)
|
||||
{
|
||||
@@ -548,9 +575,13 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
|
||||
if (align > 16)
|
||||
align = 16;
|
||||
if (align > 1)
|
||||
next_arg.p = FFI_ALIGN (next_arg.p, align);
|
||||
{
|
||||
next_arg.p = FFI_ALIGN (next_arg.p, align);
|
||||
if (next_arg.ul == gpr_end.ul)
|
||||
next_arg.ul = rest.ul;
|
||||
}
|
||||
}
|
||||
elt = discover_homogeneous_aggregate (*ptr, &elnum);
|
||||
elt = discover_homogeneous_aggregate (ecif->cif->abi, *ptr, &elnum);
|
||||
if (elt)
|
||||
{
|
||||
#if _CALL_ELF == 2
|
||||
@@ -576,11 +607,9 @@ ffi_prep_args64 (extended_cif *ecif, unsigned long *const stack)
|
||||
fparg_count++;
|
||||
}
|
||||
while (--elnum != 0);
|
||||
if ((next_arg.p & 3) != 0)
|
||||
{
|
||||
if (++next_arg.f == gpr_end.f)
|
||||
next_arg.f = rest.f;
|
||||
}
|
||||
if ((next_arg.p & 7) != 0)
|
||||
if (++next_arg.f == gpr_end.f)
|
||||
next_arg.f = rest.f;
|
||||
}
|
||||
else
|
||||
do
|
||||
@@ -813,7 +842,7 @@ ffi_closure_helper_LINUX64 (ffi_cif *cif,
|
||||
if (align > 1)
|
||||
pst = (unsigned long *) FFI_ALIGN ((size_t) pst, align);
|
||||
}
|
||||
elt = discover_homogeneous_aggregate (arg_types[i], &elnum);
|
||||
elt = discover_homogeneous_aggregate (cif->abi, arg_types[i], &elnum);
|
||||
if (elt)
|
||||
{
|
||||
#if _CALL_ELF == 2
|
||||
@@ -915,7 +944,9 @@ ffi_closure_helper_LINUX64 (ffi_cif *cif,
|
||||
/* Fall through. */
|
||||
#endif
|
||||
case FFI_TYPE_DOUBLE:
|
||||
#if _CALL_ELF != 2
|
||||
do_double:
|
||||
#endif
|
||||
/* On the outgoing stack all values are aligned to 8 */
|
||||
/* there are 13 64bit floating point registers */
|
||||
|
||||
@@ -930,7 +961,9 @@ ffi_closure_helper_LINUX64 (ffi_cif *cif,
|
||||
break;
|
||||
|
||||
case FFI_TYPE_FLOAT:
|
||||
#if _CALL_ELF != 2
|
||||
do_float:
|
||||
#endif
|
||||
if (pfr < end_pfr && i < nfixedargs)
|
||||
{
|
||||
/* Float values are stored as doubles in the
|
||||
|
||||
@@ -143,7 +143,7 @@ ffi_closure_LINUX64:
|
||||
stfd %f12, -104+(11*8)(%r1)
|
||||
stfd %f13, -104+(12*8)(%r1)
|
||||
|
||||
# load up the pointer to the saved fpr registers */
|
||||
# load up the pointer to the saved fpr registers
|
||||
addi %r8, %r1, -104
|
||||
|
||||
# load up the pointer to the result storage
|
||||
|
||||
@@ -129,7 +129,9 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
|
||||
cif->rtype = rtype;
|
||||
|
||||
cif->flags = 0;
|
||||
|
||||
#ifdef _M_ARM64
|
||||
cif->is_variadic = isvariadic;
|
||||
#endif
|
||||
#if HAVE_LONG_DOUBLE_VARIANT
|
||||
ffi_prep_types (abi);
|
||||
#endif
|
||||
@@ -199,7 +201,7 @@ ffi_status FFI_HIDDEN ffi_prep_cif_core(ffi_cif *cif, ffi_abi abi,
|
||||
bytes = 6*4;
|
||||
#endif
|
||||
|
||||
bytes += STACK_ARG_SIZE((*ptr)->size);
|
||||
bytes += (unsigned int)STACK_ARG_SIZE((*ptr)->size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef __x86_64__
|
||||
#if defined(__i386__) || defined(_M_IX86)
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include <stdint.h>
|
||||
@@ -756,4 +756,4 @@ ffi_raw_call(ffi_cif *cif, void (*fn)(void), void *rvalue, ffi_raw *avalue)
|
||||
ffi_call_i386 (frame, stack);
|
||||
}
|
||||
#endif /* !FFI_NO_RAW_API */
|
||||
#endif /* !__x86_64__ */
|
||||
#endif /* __i386__ */
|
||||
|
||||
@@ -282,7 +282,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
|
||||
|
||||
/* The X86_64_SSEUP_CLASS should be always preceded by
|
||||
X86_64_SSE_CLASS or X86_64_SSEUP_CLASS. */
|
||||
if (classes[i] == X86_64_SSEUP_CLASS
|
||||
if (i > 1 && classes[i] == X86_64_SSEUP_CLASS
|
||||
&& classes[i - 1] != X86_64_SSE_CLASS
|
||||
&& classes[i - 1] != X86_64_SSEUP_CLASS)
|
||||
{
|
||||
@@ -293,7 +293,7 @@ classify_argument (ffi_type *type, enum x86_64_reg_class classes[],
|
||||
|
||||
/* If X86_64_X87UP_CLASS isn't preceded by X86_64_X87_CLASS,
|
||||
everything should be passed in memory. */
|
||||
if (classes[i] == X86_64_X87UP_CLASS
|
||||
if (i > 1 && classes[i] == X86_64_X87UP_CLASS
|
||||
&& (classes[i - 1] != X86_64_X87_CLASS))
|
||||
{
|
||||
/* The first one should never be X86_64_X87UP_CLASS. */
|
||||
@@ -394,7 +394,7 @@ extern ffi_status
|
||||
ffi_prep_cif_machdep_efi64(ffi_cif *cif);
|
||||
#endif
|
||||
|
||||
ffi_status
|
||||
ffi_status FFI_HIDDEN
|
||||
ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
{
|
||||
int gprcount, ssecount, i, avn, ngpr, nsse;
|
||||
@@ -451,9 +451,11 @@ ffi_prep_cif_machdep (ffi_cif *cif)
|
||||
case FFI_TYPE_DOUBLE:
|
||||
flags = UNIX64_RET_XMM64;
|
||||
break;
|
||||
#if FFI_TYPE_LONGDOUBLE != FFI_TYPE_DOUBLE
|
||||
case FFI_TYPE_LONGDOUBLE:
|
||||
flags = UNIX64_RET_X87;
|
||||
break;
|
||||
#endif
|
||||
case FFI_TYPE_STRUCT:
|
||||
n = examine_argument (cif->rtype, classes, 1, &ngpr, &nsse);
|
||||
if (n == 0)
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_AMD64)
|
||||
#include <ffi.h>
|
||||
#include <ffi_common.h>
|
||||
#include <stdlib.h>
|
||||
@@ -33,7 +34,7 @@
|
||||
#ifdef X86_WIN64
|
||||
#define EFI64(name) name
|
||||
#else
|
||||
#define EFI64(name) name##_efi64
|
||||
#define EFI64(name) FFI_HIDDEN name##_efi64
|
||||
#endif
|
||||
|
||||
struct win64_call_frame
|
||||
@@ -48,7 +49,7 @@ struct win64_call_frame
|
||||
extern void ffi_call_win64 (void *stack, struct win64_call_frame *,
|
||||
void *closure) FFI_HIDDEN;
|
||||
|
||||
ffi_status
|
||||
ffi_status FFI_HIDDEN
|
||||
EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
|
||||
{
|
||||
int flags, n;
|
||||
@@ -306,3 +307,5 @@ ffi_closure_win64_inner(ffi_cif *cif,
|
||||
fun (cif, rvalue, avalue, user_data);
|
||||
return flags;
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
----------------------------------------------------------------------- */
|
||||
|
||||
#ifndef __x86_64__
|
||||
#ifdef __i386__
|
||||
#ifndef _MSC_VER
|
||||
|
||||
#define LIBFFI_ASM
|
||||
@@ -1122,7 +1122,7 @@ L(EFDE9):
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#endif /* ifndef _MSC_VER */
|
||||
#endif /* ifndef __x86_64__ */
|
||||
#endif /* ifdef __i386__ */
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#ifdef __x86_64__
|
||||
#define LIBFFI_ASM
|
||||
#include <fficonfig.h>
|
||||
#include <ffi.h>
|
||||
@@ -42,6 +43,7 @@
|
||||
|
||||
.align 8
|
||||
.globl C(ffi_call_win64)
|
||||
FFI_HIDDEN(C(ffi_call_win64))
|
||||
|
||||
SEH(.seh_proc ffi_call_win64)
|
||||
C(ffi_call_win64):
|
||||
@@ -169,6 +171,7 @@ E(0b, FFI_TYPE_SMALL_STRUCT_4B)
|
||||
|
||||
.align 8
|
||||
.globl C(ffi_go_closure_win64)
|
||||
FFI_HIDDEN(C(ffi_go_closure_win64))
|
||||
|
||||
SEH(.seh_proc ffi_go_closure_win64)
|
||||
C(ffi_go_closure_win64):
|
||||
@@ -188,6 +191,7 @@ C(ffi_go_closure_win64):
|
||||
|
||||
.align 8
|
||||
.globl C(ffi_closure_win64)
|
||||
FFI_HIDDEN(C(ffi_closure_win64))
|
||||
|
||||
SEH(.seh_proc ffi_closure_win64)
|
||||
C(ffi_closure_win64):
|
||||
@@ -226,6 +230,7 @@ C(ffi_closure_win64):
|
||||
|
||||
cfi_endproc
|
||||
SEH(.seh_endproc)
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
#if defined __ELF__ && defined __linux__
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2003, 2005, 2008, 2009, 2010, 2011, 2014, 2019 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -480,11 +480,11 @@ proc run-many-tests { testcases extra_flags } {
|
||||
switch $compiler_vendor {
|
||||
"clang" {
|
||||
set common "-W -Wall"
|
||||
set optimizations { "-O0" "-O2" "-Os" }
|
||||
set optimizations { "-O0" "-O2" }
|
||||
}
|
||||
"gnu" {
|
||||
set common "-W -Wall -Wno-psabi"
|
||||
set optimizations { "-O0" "-O2" "-Os" "-O2 -fomit-frame-pointer" }
|
||||
set optimizations { "-O0" "-O2" "-O2 -fomit-frame-pointer" }
|
||||
}
|
||||
default {
|
||||
# Assume we are using the vendor compiler.
|
||||
|
||||
@@ -33,19 +33,20 @@ int main (void)
|
||||
|
||||
f = 3.14159;
|
||||
|
||||
#if 1
|
||||
/* This is ifdef'd out for now. long double support under SunOS/gcc
|
||||
is pretty much non-existent. You'll get the odd bus error in library
|
||||
routines like printf(). */
|
||||
#if defined(__sun) && defined(__GNUC__)
|
||||
/* long double support under SunOS/gcc is pretty much non-existent.
|
||||
You'll get the odd bus error in library routines like printf() */
|
||||
#else
|
||||
printf ("%Lf\n", ldblit(f));
|
||||
#endif
|
||||
|
||||
ld = 666;
|
||||
ffi_call(&cif, FFI_FN(ldblit), &ld, values);
|
||||
|
||||
#if 1
|
||||
/* This is ifdef'd out for now. long double support under SunOS/gcc
|
||||
is pretty much non-existent. You'll get the odd bus error in library
|
||||
routines like printf(). */
|
||||
#if defined(__sun) && defined(__GNUC__)
|
||||
/* long double support under SunOS/gcc is pretty much non-existent.
|
||||
You'll get the odd bus error in library routines like printf() */
|
||||
#else
|
||||
printf ("%Lf, %Lf, %Lf, %Lf\n", ld, ldblit(f), ld - ldblit(f), LDBL_EPSILON);
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user