summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author couriersud <couriersud@users.noreply.github.com>2022-05-19 19:40:00 +0200
committer GitHub <noreply@github.com>2022-05-19 19:40:00 +0200
commit0c258c9d707c7775a8f1943d52c5a54781838c0f (patch)
treed58a893f89e543437a69458510a9d159d85e4423
parent299aa2eda394f50bef88cf6a7ef253c96dbf08ab (diff)
netlist: Fixes to address PR #9752 and issue #8590 / EMSCRIPTEN (#9773)
netlist: pointer to member function code - Address PR #9752 and issue #8590 - change comments in ppmf.h - add support for function desciptors (IA64) - sizeof(size_t) may be different on build targets make plib::hash use uint64 to ensure consistent static solver hashes across platforms (EMSCRIPTEN) - Moved constructor and member functions outside the class declaration with the exception of "call" member functions. - Updated comment on accessing RDX - Added more test cases * Removed execution bit on certain files I have separated out the raw processing code into `ppmf.cpp`. I have also taken first steps to clean the abi identification. The code submitted now supports: a) The unknown virtual inheritance case with specific code for MSVC for simple (i.e. scalar, void, reference, pointer) return types using the optimized code. This is the test case only supported under MSVC and which should return 7. Please have a look at the code. Basically m_vptr_offset is an index into a pointer table. It needs to be multiplied by `sizeof(void *)`. b) If you enable PPMF_EXPERIMENTAL complex return type member functions for MSVC will also use the optimized code path. This is explained in detail in the code in ppmf, including caveats and possible solutions. c) Enabling PPMF_USE_MAME_DELEGATES will use `src/lib/util/delegate.h` as a replacement for `ppmf.h`. This allows to run the same tests (`nltool -c tests` from standalone build) as for the ppmf code. d) The code now also supports `clang-cl` e) sizeof(size_t) may be different on build targets. Make plib::hash use uint64 to ensure consistent static solver hashes across platforms. This fixes loading static solvers (if enabled) on EMSCRIPTEN.
-rw-r--r--scripts/src/netlist.lua1
-rw-r--r--src/lib/netlist/build/makefile1
-rwxr-xr-xsrc/lib/netlist/buildVS/netlist.sln14
-rwxr-xr-xsrc/lib/netlist/buildVS/netlistlib.vcxproj53
-rwxr-xr-xsrc/lib/netlist/buildVS/netlistlib.vcxproj.filters3
-rwxr-xr-xsrc/lib/netlist/buildVS/nltool.vcxproj74
-rwxr-xr-xsrc/lib/netlist/buildVS/nlwav.vcxproj73
-rw-r--r--src/lib/netlist/core/core_device.h2
-rw-r--r--src/lib/netlist/plib/ppmf.cpp109
-rw-r--r--src/lib/netlist/plib/ppmf.h428
-rw-r--r--src/lib/netlist/plib/ptypes.h22
-rw-r--r--src/lib/netlist/plib/putil.h6
-rw-r--r--src/lib/netlist/solver/nld_ms_gcr.h2
-rw-r--r--[-rwxr-xr-x]src/lib/netlist/tests/test_pmfp.cpp5
-rw-r--r--src/lib/netlist/tests/test_pmfp_multibase.cpp92
15 files changed, 680 insertions, 205 deletions
diff --git a/scripts/src/netlist.lua b/scripts/src/netlist.lua
index b5d569c6279..9c70cacebd7 100644
--- a/scripts/src/netlist.lua
+++ b/scripts/src/netlist.lua
@@ -92,6 +92,7 @@ project "netlist"
MAME_DIR .. "src/lib/netlist/plib/pomp.h",
MAME_DIR .. "src/lib/netlist/plib/poptions.cpp",
MAME_DIR .. "src/lib/netlist/plib/poptions.h",
+ MAME_DIR .. "src/lib/netlist/plib/ppmf.cpp",
MAME_DIR .. "src/lib/netlist/plib/ppmf.h",
MAME_DIR .. "src/lib/netlist/plib/ppreprocessor.cpp",
MAME_DIR .. "src/lib/netlist/plib/ppreprocessor.h",
diff --git a/src/lib/netlist/build/makefile b/src/lib/netlist/build/makefile
index eb7f3b133fc..b44ed3e727e 100644
--- a/src/lib/netlist/build/makefile
+++ b/src/lib/netlist/build/makefile
@@ -180,6 +180,7 @@ PSOURCES := \
$(PSRC)/pfmtlog.cpp \
$(PSRC)/pmain.cpp \
$(PSRC)/poptions.cpp \
+ $(PSRC)/ppmf.cpp \
$(PSRC)/ppreprocessor.cpp \
$(PSRC)/ptokenizer.cpp \
$(PSRC)/putil.cpp \
diff --git a/src/lib/netlist/buildVS/netlist.sln b/src/lib/netlist/buildVS/netlist.sln
index 433d034cf6f..ff0207d81a4 100755
--- a/src/lib/netlist/buildVS/netlist.sln
+++ b/src/lib/netlist/buildVS/netlist.sln
@@ -11,12 +11,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nlwav", "nlwav.vcxproj", "{
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ CLRelease|x64 = CLRelease|x64
+ CLRelease|x86 = CLRelease|x86
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A374399B-B87F-4E0F-9525-6C099600705F}.CLRelease|x64.ActiveCfg = CLRelease|x64
+ {A374399B-B87F-4E0F-9525-6C099600705F}.CLRelease|x64.Build.0 = CLRelease|x64
+ {A374399B-B87F-4E0F-9525-6C099600705F}.CLRelease|x86.ActiveCfg = CLRelease|Win32
+ {A374399B-B87F-4E0F-9525-6C099600705F}.CLRelease|x86.Build.0 = CLRelease|Win32
{A374399B-B87F-4E0F-9525-6C099600705F}.Debug|x64.ActiveCfg = Debug|x64
{A374399B-B87F-4E0F-9525-6C099600705F}.Debug|x64.Build.0 = Debug|x64
{A374399B-B87F-4E0F-9525-6C099600705F}.Debug|x86.ActiveCfg = Debug|Win32
@@ -25,6 +31,10 @@ Global
{A374399B-B87F-4E0F-9525-6C099600705F}.Release|x64.Build.0 = Release|x64
{A374399B-B87F-4E0F-9525-6C099600705F}.Release|x86.ActiveCfg = Release|Win32
{A374399B-B87F-4E0F-9525-6C099600705F}.Release|x86.Build.0 = Release|Win32
+ {9204EC28-A29B-4A36-9E47-2C46041D67D3}.CLRelease|x64.ActiveCfg = CLRelease|x64
+ {9204EC28-A29B-4A36-9E47-2C46041D67D3}.CLRelease|x64.Build.0 = CLRelease|x64
+ {9204EC28-A29B-4A36-9E47-2C46041D67D3}.CLRelease|x86.ActiveCfg = CLRelease|Win32
+ {9204EC28-A29B-4A36-9E47-2C46041D67D3}.CLRelease|x86.Build.0 = CLRelease|Win32
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Debug|x64.ActiveCfg = Debug|x64
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Debug|x64.Build.0 = Debug|x64
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Debug|x86.ActiveCfg = Debug|Win32
@@ -33,6 +43,10 @@ Global
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Release|x64.Build.0 = Release|x64
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Release|x86.ActiveCfg = Release|Win32
{9204EC28-A29B-4A36-9E47-2C46041D67D3}.Release|x86.Build.0 = Release|Win32
+ {48D0ADAF-62EC-472E-A51B-8D837280649D}.CLRelease|x64.ActiveCfg = CLRelease|x64
+ {48D0ADAF-62EC-472E-A51B-8D837280649D}.CLRelease|x64.Build.0 = CLRelease|x64
+ {48D0ADAF-62EC-472E-A51B-8D837280649D}.CLRelease|x86.ActiveCfg = CLRelease|Win32
+ {48D0ADAF-62EC-472E-A51B-8D837280649D}.CLRelease|x86.Build.0 = CLRelease|Win32
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Debug|x64.ActiveCfg = Debug|x64
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Debug|x64.Build.0 = Debug|x64
{48D0ADAF-62EC-472E-A51B-8D837280649D}.Debug|x86.ActiveCfg = Debug|Win32
diff --git a/src/lib/netlist/buildVS/netlistlib.vcxproj b/src/lib/netlist/buildVS/netlistlib.vcxproj
index 588502552b0..47338e4c6c6 100755
--- a/src/lib/netlist/buildVS/netlistlib.vcxproj
+++ b/src/lib/netlist/buildVS/netlistlib.vcxproj
@@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="CLRelease|Win32">
+ <Configuration>CLRelease</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="CLRelease|x64">
+ <Configuration>CLRelease</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
@@ -34,6 +42,11 @@
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
@@ -44,6 +57,11 @@
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'" Label="Configuration">
+ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>ClangCL</PlatformToolset>
+ </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@@ -55,12 +73,18 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'" 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|Win32'">
<LinkIncremental>true</LinkIncremental>
@@ -68,6 +92,9 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
@@ -98,6 +125,22 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ <AdditionalIncludeDirectories>..\..\</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <TargetMachine>MachineX86</TargetMachine>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Windows</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ </Link>
+ </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>$(SolutionDir)..;$(SolutionDir)..\..</AdditionalIncludeDirectories>
@@ -107,6 +150,15 @@
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..;$(SolutionDir)..\..</AdditionalIncludeDirectories>
+ <Optimization>Full</Optimization>
+ <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
+ <AdditionalOptions>/bigobj</AdditionalOptions>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<LanguageStandard>stdcpp17</LanguageStandard>
@@ -204,6 +256,7 @@
<ClCompile Include="..\plib\pfunction.cpp" />
<ClCompile Include="..\plib\pmain.cpp" />
<ClCompile Include="..\plib\poptions.cpp" />
+ <ClCompile Include="..\plib\ppmf.cpp" />
<ClCompile Include="..\plib\ppreprocessor.cpp" />
<ClCompile Include="..\plib\pstring.cpp" />
<ClCompile Include="..\plib\ptokenizer.cpp" />
diff --git a/src/lib/netlist/buildVS/netlistlib.vcxproj.filters b/src/lib/netlist/buildVS/netlistlib.vcxproj.filters
index 68df009f9ec..2b7549429b1 100755
--- a/src/lib/netlist/buildVS/netlistlib.vcxproj.filters
+++ b/src/lib/netlist/buildVS/netlistlib.vcxproj.filters
@@ -309,6 +309,9 @@
<ClCompile Include="..\macro\modules\nlmod_rtest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\plib\ppmf.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\nl_errstr.h">
diff --git a/src/lib/netlist/buildVS/nltool.vcxproj b/src/lib/netlist/buildVS/nltool.vcxproj
index ab4233430ba..508833656e0 100755
--- a/src/lib/netlist/buildVS/nltool.vcxproj
+++ b/src/lib/netlist/buildVS/nltool.vcxproj
@@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="CLRelease|Win32">
+ <Configuration>CLRelease</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="CLRelease|x64">
+ <Configuration>CLRelease</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
@@ -38,6 +46,13 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
@@ -51,6 +66,13 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>ClangCL</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@@ -62,12 +84,18 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'" 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|Win32'">
<LinkIncremental>true</LinkIncremental>
@@ -78,10 +106,17 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<IncludePath>$(ProjectDir)\..\..;$(IncludePath)</IncludePath>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <IncludePath>$(ProjectDir)\..\..;$(IncludePath)</IncludePath>
+ </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
@@ -127,6 +162,24 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>..\..\</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
@@ -146,10 +199,31 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\;$(SolutionDir)..\</AdditionalIncludeDirectories>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\prg\nltool.cpp">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\;$(SolutionDir)..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'">$(SolutionDir)..\;$(SolutionDir)..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj</AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'">/bigobj</AdditionalOptions>
</ClCompile>
<ClCompile Include="..\tests\test_pfunction.cpp" />
<ClCompile Include="..\tests\test_pmfp.cpp" />
diff --git a/src/lib/netlist/buildVS/nlwav.vcxproj b/src/lib/netlist/buildVS/nlwav.vcxproj
index 7471dc0dc1e..239fcf7ba5c 100755
--- a/src/lib/netlist/buildVS/nlwav.vcxproj
+++ b/src/lib/netlist/buildVS/nlwav.vcxproj
@@ -1,6 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="CLRelease|Win32">
+ <Configuration>CLRelease</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="CLRelease|x64">
+ <Configuration>CLRelease</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
@@ -47,6 +55,13 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v142</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
@@ -60,6 +75,13 @@
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>ClangCL</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@@ -71,16 +93,25 @@
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'" 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)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
@@ -90,6 +121,9 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
@@ -111,6 +145,27 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|x64'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>
+ </SDLCheck>
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\;$(SolutionDir)..\</AdditionalIncludeDirectories>
+ <LanguageStandard>stdcpp17</LanguageStandard>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
@@ -158,6 +213,24 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='CLRelease|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>
+ </PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <SDLCheck>true</SDLCheck>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <ConformanceMode>true</ConformanceMode>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ </Link>
+ </ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
diff --git a/src/lib/netlist/core/core_device.h b/src/lib/netlist/core/core_device.h
index b9d09e14aca..5b402ab102a 100644
--- a/src/lib/netlist/core/core_device.h
+++ b/src/lib/netlist/core/core_device.h
@@ -33,7 +33,7 @@ namespace netlist
{
gsl_Expects(m_active_outputs >= 0);
- if (m_activate && m_hint_deactivate)
+ if (!m_activate.isnull() && m_hint_deactivate)
{
if (++m_active_outputs == 1)
{
diff --git a/src/lib/netlist/plib/ppmf.cpp b/src/lib/netlist/plib/ppmf.cpp
new file mode 100644
index 00000000000..8100b94ade0
--- /dev/null
+++ b/src/lib/netlist/plib/ppmf.cpp
@@ -0,0 +1,109 @@
+// license:BSD-3-Clause
+// copyright-holders:Couriersud
+
+#include "ppmf.h"
+
+#if PPMF_USE_MAME_DELEGATES
+#include "../../util/delegate.cpp"
+#else
+
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpmf-conversions"
+#pragma GCC diagnostic ignored "-Wpedantic"
+#endif
+
+namespace plib {
+
+ void mfp_raw<PPMF_TYPE_INTERNAL_ITANIUM>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const
+ {
+ // apply the "this" delta to the object first
+ // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult,cppcoreguidelines-pro-type-reinterpret-cast)
+ auto *o_p_delta = reinterpret_cast<mfp_generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
+
+ // if the low bit of the vtable index is clear, then it is just a raw function pointer
+ if ((m_function & 1) == 0)
+ {
+ // NOLINTNEXTLINE(performance-no-int-to-ptr,cppcoreguidelines-pro-type-reinterpret-cast)
+ func = reinterpret_cast<generic_function>(m_function);
+ }
+ else
+ {
+ // otherwise, it is the byte index into the vtable where the actual function lives
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ std::uint8_t *vtable_base = *reinterpret_cast<std::uint8_t **>(o_p_delta);
+ if (compile_info::abi_vtable_function_descriptors::value)
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ func = reinterpret_cast<generic_function>(uintptr_t(vtable_base + m_function - 1));
+ else
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ func = *reinterpret_cast<generic_function *>(vtable_base + m_function - 1);
+ }
+ object = o_p_delta;
+ }
+
+ void mfp_raw<PPMF_TYPE_INTERNAL_ARM>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ object = reinterpret_cast<mfp_generic_class *>(reinterpret_cast<std::uint8_t *>(object) + (m_this_delta >> 1));
+ if ((m_this_delta & 1) == 0)
+ {
+ // NOLINTNEXTLINE(performance-no-int-to-ptr,cppcoreguidelines-pro-type-reinterpret-cast)
+ func = reinterpret_cast<generic_function>(m_function);
+ }
+ else
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ std::uint8_t *vtable_base = *reinterpret_cast<std::uint8_t **>(object) + m_function;
+ if (compile_info::abi_vtable_function_descriptors::value)
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ func = reinterpret_cast<generic_function>(uintptr_t(vtable_base));
+ else
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ func = *reinterpret_cast<generic_function *>(vtable_base);
+ }
+ }
+
+ struct unknown_base_equiv_novtdisp { mfp_raw<PPMF_TYPE_INTERNAL_MSC>::generic_function fptr; int thisdisp, vptrdisp; };
+
+ void mfp_raw<PPMF_TYPE_INTERNAL_MSC>::convert_to_generic(generic_function &func, mfp_generic_class *&object) const
+ {
+ //printf("%lx, %lx, %lx, %lx %lx\n", m_function, m_this_delta, m_vptr_offs, m_vt_index, m_size);
+
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto *byteptr = reinterpret_cast<std::uint8_t *>(object);
+
+ // test for pointer to member function cast across virtual inheritance relationship
+ //if ((sizeof(unknown_base_equiv) == m_size) && m_vt_index)
+ if ((sizeof(unknown_base_equiv) == m_size) || (sizeof(unknown_base_equiv_novtdisp) == m_size))
+ {
+ // add index from "this" pointer to location of vptr. This actually is an index,
+ // it needs to be multiplied by sizeof(void *)
+ byteptr += (m_vptr_index * static_cast<ptrdiff_t>(sizeof(void *)));
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ std::uint8_t const *const vptr = *reinterpret_cast<std::uint8_t const *const *>(byteptr);
+ // and add offset to virtual base from vtable
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ if (sizeof(unknown_base_equiv) == m_size)
+ byteptr += *reinterpret_cast<int const *>(vptr + m_vt_index);
+ }
+
+ // add "this" pointer displacement if present in the pointer to member function
+ if (sizeof(single_base_equiv) < m_size)
+ byteptr += m_this_delta;
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ object = reinterpret_cast<mfp_generic_class *>(byteptr);
+
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,performance-no-int-to-ptr)
+ auto const *funcx = reinterpret_cast<std::uint8_t const *>(m_function);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,performance-no-int-to-ptr)
+ func = reinterpret_cast<generic_function>(std::uintptr_t(funcx));
+ }
+
+} // namespace plib
+
+#if defined(__GNUC__) && !defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+
+#endif
diff --git a/src/lib/netlist/plib/ppmf.h b/src/lib/netlist/plib/ppmf.h
index 982ef573e70..31818f9f12c 100644
--- a/src/lib/netlist/plib/ppmf.h
+++ b/src/lib/netlist/plib/ppmf.h
@@ -28,6 +28,51 @@
///
///
+/// \brief Enable experimental code on Visual Studio builds and VS clang llvm builds
+///
+/// This enables experimental code which uses optimized builds the
+/// PPMF_TYPE_INTERNAL_MSC path also for complex (struct/union) return types.
+/// This currently depends on whether the code can adequately determine on
+/// x64 builds if the return type is returned through registers or passed as a
+/// second argument as a pointer to the member function.
+///
+/// The experimental code uses a temporary storage for the return value. This a
+/// copy overhead for causes for large sized return types a copy overhead.
+/// It would be easier if we would be able to obtain the RDX register on entry
+/// to the call. On MSVC this seems not to be possible since on x64 inline
+/// assembly is not supported. Even with clang-cl inline assembly this was not
+/// successful when optimized code was compiled. Therefore we have to live with
+/// the limitations.
+///
+/// This code path is disabled by default currently.
+///
+#define PPMF_EXPERIMENTAL 0
+
+/// brief Enable using MAME delegates as a replacement for ppmf.
+///
+/// This define enables the use of MAME delegates (src/lib/util/delegate.h
+/// as a replacement to ppmf. Enable this setting if you want to use the nltool
+/// test suite (nltool -c tests) to produce comparisons to ppmf.
+///
+#define PPMF_USE_MAME_DELEGATES 0
+
+#if PPMF_USE_MAME_DELEGATES
+
+#include "../../util/delegate.h"
+
+namespace plib {
+ template<typename Signature>
+ class pmfp : public delegate<Signature>
+ {
+ public:
+ using basetype = delegate<Signature>;
+ using basetype::basetype;
+ using basetype::object;
+ explicit operator bool() const { return !this->isnull(); }
+ };
+}
+#else
+
#include "pconfig.h"
#include "ptypes.h"
@@ -48,12 +93,6 @@
#define PPMF_TYPE_INTERNAL_ARM 3
#define PPMF_TYPE_INTERNAL_MSC 4
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wpmf-conversions"
-#pragma GCC diagnostic ignored "-Wpedantic"
-#endif
-
#ifndef PPMF_FORCE_TYPE
#define PPMF_FORCE_TYPE -1
#endif
@@ -69,11 +108,11 @@ namespace plib {
&& ci::os() == ci_os::WINDOWS) ? PPMF_TYPE_PMF :
(ci::mingw() && !ci::m64() && ci::version() >= 407) ? PPMF_TYPE_PMF :
(ci::mingw() && !ci::m64()) ? PPMF_TYPE_PMF : // Dropped support for mingw32 < 407 PPMF_TYPE_INTERNAL_ITANIUM :
+ (ci::env() == ci_env::MSVC && ci::m64()) ? PPMF_TYPE_INTERNAL_MSC :
((ci::type() == ci_compiler::CLANG || ci::type() == ci_compiler::GCC)
&& (ci::arch() == ci_arch::MIPS
|| ci::arch() == ci_arch::ARM
|| ci::os() == ci_os::EMSCRIPTEN)) ? PPMF_TYPE_INTERNAL_ARM :
- (ci::type() == ci_compiler::MSC && ci::m64()) ? PPMF_TYPE_INTERNAL_MSC :
(ci::type() == ci_compiler::CLANG || ci::type() == ci_compiler::GCC) ? PPMF_TYPE_INTERNAL_ITANIUM :
PPMF_TYPE_PMF
};
@@ -93,6 +132,7 @@ namespace plib {
class mfp_generic_class;
+
///
/// \brief Used to derive a pointer to a member function.
///
@@ -109,44 +149,17 @@ namespace plib {
using generic_function = void (*)();
template<typename MemberFunctionType>
- mfp_raw(MemberFunctionType mftp)
- : m_function(0), m_this_delta(0)
- {
- static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch");
- *reinterpret_cast<MemberFunctionType *>(this) = mftp; // NOLINT
- // NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
- }
+ mfp_raw(MemberFunctionType mftp);
- //private:
// extract the generic function and adjust the object pointer
- void convert_to_generic(generic_function &func, mfp_generic_class *&object) const
- {
- // apply the "this" delta to the object first
- // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult,cppcoreguidelines-pro-type-reinterpret-cast)
- auto *o_p_delta = reinterpret_cast<mfp_generic_class *>(reinterpret_cast<std::uint8_t *>(object) + m_this_delta);
-
- // if the low bit of the vtable index is clear, then it is just a raw function pointer
- if ((m_function & 1) == 0)
- {
- // NOLINTNEXTLINE(performance-no-int-to-ptr,cppcoreguidelines-pro-type-reinterpret-cast)
- func = reinterpret_cast<generic_function>(m_function);
- }
- else
- {
- // otherwise, it is the byte index into the vtable where the actual function lives
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- std::uint8_t *vtable_base = *reinterpret_cast<std::uint8_t **>(o_p_delta);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- func = *reinterpret_cast<generic_function *>(vtable_base + m_function - 1);
- }
- object = o_p_delta;
- }
+ void convert_to_generic(generic_function &func, mfp_generic_class *&object) const;
// actual state
- uintptr_t m_function; // first item can be one of two things:
- // if even, it's a pointer to the function
- // if odd, it's the byte offset into the vtable
- ptrdiff_t m_this_delta; // delta to apply to the 'this' pointer
+ uintptr_t m_function; // first item can be one of two things:
+ // if even, it's a pointer to the function
+ // if odd, it's the byte offset into the vtable
+ // or a byte offset into the function descriptors on IA64
+ ptrdiff_t m_this_delta; // delta to apply to the 'this' pointer
};
template <>
@@ -157,42 +170,16 @@ namespace plib {
using generic_function = void (*)();
template<typename MemberFunctionType>
- mfp_raw(MemberFunctionType mftp)
- : m_function(0), m_this_delta(0)
- {
- static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch");
- *reinterpret_cast<MemberFunctionType *>(this) = mftp; // NOLINT
- }
+ mfp_raw(MemberFunctionType mftp);
- //private:
// extract the generic function and adjust the object pointer
- void convert_to_generic(generic_function &func, mfp_generic_class *&object) const
- {
- if ((m_this_delta & 1) == 0)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- object = reinterpret_cast<mfp_generic_class *>(reinterpret_cast<std::uint8_t *>(object) + (m_this_delta >> 1));
- // NOLINTNEXTLINE(performance-no-int-to-ptr,cppcoreguidelines-pro-type-reinterpret-cast)
- func = reinterpret_cast<generic_function>(m_function);
- }
- else
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- object = reinterpret_cast<mfp_generic_class *>(reinterpret_cast<std::uint8_t *>(object));
-
- // otherwise, it is the byte index into the vtable where the actual function lives
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- std::uint8_t *vtable_base = *reinterpret_cast<std::uint8_t **>(object);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- func = *reinterpret_cast<generic_function *>(vtable_base + m_function + m_this_delta - 1);
- }
- }
+ void convert_to_generic(generic_function &func, mfp_generic_class *&object) const;
// actual state
- uintptr_t m_function; // first item can be one of two things:
- // if even, it's a pointer to the function
- // if odd, it's the byte offset into the vtable
- ptrdiff_t m_this_delta; // delta to apply to the 'this' pointer
+ uintptr_t m_function; // first item can pointer to the function or a byte offset into the vtable
+ ptrdiff_t m_this_delta; // delta to apply to the 'this' pointer after right shifting by one bit
+ // m_function is the byte offset into the vtable
+ // On IA64 it may also be a byte offset into the function descriptors
};
template <>
@@ -205,55 +192,28 @@ namespace plib {
struct single_base_equiv { generic_function fptr; };
template<typename MemberFunctionType>
- mfp_raw(MemberFunctionType mftp)
- : m_function(0), m_this_delta(0), m_vptr_offs(0), m_vt_index(0), m_size(0)
- {
- static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch");
- *reinterpret_cast<MemberFunctionType *>(this) = mftp; // NOLINT
- m_size = sizeof(mftp); //NOLINT
- }
+ mfp_raw(MemberFunctionType mftp);
- //private:
// extract the generic function and adjust the object pointer
- void convert_to_generic(generic_function &func, mfp_generic_class *&object) const
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto *byteptr = reinterpret_cast<std::uint8_t *>(object);
-
- // test for pointer to member function cast across virtual inheritance relationship
- if ((sizeof(unknown_base_equiv) == m_size) && m_vt_index)
- {
- // add offset from "this" pointer to location of vptr, and add offset to virtual base from vtable
- byteptr += m_vptr_offs;
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- std::uint8_t const *const vptr = *reinterpret_cast<std::uint8_t const *const *>(byteptr);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- byteptr += *reinterpret_cast<int const *>(vptr + m_vt_index);
- }
-
- // add "this" pointer displacement if present in the pointer to member function
- if (sizeof(single_base_equiv) < m_size)
- byteptr += m_this_delta;
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- object = reinterpret_cast<mfp_generic_class *>(byteptr);
-
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,performance-no-int-to-ptr)
- auto const *funcx = reinterpret_cast<std::uint8_t const *>(m_function);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,performance-no-int-to-ptr)
- func = reinterpret_cast<generic_function>(std::uintptr_t(funcx));
- }
+ void convert_to_generic(generic_function &func, mfp_generic_class *&object) const;
// actual state
- uintptr_t m_function; // first item can be one of two things:
- // if even, it's a pointer to the function
- // if odd, it's the byte offset into the vtable
+ uintptr_t m_function; // pointer to the function
int m_this_delta; // delta to apply to the 'this' pointer
- int m_vptr_offs; // only used for visual studio x64
- int m_vt_index;
+ int m_vptr_index; // index into the vptr table.
+ int m_vt_index; // offset to be applied after vptr table lookup.
unsigned m_size;
};
+ template <typename R>
+ using pmf_is_register_return_type = std::integral_constant<bool,
+ std::is_void_v<R> ||
+ std::is_scalar_v<R> ||
+ std::is_reference_v<R> ||
+ std::is_same_v<std::remove_cv_t<R>, compile_info::int128_type> ||
+ std::is_same_v<std::remove_cv_t<R>, compile_info::uint128_type> >;
+
template<int PMFINTERNAL, typename R, typename... Targs>
struct mfp_helper
{
@@ -267,38 +227,36 @@ namespace plib {
using raw_type = mfp_raw<PMFINTERNAL>;
using generic_function_storage = typename raw_type::generic_function;
- mfp_helper()
- : m_obj(nullptr)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto *s = reinterpret_cast<std::uint8_t *>(&m_resolved);
- std::fill(s, s + sizeof(m_resolved), 0);
- }
+ mfp_helper();
template<typename O, typename F>
- void bind(O *object, F *mftp)
- {
- typename traits::template specific_member_function<O> pFunc;
- static_assert(sizeof(pFunc) >= sizeof(F), "size error");
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- //*reinterpret_cast<F *>(&pFunc) = *mftp;
- reinterpret_copy(*mftp, pFunc);
- raw_type mfpo(pFunc);
- generic_function_storage rfunc(nullptr);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto *robject = reinterpret_cast<mfp_generic_class *>(object);
- mfpo.convert_to_generic(rfunc, robject);
- reinterpret_copy(rfunc, this->m_resolved);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- m_obj = reinterpret_cast<mfp_generic_class *>(robject);
- }
+ void bind(O *object, F *mftp);
R call(Targs&&... args) const noexcept(true)
{
+#if defined(_MSC_VER) && (PPMF_EXPERIMENTAL)
+ if constexpr (pmf_is_register_return_type<R>::value)
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ const auto* func = reinterpret_cast<const generic_member_abi_function*>(&m_resolved);
+ return (*func)(m_obj, std::forward<Targs>(args)...);
+ }
+ else
+ {
+ using generic_member_abi_function_alt = void (*)(mfp_generic_class *,void *, Targs...);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ const auto* func = reinterpret_cast<const generic_member_abi_function_alt*>(&m_resolved);
+ std::uint8_t temp[sizeof(typename std::conditional<std::is_void_v<R>, void *, R>::type)];
+ (*func)(m_obj, &temp[0], std::forward<Targs>(args)...);
+ return *reinterpret_cast<R *>(&temp);
+ }
+#else
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- const auto* func = reinterpret_cast<const generic_member_abi_function *>(&m_resolved);
+ const auto* func = reinterpret_cast<const generic_member_abi_function*>(&m_resolved);
return (*func)(m_obj, std::forward<Targs>(args)...);
+#endif
}
+
generic_function_storage m_resolved;
mfp_generic_class *m_obj;
};
@@ -313,23 +271,10 @@ namespace plib {
template <class C>
using member_abi_function = typename traits::template specific_member_function<C>;
- mfp_helper()
- : m_obj(nullptr)
- , m_stub(nullptr)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto *s = reinterpret_cast<std::uint8_t *>(&m_resolved);
- std::fill(s, s + sizeof(m_resolved), 0);
- }
+ mfp_helper();
template<typename O, typename F>
- void bind(O *object, F *mftp)
- {
- reinterpret_copy(*mftp, this->m_resolved);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- m_obj = reinterpret_cast<mfp_generic_class *>(object);
- m_stub = &stub<O>;
- }
+ void bind(O *object, F *mftp);
R call(Targs&&... args) const noexcept(true)
{
@@ -344,14 +289,7 @@ namespace plib {
private:
template<typename O>
- static R stub(const generic_member_function *funci, mfp_generic_class *obji, Targs&&... args) noexcept(true)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto *obj = reinterpret_cast<O *>(obji);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto *func = reinterpret_cast<const member_abi_function<O> *>(funci);
- return (obj->*(*func))(std::forward<Targs>(args)...);
- }
+ static R stub(const generic_member_function* funci, mfp_generic_class* obji, Targs&&... args) noexcept(true);
};
#if NVCCBUILD == 0
@@ -364,23 +302,10 @@ namespace plib {
template <class C>
using member_abi_function = typename traits::template member_static_ptr<C>;
- mfp_helper()
- : m_obj(nullptr)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto *s = reinterpret_cast<std::uint8_t *>(&m_resolved);
- std::fill(s, s + sizeof(m_resolved), 0);
- }
+ mfp_helper();
template<typename O, typename F>
- void bind(O *object, F *mftp)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- member_abi_function<O> t = reinterpret_cast<member_abi_function<O>>(object->*(*mftp));
- reinterpret_copy(t, this->m_resolved);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- m_obj = reinterpret_cast<mfp_generic_class *>(object);
- }
+ void bind(O *object, F *mftp);
R call(Targs&&... args) const noexcept(true)
{
@@ -396,9 +321,8 @@ namespace plib {
template <int PMFINTERNAL, typename R, typename... Targs>
using pmfp_helper_select = std::conditional<
- std::is_void_v<R> ||
- std::is_scalar_v<R> ||
- std::is_reference_v<R> || PMFINTERNAL != PPMF_TYPE_INTERNAL_MSC,
+ pmf_is_register_return_type<R>::value
+ || PMFINTERNAL != PPMF_TYPE_INTERNAL_MSC || (PPMF_EXPERIMENTAL),
mfp_helper<PMFINTERNAL, R, Targs...>, mfp_helper<PPMF_TYPE_PMF, R, Targs...>>;
template<int PMFINTERNAL, typename SIGNATURE> class pmfp_base;
@@ -481,13 +405,7 @@ namespace plib {
using static_creator = return_type (*)(const generic_member_function *, mfp_generic_class *);
template<typename O>
- late_pmfp(typename traits::template specific_member_function<O> mftp)
- : m_creator(creator<O>)
- {
- static_assert(sizeof(m_raw) >= sizeof(typename traits::template specific_member_function<O>), "size issue");
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- *reinterpret_cast<typename traits::template specific_member_function<O> *>(&m_raw) = mftp;
- }
+ late_pmfp(typename traits::template specific_member_function<O> mftp);
template<typename O>
return_type operator()(O *object) const
@@ -499,23 +417,141 @@ namespace plib {
private:
template <typename O>
- static return_type creator(const generic_member_function *raw, mfp_generic_class *obj)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto p = reinterpret_cast<const typename traits::template specific_member_function<O> *>(raw);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- auto o = reinterpret_cast<O *>(obj);
- return return_type(*p, o);
- }
+ static return_type creator(const generic_member_function *raw, mfp_generic_class *obj);
generic_member_function m_raw;
static_creator m_creator;
};
-} // namespace plib
+ template<typename MemberFunctionType>
+ mfp_raw<PPMF_TYPE_INTERNAL_ITANIUM>::mfp_raw(MemberFunctionType mftp)
+ : m_function(0), m_this_delta(0)
+ {
+ static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch");
+ *reinterpret_cast<MemberFunctionType *>(this) = mftp; // NOLINT
+ // NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
+ }
+
+ template<typename MemberFunctionType>
+ mfp_raw<PPMF_TYPE_INTERNAL_ARM>::mfp_raw(MemberFunctionType mftp)
+ : m_function(0), m_this_delta(0)
+ {
+ static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch");
+ *reinterpret_cast<MemberFunctionType *>(this) = mftp; // NOLINT
+ }
+
+ template<typename MemberFunctionType>
+ mfp_raw<PPMF_TYPE_INTERNAL_MSC>::mfp_raw(MemberFunctionType mftp)
+ : m_function(0), m_this_delta(0), m_vptr_index(0), m_vt_index(0), m_size(0)
+ {
+ static_assert(sizeof(*this) >= sizeof(MemberFunctionType), "size mismatch");
+ *reinterpret_cast<MemberFunctionType *>(this) = mftp; // NOLINT
+ m_size = sizeof(mftp); //NOLINT
+ }
+
+ template<int PMFINTERNAL, typename R, typename... Targs>
+ mfp_helper<PMFINTERNAL, R, Targs...>::mfp_helper()
+ : m_obj(nullptr)
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto *s = reinterpret_cast<std::uint8_t *>(&m_resolved);
+ std::fill(s, s + sizeof(m_resolved), 0);
+ }
+
+ template<int PMFINTERNAL, typename R, typename... Targs>
+ template<typename O, typename F>
+ void mfp_helper<PMFINTERNAL, R, Targs...>::bind(O *object, F *mftp)
+ {
+ typename traits::template specific_member_function<O> pFunc;
+ static_assert(sizeof(pFunc) >= sizeof(F), "size error");
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ //*reinterpret_cast<F *>(&pFunc) = *mftp;
+ reinterpret_copy(*mftp, pFunc);
+ raw_type mfpo(pFunc);
+ generic_function_storage rfunc(nullptr);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto *robject = reinterpret_cast<mfp_generic_class *>(object);
+ mfpo.convert_to_generic(rfunc, robject);
+ reinterpret_copy(rfunc, this->m_resolved);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ m_obj = reinterpret_cast<mfp_generic_class *>(robject);
+ }
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
+ template<typename R, typename... Targs>
+ mfp_helper<PPMF_TYPE_PMF, R, Targs...>::mfp_helper()
+ : m_obj(nullptr)
+ , m_stub(nullptr)
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto *s = reinterpret_cast<std::uint8_t *>(&m_resolved);
+ std::fill(s, s + sizeof(m_resolved), 0);
+ }
+
+ template<typename R, typename... Targs>
+ template<typename O, typename F>
+ void mfp_helper<PPMF_TYPE_PMF, R, Targs...>::bind(O *object, F *mftp)
+ {
+ reinterpret_copy(*mftp, this->m_resolved);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ m_obj = reinterpret_cast<mfp_generic_class *>(object);
+ m_stub = &stub<O>;
+ }
+
+ template<typename R, typename... Targs>
+ template<typename O>
+ R mfp_helper<PPMF_TYPE_PMF, R, Targs...>::stub(const generic_member_function* funci, mfp_generic_class* obji, Targs&&... args) noexcept(true)
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto* obj = reinterpret_cast<O*>(obji);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto* func = reinterpret_cast<const member_abi_function<O> *>(funci);
+ return (obj->*(*func))(std::forward<Targs>(args)...);
+ }
+
+#if NVCCBUILD == 0
+ template<typename R, typename... Targs>
+ mfp_helper<PPMF_TYPE_GNUC_PMF_CONV, R, Targs...>::mfp_helper()
+ : m_obj(nullptr)
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto *s = reinterpret_cast<std::uint8_t *>(&m_resolved);
+ std::fill(s, s + sizeof(m_resolved), 0);
+ }
+
+ template<typename R, typename... Targs>
+ template<typename O, typename F>
+ void mfp_helper<PPMF_TYPE_GNUC_PMF_CONV, R, Targs...>::bind(O *object, F *mftp)
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ member_abi_function<O> t = reinterpret_cast<member_abi_function<O>>(object->*(*mftp));
+ reinterpret_copy(t, this->m_resolved);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ m_obj = reinterpret_cast<mfp_generic_class *>(object);
+ }
#endif
+ template<typename T>
+ template<typename O>
+ late_pmfp<T>::late_pmfp(typename traits::template specific_member_function<O> mftp)
+ : m_creator(creator<O>)
+ {
+ static_assert(sizeof(m_raw) >= sizeof(typename traits::template specific_member_function<O>), "size issue");
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ *reinterpret_cast<typename traits::template specific_member_function<O> *>(&m_raw) = mftp;
+ }
+
+ template<typename T>
+ template<typename O>
+ typename late_pmfp<T>::return_type late_pmfp<T>::creator(const typename late_pmfp<T>::generic_member_function *raw, mfp_generic_class *obj)
+ {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto p = reinterpret_cast<const typename late_pmfp<T>::traits::template specific_member_function<O> *>(raw);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+ auto o = reinterpret_cast<O *>(obj);
+ return return_type(*p, o);
+ }
+
+} // namespace plib
+
+#endif
#endif // PPMF_H_
diff --git a/src/lib/netlist/plib/ptypes.h b/src/lib/netlist/plib/ptypes.h
index 2c5fe088a2b..f46eb0b65c1 100644
--- a/src/lib/netlist/plib/ptypes.h
+++ b/src/lib/netlist/plib/ptypes.h
@@ -105,6 +105,12 @@ namespace plib
IA64
};
+ enum class ci_env
+ {
+ DEFAULT,
+ MSVC
+ };
+
struct compile_info
{
#ifdef _WIN32
@@ -134,15 +140,15 @@ namespace plib
#if (NVCCBUILD > 0)
using type = std::integral_constant<ci_compiler, ci_compiler::NVCC>;
using version = std::integral_constant<int, NVCCBUILD>;
- #elif defined(_MSC_VER)
- using type = std::integral_constant<ci_compiler, ci_compiler::MSC>;
- using version = std::integral_constant<int, _MSC_VER>;
#elif defined(__clang__)
using type = std::integral_constant<ci_compiler, ci_compiler::CLANG>;
using version = std::integral_constant<int, (__clang_major__) * 100 + (__clang_minor__)>;
#elif defined(__GNUC__)
using type = std::integral_constant<ci_compiler, ci_compiler::GCC>;
using version = std::integral_constant<int, (__GNUC__) * 100 + (__GNUC_MINOR__)>;
+ #elif defined(_MSC_VER)
+ using type = std::integral_constant<ci_compiler, ci_compiler::MSC>;
+ using version = std::integral_constant<int, _MSC_VER>;
#else
using type = std::integral_constant<ci_compiler, ci_compiler::UNKNOWN>;
using version = std::integral_constant<int, 0>;
@@ -193,6 +199,16 @@ namespace plib
#else
using clang_apple_noexcept_issue = std::integral_constant<bool, false>;
#endif
+ #if defined(__ia64__)
+ using abi_vtable_function_descriptors = std::integral_constant<bool, true>;
+ #else
+ using abi_vtable_function_descriptors = std::integral_constant<bool, false>;
+ #endif
+ #if defined(_MSC_VER)
+ using env = std::integral_constant<ci_env, ci_env::MSVC>;
+ #else
+ using env = std::integral_constant<ci_env, ci_env::DEFAULT>;
+ #endif
};
} // namespace plib
diff --git a/src/lib/netlist/plib/putil.h b/src/lib/netlist/plib/putil.h
index 2aa263d22cf..e75dbbf8612 100644
--- a/src/lib/netlist/plib/putil.h
+++ b/src/lib/netlist/plib/putil.h
@@ -146,10 +146,10 @@ namespace plib
// simple hash
// ----------------------------------------------------------------------------------------
- template <typename T>
- std::size_t hash(const T *buf, std::size_t size)
+ template <typename V, typename T>
+ V hash(const T *buf, std::size_t size)
{
- std::size_t result = 5381; // NOLINT
+ V result = 5381; // NOLINT
for (const T* p = buf; p != buf + size; p++)
result = ((result << 5) + result ) ^ (result >> (32 - 5)) ^ narrow_cast<std::size_t>(*p); // NOLINT
return result;
diff --git a/src/lib/netlist/solver/nld_ms_gcr.h b/src/lib/netlist/solver/nld_ms_gcr.h
index 5d950793bea..e77550a188a 100644
--- a/src/lib/netlist/solver/nld_ms_gcr.h
+++ b/src/lib/netlist/solver/nld_ms_gcr.h
@@ -281,7 +281,7 @@ namespace netlist::solver
plib::putf8_fmt_writer w(&t);
generate_code(w);
//std::hash<typename std::remove_const<std::remove_reference<decltype(t.str())>::type>::type> h;
- return plib::pfmt("nl_gcr_{1:x}_{2}_{3}_{4}")(plib::hash( t.str().c_str(), t.str().size() ))(mat.nz_num)(str_fptype)(str_floattype);
+ return plib::pfmt("nl_gcr_{1:x}_{2}_{3}_{4}")(plib::hash<uint64_t>( t.str().c_str(), t.str().size() ))(mat.nz_num)(str_fptype)(str_floattype);
}
template <typename FT, int SIZE>
diff --git a/src/lib/netlist/tests/test_pmfp.cpp b/src/lib/netlist/tests/test_pmfp.cpp
index f8bdaa9c0ae..1f526806b6b 100755..100644
--- a/src/lib/netlist/tests/test_pmfp.cpp
+++ b/src/lib/netlist/tests/test_pmfp.cpp
@@ -37,6 +37,7 @@ protected:
PTEST_F(test_late_pmfp, late_pmfp)
{
+#if !PPMF_USE_MAME_DELEGATES
plib::late_pmfp<plib::pmfp<void (int &)>> late(&Ta::ap);
Ta a;
@@ -45,19 +46,21 @@ PTEST_F(test_late_pmfp, late_pmfp)
int r(0);
mfp(r);
PEXPECT_TRUE(r == 1);
+#endif
}
PTEST(test_compile, compile)
{
+#if !PPMF_USE_MAME_DELEGATES
plib::pmfp_base<PPMF_TYPE_PMF, void(int)> mfp_PPMF_TYPE_PMF;
plib::pmfp_base<PPMF_TYPE_INTERNAL_ITANIUM, void(int)> mfp_PPMF_TYPE_INTERNAL_ITANIUM;
plib::pmfp_base<PPMF_TYPE_INTERNAL_ARM, void(int)> mfp_PPMF_TYPE_INTERNAL_ARM;
plib::pmfp_base<PPMF_TYPE_INTERNAL_MSC, void(int)> mfp_PPMF_TYPE_INTERNAL_MSC;
-
PEXPECT_TRUE(mfp_PPMF_TYPE_PMF.isnull());
PEXPECT_TRUE(mfp_PPMF_TYPE_INTERNAL_ITANIUM.isnull());
PEXPECT_TRUE(mfp_PPMF_TYPE_INTERNAL_ARM.isnull());
PEXPECT_TRUE(mfp_PPMF_TYPE_INTERNAL_MSC.isnull());
+#endif
#if defined(__GNUC__) && !defined(__clang__) && (NVCCBUILD == 0)
plib::pmfp_base<PPMF_TYPE_GNUC_PMF_CONV, void(int)> mfp_PPMF_TYPE_GNUC_PMF_CONV;
diff --git a/src/lib/netlist/tests/test_pmfp_multibase.cpp b/src/lib/netlist/tests/test_pmfp_multibase.cpp
index 20a1fc9aba8..01aba2876e5 100644
--- a/src/lib/netlist/tests/test_pmfp_multibase.cpp
+++ b/src/lib/netlist/tests/test_pmfp_multibase.cpp
@@ -41,6 +41,37 @@ class pmfp_test_complex_return : public plib::testing::Test
protected:
using ret_t = std::pair<void *, int>;
+ template <std::size_t N>
+ class tstruct
+ {
+ public:
+ struct r1type
+ {
+ char m[N];
+ };
+
+ r1type f1(const char v)
+ {
+ r1type r;
+ for (std::size_t i=0; i<N; i++) r.m[i] = v;
+ return r;
+ }
+
+ template <typename T>
+ T ft(const T v)
+ {
+ return v;
+ }
+
+ template <typename T>
+ T run_ft(const T v)
+ {
+ using pf_t = plib::pmfp<T (const T)>;
+ pf_t pf(&tstruct::ft<T>, this);
+ return pf(v);
+ }
+ };
+
//using test_delegate1 = plib::pmfp<ret_t (int, int)>;
using test_delegate = plib::pmfp<ret_t ()>;
@@ -274,6 +305,66 @@ PTEST_F(pmfp_test_complex_return, multibase_test)
PEXPECT_EQ(f().second, 8);
f = make_forward_delegate(&forward::zp, &obj2);
PEXPECT_EQ(f().second, 9);
+ //PEXPECT_EQ(plib::ppmf_internal::value, PPMF_TYPE_PMF);
+
+ // test return size handling
+
+ tstruct<3> ts3;
+ using pfmp3_t = plib::pmfp<tstruct<3>::r1type(char)>;
+ pfmp3_t pf3(&tstruct<3>::f1, &ts3);
+ auto r3 = pf3(3);
+ PEXPECT_EQ(static_cast<int>(r3.m[2]), 3);
+ PEXPECT_EQ(sizeof(r3), 3u);
+
+ tstruct<5> ts5;
+ using pfmp5_t = plib::pmfp<tstruct<5>::r1type(char)>;
+ pfmp5_t pf5(&tstruct<5>::f1, &ts5);
+ auto r5 = pf5(5);
+ PEXPECT_EQ(static_cast<int>(r5.m[3]), 5);
+ PEXPECT_EQ(sizeof(r5), 5u);
+
+ tstruct<8> ts8;
+ using pfmp8_t = plib::pmfp<tstruct<8>::r1type(char)>;
+ pfmp8_t pf8(&tstruct<8>::f1, &ts8);
+ auto r8 = pf8(8);
+ PEXPECT_EQ(static_cast<int>(r8.m[3]), 8);
+ PEXPECT_EQ(sizeof(r8), 8u);
+
+ tstruct<9> ts9;
+ using pfmp9_t = plib::pmfp<tstruct<9>::r1type (char)>;
+ pfmp9_t pf9(&tstruct<9>::f1, &ts9);
+ auto r9=pf9(9);
+ PEXPECT_EQ(static_cast<int>(r9.m[3]), 9);
+ PEXPECT_EQ(sizeof(r9), 9u);
+
+ tstruct<17> ts17;
+ using pfmp17_t = plib::pmfp<tstruct<17>::r1type(char)>;
+ pfmp17_t pf17(&tstruct<17>::f1, &ts17);
+ auto r17 = pf17(17);
+ PEXPECT_EQ(static_cast<int>(r17.m[3]), 17);
+ PEXPECT_EQ(sizeof(r17), 17u);
+
+#if !(defined(_MSC_VER) && !defined(__clang__))
+ if constexpr (plib::compile_info::has_int128::value)
+ {
+ PEXPECT_EQ(static_cast<int>(ts17.run_ft<INT128>(17)), 17); // FIXME: no operator << for INT128 yet
+ PEXPECT_EQ(sizeof(INT128), 16u);
+ }
+#endif
+ PEXPECT_EQ(ts17.run_ft<long double>(17), 17);
+ PEXPECT_EQ(ts17.run_ft<double>(17), 17);
+ PEXPECT_EQ(ts17.run_ft<int>(17), 17);
+ PEXPECT_EQ(ts17.run_ft<bool>(true), true);
+ PEXPECT_EQ(ts17.run_ft<std::size_t>(20), 20u);
+
+ struct tt1_t { int a; int b; };
+ tt1_t tt1 = { 8, 9 };
+ auto tt1r = ts17.run_ft<tt1_t>(tt1);
+ PEXPECT_EQ(tt1.a, tt1r.a);
+ PEXPECT_EQ(tt1.b, tt1r.b);
+
+ PEXPECT_EQ(sizeof(ret_t), 16u);
+
}
PTEST_F(pmfp_test_simple_return, multibase_test)
@@ -357,4 +448,5 @@ PTEST_F(pmfp_test_simple_return, multibase_test)
f = make_forward_delegate(&forward::zp, &obj2);
f(fr);
PEXPECT_EQ(fr.second, 9);
+ //PEXPECT_EQ(plib::ppmf_internal::value, PPMF_TYPE_INTERNAL_MSC);
}