mirror of https://github.com/PCSX2/pcsx2.git
wxgui branch: Maintenance merge against trunk, plus many cleanups and project-level changes.
* Moved the x86 emitter to /common, so that plugins can link against it if they wish. * Created a new "utility" class in /common which houses string utils, fast memcpy, common exception classes, and other handy dandies. * Removed old-style linux automake files from the pcsx2 dir since they were hopelessly out of date (and their multi-file-per-line format makes svn merging impossible >_<) git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1454 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
commit
da691894c3
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="3rdpartyDLL"
|
||||
OutputDirectory="$(SvnRootDir)\deps\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)""
|
||||
PreprocessorDefinitions="__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
StructMemberAlignment="5"
|
||||
RuntimeTypeInfo="false"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(SolutionDir)\bin\$(ProjectName).dll"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
ImportLibrary="$(OutDir)\$(ProjectName).lib"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="DefaultProjectRootDir"
|
||||
>
|
||||
<UserMacro
|
||||
Name="ProjectRootDir"
|
||||
Value="$(ProjectDir)"
|
||||
/>
|
||||
<UserMacro
|
||||
Name="SvnRootDir"
|
||||
Value="$(ProjectRootDir)\..\.."
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -24,13 +24,8 @@ AUTOMAKE_OPTIONS = foreign
|
|||
noinst_HEADERS=AAFilter.h cpu_detect.h FIRFilter.h RateTransposer.h TDStretch.h cpu_detect_x86_gcc.cpp
|
||||
noinst_LIBRARIES = libSoundTouch.a
|
||||
|
||||
if X86_64
|
||||
libSoundTouch_a_CXXFLAGS = -fPIC
|
||||
libSoundTouch_a_CFLAGS = -fPIC
|
||||
else
|
||||
libSoundTouch_a_CXXFLAGS = -msse -mmmx
|
||||
libSoundTouch_a_CFLAGS = -msse -mmmx
|
||||
endif
|
||||
|
||||
#lib_LTLIBRARIES=libSoundTouch.la
|
||||
# the mmx_gcc.cpp and cpu_detect_x86_gcc.cpp may need to be conditionally included here from things discovered in configure.ac
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
|
@ -38,9 +38,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
WarningLevel="3"
|
||||
/>
|
||||
<Tool
|
||||
|
@ -74,7 +71,7 @@
|
|||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Release.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
|
@ -95,12 +92,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -133,7 +125,7 @@
|
|||
<Configuration
|
||||
Name="Devel|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Devel.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
|
@ -154,12 +146,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
|
|
@ -11,33 +11,15 @@ AC_PROG_CXX
|
|||
AC_PROG_CC
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl Check for 64bit CPU
|
||||
AC_MSG_CHECKING(for a x86-64 CPU)
|
||||
dnl if test "$build_os" == "target_os"
|
||||
dnl then
|
||||
AC_TRY_RUN([
|
||||
int main()
|
||||
{
|
||||
int a = 0;
|
||||
int*pa = &a;
|
||||
asm(".intel_syntax\n"
|
||||
"mov %%rax, %0\n"
|
||||
"mov %%eax, [%%rax]\n"
|
||||
".att_syntax\n"
|
||||
: : "r"(pa) : "%rax");
|
||||
return 0;
|
||||
}
|
||||
],cpu64=yes,cpu64=no,)
|
||||
dnl else
|
||||
dnl cpu64=no
|
||||
dnl fi
|
||||
if test "x$cpu64" == xyes
|
||||
then
|
||||
AC_DEFINE(__x86_64__,1,[__x86_64__])
|
||||
fi
|
||||
AC_MSG_RESULT($cpu64)
|
||||
AM_CONDITIONAL(X86_64, test x$cpu64 = xyes)
|
||||
CFLAGS=
|
||||
CPPFLAGS=
|
||||
CXXFLAGS=
|
||||
CCASFLAGS=
|
||||
|
||||
CFLAGS+=" -m32 "
|
||||
CPPFLAGS+=" -m32 "
|
||||
CXXFLAGS+=" -m32 "
|
||||
CCASFLAGS+=" -m32 "
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([limits.h memory.h stdlib.h string.h])
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
|
@ -38,11 +38,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -75,7 +70,7 @@
|
|||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Release.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
|
@ -96,17 +91,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="true"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -139,7 +123,7 @@
|
|||
<Configuration
|
||||
Name="Devel|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Devel.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
|
@ -160,17 +144,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
|
|
@ -2,14 +2,19 @@
|
|||
-- Air's Notes on Using PThreads --
|
||||
-----------------------------------
|
||||
|
||||
We use pthreads as a static link because it allows for inlined calls of several methods,
|
||||
most notably the InterlockedExchange implementations. These would be DLL invocations
|
||||
otherwise, and would be roughly twice to three times the total overhead.
|
||||
The official name of the DLL is "w32pthreads.dll" -- I use the prefix to indicate with
|
||||
some vaugeness that the pthreads dll is a modified non-standard implementation (see below
|
||||
for details); just in case pthreads-win32 dlls in another universe were to be conflicting
|
||||
interests.
|
||||
|
||||
I created a subfolder for pthreads' publicall exposed header files, since "config.h" was
|
||||
I created a subfolder for pthreads' publically exposed header files, since "config.h" was
|
||||
rather brutal include file namespace pollution. >_<
|
||||
|
||||
Important: pthread_cond is an inherently flawed concept, and is quite incredibly slow
|
||||
on top of it. It's primarily meant for inter-process thread regulation, of which we
|
||||
do none. Therefore it has been excluded from the library builds. Don't use it!
|
||||
|
||||
I've also disabled rwlocks, since they use pthread_cond internally. Again, there should
|
||||
be little or no reason to have to use those within the context of a high performance app
|
||||
like Pcsx2.
|
||||
|
||||
|
|
|
@ -1077,6 +1077,7 @@ PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t *
|
|||
/*
|
||||
* Condition Variable Functions
|
||||
*/
|
||||
#ifdef PCSX2_ALLOW_COND
|
||||
PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond,
|
||||
const pthread_condattr_t * attr);
|
||||
|
||||
|
@ -1092,6 +1093,7 @@ PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond,
|
|||
PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond);
|
||||
|
||||
PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Scheduling
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="pthreads"
|
||||
Name="w32pthreads"
|
||||
ProjectGUID="{26511268-2902-4997-8421-ECD7055F9E28}"
|
||||
RootNamespace="pthreads"
|
||||
Keyword="Win32Proj"
|
||||
|
@ -18,8 +18,8 @@
|
|||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdpartyDLL.vsprops;..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
|
@ -39,15 +39,11 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)\include""
|
||||
PreprocessorDefinitions="PTW32_STATIC_LIB;__CLEANUP_SEH;WIN32;_DEBUG;_LIB"
|
||||
PreprocessorDefinitions="PTW32_BUILD;__CLEANUP_SEH;_DEBUG"
|
||||
ExceptionHandling="2"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
|
@ -60,11 +56,15 @@
|
|||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
|
@ -74,14 +74,18 @@
|
|||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdpartyDLL.vsprops;..\..\common\vsprops\CodeGen_Release.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
|
@ -102,23 +106,11 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
EnableFiberSafeOptimizations="true"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)\include""
|
||||
PreprocessorDefinitions="PTW32_STATIC_LIB;PTW32_BUILD_INLINED;__CLEANUP_SEH;WIN32;NDEBUG;_LIB"
|
||||
StringPooling="true"
|
||||
PreprocessorDefinitions="PTW32_BUILD;__CLEANUP_SEH;NDEBUG"
|
||||
ExceptionHandling="2"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="5"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="false"
|
||||
UsePrecompiledHeader="0"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
|
@ -131,11 +123,15 @@
|
|||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
|
@ -145,14 +141,17 @@
|
|||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Devel|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
ConfigurationType="2"
|
||||
InheritedPropertySheets="..\DefaultProjectRootDir.vsprops;..\3rdpartyDLL.vsprops;..\..\common\vsprops\CodeGen_Devel.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
|
@ -173,22 +172,11 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
EnableFiberSafeOptimizations="true"
|
||||
WholeProgramOptimization="false"
|
||||
AdditionalIncludeDirectories=""$(ProjectDir)";"$(ProjectDir)\include""
|
||||
PreprocessorDefinitions="PTW32_STATIC_LIB;PTW32_BUILD_INLINED;__CLEANUP_SEH;WIN32;NDEBUG;_LIB"
|
||||
StringPooling="true"
|
||||
PreprocessorDefinitions="PTW32_BUILD;__CLEANUP_SEH;NDEBUG"
|
||||
ExceptionHandling="2"
|
||||
RuntimeLibrary="0"
|
||||
StructMemberAlignment="5"
|
||||
BufferSecurityCheck="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="1"
|
||||
/>
|
||||
<Tool
|
||||
|
@ -201,11 +189,15 @@
|
|||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
|
@ -215,6 +207,9 @@
|
|||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
|
@ -439,6 +434,10 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dll.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\errno.c"
|
||||
>
|
||||
|
@ -754,6 +753,7 @@
|
|||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -764,6 +764,7 @@
|
|||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -774,6 +775,7 @@
|
|||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Devel|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="wxCommon"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions="WIN32;__WXMSW__;_LIB;wxUSE_UNICODE=1"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="ProjectRootDir"
|
||||
>
|
||||
<UserMacro
|
||||
Name="ProjectRootDir"
|
||||
Value="$(ProjectDir)\..\.."
|
||||
/>
|
||||
<UserMacro
|
||||
Name="SvnRootDir"
|
||||
Value="$(ProjectRootDir)\..\.."
|
||||
/>
|
||||
<UserMacro
|
||||
Name="SvnCommonDir"
|
||||
Value="$(SvnRootDir)\common"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -20,10 +20,8 @@
|
|||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\..\..\..\deps\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ProjectDir)\$(PlatformName)\$(ConfigurationName)\$(TargetName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
InheritedPropertySheets=".\ProjectRootDir.vsprops;..\..\..\3rdparty.vsprops;.\Common.vsprops;..\..\..\3rdpartyDLL.vsprops;..\..\..\..\common\vsprops\CodeGen_Release.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
|
@ -47,25 +45,12 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/EHsc "
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="2"
|
||||
FavorSizeOrSpeed="2"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib"
|
||||
PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_UNICODE=1;wxUSE_GUI=0;wxUSE_BASE=1;_CRT_SECURE_NO_WARNINGS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="false"
|
||||
PreprocessorDefinitions="wxUSE_GUI=0;wxUSE_BASE=1;NDEBUG"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="wx/wxprec.h"
|
||||
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\vc80.pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -79,8 +64,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/wxBase28.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
@ -102,10 +85,8 @@
|
|||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\..\..\..\deps\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ProjectDir)\$(PlatformName)\$(ConfigurationName)\$(TargetName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
InheritedPropertySheets=".\ProjectRootDir.vsprops;..\..\..\3rdparty.vsprops;.\Common.vsprops;..\..\..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
|
@ -128,18 +109,12 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/EHsc "
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib"
|
||||
PreprocessorDefinitions="WIN32;_LIB;_DEBUG;__WXMSW__;__WXDEBUG__;wxUSE_GUI=0;wxUSE_BASE=1;wxUSE_UNICODE=1;_CRT_SECURE_NO_WARNINGS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
PreprocessorDefinitions="_DEBUG;__WXDEBUG__;wxUSE_BASE=1;wxUSE_GUI=0"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="wx/wxprec.h"
|
||||
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -153,7 +128,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
@ -175,10 +149,8 @@
|
|||
</Configuration>
|
||||
<Configuration
|
||||
Name="Devel|Win32"
|
||||
OutputDirectory="..\..\..\..\deps\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ProjectDir)\$(PlatformName)\$(ConfigurationName)\$(TargetName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
InheritedPropertySheets=".\ProjectRootDir.vsprops;..\..\..\3rdparty.vsprops;.\Common.vsprops;..\..\..\..\common\vsprops\CodeGen_Devel.vsprops;..\..\..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
|
@ -207,16 +179,10 @@
|
|||
FavorSizeOrSpeed="2"
|
||||
WholeProgramOptimization="false"
|
||||
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib"
|
||||
PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_UNICODE=1;wxUSE_GUI=0;wxUSE_BASE=1;_CRT_SECURE_NO_WARNINGS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PreprocessorDefinitions="wxUSE_GUI=0;wxUSE_BASE=1;NDEBUG"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="wx/wxprec.h"
|
||||
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\vc80.pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
|
@ -232,8 +198,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile="$(OutDir)/wxBase28.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,10 +20,8 @@
|
|||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="..\..\..\..\deps\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ProjectDir)\$(PlatformName)\$(ConfigurationName)\$(TargetName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
InheritedPropertySheets=".\ProjectRootDir.vsprops;..\..\..\3rdparty.vsprops;.\Common.vsprops;..\..\..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
|
@ -46,18 +44,12 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/EHsc "
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png"
|
||||
PreprocessorDefinitions="WIN32;_LIB;_DEBUG;__WXMSW__;__WXDEBUG__;wxUSE_BASE=0;wxUSE_UNICODE=1;_CRT_SECURE_NO_WARNINGS"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
AdditionalIncludeDirectories=""$(ProjectRootDir)\include";"$(ProjectRootDir)\include\msvc";"$(SvnRootDir)\3rdparty\zlib";"$(ProjectRootDir)\src\png""
|
||||
PreprocessorDefinitions="_DEBUG;__WXDEBUG__;wxUSE_BASE=0;wxUSE_GUI=1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="wx/wxprec.h"
|
||||
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -71,7 +63,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
@ -93,10 +84,8 @@
|
|||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="..\..\..\..\deps\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ProjectDir)\$(PlatformName)\$(ConfigurationName)\$(TargetName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
InheritedPropertySheets=".\ProjectRootDir.vsprops;..\..\..\3rdparty.vsprops;.\Common.vsprops;..\..\..\..\common\vsprops\CodeGen_Release.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
|
@ -120,25 +109,12 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/EHsc "
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="2"
|
||||
FavorSizeOrSpeed="2"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png"
|
||||
PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_BASE=0;wxUSE_UNICODE=1;_CRT_SECURE_NO_WARNINGS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
EnableFunctionLevelLinking="false"
|
||||
PreprocessorDefinitions="wxUSE_BASE=0;wxUSE_GUI=1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="wx/wxprec.h"
|
||||
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\vc80.pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -152,7 +128,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
@ -174,10 +149,8 @@
|
|||
</Configuration>
|
||||
<Configuration
|
||||
Name="Devel|Win32"
|
||||
OutputDirectory="..\..\..\..\deps\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ProjectDir)\$(PlatformName)\$(ConfigurationName)\$(TargetName)"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\..\3rdparty.vsprops"
|
||||
InheritedPropertySheets=".\ProjectRootDir.vsprops;..\..\..\3rdparty.vsprops;.\Common.vsprops;..\..\..\..\common\vsprops\CodeGen_Devel.vsprops;..\..\..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="1"
|
||||
|
@ -201,23 +174,12 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalOptions="/EHsc "
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="1"
|
||||
FavorSizeOrSpeed="2"
|
||||
WholeProgramOptimization="false"
|
||||
AdditionalIncludeDirectories="..\..\Include;..\..\Include\msvc;..\..\..\zlib;..\..\src\png"
|
||||
PreprocessorDefinitions="WIN32;_LIB;__WXMSW__;wxUSE_BASE=0;wxUSE_UNICODE=1;_CRT_SECURE_NO_WARNINGS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PreprocessorDefinitions="wxUSE_BASE=0;wxUSE_GUI=1"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="wx/wxprec.h"
|
||||
PrecompiledHeaderFile="$(IntDir)\$(TargetName).pch"
|
||||
AssemblerListingLocation="$(IntDir)\"
|
||||
ObjectFile="$(IntDir)\"
|
||||
ProgramDataBaseFileName="$(IntDir)\vc80.pdb"
|
||||
WarningLevel="4"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -231,7 +193,6 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Debug.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
|
@ -38,11 +38,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -75,7 +71,7 @@
|
|||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Release.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
|
@ -96,15 +92,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
@ -137,7 +125,7 @@
|
|||
<Configuration
|
||||
Name="Devel|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
InheritedPropertySheets="..\3rdparty.vsprops;..\..\common\vsprops\CodeGen_Devel.vsprops;..\..\common\vsprops\IncrementalLinking.vsprops"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="0"
|
||||
>
|
||||
|
@ -158,17 +146,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="false"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
BufferSecurityCheck="false"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
# Usage: ruby build.rb [option] [pcsx2, plugins, <plugin name>] [dev,debug,release] [all, install, clean]
|
||||
# If you don't specify pcsx2, plugins, or a plugin name, it will assume you want to rebuild everything.
|
||||
# If you don't specify dev or debug, it assumes a release build.
|
||||
# If it isn't all, install, or clean, it assumes install.
|
||||
|
||||
# If you want other options, add them to $pcsx2_build_types. This is still a work in progress...
|
||||
# --arcum42
|
||||
|
||||
require "fileutils.rb"
|
||||
include FileUtils
|
||||
|
||||
$main_dir = Dir.pwd
|
||||
$pcsx2_install_dir = "#{$main_dir}/bin"
|
||||
$plugin_install_dir = "#{$main_dir}/bin/plugins"
|
||||
|
||||
$pcsx2_dir = "#{$main_dir}/pcsx2"
|
||||
$plugins_dir = "#{$main_dir}/plugins"
|
||||
|
||||
$pcsx2_prefix = " --prefix #{$main_dir}"
|
||||
$plugins_prefix = " --prefix #{$plugin_install_dir}"
|
||||
|
||||
$plugin_list=["CDVDnull", "dev9null", "FWnull", "USBnull", "SPU2null", "zerogs", "zzogl", "zeropad", "zerospu2", "PeopsSPU2", "CDVDiso", "CDVDisoEFP", "CDVDlinuz"]
|
||||
$full_plugin_list=["CDVDnull", "dev9null", "FWnull", "USBnull", "SPU2null", "zerogs", "zzogl", "zeropad", "zerospu2", "PeopsSPU2", "CDVDiso", "CDVDisoEFP", "CDVDlinuz","GSnull","PadNull","wxpad"]
|
||||
|
||||
$pcsx2_build_types = {
|
||||
"dev" => " --enable-devbuild ",
|
||||
"debug" => " --enable-debug ",
|
||||
"release" => " "
|
||||
}
|
||||
|
||||
$pcsx2_release_params=["dev","debug","release"]
|
||||
$make_params=["all", "clean","install"]
|
||||
|
||||
$build_report =""
|
||||
$build_counter = 0
|
||||
|
||||
def plugin_src_dir(plugin_name)
|
||||
name = "#{$plugins_dir}/#{plugin_name}/"
|
||||
case plugin_name
|
||||
when "CDVDiso" then
|
||||
name += "src"
|
||||
when "CDVDisoEFP" then
|
||||
name += "src/Linux"
|
||||
when "CDVDlinuz"
|
||||
name += "Src/Linux"
|
||||
when "zerogs", "zzogl"
|
||||
name += "opengl"
|
||||
end
|
||||
|
||||
return name
|
||||
end
|
||||
|
||||
def announce(my_program)
|
||||
print "---------------\n"
|
||||
print "Building #{my_program}\n"
|
||||
print "---------------\n"
|
||||
end
|
||||
|
||||
def make(options)
|
||||
system("make #{options}")
|
||||
($? == 0)
|
||||
end
|
||||
|
||||
def rebuild(options)
|
||||
system("aclocal")
|
||||
system("automake")
|
||||
system("autoconf")
|
||||
system("chmod +x configure")
|
||||
system("./configure #{options}")
|
||||
make "clean"
|
||||
end
|
||||
|
||||
def install(build_name)
|
||||
ret = make "install"
|
||||
|
||||
case build_name
|
||||
# If the package isn't inclined to obey simple instructions...
|
||||
when "CDVDisoEFP" then
|
||||
system("cp #{plugin_src_dir(build_name)}/cfgCDVDisoEFP #{$plugin_install_dir}")
|
||||
system("cp #{plugin_src_dir(build_name)}/libCDVDisoEFP.so #{$plugin_install_dir}")
|
||||
when "CDVDlinuz" then
|
||||
system("cp #{plugin_src_dir(build_name)}/cfgCDVDlinuz #{$plugin_install_dir}")
|
||||
system("cp #{plugin_src_dir(build_name)}/libCDVDlinuz.so #{$plugin_install_dir}")
|
||||
when "PeopsSPU2" then
|
||||
system("cp #{plugin_src_dir(build_name)}/libspu2Peops*.so* #{$plugin_install_dir}")
|
||||
|
||||
# Copy the shaders over. Shouldn't the makefile do this?
|
||||
when "zzogl","zerogs" then
|
||||
system("cp #{plugin_src_dir(build_name)}/Win32/ps2hw.dat #{$plugin_install_dir}")
|
||||
|
||||
#And while we have the opportunity...
|
||||
when "pcsx2" then
|
||||
svn_revision = `svn info | grep Revision:`
|
||||
svn_revision = /[0-9]+/.match(svn_revision)
|
||||
system("cp #{$pcsx2_install_dir}/pcsx2 #{$pcsx2_install_dir}/pcsx2-#{svn_revision}")
|
||||
end
|
||||
|
||||
ret
|
||||
end
|
||||
|
||||
def build(build_name, make_parameter)
|
||||
completed = true
|
||||
|
||||
announce "#{build_name.capitalize}"
|
||||
|
||||
if build_name != "pcsx2" then
|
||||
build_dir = plugin_src_dir(build_name)
|
||||
else
|
||||
build_dir = "#{$pcsx2_dir}"
|
||||
end
|
||||
|
||||
Dir.chdir build_dir
|
||||
|
||||
case make_parameter
|
||||
when "all" then
|
||||
if build_name == "pcsx2"
|
||||
rebuild($pcsx2_prefix)
|
||||
else
|
||||
rebuild($plugins_prefix)
|
||||
end
|
||||
completed = install(build_name)
|
||||
|
||||
when "clean" then
|
||||
make "clean"
|
||||
|
||||
else
|
||||
completed = install(build_name)
|
||||
end
|
||||
|
||||
Dir.chdir $main_dir
|
||||
|
||||
if completed then
|
||||
$build_report += "#{build_name} was built successfully.\n"
|
||||
$build_counter += 1
|
||||
else
|
||||
$build_report += "#{build_name} was not built successfully.\n"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
build_parameter = "all"
|
||||
make_parameter = ""
|
||||
build_items = Array.new([])
|
||||
|
||||
ARGV.each do |x|
|
||||
make_parameter = x if $make_params.include?(x)
|
||||
|
||||
build_items.push(x) if $full_plugin_list.include?(x) or (x == "pcsx2")
|
||||
$pcsx2_prefix = $pcsx2_build_types[x] + $pcsx2_prefix if $pcsx2_release_params.include?(x)
|
||||
|
||||
if (x == "plugins") then
|
||||
x = $plugin_list
|
||||
build_items.push(x)
|
||||
end
|
||||
end
|
||||
|
||||
if build_items.empty? then
|
||||
build_items.push($plugin_list)
|
||||
build_items.push("pcsx2")
|
||||
end
|
||||
|
||||
build_items.flatten!
|
||||
|
||||
build_items.each do |x|
|
||||
build(x,make_parameter)
|
||||
end
|
||||
|
||||
print "\n--\n"
|
||||
print "Build Summary:\n"
|
||||
print $build_report
|
||||
print "\n"
|
||||
print "#{$build_counter}/#{build_items.count} Successful.\n"
|
19
build.sh
19
build.sh
|
@ -11,8 +11,14 @@
|
|||
#Optimized, but a devbuild
|
||||
export PCSX2OPTIONS="--enable-devbuild --prefix `pwd`"
|
||||
|
||||
#Debug / Devbuild version
|
||||
#export PCSX2OPTIONS="--enable-debug --enable-devbuild --prefix `pwd`"
|
||||
#Debug version (which now implies a devbuild)
|
||||
#export PCSX2OPTIONS="--enable-debug --prefix `pwd`"
|
||||
|
||||
#Normal, but unoptimized
|
||||
#export PCSX2OPTIONS="--disable-optimization --prefix `pwd`"
|
||||
|
||||
#Normal, with warnings
|
||||
#export PCSX2OPTIONS="--enable-warnings --prefix `pwd`"
|
||||
|
||||
#ZeroGS Normal mode
|
||||
export ZEROGSOPTIONS="--enable-sse2"
|
||||
|
@ -23,12 +29,16 @@ export ZEROGSOPTIONS="--enable-sse2"
|
|||
#ZeroSPU2 Debug mode (Don't enable right now)
|
||||
#export ZEROSPU2OPTIONS="--enable-debug --enable-devbuild"
|
||||
|
||||
#GSnull debug options.
|
||||
#export GSnullOPTIONS="--enable-debug"
|
||||
|
||||
option=$@
|
||||
export PCSX2PLUGINS="`pwd`/bin/plugins"
|
||||
curdir=`pwd`
|
||||
|
||||
echo
|
||||
echo "Building the Pcsx2 Suite."
|
||||
echo "Note: will not compile on Linux x64."
|
||||
echo "Note: binaries generated are 32 bit, and require 32 bit versions of all dependencies."
|
||||
cd ${curdir}/plugins
|
||||
sh build.sh $option
|
||||
|
||||
|
@ -38,8 +48,9 @@ echo Error with building plugins
|
|||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Building Pcsx2."
|
||||
echo "Note: will not compile on Linux x64."
|
||||
echo "Note: binaries generated are 32 bit, and require 32 bit versions of all dependencies."
|
||||
cd ${curdir}/pcsx2
|
||||
sh build.sh $option
|
||||
|
||||
|
|
|
@ -0,0 +1,421 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="Utilities"
|
||||
ProjectGUID="{4639972E-424E-4E13-8B07-CA403C481346}"
|
||||
RootNamespace="x86emitter"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\vsprops\CommonLibrary.vsprops;..\..\vsprops\CodeGen_Debug.vsprops;..\..\vsprops\IncrementalLinking.vsprops;..\..\vsprops\pthreads.vsprops"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
ExceptionHandling="2"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\vsprops\CommonLibrary.vsprops;..\..\vsprops\CodeGen_Release.vsprops;..\..\vsprops\pthreads.vsprops"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
ExceptionHandling="2"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Devel|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\vsprops\CommonLibrary.vsprops;..\..\vsprops\IncrementalLinking.vsprops;..\..\vsprops\CodeGen_Devel.vsprops;..\..\vsprops\pthreads.vsprops"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
ExceptionHandling="2"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\AlignedMalloc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\Console.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\Exceptions.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\x86\MemcpyFast.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\StringHelpers.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\ThreadTools.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\vssprintf.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\Windows\WinHostSys.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\WinMisc.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\WinThreads.cpp"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Linux"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\Linux\LnxHostSys.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Devel|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\LnxMisc.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Devel|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\LnxThreads.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Devel|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\x86\MemcpyFast.S"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Devel|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\Console.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\Dependencies.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\Exceptions.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\General.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\intrin_x86.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\lnx_memzero.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\MemcpyFast.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\Utilities\PrecompiledHeader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\RedtapeWindows.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\SafeArray.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\StringHelpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\Threading.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\win_memzero.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -0,0 +1,366 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="x86emitter"
|
||||
ProjectGUID="{A51123F5-9505-4EAE-85E7-D320290A272C}"
|
||||
RootNamespace="x86emitter"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\vsprops\CommonLibrary.vsprops;..\..\vsprops\CodeGen_Debug.vsprops;..\..\vsprops\IncrementalLinking.vsprops;..\..\vsprops\pthreads.vsprops"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\vsprops\CommonLibrary.vsprops;..\..\vsprops\CodeGen_Release.vsprops;..\..\vsprops\pthreads.vsprops"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Devel|Win32"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="..\..\vsprops\CommonLibrary.vsprops;..\..\vsprops\IncrementalLinking.vsprops;..\..\vsprops\CodeGen_Devel.vsprops;..\..\vsprops\pthreads.vsprops"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\3dnow.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\cpudetect.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\fpu.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\jmp.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\legacy.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\legacy_sse.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\PrecompiledHeader.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\simd.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\tools.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\x86emitter.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\inlines.inl"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\instructions.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\internal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\legacy_instructions.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\legacy_internal.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\legacy_types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\macros.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\src\x86emitter\PrecompiledHeader.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\sse_helpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\tools.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\types.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\x86emitter.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="Implement"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\dwshift.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\group1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\group2.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\group3.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\helpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\incdec.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\jmpcall.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\movs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\test.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\xchg.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Implement_Simd"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\xmm\arithmetic.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\xmm\basehelpers.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\xmm\comparisons.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\xmm\moremovs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\x86emitter\implement\xmm\shufflepack.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -77,10 +77,18 @@
|
|||
#define PS2E_SIO_VERSION 0x0001
|
||||
#ifdef COMMONdefs
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
u32 CALLBACK PS2EgetLibType(void);
|
||||
u32 CALLBACK PS2EgetLibVersion2(u32 type);
|
||||
char* CALLBACK PS2EgetLibName(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// key values:
|
||||
|
|
|
@ -44,30 +44,34 @@ extern SessionOverrideFlags g_Session;
|
|||
//////////////////////////////////////////////////////////////////////////
|
||||
// Pcsx2 User Configuration Options!
|
||||
|
||||
//#define PCSX2_MICROVU // Use Micro VU recs instead of Zero VU Recs
|
||||
//#define PCSX2_MICROVU_ // Fully enable Micro VU recs (temporary option for now)
|
||||
#define PCSX2_GSMULTITHREAD 1 // uses multi-threaded gs
|
||||
#define PCSX2_EEREC 0x10
|
||||
#define PCSX2_VU0REC 0x20
|
||||
#define PCSX2_VU1REC 0x40
|
||||
#define PCSX2_FRAMELIMIT_MASK 0xc00
|
||||
#define PCSX2_FRAMELIMIT_NORMAL 0x000
|
||||
#define PCSX2_FRAMELIMIT_LIMIT 0x400
|
||||
#define PCSX2_FRAMELIMIT_SKIP 0x800
|
||||
#define PCSX2_GSMULTITHREAD 0x0001 // Use Multi-Threaded GS
|
||||
#define PCSX2_EEREC 0x0010
|
||||
#define PCSX2_VU0REC 0x0020
|
||||
#define PCSX2_VU1REC 0x0040
|
||||
#define PCSX2_FRAMELIMIT_MASK 0x0c00
|
||||
#define PCSX2_FRAMELIMIT_NORMAL 0x0000
|
||||
#define PCSX2_FRAMELIMIT_LIMIT 0x0400
|
||||
#define PCSX2_FRAMELIMIT_SKIP 0x0800
|
||||
#define PCSX2_MICROVU0 0x1000 // Use Micro VU0 recs instead of Zero VU0 Recs
|
||||
#define PCSX2_MICROVU1 0x2000 // Use Micro VU1 recs instead of Zero VU1 Recs
|
||||
|
||||
#define CHECK_FRAMELIMIT (Config.Options&PCSX2_FRAMELIMIT_MASK)
|
||||
|
||||
//------------ CPU Options!!! ---------------
|
||||
#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD)
|
||||
#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD)
|
||||
#define CHECK_MICROVU0 (Config.Options&PCSX2_MICROVU0)
|
||||
#define CHECK_MICROVU1 (Config.Options&PCSX2_MICROVU1)
|
||||
#define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC)
|
||||
#define CHECK_VU0REC (!g_Session.ForceDisableVU0rec && Config.Options&PCSX2_VU0REC)
|
||||
#define CHECK_VU1REC (!g_Session.ForceDisableVU1rec && (Config.Options&PCSX2_VU1REC))
|
||||
|
||||
//------------ SPECIAL GAME FIXES!!! ---------------
|
||||
#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
|
||||
#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
|
||||
#define CHECK_VUCLIPFLAGHACK (Config.GameFixes & 0x2) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
|
||||
#define CHECK_FPUMULHACK (Config.GameFixes & 0x8) // Special Fix for Tales of Destiny hangs.
|
||||
#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x01) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
|
||||
#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x04) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
|
||||
#define CHECK_VUCLIPFLAGHACK (Config.GameFixes & 0x02) // Special Fix for Persona games, maybe others. It's to do with the VU clip flag (again).
|
||||
#define CHECK_FPUMULHACK (Config.GameFixes & 0x08) // Special Fix for Tales of Destiny hangs.
|
||||
#define CHECK_DMAEXECHACK (Config.GameFixes & 0x10) // Special Fix for Fatal Frame; breaks Gust and Tri-Ace games.
|
||||
#define CHECK_XGKICKHACK (Config.GameFixes & 0x20) // Special Fix for Erementar Gerad, adds more delay to VU XGkick instructions. Corrects the color of some graphics.
|
||||
|
||||
//------------ Advanced Options!!! ---------------
|
||||
#define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1)
|
||||
|
@ -161,12 +165,14 @@ public:
|
|||
int Patch;
|
||||
int CustomFps;
|
||||
struct Hacks_t {
|
||||
int EECycleRate;
|
||||
int EECycleRate;
|
||||
bool IOPCycleDouble;
|
||||
bool WaitCycleExt;
|
||||
bool INTCSTATSlow;
|
||||
int VUCycleSteal;
|
||||
bool IdleLoopFF;
|
||||
int VUCycleSteal;
|
||||
bool vuFlagHack;
|
||||
bool vuMinMax;
|
||||
bool ESCExits; // this is a hack!?
|
||||
} Hacks;
|
||||
int GameFixes;
|
||||
|
|
|
@ -1,120 +1,277 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2008 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __PCSX2DEFS_H__
|
||||
#define __PCSX2DEFS_H__
|
||||
|
||||
#ifndef __LINUX__
|
||||
# if defined (__linux__) // some distributions are lower case
|
||||
# define __LINUX__
|
||||
# endif
|
||||
|
||||
# ifdef __CYGWIN__
|
||||
# define __LINUX__
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "Pcsx2Types.h"
|
||||
|
||||
// Renamed ARRAYSIZE to ArraySize -- looks nice and gets rid of Windows.h conflicts (air)
|
||||
#ifndef ArraySize
|
||||
#define ArraySize(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// jASSUME - give hints to the optimizer
|
||||
// This is primarily useful for the default case switch optimizer, which enables VC to
|
||||
// generate more compact switches.
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define jBREAKPOINT() ((void) 0)
|
||||
# ifdef _MSC_VER
|
||||
# define jASSUME(exp) (__assume(exp))
|
||||
# else
|
||||
# define jASSUME(exp) ((void) sizeof(exp))
|
||||
# endif
|
||||
#else
|
||||
# if defined(_MSC_VER)
|
||||
# define jBREAKPOINT() do { __asm int 3 } while(0)
|
||||
# else
|
||||
# define jBREAKPOINT() ((void) *(volatile char *) 0)
|
||||
# endif
|
||||
# define jASSUME(exp) if(exp) ; else jBREAKPOINT()
|
||||
#endif
|
||||
|
||||
// disable the default case in a switch
|
||||
#define jNO_DEFAULT \
|
||||
{ \
|
||||
default: \
|
||||
jASSUME(0); \
|
||||
break; \
|
||||
}
|
||||
|
||||
/* common defines */
|
||||
#ifndef C_ASSERT
|
||||
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// Note: building the 'extern' into PCSX2_ALIGNED16_DECL fixes Visual Assist X's intellisense.
|
||||
|
||||
#define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
|
||||
#define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x
|
||||
#define PCSX2_ALIGNED16(x) __declspec(align(16)) x
|
||||
#define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
|
||||
|
||||
#define __naked __declspec(naked)
|
||||
#define __unused /*unused*/
|
||||
#define __noinline __declspec(noinline)
|
||||
#define CALLBACK __stdcall
|
||||
|
||||
#else
|
||||
|
||||
// fixme - is this needed for recent versions of GCC? Or can we just use the first two macros
|
||||
// instead for both definitions (implementations) and declarations (includes)? -- air
|
||||
#define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig)))
|
||||
#define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
|
||||
#define PCSX2_ALIGNED_EXTERN(alig,x) extern x __attribute((aligned(alig)))
|
||||
#define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16)))
|
||||
|
||||
#define __naked // GCC lacks the naked specifier
|
||||
#define CALLBACK // CALLBACK is a win32-specific mess
|
||||
|
||||
// GCC uses attributes for a lot of things that Visual C+ doesn't.
|
||||
#define __fastcall __attribute__((fastcall))
|
||||
#define __unused __attribute__((unused))
|
||||
#define _inline __inline__ __attribute__((unused))
|
||||
#define __forceinline __attribute__((always_inline,unused))
|
||||
#define __noinline __attribute__((noinline))
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
s8 *data;
|
||||
} freezeData;
|
||||
|
||||
// event values:
|
||||
#define KEYPRESS 1
|
||||
#define KEYRELEASE 2
|
||||
|
||||
typedef struct _keyEvent {
|
||||
u32 key;
|
||||
u32 evt;
|
||||
} keyEvent;
|
||||
|
||||
#endif
|
||||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2008 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __PCSX2DEFS_H__
|
||||
#define __PCSX2DEFS_H__
|
||||
|
||||
#if defined (__linux__) && !defined(__LINUX__) // some distributions are lower case
|
||||
# define __LINUX__
|
||||
#endif
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# define __LINUX__
|
||||
#endif
|
||||
|
||||
#include "Pcsx2Types.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Microsoft specific STL extensions for bounds checking and stuff: Enabled in devbuilds,
|
||||
// disabled in release builds. :)
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable:4244) // disable warning C4244: '=' : conversion from 'big' to 'small', possible loss of data
|
||||
# ifdef PCSX2_DEVBUILD
|
||||
# undef _SECURE_SCL
|
||||
# define _SECURE_SCL 1
|
||||
# undef _SECURE_SCL_THROWS
|
||||
# define _SECURE_SCL_THROWS 1
|
||||
# else
|
||||
# undef _SECURE_SCL
|
||||
# define _SECURE_SCL 0
|
||||
# undef _SECURE_SCL_THROWS
|
||||
# define _SECURE_SCL_THROWS 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#else
|
||||
# include <intrin_x86.h>
|
||||
#endif
|
||||
|
||||
// Renamed ARRAYSIZE to ArraySize -- looks nice and gets rid of Windows.h conflicts (air)
|
||||
// Notes: I'd have used ARRAY_SIZE instead but ran into cross-platform lib conflicts with
|
||||
// that as well. >_<
|
||||
#ifndef ArraySize
|
||||
# define ArraySize(x) (sizeof(x)/sizeof((x)[0]))
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// __releaseinline -- a forceinline macro that is enabled for RELEASE/PUBLIC builds ONLY.
|
||||
// This is useful because forceinline can make certain types of debugging problematic since
|
||||
// functions that look like they should be called won't breakpoint since their code is
|
||||
// inlined, and it can make stack traces confusing or near useless.
|
||||
//
|
||||
// Use __releaseinline for things which are generally large functions where trace debugging
|
||||
// from Devel builds is likely useful; but which should be inlined in an optimized Release
|
||||
// environment.
|
||||
//
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
# define __releaseinline
|
||||
#else
|
||||
# define __releaseinline __forceinline
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// jASSUME - give hints to the optimizer
|
||||
// This is primarily useful for the default case switch optimizer, which enables VC to
|
||||
// generate more compact switches.
|
||||
|
||||
#ifndef jASSUME
|
||||
# ifdef NDEBUG
|
||||
# define jBREAKPOINT() ((void) 0)
|
||||
# ifdef _MSC_VER
|
||||
# define jASSUME(exp) (__assume(exp))
|
||||
# else
|
||||
# define jASSUME(exp) ((void) sizeof(exp))
|
||||
# endif
|
||||
# else
|
||||
# define jBREAKPOINT() __debugbreak();
|
||||
# define jASSUME(exp) do { if(exp) ; else jBREAKPOINT(); } while(0);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization
|
||||
// under MSVC.
|
||||
//
|
||||
// How it Works: jASSUME turns into an __assume(0) under msvc compilers, which when specified
|
||||
// in the 'default:' case of a switch tells the compiler that the case is unreachable, so
|
||||
// that it will not generate any code, LUTs, or conditionals to handle it.
|
||||
//
|
||||
// * In debug builds the default case will cause an assertion.
|
||||
// * In devel builds the default case will cause a LogicError exception (C++ only)
|
||||
// (either meaning the jNO_DEFAULT has been used incorrectly, and that the default case is in
|
||||
// fact used and needs to be handled).
|
||||
//
|
||||
// MSVC Note: To stacktrace LogicError exceptions, add Exception::LogicError to the C++ First-
|
||||
// Chance Exception list (under Debug->Exceptions menu).
|
||||
//
|
||||
#ifndef jNO_DEFAULT
|
||||
#if defined(__cplusplus) && defined(PCSX2_DEVBUILD)
|
||||
# define jNO_DEFAULT \
|
||||
{ \
|
||||
default: \
|
||||
assert(0); \
|
||||
if( !IsDebugBuild ) throw Exception::LogicError( "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)" ); \
|
||||
break; \
|
||||
}
|
||||
#else
|
||||
# define jNO_DEFAULT \
|
||||
default: \
|
||||
{ \
|
||||
jASSUME(0); \
|
||||
break; \
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// compile-time assertion; usable at static variable define level.
|
||||
// (typically used to confirm the correct sizeof() for struct types where size
|
||||
// restaints must be enforced).
|
||||
//
|
||||
#ifndef C_ASSERT
|
||||
# define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Dev / Debug conditionals - Consts for using if() statements instead of uglier #ifdef.
|
||||
//
|
||||
// Note: Using if() optimizes nicely in Devel and Release builds, but will generate extra
|
||||
// code overhead in debug builds (since debug neither inlines, nor optimizes out const-
|
||||
// level conditionals). Normally not a concern, but if you stick if( IsDevbuild ) in
|
||||
// some tight loops it will likely make debug builds unusably slow.
|
||||
//
|
||||
#ifdef __cplusplus
|
||||
# ifdef PCSX2_DEVBUILD
|
||||
static const bool IsDevBuild = true;
|
||||
# else
|
||||
static const bool IsDevBuild = false;
|
||||
# endif
|
||||
|
||||
# ifdef PCSX2_DEBUG
|
||||
static const bool IsDebugBuild = true;
|
||||
# else
|
||||
static const bool IsDebugBuild = false;
|
||||
# endif
|
||||
|
||||
#else
|
||||
|
||||
# ifdef PCSX2_DEVBUILD
|
||||
static const u8 IsDevBuild = 1;
|
||||
# else
|
||||
static const u8 IsDevBuild = 0;
|
||||
# endif
|
||||
|
||||
# ifdef PCSX2_DEBUG
|
||||
static const u8 IsDebugBuild = 1;
|
||||
# else
|
||||
static const u8 IsDebugBuild = 0;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// PCSX2_ALIGNED16 - helper macros for aligning variables in MSVC and GCC.
|
||||
//
|
||||
// GCC Warning! The GCC linker (LD) typically fails to assure alignment of class members.
|
||||
// If you want alignment to be assured, the variable must either be a member of a struct
|
||||
// or a static global.
|
||||
//
|
||||
// General Performance Warning: Any function that specifies alignment on a local (stack)
|
||||
// variable will have to align the stack frame on enter, and restore it on exit (adds
|
||||
// overhead). Furthermore, compilers cannot inline functions that have aligned local
|
||||
// vars. So use local var alignment with much caution.
|
||||
//
|
||||
// Note: building the 'extern' into PCSX2_ALIGNED16 fixes Visual Assist X's intellisense.
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
|
||||
# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x
|
||||
# define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x
|
||||
# define PCSX2_ALIGNED16(x) __declspec(align(16)) x
|
||||
# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
|
||||
|
||||
# define __naked __declspec(naked)
|
||||
# define __unused /*unused*/
|
||||
# define __noinline __declspec(noinline)
|
||||
|
||||
// Don't know if there are Visual C++ equivalents of these.
|
||||
# define __hot
|
||||
# define __cold
|
||||
# define likely(x) x
|
||||
# define unlikely(x) x
|
||||
|
||||
# define CALLBACK __stdcall
|
||||
|
||||
#else
|
||||
|
||||
// GCC 4.4.0 is a bit nutty, as compilers go. it gets a define to itself.
|
||||
# define GCC_VERSION (__GNUC__ * 10000 \
|
||||
+ __GNUC_MINOR__ * 100 \
|
||||
+ __GNUC_PATCHLEVEL__)
|
||||
|
||||
/* Test for GCC > 4.4.0; Should be adjusted when new versions come out */
|
||||
# if GCC_VERSION >= 40400
|
||||
# define THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0
|
||||
# define __nooptimization __attribute__((optimize("O0")))
|
||||
# endif
|
||||
|
||||
/*
|
||||
This theoretically unoptimizes. Not having much luck so far.
|
||||
# ifdef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0
|
||||
# pragma GCC optimize ("O0")
|
||||
# endif
|
||||
|
||||
# ifdef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0
|
||||
# pragma GCC reset_options
|
||||
# endif
|
||||
|
||||
*/
|
||||
|
||||
// fixme - is this needed for recent versions of GCC? Or can we just use the first two macros
|
||||
// instead for both definitions (implementations) and declarations (includes)? -- air
|
||||
# define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig)))
|
||||
# define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
|
||||
# define PCSX2_ALIGNED_EXTERN(alig,x) extern x __attribute((aligned(alig)))
|
||||
# define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16)))
|
||||
|
||||
# define __naked // GCC lacks the naked specifier
|
||||
# define CALLBACK // CALLBACK is a win32-specific mess
|
||||
|
||||
// GCC uses attributes for a lot of things that Visual C+ doesn't.
|
||||
# define __fastcall __attribute__((fastcall))
|
||||
# define __unused __attribute__((unused))
|
||||
# define _inline __inline__ __attribute__((unused))
|
||||
# define __forceinline __attribute__((always_inline,unused))
|
||||
# define __noinline __attribute__((noinline))
|
||||
# define __hot __attribute__((hot))
|
||||
# define __cold __attribute__((cold))
|
||||
# define likely(x) __builtin_expect(!!(x), 1)
|
||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
#endif
|
||||
|
||||
#ifndef THE_UNBEARABLE_LIGHTNESS_OF_BEING_GCC_4_4_0
|
||||
# define __nooptimization
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int size;
|
||||
s8 *data;
|
||||
} freezeData;
|
||||
|
||||
// event values:
|
||||
#define KEYPRESS 1
|
||||
#define KEYRELEASE 2
|
||||
|
||||
typedef struct _keyEvent {
|
||||
u32 key;
|
||||
u32 evt;
|
||||
} keyEvent;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -107,6 +107,7 @@ typedef s32 sptr;
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// A rough-and-ready cross platform 128-bit datatype, Non-SSE style.
|
||||
//
|
||||
#ifdef __cplusplus
|
||||
struct u128
|
||||
{
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "StringHelpers.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Console Namespace -- For printing messages to the console.
|
||||
//
|
||||
// SysPrintf is depreciated; We should phase these in over time.
|
||||
//
|
||||
namespace Console
|
||||
{
|
||||
enum Colors
|
||||
{
|
||||
Color_Black = 0,
|
||||
Color_Red,
|
||||
Color_Green,
|
||||
Color_Yellow,
|
||||
Color_Blue,
|
||||
Color_Magenta,
|
||||
Color_Cyan,
|
||||
Color_White
|
||||
};
|
||||
|
||||
// va_args version of WriteLn, mostly for internal use only.
|
||||
extern void __fastcall _WriteLn( Colors color, const char* fmt, va_list args );
|
||||
|
||||
extern void __fastcall SetTitle( const wxString& title );
|
||||
|
||||
// Changes the active console color.
|
||||
// This color will be unset by calls to colored text methods
|
||||
// such as ErrorMsg and Notice.
|
||||
extern void __fastcall SetColor( Colors color );
|
||||
|
||||
// Restores the console color to default (usually low-intensity white on Win32)
|
||||
extern void ClearColor();
|
||||
|
||||
// The following Write functions return bool so that we can use macros to exclude
|
||||
// them from different build types. The return values are always zero.
|
||||
|
||||
// Writes a newline to the console.
|
||||
extern bool Newline();
|
||||
|
||||
// Writes an unformatted string of text to the console (fast!)
|
||||
// No newline is appended.
|
||||
extern bool __fastcall Write( const char* text );
|
||||
|
||||
// Writes an unformatted string of text to the console (fast!)
|
||||
// A newline is automatically appended, and the console color reset to default
|
||||
// after the log is written.
|
||||
extern bool __fastcall Write( Colors color, const char* text );
|
||||
|
||||
// Writes an unformatted string of text to the console (fast!)
|
||||
// A newline is automatically appended.
|
||||
extern bool __fastcall WriteLn( const char* text );
|
||||
|
||||
// Writes an unformatted string of text to the console (fast!)
|
||||
// A newline is automatically appended, and the console color reset to default
|
||||
// after the log is written.
|
||||
extern bool __fastcall WriteLn( Colors color, const char* text );
|
||||
|
||||
// Writes a line of colored text to the console, with automatic newline appendage.
|
||||
// The console color is reset to default when the operation is complete.
|
||||
extern bool WriteLn( Colors color, const char* fmt, VARG_PARAM dummy, ... );
|
||||
|
||||
// Writes a formatted message to the console, with appended newline.
|
||||
extern bool WriteLn( const char* fmt, VARG_PARAM dummy, ... );
|
||||
|
||||
// Writes a line of colored text to the console (no newline).
|
||||
// The console color is reset to default when the operation is complete.
|
||||
extern bool Write( Colors color, const char* fmt, VARG_PARAM dummy, ... );
|
||||
|
||||
// Writes a formatted message to the console (no newline)
|
||||
extern bool Write( const char* fmt, VARG_PARAM dummy, ... );
|
||||
|
||||
// Displays a message in the console with red emphasis.
|
||||
// Newline is automatically appended.
|
||||
extern bool Error( const char* fmt, VARG_PARAM dummy, ... );
|
||||
extern bool __fastcall Error( const char* text );
|
||||
|
||||
// Displays a message in the console with yellow emphasis.
|
||||
// Newline is automatically appended.
|
||||
extern bool Notice( const char* fmt, VARG_PARAM dummy, ... );
|
||||
extern bool __fastcall Notice( const char* text );
|
||||
|
||||
// Displays a message in the console with yellow emphasis.
|
||||
// Newline is automatically appended.
|
||||
extern bool Status( const char* fmt, VARG_PARAM dummy, ... );
|
||||
extern bool __fastcall Status( const char* text );
|
||||
|
||||
|
||||
extern bool __fastcall Write( const wxString& text );
|
||||
extern bool __fastcall Write( Colors color, const wxString& text );
|
||||
extern bool __fastcall WriteLn( const wxString& text );
|
||||
extern bool __fastcall WriteLn( Colors color, const wxString& text );
|
||||
|
||||
extern bool __fastcall Error( const wxString& text );
|
||||
extern bool __fastcall Notice( const wxString& text );
|
||||
extern bool __fastcall Status( const wxString& text );
|
||||
}
|
||||
|
||||
using Console::Color_Red;
|
||||
using Console::Color_Green;
|
||||
using Console::Color_Blue;
|
||||
using Console::Color_Magenta;
|
||||
using Console::Color_Cyan;
|
||||
using Console::Color_Yellow;
|
||||
using Console::Color_White;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// DevCon / DbgCon
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
# define DevCon Console
|
||||
# define DevMsg MsgBox
|
||||
#else
|
||||
# define DevCon 0&&Console
|
||||
# define DevMsg
|
||||
#endif
|
||||
|
||||
#ifdef PCSX2_DEBUG
|
||||
# define DbgCon Console
|
||||
#else
|
||||
# define DbgCon 0&&Console
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2008 Pcsx2 Team
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
|
@ -15,29 +15,20 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
//============================================
|
||||
//=== Audio XA decoding
|
||||
//=== Kazzuya
|
||||
//============================================
|
||||
|
||||
#ifndef DECODEXA_H
|
||||
#define DECODEXA_H
|
||||
#pragma once
|
||||
|
||||
typedef struct {
|
||||
long y0, y1;
|
||||
} ADPCM_Decode_t;
|
||||
#include "Pcsx2Defs.h"
|
||||
|
||||
typedef struct {
|
||||
int freq;
|
||||
int nbits;
|
||||
int stereo;
|
||||
int nsamples;
|
||||
ADPCM_Decode_t left, right;
|
||||
short pcm[16384];
|
||||
} xa_decode_t;
|
||||
#include <wx/string.h>
|
||||
#include <wx/tokenzr.h>
|
||||
#include <wx/gdicmn.h> // for wxPoint/wxRect stuff
|
||||
#include <wx/intl.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
long xa_decode_sector( xa_decode_t *xdp,
|
||||
unsigned char *sectorp,
|
||||
int is_first_sector );
|
||||
|
||||
#endif
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cstring> // string.h under c++
|
||||
#include <cstdio> // stdio.h under c++
|
||||
#include <cstdlib>
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "Dependencies.h"
|
||||
|
||||
extern void DevAssert( bool condition, const char* msg );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This class provides an easy and clean method for ensuring objects are not copyable.
|
||||
class NoncopyableObject
|
||||
|
@ -56,11 +60,6 @@ protected:
|
|||
// for every class that derives from it.
|
||||
#define Sealed private virtual __BaseSealed<__COUNTER__>
|
||||
|
||||
extern wxLocale* g_EnglishLocale;
|
||||
|
||||
extern wxString GetEnglish( const char* msg );
|
||||
extern wxString GetTranslation( const char* msg );
|
||||
|
||||
namespace Exception
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -104,7 +103,7 @@ namespace Exception
|
|||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc).
|
||||
// Translation Note: These exceptions are never translated, except to issue a general
|
||||
// error message to the user (which is xspecified below).
|
||||
// error message to the user (which is specified below).
|
||||
//
|
||||
class Ps2Generic : public BaseException
|
||||
{
|
||||
|
@ -151,6 +150,18 @@ namespace Exception
|
|||
BaseException( msg_eng, msg_xlt ) { }
|
||||
};
|
||||
|
||||
class AssertionFailure : public LogicError
|
||||
{
|
||||
public:
|
||||
explicit AssertionFailure( const char* msg="Assertion Failure" ) :
|
||||
LogicError( msg ) {}
|
||||
|
||||
explicit AssertionFailure( const wxString& msg_eng, const wxString& msg_xlt ) :
|
||||
LogicError( msg_eng, msg_xlt ) { }
|
||||
|
||||
virtual ~AssertionFailure() throw() {}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class OutOfMemory : public RuntimeError
|
|
@ -0,0 +1,57 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum PageProtectionMode
|
||||
{
|
||||
Protect_NoAccess = 0,
|
||||
Protect_ReadOnly,
|
||||
Protect_ReadWrite
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// HostSys - Namespace housing general system-level implementations relating to loading
|
||||
// plugins and allocating memory. For now, these functions are all accessed via Sys*
|
||||
// versions defined in System.h/cpp.
|
||||
//
|
||||
namespace HostSys
|
||||
{
|
||||
// Maps a block of memory for use as a recompiled code buffer.
|
||||
// The allocated block has code execution privileges.
|
||||
// Returns NULL on allocation failure.
|
||||
extern void *Mmap(uptr base, u32 size);
|
||||
|
||||
// Unmaps a block allocated by SysMmap
|
||||
extern void Munmap(uptr base, u32 size);
|
||||
|
||||
extern void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution=false );
|
||||
|
||||
static __forceinline void Munmap( void* base, u32 size )
|
||||
{
|
||||
Munmap( (uptr)base, size );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
extern void InitCPUTicks();
|
||||
extern u64 GetTickFrequency();
|
||||
extern u64 GetCPUTicks();
|
|
@ -18,28 +18,26 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "windows/memzero.h"
|
||||
#else
|
||||
#include "Linux/memzero.h"
|
||||
#endif // WIN32
|
||||
|
||||
// Only used in the Windows version of memzero.h. But it's in Misc.cpp for some reason.
|
||||
void _memset16_unaligned( void* dest, u16 data, size_t size );
|
||||
|
||||
// The new simplified memcpy_amd_ is now faster than memcpy_raz_.
|
||||
// memcpy_amd_ also does mmx register saving, negating the need for freezeregs (code cleanup!)
|
||||
// Additionally, using one single memcpy implementation keeps the code cache cleaner.
|
||||
|
||||
#ifdef __LINUX__
|
||||
|
||||
# include "lnx_memzero.h"
|
||||
|
||||
extern "C" void __fastcall memcpy_amd_(void *dest, const void *src, size_t bytes);
|
||||
extern "C" u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
|
||||
extern "C" void memxor_mmx(void* dst, const void* src1, int cmpsize);
|
||||
|
||||
#else
|
||||
|
||||
# include "win_memzero.h"
|
||||
|
||||
extern void __fastcall memcpy_amd_(void *dest, const void *src, size_t bytes);
|
||||
extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize);
|
||||
extern void memxor_mmx(void* dst, const void* src1, int cmpsize);
|
||||
|
||||
#endif
|
||||
|
||||
// Only used in the Windows version of memzero.h. But it's in Misc.cpp for some reason.
|
||||
void _memset16_unaligned( void* dest, u16 data, size_t size );
|
||||
|
||||
#define memcpy_fast memcpy_amd_
|
||||
#define memcpy_aligned memcpy_amd_
|
|
@ -0,0 +1,45 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Windows Redtape! No windows.h should be included without it!
|
||||
//
|
||||
// This header's purpose is to include windows.h with the correct OS version info, and
|
||||
// to undefine some of windows.h's more evil macros (min/max). It also does a _WIN32
|
||||
// check, so that we don't have to do it explicitly in every instance where it might
|
||||
// be needed from non-Win32-specific files
|
||||
|
||||
#define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead)
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// Force availability of to WinNT APIs (change to 0x600 to enable XP-specific APIs)
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0501
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// disable Windows versions of min/max -- we'll use the typesafe STL versions instead.
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#endif
|
|
@ -74,26 +74,24 @@ class SafeArray : public NoncopyableObject
|
|||
public:
|
||||
static const int DefaultChunkSize = 0x1000 * sizeof(T);
|
||||
|
||||
public:
|
||||
const wxString Name; // user-assigned block name
|
||||
public:
|
||||
const wxChar* Name; // user-assigned block name
|
||||
int ChunkSize;
|
||||
|
||||
protected:
|
||||
T* m_ptr;
|
||||
int m_size; // size of the allocation of memory
|
||||
|
||||
const static wxString m_str_Unnamed;
|
||||
|
||||
protected:
|
||||
// Internal constructor for use by derived classes. This allows a derived class to
|
||||
// use its own memory allocation (with an aligned memory, for example).
|
||||
// Throws:
|
||||
// Exception::OutOfMemory if the allocated_mem pointer is NULL.
|
||||
explicit SafeArray( const wxString& name, T* allocated_mem, int initSize ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( allocated_mem )
|
||||
, m_size( initSize )
|
||||
explicit SafeArray( const wxChar* name, T* allocated_mem, int initSize ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( allocated_mem )
|
||||
, m_size( initSize )
|
||||
{
|
||||
if( m_ptr == NULL )
|
||||
throw Exception::OutOfMemory();
|
||||
|
@ -101,7 +99,10 @@ protected:
|
|||
|
||||
virtual T* _virtual_realloc( int newsize )
|
||||
{
|
||||
return (T*)realloc( m_ptr, newsize * sizeof(T) );
|
||||
return (T*)((m_ptr == NULL) ?
|
||||
malloc( newsize * sizeof(T) ) :
|
||||
realloc( m_ptr, newsize * sizeof(T) )
|
||||
);
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -110,67 +111,72 @@ public:
|
|||
safe_free( m_ptr );
|
||||
}
|
||||
|
||||
explicit SafeArray( const wxString& name = L"Unnamed" ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( NULL )
|
||||
, m_size( 0 )
|
||||
explicit SafeArray( const wxChar* name=L"Unnamed" ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( NULL )
|
||||
, m_size( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
explicit SafeArray( const char* name ) :
|
||||
Name( wxString::FromAscii(name) )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( NULL )
|
||||
, m_size( 0 )
|
||||
explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) ) )
|
||||
, m_size( initialSize )
|
||||
{
|
||||
}
|
||||
|
||||
explicit SafeArray( int initialSize, const wxString& name = L"Unnamed" ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
|
||||
, m_size( initialSize )
|
||||
{
|
||||
if( m_ptr == NULL )
|
||||
if( (initialSize != 0) && (m_ptr == NULL) )
|
||||
throw Exception::OutOfMemory();
|
||||
}
|
||||
|
||||
explicit SafeArray( int initialSize, const char* name ) :
|
||||
Name( wxString::FromAscii(name) )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
|
||||
, m_size( initialSize )
|
||||
|
||||
// Clears the contents of the array to zero, and frees all memory allocations.
|
||||
void Dispose()
|
||||
{
|
||||
if( m_ptr == NULL )
|
||||
throw Exception::OutOfMemory();
|
||||
m_size = 0;
|
||||
safe_free( m_ptr );
|
||||
}
|
||||
|
||||
bool IsDisposed() const { return (m_ptr==NULL); }
|
||||
|
||||
// Returns the size of the memory allocation, as according to the array type.
|
||||
int GetLength() const { return m_size; }
|
||||
// Returns the size of the memory allocation in bytes.
|
||||
int GetSizeInBytes() const { return m_size * sizeof(T); }
|
||||
|
||||
// Ensures that the allocation is large enough to fit data of the
|
||||
// amount requested. The memory allocation is not resized smaller.
|
||||
void MakeRoomFor( int blockSize )
|
||||
// reallocates the array to the explicit size. Can be used to shrink or grow an
|
||||
// array, and bypasses the internal threshold growth indicators.
|
||||
void ExactAlloc( int newsize )
|
||||
{
|
||||
if( blockSize > m_size )
|
||||
if( newsize == m_size ) return;
|
||||
|
||||
m_ptr = _virtual_realloc( newsize );
|
||||
if( m_ptr == NULL )
|
||||
{
|
||||
const uint newalloc = blockSize + ChunkSize;
|
||||
m_ptr = _virtual_realloc( newalloc );
|
||||
if( m_ptr == NULL )
|
||||
{
|
||||
|
||||
throw Exception::OutOfMemory(
|
||||
wxsFormat( // english (for diagnostic)
|
||||
L"Out-of-memory on SafeArray block re-allocation.\n"
|
||||
L"Old size: %d bytes, New size: %d bytes.",
|
||||
m_size, newalloc
|
||||
m_size, newsize
|
||||
)
|
||||
);
|
||||
}
|
||||
m_size = newalloc;
|
||||
}
|
||||
m_size = newsize;
|
||||
}
|
||||
|
||||
// Ensures that the allocation is large enough to fit data of the
|
||||
// amount requested. The memory allocation is not resized smaller.
|
||||
void MakeRoomFor( int newsize )
|
||||
{
|
||||
if( newsize > m_size )
|
||||
ExactAlloc( newsize );
|
||||
}
|
||||
|
||||
// Extends the containment area of the array. Extensions are performed
|
||||
// in chunks.
|
||||
void GrowBy( int items )
|
||||
{
|
||||
MakeRoomFor( m_size + ChunkSize + items + 1 );
|
||||
}
|
||||
|
||||
// Gets a pointer to the requested allocation index.
|
||||
|
@ -205,36 +211,40 @@ protected:
|
|||
#endif
|
||||
return &m_ptr[i];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SafeList - Simple growable container without all the mess or hassle of std containers.
|
||||
//
|
||||
// This container is intended for reasonably simple class types only. Things which this
|
||||
// container does not handle with desired robustness:
|
||||
//
|
||||
// * Classes with non-trivial constructors (such that construction creates much overhead)
|
||||
// * Classes with copy constructors (copying is done using performance memcpy)
|
||||
// * Classes with destructors (they're not called, sorry!)
|
||||
//
|
||||
template< typename T >
|
||||
class SafeList
|
||||
class SafeList : public NoncopyableObject
|
||||
{
|
||||
public:
|
||||
static const int DefaultChunkSize = 0x80 * sizeof(T);
|
||||
|
||||
public:
|
||||
const wxString Name; // user-assigned block name
|
||||
int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time.
|
||||
public:
|
||||
const wxChar* Name; // user-assigned block name
|
||||
int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time.
|
||||
|
||||
protected:
|
||||
T* m_ptr;
|
||||
int m_allocsize; // size of the allocation of memory
|
||||
uint m_length; // length of the array (active items, not buffer allocation)
|
||||
|
||||
const static wxString m_str_Unnamed;
|
||||
|
||||
protected:
|
||||
virtual T* _virtual_realloc( int newsize )
|
||||
{
|
||||
return (T*)realloc( m_ptr, newsize * sizeof(T) );
|
||||
}
|
||||
|
||||
void _boundsCheck( uint i ) const
|
||||
|
||||
void _boundsCheck( uint i ) const
|
||||
{
|
||||
if( IsDevBuild && i >= (uint)m_length )
|
||||
throw Exception::IndexBoundsFault( Name, i, m_length );
|
||||
|
@ -243,9 +253,10 @@ protected:
|
|||
public:
|
||||
virtual ~SafeList()
|
||||
{
|
||||
safe_free( m_ptr );
|
||||
}
|
||||
|
||||
explicit SafeList( const wxString& name = L"Unnamed" ) :
|
||||
explicit SafeList( const wxChar* name=L"Unnamed" ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( NULL )
|
||||
|
@ -254,16 +265,7 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
explicit SafeList( const char* name ) :
|
||||
Name( wxString::FromAscii(name) )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( NULL )
|
||||
, m_allocsize( 0 )
|
||||
, m_length( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
explicit SafeList( int initialSize, const wxString& name = L"Unnamed" ) :
|
||||
explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" ) :
|
||||
Name( name )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
|
||||
|
@ -272,17 +274,12 @@ public:
|
|||
{
|
||||
if( m_ptr == NULL )
|
||||
throw Exception::OutOfMemory();
|
||||
}
|
||||
|
||||
explicit SafeList( int initialSize, const char* name ) :
|
||||
Name( wxString::FromAscii(name) )
|
||||
, ChunkSize( DefaultChunkSize )
|
||||
, m_ptr( (T*)malloc( initialSize * sizeof(T) ) )
|
||||
, m_allocsize( initialSize )
|
||||
, m_length( 0 )
|
||||
{
|
||||
if( m_ptr == NULL )
|
||||
throw Exception::OutOfMemory();
|
||||
for( int i=0; i<m_allocsize; ++i )
|
||||
{
|
||||
new (&m_ptr[i]) T();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Returns the size of the list, as according to the array type. This includes
|
||||
|
@ -299,7 +296,7 @@ public:
|
|||
{
|
||||
if( blockSize > m_allocsize )
|
||||
{
|
||||
const uint newalloc = blockSize + ChunkSize;
|
||||
const int newalloc = blockSize + ChunkSize;
|
||||
m_ptr = _virtual_realloc( newalloc );
|
||||
if( m_ptr == NULL )
|
||||
{
|
||||
|
@ -312,22 +309,58 @@ public:
|
|||
)
|
||||
);
|
||||
}
|
||||
m_allocsize = newalloc;
|
||||
|
||||
for( ; m_allocsize<newalloc; ++m_allocsize )
|
||||
{
|
||||
new (&m_ptr[m_allocsize]) T();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GrowBy( int items )
|
||||
{
|
||||
MakeRoomFor( m_length + ChunkSize + items + 1 );
|
||||
}
|
||||
|
||||
// Sets the item length to zero. Does not free memory allocations.
|
||||
void Clear()
|
||||
{
|
||||
m_length = 0;
|
||||
}
|
||||
|
||||
// Appends an item to the end of the list and returns a handle to it.
|
||||
T& New()
|
||||
{
|
||||
_MakeRoomFor_threshold( m_length + 1 );
|
||||
return m_ptr[m_length++];
|
||||
}
|
||||
|
||||
// Gets an element of this memory allocation much as if it were an array.
|
||||
// DevBuilds : Throws Exception::IndexBoundsFault() if the index is invalid.
|
||||
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
|
||||
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
|
||||
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); }
|
||||
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); }
|
||||
|
||||
T* GetPtr() { return m_ptr; }
|
||||
const T* GetPtr() const { return m_ptr; }
|
||||
|
||||
T& GetLast() { return m_ptr[m_length-1]; }
|
||||
const T& GetLast() const{ return m_ptr[m_length-1]; }
|
||||
|
||||
int Add( const T& src )
|
||||
{
|
||||
MakeRoomFor( m_length + 1 );
|
||||
_MakeRoomFor_threshold( m_length + 1 );
|
||||
m_ptr[m_length] = src;
|
||||
return m_length++;
|
||||
}
|
||||
|
||||
// Same as Add, but returns the handle of the new object instead of it's array index.
|
||||
T& AddNew( const T& src )
|
||||
{
|
||||
_MakeRoomFor_threshold( m_length + 1 );
|
||||
m_ptr[m_length] = src;
|
||||
return m_ptr[m_length];
|
||||
}
|
||||
|
||||
// Performs a standard array-copy removal of the given item. All items past the
|
||||
// given item are copied over. Throws Exception::IndexBoundsFault() if the index
|
||||
// is invalid (devbuilds only)
|
||||
|
@ -347,6 +380,12 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
|
||||
void _MakeRoomFor_threshold( int newsize )
|
||||
{
|
||||
MakeRoomFor( newsize + ChunkSize );
|
||||
}
|
||||
|
||||
// A safe array index fetcher. Throws an exception if the array index
|
||||
// is outside the bounds of the array.
|
||||
// Performance Considerations: This function adds quite a bit of overhead
|
||||
|
@ -371,18 +410,14 @@ class SafeAlignedArray : public SafeArray<T>
|
|||
protected:
|
||||
T* _virtual_realloc( int newsize )
|
||||
{
|
||||
return (T*)_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment );
|
||||
return (T*)( ( this->m_ptr == NULL ) ?
|
||||
_aligned_malloc( newsize * sizeof(T), Alignment ) :
|
||||
_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment )
|
||||
);
|
||||
}
|
||||
|
||||
// Appends "(align: xx)" to the name of the allocation in devel builds.
|
||||
// Maybe useful,maybe not... no harm in attaching it. :D
|
||||
wxString _getName( const wxString& src )
|
||||
{
|
||||
if( IsDevBuild )
|
||||
return src + wxsFormat( L"(align: %d)", Alignment );
|
||||
else
|
||||
return src;
|
||||
}
|
||||
|
||||
public:
|
||||
virtual ~SafeAlignedArray()
|
||||
|
@ -391,28 +426,14 @@ public:
|
|||
// mptr is set to null, so the parent class's destructor won't re-free it.
|
||||
}
|
||||
|
||||
explicit SafeAlignedArray( const wxString& name = L"Unnamed") :
|
||||
explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) :
|
||||
SafeArray<T>::SafeArray( name )
|
||||
{
|
||||
}
|
||||
|
||||
explicit SafeAlignedArray( const char* name ) :
|
||||
SafeArray<T>::SafeArray( name )
|
||||
{
|
||||
}
|
||||
|
||||
explicit SafeAlignedArray( int initialSize, const wxString& name = L"Unnamed") :
|
||||
explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" ) :
|
||||
SafeArray<T>::SafeArray(
|
||||
_getName(name),
|
||||
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
|
||||
initialSize
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
explicit SafeAlignedArray( int initialSize, const char* name ) :
|
||||
SafeArray<T>::SafeArray(
|
||||
_getName(wxString::FromAscii(name)),
|
||||
name,
|
||||
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ),
|
||||
initialSize
|
||||
)
|
|
@ -0,0 +1,91 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/tokenzr.h>
|
||||
#include <wx/gdicmn.h> // for wxPoint/wxRect stuff
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers for wxWidgets stuff!
|
||||
//
|
||||
|
||||
// wxWidgets lacks one of its own...
|
||||
extern const wxRect wxDefaultRect;
|
||||
|
||||
// This should prove useful....
|
||||
#define wxsFormat wxString::Format
|
||||
|
||||
extern wxString ToString( const wxPoint& src, const wxString& separator=L"," );
|
||||
extern wxString ToString( const wxSize& src, const wxString& separator=L"," );
|
||||
extern wxString ToString( const wxRect& src, const wxString& separator=L"," );
|
||||
|
||||
extern bool TryParse( wxPoint& dest, const wxStringTokenizer& parts );
|
||||
extern bool TryParse( wxSize& dest, const wxStringTokenizer& parts );
|
||||
|
||||
extern bool TryParse( wxPoint& dest, const wxString& src, const wxPoint& defval=wxDefaultPosition, const wxString& separators=L",");
|
||||
extern bool TryParse( wxSize& dest, const wxString& src, const wxSize& defval=wxDefaultSize, const wxString& separators=L",");
|
||||
extern bool TryParse( wxRect& dest, const wxString& src, const wxRect& defval=wxDefaultRect, const wxString& separators=L",");
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// dummy structure used to type-guard the dummy parameter that's been inserted to
|
||||
// allow us to use the va_list feature on references.
|
||||
struct _VARG_PARAM
|
||||
{
|
||||
// just some value to make the struct length 32bits instead of 8 bits, so that the
|
||||
// compiler generates somewhat more efficient code.
|
||||
uint someval;
|
||||
};
|
||||
|
||||
#ifdef PCSX2_DEBUG
|
||||
|
||||
#define params va_arg_dummy,
|
||||
#define varg_assert() // jASSUME( dummy == &va_arg_dummy );
|
||||
// typedef the Va-Arg value to be a value type in debug builds. The value
|
||||
// type requires a little more overhead in terms of code generation, but is always
|
||||
// type-safe. The compiler will generate errors for any forgotten params value.
|
||||
typedef _VARG_PARAM VARG_PARAM;
|
||||
|
||||
#else
|
||||
|
||||
#define params NULL, // using null is faster / more compact!
|
||||
#define varg_assert() jASSUME( dummy == NULL );
|
||||
// typedef the Va-Arg value to be a pointer in release builds. Pointers
|
||||
// generate more compact code by a small margin, but aren't entirely type safe since
|
||||
// the compiler won't generate errors if you pass NULL or other values.
|
||||
typedef _VARG_PARAM const * VARG_PARAM;
|
||||
|
||||
#endif
|
||||
|
||||
extern const _VARG_PARAM va_arg_dummy;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Custom internal sprintf functions, which are ASCII only (even in UNICODE builds)
|
||||
//
|
||||
// These functions are useful since they are ASCII always, even under Unicode. Typically
|
||||
// even in a unicode app.
|
||||
|
||||
extern void ssprintf(std::string& dest, const char* fmt, ...);
|
||||
extern void ssappendf(std::string& dest, const char* format, ...);
|
||||
extern void vssprintf(std::string& dest, const char* format, va_list args);
|
||||
extern void vssappendf(std::string& dest, const char* format, va_list args);
|
||||
|
||||
extern std::string fmt_string( const char* fmt, ... );
|
||||
extern std::string vfmt_string( const char* fmt, va_list args );
|
|
@ -15,11 +15,11 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _THREADING_H_
|
||||
#define _THREADING_H_
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <errno.h> // EBUSY
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include "Pcsx2Defs.h"
|
||||
|
@ -276,4 +276,3 @@ namespace Threading
|
|||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -16,8 +16,7 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef _WIN_MEMZERO_H_
|
||||
#define _WIN_MEMZERO_H_
|
||||
#pragma once
|
||||
|
||||
// These functions are meant for memset operations of constant length only.
|
||||
// For dynamic length clears, use the C-compiler provided memset instead.
|
||||
|
@ -36,6 +35,11 @@
|
|||
// structures, which are constant in size, thus allowing us to generate optimal compile-
|
||||
// time code for each use of the function.
|
||||
|
||||
// Use of CLD (Clear Direction Flag):
|
||||
// On Windows platforms the ABI declares that the direction flag should be cleared upon
|
||||
// entry of *any* function. Therefore there is no need to have CLD prior to our use of
|
||||
// rep strosd here.
|
||||
|
||||
// Notes on XMM0's "storage" area (_xmm_backup):
|
||||
// Unfortunately there's no way to guarantee alignment for this variable. If I use the
|
||||
// __declspec(aligned(16)) decorator, MSVC fails to inline the function since stack
|
||||
|
@ -197,7 +201,6 @@ static __forceinline void memzero_ptr( void *dest )
|
|||
case 3:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest
|
||||
xor eax, eax
|
||||
stosd
|
||||
|
@ -209,7 +212,6 @@ static __forceinline void memzero_ptr( void *dest )
|
|||
case 4:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest
|
||||
xor eax, eax
|
||||
stosd
|
||||
|
@ -222,7 +224,6 @@ static __forceinline void memzero_ptr( void *dest )
|
|||
case 5:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest
|
||||
xor eax, eax
|
||||
stosd
|
||||
|
@ -236,7 +237,6 @@ static __forceinline void memzero_ptr( void *dest )
|
|||
default:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov ecx, remdat
|
||||
mov edi, dest
|
||||
xor eax, eax
|
||||
|
@ -336,7 +336,6 @@ static __forceinline void memset_8( void *dest )
|
|||
case 3:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -348,7 +347,6 @@ static __forceinline void memset_8( void *dest )
|
|||
case 4:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -361,7 +359,6 @@ static __forceinline void memset_8( void *dest )
|
|||
case 5:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -375,7 +372,6 @@ static __forceinline void memset_8( void *dest )
|
|||
default:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov ecx, remdat;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
|
@ -428,7 +424,6 @@ static __forceinline void memset_16( void *dest )
|
|||
case 3:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -440,7 +435,6 @@ static __forceinline void memset_16( void *dest )
|
|||
case 4:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -453,7 +447,6 @@ static __forceinline void memset_16( void *dest )
|
|||
case 5:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -467,7 +460,6 @@ static __forceinline void memset_16( void *dest )
|
|||
default:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov ecx, remdat;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
|
@ -515,7 +507,6 @@ static __forceinline void memset_32( void *dest )
|
|||
case 3:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -527,7 +518,6 @@ static __forceinline void memset_32( void *dest )
|
|||
case 4:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -540,7 +530,6 @@ static __forceinline void memset_32( void *dest )
|
|||
case 5:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
stosd;
|
||||
|
@ -554,7 +543,6 @@ static __forceinline void memset_32( void *dest )
|
|||
default:
|
||||
__asm
|
||||
{
|
||||
cld;
|
||||
mov ecx, remdat;
|
||||
mov edi, dest;
|
||||
mov eax, data32;
|
||||
|
@ -594,5 +582,3 @@ static __forceinline void memset32_obj( T& object )
|
|||
memset_32<data, sizeof(T)>( &object );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,954 @@
|
|||
/*
|
||||
Compatibility <intrin_x86.h> header for GCC -- GCC equivalents of intrinsic
|
||||
Microsoft Visual C++ functions. Originally developed for the ReactOS
|
||||
(<http://www.reactos.org/>) and TinyKrnl (<http://www.tinykrnl.org/>)
|
||||
projects.
|
||||
|
||||
Copyright (c) 2006 KJK::Hyperion <hackbunny@reactos.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef KJK_INTRIN_X86_H_
|
||||
#define KJK_INTRIN_X86_H_
|
||||
|
||||
/*
|
||||
FIXME: review all "memory" clobbers, add/remove to match Visual C++
|
||||
behavior: some "obvious" memory barriers are not present in the Visual C++
|
||||
implementation - e.g. __stosX; on the other hand, some memory barriers that
|
||||
*are* present could have been missed
|
||||
*/
|
||||
|
||||
/*
|
||||
NOTE: this is a *compatibility* header. Some functions may look wrong at
|
||||
first, but they're only "as wrong" as they would be on Visual C++. Our
|
||||
priority is compatibility
|
||||
|
||||
NOTE: unlike most people who write inline asm for GCC, I didn't pull the
|
||||
constraints and the uses of __volatile__ out of my... hat. Do not touch
|
||||
them. I hate cargo cult programming
|
||||
|
||||
NOTE: be very careful with declaring "memory" clobbers. Some "obvious"
|
||||
barriers aren't there in Visual C++ (e.g. __stosX)
|
||||
|
||||
NOTE: review all intrinsics with a return value, add/remove __volatile__
|
||||
where necessary. If an intrinsic whose value is ignored generates a no-op
|
||||
under Visual C++, __volatile__ must be omitted; if it always generates code
|
||||
(for example, if it has side effects), __volatile__ must be specified. GCC
|
||||
will only optimize out non-volatile asm blocks with outputs, so input-only
|
||||
blocks are safe. Oddities such as the non-volatile 'rdmsr' are intentional
|
||||
and follow Visual C++ behavior
|
||||
|
||||
NOTE: on GCC 4.1.0, please use the __sync_* built-ins for barriers and
|
||||
atomic operations. Test the version like this:
|
||||
|
||||
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
...
|
||||
|
||||
Pay attention to the type of barrier. Make it match with what Visual C++
|
||||
would use in the same case
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __SIZE_T
|
||||
#define __SIZE_T
|
||||
typedef unsigned int size_t;
|
||||
#endif
|
||||
|
||||
/*** Stack frame juggling ***/
|
||||
#define _ReturnAddress() (__builtin_return_address(0))
|
||||
#define _AddressOfReturnAddress() (&(((void **)(__builtin_frame_address(0)))[1]))
|
||||
/* TODO: __getcallerseflags but how??? */
|
||||
|
||||
|
||||
/*** Atomic operations ***/
|
||||
|
||||
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
#define _ReadWriteBarrier() __sync_synchronize()
|
||||
#else
|
||||
static void __inline__ __attribute__((always_inline)) _MemoryBarrier(void)
|
||||
{
|
||||
__asm__ __volatile__("" : : : "memory");
|
||||
}
|
||||
#define _ReadWriteBarrier() _MemoryBarrier()
|
||||
#endif
|
||||
|
||||
/* BUGBUG: GCC only supports full barriers */
|
||||
#define _ReadBarrier _ReadWriteBarrier
|
||||
#define _WriteBarrier _ReadWriteBarrier
|
||||
|
||||
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value)
|
||||
{
|
||||
/* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
|
||||
__sync_synchronize();
|
||||
return __sync_lock_test_and_set(Target, Value);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
|
||||
{
|
||||
/* NOTE: ditto */
|
||||
__sync_synchronize();
|
||||
return __sync_lock_test_and_set(Target, Value);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
|
||||
{
|
||||
return __sync_fetch_and_add(Addend, Value);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)
|
||||
{
|
||||
return __sync_fetch_and_and(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask)
|
||||
{
|
||||
return __sync_fetch_and_and(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask)
|
||||
{
|
||||
return __sync_fetch_and_and(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask)
|
||||
{
|
||||
return __sync_fetch_and_or(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask)
|
||||
{
|
||||
return __sync_fetch_and_or(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask)
|
||||
{
|
||||
return __sync_fetch_and_or(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask)
|
||||
{
|
||||
return __sync_fetch_and_xor(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask)
|
||||
{
|
||||
return __sync_fetch_and_xor(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask)
|
||||
{
|
||||
return __sync_fetch_and_xor(value, mask);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
|
||||
{
|
||||
char retval = Comperand;
|
||||
__asm__("lock; cmpxchgb %b[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange) : "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
|
||||
{
|
||||
short retval = Comperand;
|
||||
__asm__("lock; cmpxchgw %w[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange): "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
|
||||
{
|
||||
long retval = Comperand;
|
||||
__asm__("lock; cmpxchgl %k[Exchange], %[Destination]" : [retval] "+a" (retval) : [Destination] "m" (*Destination), [Exchange] "q" (Exchange): "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
|
||||
{
|
||||
long long retval = Comperand;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"cmpxchg8b %[Destination]" :
|
||||
[retval] "+A" (retval) :
|
||||
[Destination] "m" (*Destination),
|
||||
"b" ((unsigned long)((Exchange >> 0) & 0xFFFFFFFF)),
|
||||
"c" ((unsigned long)((Exchange >> 32) & 0xFFFFFFFF)) :
|
||||
"memory"
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
|
||||
{
|
||||
void * retval = (void *)Comperand;
|
||||
__asm__("lock; cmpxchgl %k[Exchange], %[Destination]" : [retval] "=a" (retval) : "[retval]" (retval), [Destination] "m" (*Destination), [Exchange] "q" (Exchange) : "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value)
|
||||
{
|
||||
long retval = Value;
|
||||
__asm__("xchgl %[retval], %[Target]" : [retval] "+r" (retval) : [Target] "m" (*Target) : "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
|
||||
{
|
||||
void * retval = Value;
|
||||
__asm__("xchgl %[retval], %[Target]" : [retval] "+r" (retval) : [Target] "m" (*Target) : "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
|
||||
{
|
||||
long retval = Value;
|
||||
__asm__("lock; xaddl %[retval], %[Addend]" : [retval] "+r" (retval) : [Addend] "m" (*Addend) : "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)
|
||||
{
|
||||
char x;
|
||||
char y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange8(value, x & mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask)
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange16(value, x & mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask)
|
||||
{
|
||||
long x;
|
||||
long y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange(value, x & mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask)
|
||||
{
|
||||
char x;
|
||||
char y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange8(value, x | mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask)
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange16(value, x | mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask)
|
||||
{
|
||||
long x;
|
||||
long y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange(value, x | mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask)
|
||||
{
|
||||
char x;
|
||||
char y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange8(value, x ^ mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask)
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange16(value, x ^ mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask)
|
||||
{
|
||||
long x;
|
||||
long y;
|
||||
|
||||
y = *value;
|
||||
|
||||
do
|
||||
{
|
||||
x = y;
|
||||
y = _InterlockedCompareExchange(value, x ^ mask, x);
|
||||
}
|
||||
while(y != x);
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value)
|
||||
{
|
||||
__asm__
|
||||
(
|
||||
"lock; add %[Value], %[Lo32];"
|
||||
"jae LABEL%=;"
|
||||
"lock; adc $0, %[Hi32];"
|
||||
"LABEL%=:;" :
|
||||
[Lo32] "=m" (*((volatile long *)(Addend) + 0)), [Hi32] "=m" (*((volatile long *)(Addend) + 1)) :
|
||||
[Value] "ir" (Value)
|
||||
);
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedDecrement(volatile long * const lpAddend)
|
||||
{
|
||||
return _InterlockedExchangeAdd(lpAddend, -1) - 1;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedIncrement(volatile long * const lpAddend)
|
||||
{
|
||||
return _InterlockedExchangeAdd(lpAddend, 1) + 1;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandreset(volatile long * a, const long b)
|
||||
{
|
||||
unsigned char retval;
|
||||
__asm__("lock; btrl %[b], %[a]; setb %b[retval]" : [retval] "=r" (retval), [a] "=m" (a) : [b] "Ir" (b) : "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandset(volatile long * a, const long b)
|
||||
{
|
||||
unsigned char retval;
|
||||
__asm__("lock; btsl %[b], %[a]; setc %b[retval]" : [retval] "=r" (retval), [a] "=m" (a) : [b] "Ir" (b) : "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*** String operations ***/
|
||||
/* NOTE: we don't set a memory clobber in the __stosX functions because Visual C++ doesn't */
|
||||
static __inline__ __attribute__((always_inline)) void __stosb(unsigned char * Dest, const unsigned char Data, size_t Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; stosb" :
|
||||
[Dest] "=D" (Dest), [Count] "=c" (Count) :
|
||||
"[Dest]" (Dest), "a" (Data), "[Count]" (Count)
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __stosw(unsigned short * Dest, const unsigned short Data, size_t Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; stosw" :
|
||||
[Dest] "=D" (Dest), [Count] "=c" (Count) :
|
||||
"[Dest]" (Dest), "a" (Data), "[Count]" (Count)
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __stosd(unsigned long * Dest, const unsigned long Data, size_t Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; stosl" :
|
||||
[Dest] "=D" (Dest), [Count] "=c" (Count) :
|
||||
"[Dest]" (Dest), "a" (Data), "[Count]" (Count)
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __movsb(unsigned char * Destination, const unsigned char * Source, size_t Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; movsb" :
|
||||
[Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) :
|
||||
"[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count)
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __movsw(unsigned short * Destination, const unsigned short * Source, size_t Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; movsw" :
|
||||
[Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) :
|
||||
"[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count)
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __movsd(unsigned long * Destination, const unsigned long * Source, size_t Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; movsd" :
|
||||
[Destination] "=D" (Destination), [Source] "=S" (Source), [Count] "=c" (Count) :
|
||||
"[Destination]" (Destination), "[Source]" (Source), "[Count]" (Count)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*** FS segment addressing ***/
|
||||
static __inline__ __attribute__((always_inline)) void __writefsbyte(const unsigned long Offset, const unsigned char Data)
|
||||
{
|
||||
__asm__("movb %b[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writefsword(const unsigned long Offset, const unsigned short Data)
|
||||
{
|
||||
__asm__("movw %w[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writefsdword(const unsigned long Offset, const unsigned long Data)
|
||||
{
|
||||
__asm__("movl %k[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char __readfsbyte(const unsigned long Offset)
|
||||
{
|
||||
unsigned char value;
|
||||
__asm__("movb %%fs:%a[Offset], %b[value]" : [value] "=q" (value) : [Offset] "irm" (Offset));
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned short __readfsword(const unsigned long Offset)
|
||||
{
|
||||
unsigned short value;
|
||||
__asm__("movw %%fs:%a[Offset], %w[value]" : [value] "=q" (value) : [Offset] "irm" (Offset));
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __readfsdword(const unsigned long Offset)
|
||||
{
|
||||
unsigned long value;
|
||||
__asm__("movl %%fs:%a[Offset], %k[value]" : [value] "=q" (value) : [Offset] "irm" (Offset));
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __incfsbyte(const unsigned long Offset)
|
||||
{
|
||||
__asm__("incb %%fs:%a[Offset]" : : [Offset] "ir" (Offset));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __incfsword(const unsigned long Offset)
|
||||
{
|
||||
__asm__("incw %%fs:%a[Offset]" : : [Offset] "ir" (Offset));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __incfsdword(const unsigned long Offset)
|
||||
{
|
||||
__asm__("incl %%fs:%a[Offset]" : : [Offset] "ir" (Offset));
|
||||
}
|
||||
|
||||
/* NOTE: the bizarre implementation of __addfsxxx mimics the broken Visual C++ behavior */
|
||||
static __inline__ __attribute__((always_inline)) void __addfsbyte(const unsigned long Offset, const unsigned char Data)
|
||||
{
|
||||
if(!__builtin_constant_p(Offset))
|
||||
__asm__("addb %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset));
|
||||
else
|
||||
__asm__("addb %b[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __addfsword(const unsigned long Offset, const unsigned short Data)
|
||||
{
|
||||
if(!__builtin_constant_p(Offset))
|
||||
__asm__("addw %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset));
|
||||
else
|
||||
__asm__("addw %w[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __addfsdword(const unsigned long Offset, const unsigned int Data)
|
||||
{
|
||||
if(!__builtin_constant_p(Offset))
|
||||
__asm__("addl %k[Offset], %%fs:%a[Offset]" : : [Offset] "r" (Offset));
|
||||
else
|
||||
__asm__("addl %k[Data], %%fs:%a[Offset]" : : [Offset] "ir" (Offset), [Data] "iq" (Data));
|
||||
}
|
||||
|
||||
|
||||
/*** Bit manipulation ***/
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask)
|
||||
{
|
||||
__asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
|
||||
return Mask ? 1 : 0;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask)
|
||||
{
|
||||
__asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask));
|
||||
return Mask ? 1 : 0;
|
||||
}
|
||||
|
||||
/* NOTE: again, the bizarre implementation follows Visual C++ */
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b)
|
||||
{
|
||||
unsigned char retval;
|
||||
|
||||
if(__builtin_constant_p(b))
|
||||
__asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32));
|
||||
else
|
||||
__asm__("bt %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _bittestandcomplement(long * const a, const long b)
|
||||
{
|
||||
unsigned char retval;
|
||||
|
||||
if(__builtin_constant_p(b))
|
||||
__asm__("btc %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32));
|
||||
else
|
||||
__asm__("btc %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _bittestandreset(long * const a, const long b)
|
||||
{
|
||||
unsigned char retval;
|
||||
|
||||
if(__builtin_constant_p(b))
|
||||
__asm__("btr %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32));
|
||||
else
|
||||
__asm__("btr %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _bittestandset(long * const a, const long b)
|
||||
{
|
||||
unsigned char retval;
|
||||
|
||||
if(__builtin_constant_p(b))
|
||||
__asm__("bts %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*(a + (b / 32))), [b] "Ir" (b % 32));
|
||||
else
|
||||
__asm__("bts %[b], %[a]; setb %b[retval]" : [retval] "=q" (retval) : [a] "mr" (*a), [b] "r" (b));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _rotl8(const unsigned char value, const unsigned char shift)
|
||||
{
|
||||
unsigned char retval;
|
||||
__asm__("rolb %b[shift], %b[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned short _rotl16(const unsigned short value, const unsigned char shift)
|
||||
{
|
||||
unsigned short retval;
|
||||
__asm__("rolw %b[shift], %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _rotr8(const unsigned char value, const unsigned char shift)
|
||||
{
|
||||
unsigned char retval;
|
||||
__asm__("rorb %b[shift], %b[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned short _rotr16(const unsigned short value, const unsigned char shift)
|
||||
{
|
||||
unsigned short retval;
|
||||
__asm__("rorw %b[shift], %w[retval]" : [retval] "=rm" (retval) : "[retval]" (value), [shift] "Nc" (shift));
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
NOTE: in __ll_lshift, __ll_rshift and __ull_rshift we use the "A"
|
||||
constraint (edx:eax) for the Mask argument, because it's the only way GCC
|
||||
can pass 64-bit operands around - passing the two 32 bit parts separately
|
||||
just confuses it. Also we declare Bit as an int and then truncate it to
|
||||
match Visual C++ behavior
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, const int Bit)
|
||||
{
|
||||
unsigned long long retval = Mask;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"shldl %b[Bit], %%eax, %%edx; sall %b[Bit], %%eax" :
|
||||
"+A" (retval) :
|
||||
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit)
|
||||
{
|
||||
unsigned long long retval = Mask;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"shldl %b[Bit], %%eax, %%edx; sarl %b[Bit], %%eax" :
|
||||
"+A" (retval) :
|
||||
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
|
||||
{
|
||||
unsigned long long retval = Mask;
|
||||
|
||||
__asm__
|
||||
(
|
||||
"shrdl %b[Bit], %%eax, %%edx; shrl %b[Bit], %%eax" :
|
||||
"+A" (retval) :
|
||||
[Bit] "Nc" ((unsigned char)((unsigned long)Bit) & 0xFF)
|
||||
);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*** 64-bit math ***/
|
||||
static __inline__ __attribute__((always_inline)) long long __emul(const int a, const int b)
|
||||
{
|
||||
long long retval;
|
||||
__asm__("imull %[b]" : "=A" (retval) : [a] "a" (a), [b] "rm" (b));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __emulu(const unsigned int a, const unsigned int b)
|
||||
{
|
||||
unsigned long long retval;
|
||||
__asm__("mull %[b]" : "=A" (retval) : [a] "a" (a), [b] "rm" (b));
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*** Port I/O ***/
|
||||
static __inline__ __attribute__((always_inline)) unsigned char __inbyte(const unsigned short Port)
|
||||
{
|
||||
unsigned char byte;
|
||||
__asm__ __volatile__("inb %w[Port], %b[byte]" : [byte] "=a" (byte) : [Port] "Nd" (Port));
|
||||
return byte;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned short __inword(const unsigned short Port)
|
||||
{
|
||||
unsigned short word;
|
||||
__asm__ __volatile__("inw %w[Port], %w[word]" : [word] "=a" (word) : [Port] "Nd" (Port));
|
||||
return word;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __indword(const unsigned short Port)
|
||||
{
|
||||
unsigned long dword;
|
||||
__asm__ __volatile__("inl %w[Port], %k[dword]" : [dword] "=a" (dword) : [Port] "Nd" (Port));
|
||||
return dword;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __inbytestring(unsigned short Port, unsigned char * Buffer, unsigned long Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; insb" :
|
||||
[Buffer] "=D" (Buffer), [Count] "=c" (Count) :
|
||||
"d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) :
|
||||
"memory"
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __inwordstring(unsigned short Port, unsigned short * Buffer, unsigned long Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; insw" :
|
||||
[Buffer] "=D" (Buffer), [Count] "=c" (Count) :
|
||||
"d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) :
|
||||
"memory"
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __indwordstring(unsigned short Port, unsigned long * Buffer, unsigned long Count)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
"rep; insl" :
|
||||
[Buffer] "=D" (Buffer), [Count] "=c" (Count) :
|
||||
"d" (Port), "[Buffer]" (Buffer), "[Count]" (Count) :
|
||||
"memory"
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outbyte(unsigned short const Port, const unsigned char Data)
|
||||
{
|
||||
__asm__ __volatile__("outb %b[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outword(unsigned short const Port, const unsigned short Data)
|
||||
{
|
||||
__asm__ __volatile__("outw %w[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outdword(unsigned short const Port, const unsigned long Data)
|
||||
{
|
||||
__asm__ __volatile__("outl %k[Data], %w[Port]" : : [Port] "Nd" (Port), [Data] "a" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outbytestring(unsigned short const Port, const unsigned char * const Buffer, const unsigned long Count)
|
||||
{
|
||||
__asm__ __volatile__("rep; outsb" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outwordstring(unsigned short const Port, const unsigned short * const Buffer, const unsigned long Count)
|
||||
{
|
||||
__asm__ __volatile__("rep; outsw" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outdwordstring(unsigned short const Port, const unsigned long * const Buffer, const unsigned long Count)
|
||||
{
|
||||
__asm__ __volatile__("rep; outsl" : : [Port] "d" (Port), [Buffer] "S" (Buffer), "c" (Count));
|
||||
}
|
||||
|
||||
|
||||
/*** System information ***/
|
||||
static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType)
|
||||
{
|
||||
__asm__ __volatile__("cpuid" : "=a" (CPUInfo[0]), "=b" (CPUInfo[1]), "=c" (CPUInfo[2]), "=d" (CPUInfo[3]) : "a" (InfoType));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void)
|
||||
{
|
||||
unsigned long long retval;
|
||||
__asm__ __volatile__("rdtsc" : "=A"(retval));
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*** Interrupts ***/
|
||||
static __inline__ __attribute__((always_inline)) void __debugbreak(void)
|
||||
{
|
||||
__asm__("int $3");
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __int2c(void)
|
||||
{
|
||||
__asm__("int $0x2c");
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void _disable(void)
|
||||
{
|
||||
__asm__("cli");
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void _enable(void)
|
||||
{
|
||||
__asm__("sti");
|
||||
}
|
||||
|
||||
|
||||
/*** Protected memory management ***/
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __readcr0(void)
|
||||
{
|
||||
unsigned long value;
|
||||
__asm__ __volatile__("mov %%cr0, %[value]" : [value] "=q" (value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __readcr2(void)
|
||||
{
|
||||
unsigned long value;
|
||||
__asm__ __volatile__("mov %%cr2, %[value]" : [value] "=q" (value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __readcr3(void)
|
||||
{
|
||||
unsigned long value;
|
||||
__asm__ __volatile__("mov %%cr3, %[value]" : [value] "=q" (value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __readcr4(void)
|
||||
{
|
||||
unsigned long value;
|
||||
__asm__ __volatile__("mov %%cr4, %[value]" : [value] "=q" (value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writecr0(const unsigned long long Data)
|
||||
{
|
||||
__asm__("mov %[Data], %%cr0" : : [Data] "q" ((const unsigned long)(Data & 0xFFFFFFFF)) : "memory");
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writecr3(const unsigned long long Data)
|
||||
{
|
||||
__asm__("mov %[Data], %%cr3" : : [Data] "q" ((const unsigned long)(Data & 0xFFFFFFFF)) : "memory");
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writecr4(const unsigned long long Data)
|
||||
{
|
||||
__asm__("mov %[Data], %%cr4" : : [Data] "q" ((const unsigned long)(Data & 0xFFFFFFFF)) : "memory");
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __invlpg(void * const Address)
|
||||
{
|
||||
__asm__("invlpg %[Address]" : : [Address] "m" (*((unsigned char *)(Address))));
|
||||
}
|
||||
|
||||
|
||||
/*** System operations ***/
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __readmsr(const int reg)
|
||||
{
|
||||
unsigned long long retval;
|
||||
__asm__ __volatile__("rdmsr" : "=A" (retval) : "c" (reg));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writemsr(const unsigned long Register, const unsigned long long Value)
|
||||
{
|
||||
__asm__ __volatile__("wrmsr" : : "A" (Value), "c" (Register));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __readpmc(const int counter)
|
||||
{
|
||||
unsigned long long retval;
|
||||
__asm__ __volatile__("rdpmc" : "=A" (retval) : "c" (counter));
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* NOTE: an immediate value for 'a' will raise an ICE in Visual C++ */
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __segmentlimit(const unsigned long a)
|
||||
{
|
||||
unsigned long retval;
|
||||
__asm__ __volatile__("lsl %[a], %[retval]" : [retval] "=r" (retval) : [a] "rm" (a));
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __wbinvd(void)
|
||||
{
|
||||
__asm__ __volatile__("wbinvd");
|
||||
}
|
||||
|
||||
#endif /* KJK_INTRIN_X86_H_ */
|
||||
|
||||
/* EOF */
|
|
@ -47,22 +47,6 @@ public:
|
|||
EmitSibMagic( from, to );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __forceinline void operator()( const xRegister<T>& to, const void* src ) const
|
||||
{
|
||||
prefix16<T>();
|
||||
xWrite8( (Is8BitOp<T>() ? 2 : 3) | (InstType<<3) );
|
||||
EmitSibMagic( to, src );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __forceinline void operator()( void* dest, const xRegister<T>& from ) const
|
||||
{
|
||||
prefix16<T>();
|
||||
xWrite8( (Is8BitOp<T>() ? 0 : 1) | (InstType<<3) );
|
||||
EmitSibMagic( from, dest );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const ModSibBase& sibdest, const xRegister<T>& from ) const
|
||||
{
|
||||
|
@ -126,6 +110,37 @@ public:
|
|||
xWrite<T>( imm );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg<T>& immOrReg ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, immOrReg );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, const xImmReg<T>& immOrReg ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, immOrReg );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, int imm ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, imm );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, const xDirectOrIndirect<T>& from ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, from );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xRegister<T>& to, const xDirectOrIndirect<T>& from ) const
|
||||
{
|
||||
_DoI_helpermess( *this, xDirectOrIndirect<T>( to ), from );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, const xRegister<T>& from ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, xDirectOrIndirect<T>( from ) );
|
||||
}
|
||||
|
||||
xImpl_Group1() {} // Why does GCC need these?
|
||||
};
|
||||
|
@ -168,7 +183,6 @@ protected:
|
|||
template< u8 Prefix > struct Woot
|
||||
{
|
||||
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType cmptype ) const{ xOpWrite0F( Prefix, 0xc2, to, from, (u8)cmptype ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from, SSE2_ComparisonType cmptype ) const { xOpWrite0F( Prefix, 0xc2, to, from, (u8)cmptype ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from, SSE2_ComparisonType cmptype ) const { xOpWrite0F( Prefix, 0xc2, to, from, (u8)cmptype ); }
|
||||
Woot() {}
|
||||
};
|
|
@ -94,5 +94,17 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, u8 imm ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, imm );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, const xRegisterCL& from ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, from );
|
||||
}
|
||||
|
||||
|
||||
Group2ImplAll() {} // I am a class with no members, so I need an explicit constructor! Sense abounds.
|
||||
};
|
|
@ -52,7 +52,11 @@ public:
|
|||
xWrite8( Is8BitOp<T>() ? 0xf6 : 0xf7 );
|
||||
EmitSibMagic( InstType, from );
|
||||
}
|
||||
|
||||
|
||||
template< typename T > __emitinline void operator()( const xDirectOrIndirect<T>& from ) const
|
||||
{
|
||||
_DoI_helpermess( *this, from );
|
||||
}
|
||||
xImpl_Group3() {}
|
||||
};
|
||||
|
||||
|
@ -97,13 +101,11 @@ public:
|
|||
using ImplMulDivBase<G3Type_iMUL,0x59>::operator();
|
||||
|
||||
__forceinline void operator()( const xRegister32& to, const xRegister32& from ) const { xOpWrite0F( 0xaf, to, from ); }
|
||||
__forceinline void operator()( const xRegister32& to, const void* src ) const { xOpWrite0F( 0xaf, to, src ); }
|
||||
__forceinline void operator()( const xRegister32& to, const ModSibBase& src ) const { xOpWrite0F( 0xaf, to, src ); }
|
||||
__forceinline void operator()( const xRegister32& to, const xRegister32& from, s32 imm ) const{ ImmStyle( to, from, imm ); }
|
||||
__forceinline void operator()( const xRegister32& to, const ModSibBase& from, s32 imm ) const { ImmStyle( to, from, imm ); }
|
||||
|
||||
__forceinline void operator()( const xRegister16& to, const xRegister16& from ) const { xOpWrite0F( 0x66, 0xaf, to, from ); }
|
||||
__forceinline void operator()( const xRegister16& to, const void* src ) const { xOpWrite0F( 0x66, 0xaf, to, src ); }
|
||||
__forceinline void operator()( const xRegister16& to, const ModSibBase& src ) const { xOpWrite0F( 0x66, 0xaf, to, src ); }
|
||||
__forceinline void operator()( const xRegister16& to, const xRegister16& from, s16 imm ) const{ ImmStyle( to, from, imm ); }
|
||||
__forceinline void operator()( const xRegister16& to, const ModSibBase& from, s16 imm ) const { ImmStyle( to, from, imm ); }
|
|
@ -0,0 +1,157 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// helpers.h -- Various universally helpful functions for emitter convenience!
|
||||
//
|
||||
// Note: Header file should be included from the x86Emitter::Internal namespace, such
|
||||
// that all members contained within are in said namespace.
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
extern void SimdPrefix( u8 prefix, u16 opcode );
|
||||
extern void EmitSibMagic( uint regfield, const void* address );
|
||||
extern void EmitSibMagic( uint regfield, const ModSibBase& info );
|
||||
extern void xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward );
|
||||
|
||||
template< typename T > bool Is8BitOp() { return sizeof(T) == 1; }
|
||||
template< typename T > void prefix16() { if( sizeof(T) == 2 ) xWrite8( 0x66 ); }
|
||||
|
||||
|
||||
// Writes a ModRM byte for "Direct" register access forms, which is used for all
|
||||
// instructions taking a form of [reg,reg].
|
||||
template< typename T > __emitinline
|
||||
void EmitSibMagic( uint reg1, const xRegisterBase<T>& reg2 )
|
||||
{
|
||||
xWrite8( (Mod_Direct << 6) | (reg1 << 3) | reg2.Id );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void EmitSibMagic( const xRegisterBase<T1> reg1, const xRegisterBase<T2>& reg2 )
|
||||
{
|
||||
xWrite8( (Mod_Direct << 6) | (reg1.Id << 3) | reg2.Id );
|
||||
}
|
||||
|
||||
template< typename T1 > __emitinline
|
||||
void EmitSibMagic( const xRegisterBase<T1> reg1, const void* src ) { EmitSibMagic( reg1.Id, src ); }
|
||||
|
||||
template< typename T1 > __emitinline
|
||||
void EmitSibMagic( const xRegisterBase<T1> reg1, const ModSibBase& sib ) { EmitSibMagic( reg1.Id, sib ); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
if( prefix != 0 )
|
||||
xWrite16( (opcode<<8) | prefix );
|
||||
else
|
||||
xWrite8( opcode );
|
||||
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
SimdPrefix( prefix, opcode );
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8 )
|
||||
{
|
||||
xOpWrite0F( prefix, opcode, param1, param2 );
|
||||
xWrite8( imm8 );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2 ) { xOpWrite0F( 0, opcode, param1, param2 ); }
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) { xOpWrite0F( 0, opcode, param1, param2, imm8 ); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
template< typename xImpl, typename T >
|
||||
void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect<T>& to, const xImmReg<T>& immOrReg )
|
||||
{
|
||||
if( to.IsDirect() )
|
||||
{
|
||||
if( immOrReg.IsReg() )
|
||||
helpme( to.GetReg(), immOrReg.GetReg() );
|
||||
else
|
||||
helpme( to.GetReg(), immOrReg.GetImm() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( immOrReg.IsReg() )
|
||||
helpme( to.GetMem(), immOrReg.GetReg() );
|
||||
else
|
||||
helpme( to.GetMem(), immOrReg.GetImm() );
|
||||
}
|
||||
}
|
||||
|
||||
template< typename xImpl, typename T >
|
||||
void _DoI_helpermess( const xImpl& helpme, const ModSibBase& to, const xImmReg<T>& immOrReg )
|
||||
{
|
||||
if( immOrReg.IsReg() )
|
||||
helpme( to, immOrReg.GetReg() );
|
||||
else
|
||||
helpme( ModSibStrict<T>(to), immOrReg.GetImm() );
|
||||
}
|
||||
|
||||
template< typename xImpl, typename T >
|
||||
void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect<T>& to, int imm )
|
||||
{
|
||||
if( to.IsDirect() )
|
||||
helpme( to.GetReg(), imm );
|
||||
else
|
||||
helpme( to.GetMem(), imm );
|
||||
}
|
||||
|
||||
template< typename xImpl, typename T >
|
||||
void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect<T>& parm )
|
||||
{
|
||||
if( parm.IsDirect() )
|
||||
helpme( parm.GetReg() );
|
||||
else
|
||||
helpme( parm.GetMem() );
|
||||
}
|
||||
|
||||
template< typename xImpl, typename T >
|
||||
void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect<T>& to, const xDirectOrIndirect<T>& from )
|
||||
{
|
||||
if( to.IsDirect() && from.IsDirect() )
|
||||
helpme( to.GetReg(), from.GetReg() );
|
||||
|
||||
else if( to.IsDirect() )
|
||||
helpme( to.GetReg(), from.GetMem() );
|
||||
|
||||
else if( from.IsDirect() )
|
||||
helpme( to.GetMem(), from.GetReg() );
|
||||
|
||||
else
|
||||
|
||||
// One of the fields needs to be direct, or else we cannot complete the operation.
|
||||
// (intel doesn't support indirects in both fields)
|
||||
|
||||
jASSUME( false );
|
||||
}
|
|
@ -0,0 +1,239 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Header: ix86_impl_movs.h -- covers mov, cmov, movsx/movzx, and SETcc (which shares
|
||||
// with cmov many similarities).
|
||||
|
||||
// Note: This header is meant to be included from within the x86Emitter::Internal namespace.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MOV instruction Implementation
|
||||
|
||||
class MovImplAll
|
||||
{
|
||||
public:
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __forceinline void operator()( const xRegister<T>& to, const xRegister<T>& from ) const
|
||||
{
|
||||
if( to == from ) return; // ignore redundant MOVs.
|
||||
|
||||
prefix16<T>();
|
||||
xWrite8( Is8BitOp<T>() ? 0x88 : 0x89 );
|
||||
EmitSibMagic( from, to );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const ModSibBase& dest, const xRegister<T>& from ) const
|
||||
{
|
||||
prefix16<T>();
|
||||
|
||||
// mov eax has a special from when writing directly to a DISP32 address
|
||||
// (sans any register index/base registers).
|
||||
|
||||
if( from.IsAccumulator() && dest.Index.IsEmpty() && dest.Base.IsEmpty() )
|
||||
{
|
||||
xWrite8( Is8BitOp<T>() ? 0xa2 : 0xa3 );
|
||||
xWrite32( dest.Displacement );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite8( Is8BitOp<T>() ? 0x88 : 0x89 );
|
||||
EmitSibMagic( from.Id, dest );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const xRegister<T>& to, const ModSibBase& src ) const
|
||||
{
|
||||
prefix16<T>();
|
||||
|
||||
// mov eax has a special from when reading directly from a DISP32 address
|
||||
// (sans any register index/base registers).
|
||||
|
||||
if( to.IsAccumulator() && src.Index.IsEmpty() && src.Base.IsEmpty() )
|
||||
{
|
||||
xWrite8( Is8BitOp<T>() ? 0xa0 : 0xa1 );
|
||||
xWrite32( src.Displacement );
|
||||
}
|
||||
else
|
||||
{
|
||||
xWrite8( Is8BitOp<T>() ? 0x8a : 0x8b );
|
||||
EmitSibMagic( to, src );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const ModSibStrict<T>& dest, int imm ) const
|
||||
{
|
||||
prefix16<T>();
|
||||
xWrite8( Is8BitOp<T>() ? 0xc6 : 0xc7 );
|
||||
EmitSibMagic( 0, dest );
|
||||
xWrite<T>( imm );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// preserve_flags - set to true to disable optimizations which could alter the state of
|
||||
// the flags (namely replacing mov reg,0 with xor).
|
||||
template< typename T > __emitinline void operator()( const xRegister<T>& to, int imm, bool preserve_flags=false ) const
|
||||
{
|
||||
if( !preserve_flags && (imm == 0) )
|
||||
xXOR( to, to );
|
||||
else
|
||||
{
|
||||
// Note: MOV does not have (reg16/32,imm8) forms.
|
||||
|
||||
prefix16<T>();
|
||||
xWrite8( (Is8BitOp<T>() ? 0xb0 : 0xb8) | to.Id );
|
||||
xWrite<T>( imm );
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg<T>& immOrReg ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, immOrReg );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, const xImmReg<T>& immOrReg ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, immOrReg );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, int imm ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, imm );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, const xDirectOrIndirect<T>& from ) const
|
||||
{
|
||||
if( to == from ) return;
|
||||
_DoI_helpermess( *this, to, from );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xRegister<T>& to, const xDirectOrIndirect<T>& from ) const
|
||||
{
|
||||
_DoI_helpermess( *this, xDirectOrIndirect<T>( to ), from );
|
||||
}
|
||||
|
||||
template< typename T > __noinline void operator()( const xDirectOrIndirect<T>& to, const xRegister<T>& from ) const
|
||||
{
|
||||
_DoI_helpermess( *this, to, xDirectOrIndirect<T>( from ) );
|
||||
}
|
||||
|
||||
MovImplAll() {} // Satisfy GCC's whims.
|
||||
};
|
||||
|
||||
#define ccSane() jASSUME( ccType >= 0 && ccType <= 0x0f )
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CMOV !! [in all of it's disappointing lack-of glory] .. and ..
|
||||
// SETcc!! [more glory, less lack!]
|
||||
//
|
||||
// CMOV Disclaimer: Caution! This instruction can look exciting and cool, until you
|
||||
// realize that it cannot load immediate values into registers. -_-
|
||||
//
|
||||
// I use explicit method declarations here instead of templates, in order to provide
|
||||
// *only* 32 and 16 bit register operand forms (8 bit registers are not valid in CMOV).
|
||||
//
|
||||
class CMovImplGeneric
|
||||
{
|
||||
public:
|
||||
__forceinline void operator()( JccComparisonType ccType, const xRegister32& to, const xRegister32& from ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, from ); }
|
||||
__noinline void operator()( JccComparisonType ccType, const xRegister32& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x40 | ccType, to, sibsrc ); }
|
||||
//__noinline void operator()( JccComparisonType ccType, const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); } // too.. lazy.. to fix.
|
||||
|
||||
__forceinline void operator()( JccComparisonType ccType, const xRegister16& to, const xRegister16& from ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, from ); }
|
||||
__noinline void operator()( JccComparisonType ccType, const xRegister16& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x66, 0x40 | ccType, to, sibsrc ); }
|
||||
//__noinline void operator()( JccComparisonType ccType, const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); }
|
||||
|
||||
CMovImplGeneric() {} // don't ask.
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< JccComparisonType ccType >
|
||||
class CMovImplAll
|
||||
{
|
||||
static const u16 Opcode = 0x40 | ccType;
|
||||
|
||||
public:
|
||||
__forceinline void operator()( const xRegister32& to, const xRegister32& from ) const { ccSane(); xOpWrite0F( Opcode, to, from ); }
|
||||
__noinline void operator()( const xRegister32& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( Opcode, to, sibsrc ); }
|
||||
__noinline void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); }
|
||||
|
||||
__forceinline void operator()( const xRegister16& to, const xRegister16& from ) const { ccSane(); xOpWrite0F( 0x66, Opcode, to, from ); }
|
||||
__noinline void operator()( const xRegister16& to, const ModSibBase& sibsrc ) const { ccSane(); xOpWrite0F( 0x66, Opcode, to, sibsrc ); }
|
||||
__noinline void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const { ccSane(); _DoI_helpermess( *this, to, from ); }
|
||||
|
||||
CMovImplAll() {} // don't ask.
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
class SetImplGeneric
|
||||
{
|
||||
// note: SETcc are 0x90, with 0 in the Reg field of ModRM.
|
||||
public:
|
||||
__forceinline void operator()( JccComparisonType ccType, const xRegister8& to ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, to ); }
|
||||
__noinline void operator()( JccComparisonType ccType, const ModSibStrict<u8>& dest ) const { ccSane(); xOpWrite0F( 0x90 | ccType, 0, dest ); }
|
||||
|
||||
SetImplGeneric() {} // if you do, ask GCC.
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< JccComparisonType ccType >
|
||||
class SetImplAll
|
||||
{
|
||||
static const u16 Opcode = 0x90 | ccType; // SETcc are 0x90 base opcode, with 0 in the Reg field of ModRM.
|
||||
|
||||
public:
|
||||
__forceinline void operator()( const xRegister8& to ) const { ccSane(); xOpWrite0F( Opcode, 0, to ); }
|
||||
__noinline void operator()( const ModSibStrict<u8>& dest ) const { ccSane(); xOpWrite0F( Opcode, 0, dest ); }
|
||||
__noinline void operator()( const xDirectOrIndirect8& dest ) const { ccSane(); _DoI_helpermess( *this, dest ); }
|
||||
|
||||
SetImplAll() {} // if you do, ask GCC.
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Mov with sign/zero extension implementations (movsx / movzx)
|
||||
//
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< bool SignExtend >
|
||||
class MovExtendImplAll
|
||||
{
|
||||
protected:
|
||||
static const u16 Opcode = 0xb6 | (SignExtend ? 8 : 0 );
|
||||
|
||||
public:
|
||||
__forceinline void operator()( const xRegister32& to, const xRegister16& from ) const { xOpWrite0F( Opcode+1, to, from ); }
|
||||
__noinline void operator()( const xRegister32& to, const ModSibStrict<u16>& sibsrc ) const { xOpWrite0F( Opcode+1, to, sibsrc ); }
|
||||
__noinline void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const { _DoI_helpermess( *this, to, src ); }
|
||||
|
||||
__forceinline void operator()( const xRegister32& to, const xRegister8& from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
__noinline void operator()( const xRegister32& to, const ModSibStrict<u8>& sibsrc ) const { xOpWrite0F( Opcode, to, sibsrc ); }
|
||||
__noinline void operator()( const xRegister32& to, const xDirectOrIndirect8& src ) const { _DoI_helpermess( *this, to, src ); }
|
||||
|
||||
__forceinline void operator()( const xRegister16& to, const xRegister8& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); }
|
||||
__noinline void operator()( const xRegister16& to, const ModSibStrict<u8>& sibsrc ) const { xOpWrite0F( 0x66, Opcode, to, sibsrc ); }
|
||||
__noinline void operator()( const xRegister16& to, const xDirectOrIndirect8& src ) const { _DoI_helpermess( *this, to, src ); }
|
||||
|
||||
MovExtendImplAll() {} // don't ask.
|
||||
};
|
||||
|
|
@ -86,8 +86,6 @@ public:
|
|||
|
||||
__forceinline void operator()( const xRegister32& to, const xRegister32& from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegister16& to, const xRegister16& from ) const { xOpWrite0F( 0x66, Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegister32& to, const void* src ) const { xOpWrite0F( Opcode, to, src ); }
|
||||
__forceinline void operator()( const xRegister16& to, const void* src ) const { xOpWrite0F( 0x66, Opcode, to, src ); }
|
||||
__forceinline void operator()( const xRegister32& to, const ModSibBase& sibsrc ) const { xOpWrite0F( Opcode, to, sibsrc ); }
|
||||
__forceinline void operator()( const xRegister16& to, const ModSibBase& sibsrc ) const { xOpWrite0F( 0x66, Opcode, to, sibsrc ); }
|
||||
};
|
||||
|
@ -104,13 +102,9 @@ public:
|
|||
__forceinline void operator()( const xRegister16& bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitbase, bitoffset ); }
|
||||
__forceinline void operator()( const ModSibBase& bitbase, const xRegister32& bitoffset ) const { xOpWrite0F( RegFormOp, bitoffset, bitbase ); }
|
||||
__forceinline void operator()( const ModSibBase& bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitoffset, bitbase ); }
|
||||
__forceinline void operator()( const void* bitbase, const xRegister32& bitoffset ) const { xOpWrite0F( 0xab, bitoffset, bitbase ); }
|
||||
__forceinline void operator()( const void* bitbase, const xRegister16& bitoffset ) const { xOpWrite0F( 0x66, RegFormOp, bitoffset, bitbase ); }
|
||||
|
||||
__forceinline void operator()( const ModSibStrict<u32>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
|
||||
__forceinline void operator()( const ModSibStrict<u16>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
|
||||
__forceinline void operator()( const u32* bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
|
||||
__forceinline void operator()( const u16* bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
|
||||
__forceinline void operator()( const xRegister<u32>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0xba, InstType, bitbase, bitoffset ); }
|
||||
__forceinline void operator()( const xRegister<u16>& bitbase, u8 bitoffset ) const { xOpWrite0F( 0x66, 0xba, InstType, bitbase, bitoffset ); }
|
||||
|
|
@ -29,11 +29,9 @@ public:
|
|||
_SimdShiftHelper() {}
|
||||
|
||||
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( 0x66, Opcode1, to, from ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( 0x66, Opcode1, to, from ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( 0x66, Opcode1, to, from ); }
|
||||
|
||||
__forceinline void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const { xOpWrite0F( Opcode1, to, from ); }
|
||||
__forceinline void operator()( const xRegisterMMX& to, const void* from ) const { xOpWrite0F( Opcode1, to, from ); }
|
||||
__forceinline void operator()( const xRegisterMMX& to, const ModSibBase& from ) const { xOpWrite0F( Opcode1, to, from ); }
|
||||
|
||||
|
|
@ -30,7 +30,6 @@ class SimdImpl_DestRegSSE
|
|||
{
|
||||
public:
|
||||
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
|
||||
SimdImpl_DestRegSSE() {} //GCWho?
|
||||
|
@ -45,7 +44,6 @@ class SimdImpl_DestRegImmSSE
|
|||
{
|
||||
public:
|
||||
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from, u8 imm ) const { xOpWrite0F( Prefix, Opcode, to, from, imm ); }
|
||||
|
||||
SimdImpl_DestRegImmSSE() {} //GCWho?
|
||||
|
@ -56,7 +54,6 @@ class SimdImpl_DestRegImmMMX
|
|||
{
|
||||
public:
|
||||
__forceinline void operator()( const xRegisterMMX& to, const xRegisterMMX& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); }
|
||||
__forceinline void operator()( const xRegisterMMX& to, const void* from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); }
|
||||
__forceinline void operator()( const xRegisterMMX& to, const ModSibBase& from, u8 imm ) const { xOpWrite0F( Opcode, to, from, imm ); }
|
||||
|
||||
SimdImpl_DestRegImmMMX() {} //GCWho?
|
||||
|
@ -71,11 +68,9 @@ class SimdImpl_DestRegEither
|
|||
{
|
||||
public:
|
||||
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
|
||||
__forceinline void operator()( const xRegisterMMX& to, const xRegisterMMX& from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegisterMMX& to, const void* from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
__forceinline void operator()( const xRegisterMMX& to, const ModSibBase& from ) const { xOpWrite0F( Opcode, to, from ); }
|
||||
|
||||
SimdImpl_DestRegEither() {} //GCWho?
|
||||
|
@ -95,7 +90,6 @@ class SimdImpl_DestRegStrict
|
|||
{
|
||||
public:
|
||||
__forceinline void operator()( const DestRegType& to, const SrcRegType& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const DestRegType& to, const SrcOperandType* from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const DestRegType& to, const ModSibStrict<SrcOperandType>& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
|
||||
SimdImpl_DestRegStrict() {} //GCWho?
|
|
@ -42,7 +42,6 @@ protected:
|
|||
template< u8 Prefix > struct Woot
|
||||
{
|
||||
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, 0xc2, to, from ); xWrite8( CType ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( Prefix, 0xc2, to, from ); xWrite8( CType ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, 0xc2, to, from ); xWrite8( CType ); }
|
||||
Woot() {}
|
||||
};
|
||||
|
@ -55,6 +54,22 @@ public:
|
|||
SimdImpl_Compare() {} //GCWhat?
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Compare scalar floating point values and set EFLAGS (Ordered or Unordered)
|
||||
//
|
||||
template< bool Ordered >
|
||||
class SimdImpl_COMI
|
||||
{
|
||||
protected:
|
||||
static const u16 OpcodeSSE = Ordered ? 0x2f : 0x2e;
|
||||
|
||||
public:
|
||||
const SimdImpl_DestRegSSE<0x00,OpcodeSSE> SS;
|
||||
const SimdImpl_DestRegSSE<0x66,OpcodeSSE> SD;
|
||||
|
||||
SimdImpl_COMI() {}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
|
@ -5,12 +5,12 @@
|
|||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
@ -30,8 +30,6 @@ protected:
|
|||
struct Woot
|
||||
{
|
||||
Woot() {}
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const void* to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode+1, from, to ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); }
|
||||
__forceinline void operator()( const ModSibBase& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode+1, from, to ); }
|
||||
};
|
||||
|
@ -63,12 +61,13 @@ public:
|
|||
// All implementations of Unaligned Movs will, when possible, use aligned movs instead.
|
||||
// This happens when using Mem,Reg or Reg,Mem forms where the address is simple displacement
|
||||
// which can be checked for alignment at runtime.
|
||||
//
|
||||
//
|
||||
|
||||
template< u8 Prefix, bool isAligned >
|
||||
class SimdImpl_MoveSSE
|
||||
{
|
||||
static const uint OpcodeA = 0x28; // Aligned [aps] form
|
||||
static const uint OpcodeU = 0x10; // unaligned [ups] form
|
||||
static const u16 OpcodeA = 0x28; // Aligned [aps] form
|
||||
static const u16 OpcodeU = 0x10; // unaligned [ups] form
|
||||
|
||||
public:
|
||||
SimdImpl_MoveSSE() {} //GCC.
|
||||
|
@ -78,21 +77,19 @@ public:
|
|||
if( to != from ) xOpWrite0F( Prefix, OpcodeA, to, from );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from ) const
|
||||
{
|
||||
xOpWrite0F( Prefix, (isAligned || ((uptr)from & 0x0f) == 0) ? OpcodeA : OpcodeU, to, from );
|
||||
}
|
||||
|
||||
__forceinline void operator()( void* to, const xRegisterSSE& from ) const
|
||||
{
|
||||
xOpWrite0F( Prefix, (isAligned || ((uptr)to & 0x0f) == 0) ? OpcodeA+1 : OpcodeU+1, from, to );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const
|
||||
{
|
||||
// ModSib form is aligned if it's displacement-only and the displacement is aligned:
|
||||
bool isReallyAligned = isAligned || ( ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty() );
|
||||
xOpWrite0F( Prefix, isReallyAligned ? OpcodeA : OpcodeU, to, from );
|
||||
u16 opcode;
|
||||
|
||||
// See previous comment.
|
||||
if (isReallyAligned)
|
||||
opcode = OpcodeA;
|
||||
else
|
||||
opcode = OpcodeU;
|
||||
|
||||
xOpWrite0F( Prefix, opcode, to, from );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const ModSibBase& to, const xRegisterSSE& from ) const
|
||||
|
@ -123,16 +120,6 @@ public:
|
|||
if( to != from ) xOpWrite0F( PrefixA, Opcode, to, from );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from ) const
|
||||
{
|
||||
xOpWrite0F( (isAligned || ((uptr)from & 0x0f) == 0) ? PrefixA : PrefixU, Opcode, to, from );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const void* to, const xRegisterSSE& from ) const
|
||||
{
|
||||
xOpWrite0F( (isAligned || ((uptr)from & 0x0f) == 0) ? PrefixA : PrefixU, Opcode_Alt, to, from );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const
|
||||
{
|
||||
// ModSib form is aligned if it's displacement-only and the displacement is aligned:
|
||||
|
@ -148,18 +135,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
template< u8 AltPrefix, u16 OpcodeSSE >
|
||||
class SimdImpl_UcomI
|
||||
{
|
||||
public:
|
||||
const SimdImpl_DestRegSSE<0x00,OpcodeSSE> SS;
|
||||
const SimdImpl_DestRegSSE<AltPrefix,OpcodeSSE> SD;
|
||||
SimdImpl_UcomI() {}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Blend - Conditional copying of values in src into dest.
|
||||
//
|
||||
|
@ -168,7 +143,7 @@ class SimdImpl_Blend
|
|||
public:
|
||||
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
|
||||
// mask bits in the immediate operand (bits [3:0]). Each mask bit corresponds to a
|
||||
// dword element in a 128-bit operand.
|
||||
// dword element in a 128-bit operand.
|
||||
//
|
||||
// If a mask bit is 1, then the corresponding dword in the source operand is copied
|
||||
// to dest, else the dword element in dest is left unchanged.
|
||||
|
@ -177,25 +152,25 @@ public:
|
|||
|
||||
// [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the
|
||||
// mask bits in the immediate operand (bits [1:0]). Each mask bit corresponds to a
|
||||
// quadword element in a 128-bit operand.
|
||||
// quadword element in a 128-bit operand.
|
||||
//
|
||||
// If a mask bit is 1, then the corresponding dword in the source operand is copied
|
||||
// to dest, else the dword element in dest is left unchanged.
|
||||
//
|
||||
SimdImpl_DestRegImmSSE<0x66,0x0d3a> PD;
|
||||
|
||||
|
||||
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
|
||||
// mask (bits [3:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds
|
||||
// to a dword element in the 128-bit operand.
|
||||
// to a dword element in the 128-bit operand.
|
||||
//
|
||||
// If a mask bit is 1, then the corresponding dword in the source operand is copied
|
||||
// to dest, else the dword element in dest is left unchanged.
|
||||
//
|
||||
SimdImpl_DestRegSSE<0x66,0x1438> VPS;
|
||||
|
||||
|
||||
// [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the
|
||||
// mask (bits [1:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds
|
||||
// to a quadword element in the 128-bit operand.
|
||||
// to a quadword element in the 128-bit operand.
|
||||
//
|
||||
// If a mask bit is 1, then the corresponding dword in the source operand is copied
|
||||
// to dest, else the dword element in dest is left unchanged.
|
||||
|
@ -223,7 +198,7 @@ public:
|
|||
// [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers
|
||||
// and store them in dest.
|
||||
SimdImpl_DestRegStrict<0x66,OpcodeBase+0x200,xRegisterSSE,xRegisterSSE,u16> BQ;
|
||||
|
||||
|
||||
// [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers
|
||||
// and store them in dest.
|
||||
SimdImpl_DestRegStrict<0x66,OpcodeBase+0x300,xRegisterSSE,xRegisterSSE,u64> WD;
|
|
@ -27,7 +27,6 @@ protected:
|
|||
template< u8 Prefix > struct Woot
|
||||
{
|
||||
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 cmptype ) const { xOpWrite0F( Prefix, OpcodeSSE, to, from ); xWrite8( cmptype ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from, u8 cmptype ) const { xOpWrite0F( Prefix, OpcodeSSE, to, from ); xWrite8( cmptype ); }
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from, u8 cmptype ) const { xOpWrite0F( Prefix, OpcodeSSE, to, from ); xWrite8( cmptype ); }
|
||||
Woot() {}
|
||||
};
|
||||
|
@ -185,11 +184,6 @@ protected:
|
|||
xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, to, from, imm8 );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const xRegisterSSE& to, const void* from, u8 imm8 ) const
|
||||
{
|
||||
xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, to, from, imm8 );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from, u8 imm8 ) const
|
||||
{
|
||||
xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, to, from, imm8 );
|
||||
|
@ -201,11 +195,9 @@ public:
|
|||
|
||||
// Operation can be performed on either MMX or SSE src operands.
|
||||
__forceinline void W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
||||
__forceinline void W( const xRegisterSSE& to, const void* from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
||||
__forceinline void W( const xRegisterSSE& to, const ModSibBase& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc4, to, from, imm8 ); }
|
||||
|
||||
__forceinline void W( const xRegisterMMX& to, const xRegister32& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); }
|
||||
__forceinline void W( const xRegisterMMX& to, const void* from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); }
|
||||
__forceinline void W( const xRegisterMMX& to, const ModSibBase& from, u8 imm8 ) const { xOpWrite0F( 0xc4, to, from, imm8 ); }
|
||||
|
||||
// [SSE-4.1]
|
||||
|
@ -235,11 +227,6 @@ protected:
|
|||
xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, to, from, imm8 );
|
||||
}
|
||||
|
||||
__forceinline void operator()( void* dest, const xRegisterSSE& from, u8 imm8 ) const
|
||||
{
|
||||
xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, from, dest, imm8 );
|
||||
}
|
||||
|
||||
__forceinline void operator()( const ModSibBase& dest, const xRegisterSSE& from, u8 imm8 ) const
|
||||
{
|
||||
xOpWrite0F( 0x66, (Opcode<<8) | 0x3a, from, dest, imm8 );
|
||||
|
@ -258,7 +245,6 @@ public:
|
|||
__forceinline void W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0xc5, to, from, imm8 ); }
|
||||
__forceinline void W( const xRegister32& to, const xRegisterMMX& from, u8 imm8 ) const { xOpWrite0F( 0xc5, to, from, imm8 ); }
|
||||
|
||||
__forceinline void W( void* dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0x153a, from, dest, imm8 ); }
|
||||
__forceinline void W( const ModSibBase& dest, const xRegisterSSE& from, u8 imm8 ) const { xOpWrite0F( 0x66, 0x153a, from, dest, imm8 ); }
|
||||
|
||||
// [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits
|
|
@ -46,35 +46,101 @@
|
|||
// global optimization fails to resolve the externals and junk.
|
||||
// (score one for MSVC!)
|
||||
|
||||
#include "System.h"
|
||||
|
||||
namespace x86Emitter
|
||||
{
|
||||
extern const char *const x86_regnames_gpr8[8];
|
||||
extern const char *const x86_regnames_gpr16[8];
|
||||
extern const char *const x86_regnames_gpr32[8];
|
||||
|
||||
extern const char *const x86_regnames_sse[8];
|
||||
extern const char *const x86_regnames_mmx[8];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Diagnostic -- returns a string representation of this register.
|
||||
//
|
||||
template< typename T >
|
||||
const char* xGetRegName( const xRegister<T>& src )
|
||||
{
|
||||
if( src.IsEmpty() ) return "empty";
|
||||
|
||||
switch( sizeof(T) )
|
||||
{
|
||||
case 1: return x86_regnames_gpr8[ src.Id ];
|
||||
case 2: return x86_regnames_gpr16[ src.Id ];
|
||||
case 4: return x86_regnames_gpr32[ src.Id ];
|
||||
|
||||
jNO_DEFAULT
|
||||
}
|
||||
|
||||
return "oops?";
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
const char* xGetRegName( const xRegisterSIMD<T>& src )
|
||||
{
|
||||
if( src.IsEmpty() ) return "empty";
|
||||
|
||||
switch( sizeof(T) )
|
||||
{
|
||||
case 8: return x86_regnames_mmx[ src.Id ];
|
||||
case 16: return x86_regnames_sse[ src.Id ];
|
||||
|
||||
jNO_DEFAULT
|
||||
}
|
||||
|
||||
return "oops?";
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// x86Register Method Implementations
|
||||
//
|
||||
__forceinline xAddressInfo xAddressReg::operator+( const xAddressReg& right ) const
|
||||
{
|
||||
jASSUME( Id != -1 );
|
||||
return xAddressInfo( *this, right );
|
||||
}
|
||||
|
||||
__forceinline xAddressInfo xAddressReg::operator+( const xAddressInfo& right ) const
|
||||
{
|
||||
jASSUME( Id != -1 );
|
||||
return right + *this;
|
||||
}
|
||||
|
||||
__forceinline xAddressInfo xAddressReg::operator+( s32 right ) const
|
||||
{
|
||||
jASSUME( Id != -1 );
|
||||
return xAddressInfo( *this, right );
|
||||
}
|
||||
|
||||
__forceinline xAddressInfo xAddressReg::operator+( const void* right ) const
|
||||
{
|
||||
jASSUME( Id != -1 );
|
||||
return xAddressInfo( *this, (s32)right );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
__forceinline xAddressInfo xAddressReg::operator-( s32 right ) const
|
||||
{
|
||||
jASSUME( Id != -1 );
|
||||
return xAddressInfo( *this, -right );
|
||||
}
|
||||
|
||||
__forceinline xAddressInfo xAddressReg::operator-( const void* right ) const
|
||||
{
|
||||
jASSUME( Id != -1 );
|
||||
return xAddressInfo( *this, -(s32)right );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
__forceinline xAddressInfo xAddressReg::operator*( u32 right ) const
|
||||
{
|
||||
jASSUME( Id != -1 );
|
||||
return xAddressInfo( Empty, *this, right );
|
||||
}
|
||||
|
||||
__forceinline xAddressInfo xAddressReg::operator<<( u32 shift ) const
|
||||
{
|
||||
jASSUME( Id != -1 );
|
||||
return xAddressInfo( Empty, *this, 1<<shift );
|
||||
}
|
||||
|
||||
|
@ -112,6 +178,16 @@ namespace x86Emitter
|
|||
// no reduction necessary :D
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
__forceinline ModSibBase::ModSibBase( const void* target ) :
|
||||
Base(),
|
||||
Index(),
|
||||
Scale(0),
|
||||
Displacement( (s32)target )
|
||||
{
|
||||
// no reduction necessary :D
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// xAddressInfo Method Implementations
|
||||
//
|
||||
|
@ -211,7 +287,11 @@ namespace x86Emitter
|
|||
if( !is_s8( displacement ) )
|
||||
{
|
||||
assert( false );
|
||||
// Don't ask. --arcum42
|
||||
#if !defined(__LINUX__) || !defined(DEBUG)
|
||||
|
||||
Console::Error( "Emitter Error: Invalid short jump displacement = 0x%x", params (int)displacement );
|
||||
#endif
|
||||
}
|
||||
BasePtr[-1] = (s8)displacement;
|
||||
}
|
||||
|
@ -222,4 +302,15 @@ namespace x86Emitter
|
|||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// returns the inverted conditional type for this Jcc condition. Ie, JNS will become JS.
|
||||
//
|
||||
static __forceinline JccComparisonType xInvertCond( JccComparisonType src )
|
||||
{
|
||||
jASSUME( src != Jcc_Unknown );
|
||||
if( Jcc_Unconditional == src ) return Jcc_Unconditional;
|
||||
|
||||
// x86 conditionals are clever! To invert conditional types, just invert the lower bit:
|
||||
return (JccComparisonType)((int)src ^ 1);
|
||||
}
|
||||
}
|
|
@ -179,11 +179,9 @@ namespace x86Emitter
|
|||
extern void xPUSH( const ModSibBase& from );
|
||||
|
||||
extern void xPOP( xRegister32 from );
|
||||
extern void xPOP( void* from );
|
||||
|
||||
extern void xPUSH( u32 imm );
|
||||
extern void xPUSH( xRegister32 from );
|
||||
extern void xPUSH( void* from );
|
||||
|
||||
// pushes the EFLAGS register onto the stack
|
||||
extern void xPUSHFD();
|
||||
|
@ -212,6 +210,8 @@ namespace x86Emitter
|
|||
// JMP / Jcc Instructions!
|
||||
|
||||
extern void xJcc( JccComparisonType comparison, const void* target );
|
||||
extern s8* xJcc8( JccComparisonType comparison=Jcc_Unconditional, s8 displacement=0 );
|
||||
extern s32* xJcc32( JccComparisonType comparison=Jcc_Unconditional, s32 displacement=0 );
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Conditional jumps to fixed targets.
|
||||
|
@ -344,58 +344,41 @@ namespace x86Emitter
|
|||
extern void xLDMXCSR( const u32* src );
|
||||
|
||||
extern void xMOVDZX( const xRegisterSSE& to, const xRegister32& from );
|
||||
extern void xMOVDZX( const xRegisterSSE& to, const void* src );
|
||||
extern void xMOVDZX( const xRegisterSSE& to, const ModSibBase& src );
|
||||
|
||||
extern void xMOVDZX( const xRegisterMMX& to, const xRegister32& from );
|
||||
extern void xMOVDZX( const xRegisterMMX& to, const void* src );
|
||||
extern void xMOVDZX( const xRegisterMMX& to, const ModSibBase& src );
|
||||
|
||||
extern void xMOVD( const xRegister32& to, const xRegisterSSE& from );
|
||||
extern void xMOVD( void* dest, const xRegisterSSE& from );
|
||||
extern void xMOVD( const ModSibBase& dest, const xRegisterSSE& from );
|
||||
|
||||
extern void xMOVD( const xRegister32& to, const xRegisterMMX& from );
|
||||
extern void xMOVD( void* dest, const xRegisterMMX& from );
|
||||
extern void xMOVD( const ModSibBase& dest, const xRegisterMMX& from );
|
||||
|
||||
extern void xMOVQ( const xRegisterMMX& to, const xRegisterMMX& from );
|
||||
extern void xMOVQ( const xRegisterMMX& to, const xRegisterSSE& from );
|
||||
extern void xMOVQ( const xRegisterSSE& to, const xRegisterMMX& from );
|
||||
|
||||
extern void xMOVQ( void* dest, const xRegisterSSE& from );
|
||||
extern void xMOVQ( const ModSibBase& dest, const xRegisterSSE& from );
|
||||
extern void xMOVQ( void* dest, const xRegisterMMX& from );
|
||||
extern void xMOVQ( const ModSibBase& dest, const xRegisterMMX& from );
|
||||
extern void xMOVQ( const xRegisterMMX& to, const void* src );
|
||||
extern void xMOVQ( const xRegisterMMX& to, const ModSibBase& src );
|
||||
|
||||
extern void xMOVQZX( const xRegisterSSE& to, const void* src );
|
||||
extern void xMOVQZX( const xRegisterSSE& to, const ModSibBase& src );
|
||||
extern void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
|
||||
extern void xMOVSS( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xMOVSS( const void* to, const xRegisterSSE& from );
|
||||
extern void xMOVSS( const ModSibBase& to, const xRegisterSSE& from );
|
||||
extern void xMOVSD( const xRegisterSSE& to, const xRegisterSSE& from );
|
||||
extern void xMOVSD( const void* to, const xRegisterSSE& from );
|
||||
extern void xMOVSD( const ModSibBase& to, const xRegisterSSE& from );
|
||||
|
||||
extern void xMOVSSZX( const xRegisterSSE& to, const void* from );
|
||||
extern void xMOVSSZX( const xRegisterSSE& to, const ModSibBase& from );
|
||||
extern void xMOVSDZX( const xRegisterSSE& to, const void* from );
|
||||
extern void xMOVSDZX( const xRegisterSSE& to, const ModSibBase& from );
|
||||
|
||||
extern void xMOVNTDQA( const xRegisterSSE& to, const void* from );
|
||||
extern void xMOVNTDQA( const xRegisterSSE& to, const ModSibBase& from );
|
||||
extern void xMOVNTDQ( void* to, const xRegisterSSE& from );
|
||||
extern void xMOVNTDQA( const ModSibBase& to, const xRegisterSSE& from );
|
||||
|
||||
extern void xMOVNTPD( void* to, const xRegisterSSE& from );
|
||||
extern void xMOVNTPD( const ModSibBase& to, const xRegisterSSE& from );
|
||||
extern void xMOVNTPS( void* to, const xRegisterSSE& from );
|
||||
extern void xMOVNTPS( const ModSibBase& to, const xRegisterSSE& from );
|
||||
extern void xMOVNTQ( void* to, const xRegisterMMX& from );
|
||||
extern void xMOVNTQ( const ModSibBase& to, const xRegisterMMX& from );
|
||||
|
||||
extern void xMOVMSKPS( const xRegister32& to, const xRegisterSSE& from );
|
||||
|
@ -435,11 +418,9 @@ namespace x86Emitter
|
|||
extern const Internal::SimdImpl_DestRegSSE<0xf3,0x16> xMOVSHDUP;
|
||||
|
||||
extern void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
|
||||
extern void xINSERTPS( const xRegisterSSE& to, const u32* from, u8 imm8 );
|
||||
extern void xINSERTPS( const xRegisterSSE& to, const ModSibStrict<u32>& from, u8 imm8 );
|
||||
|
||||
extern void xEXTRACTPS( const xRegister32& to, const xRegisterSSE& from, u8 imm8 );
|
||||
extern void xEXTRACTPS( u32* dest, const xRegisterSSE& from, u8 imm8 );
|
||||
extern void xEXTRACTPS( const ModSibStrict<u32>& dest, const xRegisterSSE& from, u8 imm8 );
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -449,16 +430,17 @@ namespace x86Emitter
|
|||
extern const Internal::SimdImpl_DestRegEither<0x66,0xeb> xPOR;
|
||||
extern const Internal::SimdImpl_DestRegEither<0x66,0xef> xPXOR;
|
||||
|
||||
extern const Internal::SimdImpl_AndNot xANDN;
|
||||
extern const Internal::SimdImpl_AndNot xANDN;
|
||||
|
||||
extern const Internal::SimdImpl_UcomI<0x66,0x2e> xUCOMI;
|
||||
extern const Internal::SimdImpl_rSqrt<0x53> xRCP;
|
||||
extern const Internal::SimdImpl_rSqrt<0x52> xRSQRT;
|
||||
extern const Internal::SimdImpl_Sqrt<0x51> xSQRT;
|
||||
extern const Internal::SimdImpl_COMI<true> xCOMI;
|
||||
extern const Internal::SimdImpl_COMI<false> xUCOMI;
|
||||
extern const Internal::SimdImpl_rSqrt<0x53> xRCP;
|
||||
extern const Internal::SimdImpl_rSqrt<0x52> xRSQRT;
|
||||
extern const Internal::SimdImpl_Sqrt<0x51> xSQRT;
|
||||
|
||||
extern const Internal::SimdImpl_MinMax<0x5f> xMAX;
|
||||
extern const Internal::SimdImpl_MinMax<0x5d> xMIN;
|
||||
extern const Internal::SimdImpl_Shuffle<0xc6> xSHUF;
|
||||
extern const Internal::SimdImpl_MinMax<0x5f> xMAX;
|
||||
extern const Internal::SimdImpl_MinMax<0x5d> xMIN;
|
||||
extern const Internal::SimdImpl_Shuffle<0xc6> xSHUF;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
@ -508,35 +490,35 @@ namespace x86Emitter
|
|||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
extern const Internal::SimdImpl_Shift<0xf0, 6> xPSLL;
|
||||
extern const Internal::SimdImpl_Shift<0xd0, 2> xPSRL;
|
||||
extern const Internal::SimdImpl_Shift<0xf0, 6> xPSLL;
|
||||
extern const Internal::SimdImpl_Shift<0xd0, 2> xPSRL;
|
||||
extern const Internal::SimdImpl_ShiftWithoutQ<0xe0, 4> xPSRA;
|
||||
|
||||
extern const Internal::SimdImpl_AddSub<0xdc, 0xd4> xPADD;
|
||||
extern const Internal::SimdImpl_AddSub<0xd8, 0xfb> xPSUB;
|
||||
extern const Internal::SimdImpl_PMinMax<0xde,0x3c> xPMAX;
|
||||
extern const Internal::SimdImpl_PMinMax<0xda,0x38> xPMIN;
|
||||
extern const Internal::SimdImpl_AddSub<0xdc, 0xd4> xPADD;
|
||||
extern const Internal::SimdImpl_AddSub<0xd8, 0xfb> xPSUB;
|
||||
extern const Internal::SimdImpl_PMinMax<0xde,0x3c> xPMAX;
|
||||
extern const Internal::SimdImpl_PMinMax<0xda,0x38> xPMIN;
|
||||
|
||||
extern const Internal::SimdImpl_PMul xPMUL;
|
||||
extern const Internal::SimdImpl_PCompare xPCMP;
|
||||
extern const Internal::SimdImpl_PShuffle xPSHUF;
|
||||
extern const Internal::SimdImpl_PUnpack xPUNPCK;
|
||||
extern const Internal::SimdImpl_Unpack xUNPCK;
|
||||
extern const Internal::SimdImpl_Pack xPACK;
|
||||
extern const Internal::SimdImpl_PMul xPMUL;
|
||||
extern const Internal::SimdImpl_PCompare xPCMP;
|
||||
extern const Internal::SimdImpl_PShuffle xPSHUF;
|
||||
extern const Internal::SimdImpl_PUnpack xPUNPCK;
|
||||
extern const Internal::SimdImpl_Unpack xUNPCK;
|
||||
extern const Internal::SimdImpl_Pack xPACK;
|
||||
|
||||
extern const Internal::SimdImpl_PAbsolute xPABS;
|
||||
extern const Internal::SimdImpl_PSign xPSIGN;
|
||||
extern const Internal::SimdImpl_PInsert xPINSR;
|
||||
extern const Internal::SimdImpl_PExtract xPEXTR;
|
||||
extern const Internal::SimdImpl_PMultAdd xPMADD;
|
||||
extern const Internal::SimdImpl_HorizAdd xHADD;
|
||||
extern const Internal::SimdImpl_PAbsolute xPABS;
|
||||
extern const Internal::SimdImpl_PSign xPSIGN;
|
||||
extern const Internal::SimdImpl_PInsert xPINSR;
|
||||
extern const Internal::SimdImpl_PExtract xPEXTR;
|
||||
extern const Internal::SimdImpl_PMultAdd xPMADD;
|
||||
extern const Internal::SimdImpl_HorizAdd xHADD;
|
||||
|
||||
extern const Internal::SimdImpl_Blend xBLEND;
|
||||
extern const Internal::SimdImpl_DotProduct xDP;
|
||||
extern const Internal::SimdImpl_Round xROUND;
|
||||
extern const Internal::SimdImpl_Blend xBLEND;
|
||||
extern const Internal::SimdImpl_DotProduct xDP;
|
||||
extern const Internal::SimdImpl_Round xROUND;
|
||||
|
||||
extern const Internal::SimdImpl_PMove<true> xPMOVSX;
|
||||
extern const Internal::SimdImpl_PMove<false> xPMOVZX;
|
||||
extern const Internal::SimdImpl_PMove<true> xPMOVSX;
|
||||
extern const Internal::SimdImpl_PMove<false> xPMOVZX;
|
||||
|
||||
}
|
||||
|
|
@ -18,5 +18,5 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "ix86_types.h"
|
||||
#include "ix86_instructions.h"
|
||||
#include "x86types.h"
|
||||
#include "instructions.h"
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "ix86_internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Legacy Helper Macros and Functions (depreciated)
|
||||
|
@ -31,8 +31,8 @@ using x86Emitter::xWrite16;
|
|||
using x86Emitter::xWrite32;
|
||||
using x86Emitter::xWrite64;
|
||||
|
||||
#include "ix86_legacy_types.h"
|
||||
#include "ix86_legacy_instructions.h"
|
||||
#include "legacy_types.h"
|
||||
#include "legacy_instructions.h"
|
||||
|
||||
#define MEMADDR(addr, oplen) (addr)
|
||||
|
||||
|
@ -49,5 +49,4 @@ extern void SibSB( uint ss, uint index, uint base );
|
|||
extern void SET8R( int cc, int to );
|
||||
extern u8* J8Rel( int cc, int to );
|
||||
extern u32* J32Rel( int cc, u32 to );
|
||||
extern u64 GetCPUTick( void );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,106 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// this is all that needs to be called and will fill up the below structs
|
||||
extern void cpudetectInit();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// cpu capabilities structure
|
||||
//
|
||||
struct CAPABILITIES
|
||||
{
|
||||
u32 hasFloatingPointUnit;
|
||||
u32 hasVirtual8086ModeEnhancements;
|
||||
u32 hasDebuggingExtensions;
|
||||
u32 hasPageSizeExtensions;
|
||||
u32 hasTimeStampCounter;
|
||||
u32 hasModelSpecificRegisters;
|
||||
u32 hasPhysicalAddressExtension;
|
||||
u32 hasCOMPXCHG8BInstruction;
|
||||
u32 hasAdvancedProgrammableInterruptController;
|
||||
u32 hasSEPFastSystemCall;
|
||||
u32 hasMemoryTypeRangeRegisters;
|
||||
u32 hasPTEGlobalFlag;
|
||||
u32 hasMachineCheckArchitecture;
|
||||
u32 hasConditionalMoveAndCompareInstructions;
|
||||
u32 hasFGPageAttributeTable;
|
||||
u32 has36bitPageSizeExtension;
|
||||
u32 hasProcessorSerialNumber;
|
||||
u32 hasCFLUSHInstruction;
|
||||
u32 hasDebugStore;
|
||||
u32 hasACPIThermalMonitorAndClockControl;
|
||||
u32 hasMultimediaExtensions;
|
||||
u32 hasFastStreamingSIMDExtensionsSaveRestore;
|
||||
u32 hasStreamingSIMDExtensions;
|
||||
u32 hasStreamingSIMD2Extensions;
|
||||
u32 hasSelfSnoop;
|
||||
u32 hasMultiThreading; // is TRUE for both mutli-core and Hyperthreaded CPUs.
|
||||
u32 hasThermalMonitor;
|
||||
u32 hasIntel64BitArchitecture;
|
||||
u32 hasStreamingSIMD3Extensions;
|
||||
u32 hasSupplementalStreamingSIMD3Extensions;
|
||||
u32 hasStreamingSIMD4Extensions;
|
||||
u32 hasStreamingSIMD4Extensions2;
|
||||
|
||||
// AMD-specific CPU Features
|
||||
u32 hasMultimediaExtensionsExt;
|
||||
u32 hasAMD64BitArchitecture;
|
||||
u32 has3DNOWInstructionExtensionsExt;
|
||||
u32 has3DNOWInstructionExtensions;
|
||||
u32 hasStreamingSIMD4ExtensionsA;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct CPUINFO
|
||||
{
|
||||
u32 x86Family; // Processor Family
|
||||
u32 x86Model; // Processor Model
|
||||
u32 x86PType; // Processor Type
|
||||
u32 x86StepID; // Stepping ID
|
||||
u32 x86Flags; // Feature Flags
|
||||
u32 x86Flags2; // More Feature Flags
|
||||
u32 x86EFlags; // Extended Feature Flags
|
||||
u32 x86EFlags2; // Extended Feature Flags pg2
|
||||
|
||||
u32 PhysicalCores;
|
||||
u32 LogicalCores;
|
||||
|
||||
char x86ID[16]; // Vendor ID //the vendor creator (in %s)
|
||||
char x86Type[20]; //cpu type in char format //the cpu type (in %s)
|
||||
char x86Fam[50]; // family in char format //the original cpu name string (in %s)
|
||||
u32 cpuspeed; // speed of cpu //this will give cpu speed (in %d)
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
extern CAPABILITIES cpucaps;
|
||||
extern CPUINFO cpuinfo;
|
||||
|
||||
extern u8 g_globalMMXSaved, g_globalXMMSaved;
|
||||
extern bool g_EEFreezeRegs;
|
||||
|
||||
// when using mmx/xmm regs, use; 0 is load
|
||||
// freezes no matter the state
|
||||
extern void FreezeXMMRegs(int save);
|
||||
extern void FreezeMMXRegs(int save);
|
||||
extern void FreezeRegs(int save);
|
|
@ -5,12 +5,12 @@
|
|||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
@ -45,10 +45,11 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "ix86_types.h"
|
||||
#include "ix86_instructions.h"
|
||||
#include "x86types.h"
|
||||
#include "tools.h"
|
||||
#include "instructions.h"
|
||||
|
||||
// Including legacy items for now, but these should be removed eventually,
|
||||
// once most code is no longer dependent on them.
|
||||
#include "ix86_legacy_types.h"
|
||||
#include "ix86_legacy_instructions.h"
|
||||
#include "legacy_types.h"
|
||||
#include "legacy_instructions.h"
|
|
@ -18,76 +18,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
extern void cpudetectInit();//this is all that needs to be called and will fill up the below structs
|
||||
|
||||
//cpu capabilities structure
|
||||
struct CAPABILITIES
|
||||
{
|
||||
u32 hasFloatingPointUnit;
|
||||
u32 hasVirtual8086ModeEnhancements;
|
||||
u32 hasDebuggingExtensions;
|
||||
u32 hasPageSizeExtensions;
|
||||
u32 hasTimeStampCounter;
|
||||
u32 hasModelSpecificRegisters;
|
||||
u32 hasPhysicalAddressExtension;
|
||||
u32 hasCOMPXCHG8BInstruction;
|
||||
u32 hasAdvancedProgrammableInterruptController;
|
||||
u32 hasSEPFastSystemCall;
|
||||
u32 hasMemoryTypeRangeRegisters;
|
||||
u32 hasPTEGlobalFlag;
|
||||
u32 hasMachineCheckArchitecture;
|
||||
u32 hasConditionalMoveAndCompareInstructions;
|
||||
u32 hasFGPageAttributeTable;
|
||||
u32 has36bitPageSizeExtension;
|
||||
u32 hasProcessorSerialNumber;
|
||||
u32 hasCFLUSHInstruction;
|
||||
u32 hasDebugStore;
|
||||
u32 hasACPIThermalMonitorAndClockControl;
|
||||
u32 hasMultimediaExtensions;
|
||||
u32 hasFastStreamingSIMDExtensionsSaveRestore;
|
||||
u32 hasStreamingSIMDExtensions;
|
||||
u32 hasStreamingSIMD2Extensions;
|
||||
u32 hasSelfSnoop;
|
||||
u32 hasMultiThreading; // is TRUE for both mutli-core and Hyperthreaded CPUs.
|
||||
u32 hasThermalMonitor;
|
||||
u32 hasIntel64BitArchitecture;
|
||||
u32 hasStreamingSIMD3Extensions;
|
||||
u32 hasSupplementalStreamingSIMD3Extensions;
|
||||
u32 hasStreamingSIMD4Extensions;
|
||||
u32 hasStreamingSIMD4Extensions2;
|
||||
|
||||
// AMD-specific CPU Features
|
||||
u32 hasMultimediaExtensionsExt;
|
||||
u32 hasAMD64BitArchitecture;
|
||||
u32 has3DNOWInstructionExtensionsExt;
|
||||
u32 has3DNOWInstructionExtensions;
|
||||
u32 hasStreamingSIMD4ExtensionsA;
|
||||
};
|
||||
|
||||
extern CAPABILITIES cpucaps;
|
||||
|
||||
struct CPUINFO
|
||||
{
|
||||
u32 x86Family; // Processor Family
|
||||
u32 x86Model; // Processor Model
|
||||
u32 x86PType; // Processor Type
|
||||
u32 x86StepID; // Stepping ID
|
||||
u32 x86Flags; // Feature Flags
|
||||
u32 x86Flags2; // More Feature Flags
|
||||
u32 x86EFlags; // Extended Feature Flags
|
||||
u32 x86EFlags2; // Extended Feature Flags pg2
|
||||
|
||||
u32 PhysicalCores;
|
||||
u32 LogicalCores;
|
||||
|
||||
char x86ID[16]; // Vendor ID //the vendor creator (in %s)
|
||||
char x86Type[20]; //cpu type in char format //the cpu type (in %s)
|
||||
char x86Fam[50]; // family in char format //the original cpu name string (in %s)
|
||||
u32 cpuspeed; // speed of cpu //this will give cpu speed (in %d)
|
||||
};
|
||||
|
||||
extern CPUINFO cpuinfo;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
#ifdef _MSC_VER
|
||||
#define __threadlocal __declspec(thread)
|
||||
|
@ -206,9 +136,8 @@ __forceinline void xWrite( T val )
|
|||
|
||||
int Id;
|
||||
|
||||
xRegisterBase( const xRegisterBase<OperandType>& src ) : Id( src.Id ) {}
|
||||
xRegisterBase(): Id( -1 ) {}
|
||||
explicit xRegisterBase( int regId ) : Id( regId ) { jASSUME( Id >= -1 && Id < 8 ); }
|
||||
explicit xRegisterBase( int regId ) : Id( regId ) { jASSUME( Id >= -2 && Id < 8 ); } // allow -2 for user-custom identifiers.
|
||||
|
||||
bool IsEmpty() const { return Id < 0; }
|
||||
|
||||
|
@ -220,12 +149,6 @@ __forceinline void xWrite( T val )
|
|||
|
||||
bool operator==( const xRegisterBase<OperandType>& src ) const { return (Id == src.Id); }
|
||||
bool operator!=( const xRegisterBase<OperandType>& src ) const { return (Id != src.Id); }
|
||||
|
||||
xRegisterBase<OperandType>& operator=( const xRegisterBase<OperandType>& src )
|
||||
{
|
||||
Id = src.Id;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -233,19 +156,15 @@ __forceinline void xWrite( T val )
|
|||
template< typename OperandType >
|
||||
class xRegister : public xRegisterBase<OperandType>
|
||||
{
|
||||
public:
|
||||
static const xRegister Empty; // defined as an empty/unused value (-1)
|
||||
|
||||
public:
|
||||
xRegister(): xRegisterBase<OperandType>() {}
|
||||
xRegister( const xRegister& src ) : xRegisterBase<OperandType>( src.Id ) {}
|
||||
explicit xRegister( const xRegisterBase<OperandType>& src ) : xRegisterBase<OperandType>( src ) {}
|
||||
xRegister( const xRegisterBase<OperandType>& src ) : xRegisterBase<OperandType>( src ) {}
|
||||
explicit xRegister( int regId ) : xRegisterBase<OperandType>( regId ) {}
|
||||
|
||||
bool operator==( const xRegister<OperandType>& src ) const { return this->Id == src.Id; }
|
||||
bool operator!=( const xRegister<OperandType>& src ) const { return this->Id != src.Id; }
|
||||
|
||||
xRegister<OperandType>& operator=( const xRegister<OperandType>& src )
|
||||
xRegister<OperandType>& operator=( const xRegisterBase<OperandType>& src )
|
||||
{
|
||||
this->Id = src.Id;
|
||||
return *this;
|
||||
|
@ -262,14 +181,13 @@ __forceinline void xWrite( T val )
|
|||
|
||||
public:
|
||||
xRegisterSIMD(): xRegisterBase<OperandType>() {}
|
||||
xRegisterSIMD( const xRegisterSIMD& src ) : xRegisterBase<OperandType>( src.Id ) {}
|
||||
explicit xRegisterSIMD( const xRegisterBase<OperandType>& src ) : xRegisterBase<OperandType>( src ) {}
|
||||
explicit xRegisterSIMD( int regId ) : xRegisterBase<OperandType>( regId ) {}
|
||||
|
||||
bool operator==( const xRegisterSIMD<OperandType>& src ) const { return this->Id == src.Id; }
|
||||
bool operator!=( const xRegisterSIMD<OperandType>& src ) const { return this->Id != src.Id; }
|
||||
|
||||
xRegisterSIMD<OperandType>& operator=( const xRegisterSIMD<OperandType>& src )
|
||||
xRegisterSIMD<OperandType>& operator=( const xRegisterBase<OperandType>& src )
|
||||
{
|
||||
this->Id = src.Id;
|
||||
return *this;
|
||||
|
@ -317,6 +235,10 @@ __forceinline void xWrite( T val )
|
|||
xAddressInfo operator+( const xAddressReg& right ) const;
|
||||
xAddressInfo operator+( const xAddressInfo& right ) const;
|
||||
xAddressInfo operator+( s32 right ) const;
|
||||
xAddressInfo operator+( const void* right ) const;
|
||||
|
||||
xAddressInfo operator-( s32 right ) const;
|
||||
xAddressInfo operator-( const void* right ) const;
|
||||
|
||||
xAddressInfo operator*( u32 factor ) const;
|
||||
xAddressInfo operator<<( u32 shift ) const;
|
||||
|
@ -327,7 +249,7 @@ __forceinline void xWrite( T val )
|
|||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class xAddressInfo
|
||||
|
@ -381,6 +303,7 @@ __forceinline void xWrite( T val )
|
|||
__forceinline xAddressInfo operator+( const xAddressInfo& right ) const { return xAddressInfo( *this ).Add( right ); }
|
||||
__forceinline xAddressInfo operator+( s32 imm ) const { return xAddressInfo( *this ).Add( imm ); }
|
||||
__forceinline xAddressInfo operator-( s32 imm ) const { return xAddressInfo( *this ).Add( -imm ); }
|
||||
__forceinline xAddressInfo operator+( const void* addr ) const { return xAddressInfo( *this ).Add( (uptr)addr ); }
|
||||
};
|
||||
|
||||
extern const xRegisterSSE
|
||||
|
@ -405,6 +328,33 @@ __forceinline void xWrite( T val )
|
|||
|
||||
extern const xRegisterCL cl; // I'm special!
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// xImmReg - used to represent an immediate value which can also be optimized to a register.
|
||||
// Note that the immediate value represented by this structure is *always* legal. The
|
||||
// register assignment is an optional optimization which can be implemented in cases where
|
||||
// an immediate is used enough times to merit allocating it to a register.
|
||||
//
|
||||
// Note: not all instructions support this operand type (yet). You can always implement it
|
||||
// manually by checking the status of IsReg() and generating the xOP conditionally.
|
||||
//
|
||||
template< typename OperandType >
|
||||
class xImmReg
|
||||
{
|
||||
xRegister<OperandType> m_reg;
|
||||
int m_imm;
|
||||
|
||||
public:
|
||||
xImmReg() :
|
||||
m_reg(), m_imm( 0 ) { }
|
||||
|
||||
xImmReg( int imm, const xRegister<OperandType>& reg=xRegister<OperandType>() ) :
|
||||
m_reg( reg ), m_imm( imm ) { }
|
||||
|
||||
const xRegister<OperandType>& GetReg() const { return m_reg; }
|
||||
const int GetImm() const { return m_imm; }
|
||||
bool IsReg() const { return !m_reg.IsEmpty(); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ModSib - Internal low-level representation of the ModRM/SIB information.
|
||||
//
|
||||
|
@ -429,6 +379,7 @@ __forceinline void xWrite( T val )
|
|||
explicit ModSibBase( const xAddressInfo& src );
|
||||
explicit ModSibBase( s32 disp );
|
||||
ModSibBase( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 );
|
||||
ModSibBase( const void* target );
|
||||
|
||||
bool IsByteSizeDisp() const { return is_s8( Displacement ); }
|
||||
|
||||
|
@ -455,8 +406,10 @@ __forceinline void xWrite( T val )
|
|||
public:
|
||||
static const uint OperandSize = sizeof( OperandType );
|
||||
|
||||
__forceinline explicit ModSibStrict( const ModSibBase& src ) : ModSibBase( src ) {}
|
||||
__forceinline explicit ModSibStrict( const xAddressInfo& src ) : ModSibBase( src ) {}
|
||||
__forceinline explicit ModSibStrict( s32 disp ) : ModSibBase( disp ) {}
|
||||
__forceinline ModSibStrict( const OperandType* target ) : ModSibBase( target ) {}
|
||||
__forceinline ModSibStrict( xAddressReg base, xAddressReg index, int scale=0, s32 displacement=0 ) :
|
||||
ModSibBase( base, index, scale, displacement ) {}
|
||||
|
||||
|
@ -468,6 +421,18 @@ __forceinline void xWrite( T val )
|
|||
|
||||
__forceinline ModSibStrict<OperandType> operator+( const s32 imm ) const { return ModSibStrict<OperandType>( *this ).Add( imm ); }
|
||||
__forceinline ModSibStrict<OperandType> operator-( const s32 imm ) const { return ModSibStrict<OperandType>( *this ).Add( -imm ); }
|
||||
|
||||
bool operator==( const ModSibStrict<OperandType>& src ) const
|
||||
{
|
||||
return
|
||||
( Base == src.Base ) && ( Index == src.Index ) &&
|
||||
( Scale == src.Scale ) && ( Displacement == src.Displacement );
|
||||
}
|
||||
|
||||
bool operator!=( const ModSibStrict<OperandType>& src ) const
|
||||
{
|
||||
return !operator==( src );
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -540,12 +505,64 @@ __forceinline void xWrite( T val )
|
|||
|
||||
// ptr[] - use this form for instructions which can resolve the address operand size from
|
||||
// the other register operand sizes.
|
||||
extern const xAddressIndexerBase ptr;
|
||||
extern const xAddressIndexer<u128> ptr128;
|
||||
extern const xAddressIndexer<u64> ptr64;
|
||||
extern const xAddressIndexer<u32> ptr32; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms
|
||||
extern const xAddressIndexer<u16> ptr16; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms
|
||||
extern const xAddressIndexer<u8> ptr8; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms
|
||||
extern const xAddressIndexerBase ptr;
|
||||
extern const xAddressIndexer<u128> ptr128;
|
||||
extern const xAddressIndexer<u64> ptr64;
|
||||
extern const xAddressIndexer<u32> ptr32; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms
|
||||
extern const xAddressIndexer<u16> ptr16; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms
|
||||
extern const xAddressIndexer<u8> ptr8; // explicitly typed addressing, usually needed for '[dest],imm' instruction forms
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// [TODO] - make SSE version of thise, perhaps?
|
||||
//
|
||||
template< typename OperandType >
|
||||
class xDirectOrIndirect
|
||||
{
|
||||
xRegister<OperandType> m_RegDirect;
|
||||
ModSibStrict<OperandType> m_MemIndirect;
|
||||
|
||||
public:
|
||||
xDirectOrIndirect() :
|
||||
m_RegDirect(), m_MemIndirect( 0 ) {}
|
||||
|
||||
xDirectOrIndirect( const xRegister<OperandType>& srcreg ) :
|
||||
m_RegDirect( srcreg ), m_MemIndirect( 0 ) {}
|
||||
|
||||
xDirectOrIndirect( const ModSibBase& srcmem ) :
|
||||
m_RegDirect(), m_MemIndirect( srcmem ) {}
|
||||
|
||||
xDirectOrIndirect( const ModSibStrict<OperandType>& srcmem ) :
|
||||
m_RegDirect(), m_MemIndirect( srcmem ) {}
|
||||
|
||||
const xRegister<OperandType>& GetReg() const { return m_RegDirect; }
|
||||
const ModSibStrict<OperandType>& GetMem() const { return m_MemIndirect; }
|
||||
bool IsDirect() const { return !m_RegDirect.IsEmpty(); }
|
||||
bool IsIndirect() const { return m_RegDirect.IsEmpty(); }
|
||||
|
||||
bool operator==( const xDirectOrIndirect<OperandType>& src ) const
|
||||
{
|
||||
return IsDirect() ?
|
||||
(m_RegDirect == src.m_RegDirect) :
|
||||
(m_MemIndirect == src.m_MemIndirect);
|
||||
}
|
||||
|
||||
bool operator!=( const xDirectOrIndirect<OperandType>& src ) const
|
||||
{
|
||||
return !operator==( src );
|
||||
}
|
||||
|
||||
bool operator==( const xRegister<OperandType>& src ) const { return (m_RegDirect == src); }
|
||||
bool operator!=( const xRegister<OperandType>& src ) const { return (m_RegDirect == src); }
|
||||
};
|
||||
|
||||
typedef xImmReg<u8> xImmOrReg8;
|
||||
typedef xImmReg<u16> xImmOrReg16;
|
||||
typedef xImmReg<u32> xImmOrReg32;
|
||||
|
||||
typedef xDirectOrIndirect<u8> xDirectOrIndirect8;
|
||||
typedef xDirectOrIndirect<u16> xDirectOrIndirect16;
|
||||
typedef xDirectOrIndirect<u32> xDirectOrIndirect32;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// JccComparisonType - enumerated possibilities for inspired code branching!
|
||||
|
@ -633,7 +650,7 @@ __forceinline void xWrite( T val )
|
|||
JccComparisonType m_cc; // comparison type of the instruction
|
||||
|
||||
public:
|
||||
const int GetMaxInstructionSize() const
|
||||
int GetMaxInstructionSize() const
|
||||
{
|
||||
jASSUME( m_cc != Jcc_Unknown );
|
||||
return ( m_cc == Jcc_Unconditional ) ? 5 : 6;
|
||||
|
@ -686,70 +703,7 @@ __forceinline void xWrite( T val )
|
|||
//
|
||||
namespace Internal
|
||||
{
|
||||
extern void SimdPrefix( u8 prefix, u16 opcode );
|
||||
extern void EmitSibMagic( uint regfield, const void* address );
|
||||
extern void EmitSibMagic( uint regfield, const ModSibBase& info );
|
||||
extern void xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward );
|
||||
|
||||
|
||||
// Writes a ModRM byte for "Direct" register access forms, which is used for all
|
||||
// instructions taking a form of [reg,reg].
|
||||
template< typename T > __emitinline
|
||||
void EmitSibMagic( uint reg1, const xRegisterBase<T>& reg2 )
|
||||
{
|
||||
xWrite8( (Mod_Direct << 6) | (reg1 << 3) | reg2.Id );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void EmitSibMagic( const xRegisterBase<T1> reg1, const xRegisterBase<T2>& reg2 )
|
||||
{
|
||||
xWrite8( (Mod_Direct << 6) | (reg1.Id << 3) | reg2.Id );
|
||||
}
|
||||
|
||||
template< typename T1 > __emitinline
|
||||
void EmitSibMagic( const xRegisterBase<T1> reg1, const void* src ) { EmitSibMagic( reg1.Id, src ); }
|
||||
|
||||
template< typename T1 > __emitinline
|
||||
void EmitSibMagic( const xRegisterBase<T1> reg1, const ModSibBase& sib ) { EmitSibMagic( reg1.Id, sib ); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
if( prefix != 0 )
|
||||
xWrite16( (opcode<<8) | prefix );
|
||||
else
|
||||
xWrite8( opcode );
|
||||
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 )
|
||||
{
|
||||
SimdPrefix( prefix, opcode );
|
||||
EmitSibMagic( param1, param2 );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8 )
|
||||
{
|
||||
xOpWrite0F( prefix, opcode, param1, param2 );
|
||||
xWrite8( imm8 );
|
||||
}
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2 ) { xOpWrite0F( 0, opcode, param1, param2 ); }
|
||||
|
||||
template< typename T1, typename T2 > __emitinline
|
||||
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) { xOpWrite0F( 0, opcode, param1, param2, imm8 ); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
template< typename T > bool Is8BitOp() { return sizeof(T) == 1; }
|
||||
template< typename T > void prefix16() { if( sizeof(T) == 2 ) xWrite8( 0x66 ); }
|
||||
|
||||
#include "implement/helpers.h"
|
||||
#include "implement/xmm/basehelpers.h"
|
||||
#include "implement/xmm/moremovs.h"
|
||||
#include "implement/xmm/arithmetic.h"
|
||||
|
@ -764,6 +718,26 @@ __forceinline void xWrite( T val )
|
|||
#include "implement/test.h"
|
||||
#include "implement/jmpcall.h"
|
||||
}
|
||||
|
||||
static __forceinline xAddressInfo operator+( const void* addr, const xAddressReg& reg )
|
||||
{
|
||||
return xAddressInfo( reg, (sptr)addr );
|
||||
}
|
||||
|
||||
static __forceinline xAddressInfo operator+( const void* addr, const xAddressInfo& reg )
|
||||
{
|
||||
return xAddressInfo( (sptr)addr ).Add( reg );
|
||||
}
|
||||
|
||||
static __forceinline xAddressInfo operator+( s32 addr, const xAddressReg& reg )
|
||||
{
|
||||
return xAddressInfo( reg, (sptr)addr );
|
||||
}
|
||||
|
||||
static __forceinline xAddressInfo operator+( s32 addr, const xAddressInfo& reg )
|
||||
{
|
||||
return xAddressInfo( (sptr)addr ).Add( reg );
|
||||
}
|
||||
}
|
||||
|
||||
#include "ix86_inlines.inl"
|
||||
#include "inlines.inl"
|
|
@ -20,7 +20,6 @@
|
|||
// it built into their CRT/libc.
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "System.h"
|
||||
|
||||
|
||||
struct AlignedMallocHeader
|
|
@ -0,0 +1,236 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Threading.h"
|
||||
|
||||
using namespace Threading;
|
||||
using namespace std;
|
||||
|
||||
const _VARG_PARAM va_arg_dummy = { 0 };
|
||||
|
||||
namespace Console
|
||||
{
|
||||
MutexLock m_writelock;
|
||||
std::string m_format_buffer;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall Write( Colors color, const char* fmt )
|
||||
{
|
||||
SetColor( color );
|
||||
Write( fmt );
|
||||
ClearColor();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall Write( Colors color, const wxString& fmt )
|
||||
{
|
||||
SetColor( color );
|
||||
Write( fmt );
|
||||
ClearColor();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall WriteLn( const char* fmt )
|
||||
{
|
||||
Write( fmt );
|
||||
Newline();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall WriteLn( Colors color, const char* fmt )
|
||||
{
|
||||
SetColor( color );
|
||||
Write( fmt );
|
||||
Newline();
|
||||
ClearColor();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall WriteLn( const wxString& fmt )
|
||||
{
|
||||
Write( fmt );
|
||||
Newline();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall WriteLn( Colors color, const wxString& fmt )
|
||||
{
|
||||
SetColor( color );
|
||||
Write( fmt );
|
||||
Newline();
|
||||
ClearColor();
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
__forceinline void __fastcall _Write( const char* fmt, va_list args )
|
||||
{
|
||||
ScopedLock locker( m_writelock );
|
||||
vssprintf( m_format_buffer, fmt, args );
|
||||
const char* cstr = m_format_buffer.c_str();
|
||||
|
||||
Write( fmt );
|
||||
}
|
||||
|
||||
__forceinline void __fastcall _WriteLn( const char* fmt, va_list args )
|
||||
{
|
||||
_Write( fmt, args );
|
||||
Newline();
|
||||
}
|
||||
|
||||
__forceinline void __fastcall _WriteLn( Colors color, const char* fmt, va_list args )
|
||||
{
|
||||
SetColor( color );
|
||||
_WriteLn( fmt, args );
|
||||
ClearColor();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Write( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
|
||||
va_list args;
|
||||
va_start(args,dummy);
|
||||
_Write( fmt, args );
|
||||
va_end(args);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Write( Colors color, const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
|
||||
va_list args;
|
||||
va_start(args,dummy);
|
||||
SetColor( color );
|
||||
_Write( fmt, args );
|
||||
ClearColor();
|
||||
va_end(args);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool WriteLn( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
va_list args;
|
||||
va_start(args,dummy);
|
||||
_WriteLn( fmt, args );
|
||||
va_end(args);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool WriteLn( Colors color, const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
|
||||
va_list args;
|
||||
va_start(args,dummy);
|
||||
_WriteLn( color, fmt, args );
|
||||
va_end(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Error( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
|
||||
va_list args;
|
||||
va_start(args,dummy);
|
||||
_WriteLn( Color_Red, fmt, args );
|
||||
va_end(args);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Notice( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
|
||||
va_list list;
|
||||
va_start(list,dummy);
|
||||
_WriteLn( Color_Yellow, fmt, list );
|
||||
va_end(list);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Status( const char* fmt, VARG_PARAM dummy, ... )
|
||||
{
|
||||
varg_assert();
|
||||
|
||||
va_list list;
|
||||
va_start(list,dummy);
|
||||
_WriteLn( Color_Green, fmt, list );
|
||||
va_end(list);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall Error( const char* fmt )
|
||||
{
|
||||
WriteLn( Color_Red, fmt );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall Notice( const char* fmt )
|
||||
{
|
||||
WriteLn( Color_Yellow, fmt );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall Status( const char* fmt )
|
||||
{
|
||||
WriteLn( Color_Green, fmt );
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool __fastcall Error( const wxString& src )
|
||||
{
|
||||
WriteLn( Color_Red, src );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall Notice( const wxString& src )
|
||||
{
|
||||
WriteLn( Color_Yellow, src );
|
||||
return false;
|
||||
}
|
||||
|
||||
bool __fastcall Status( const wxString& src )
|
||||
{
|
||||
WriteLn( Color_Green, src );
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -163,4 +163,3 @@ namespace Exception
|
|||
return m_message;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <signal.h>
|
||||
|
||||
namespace HostSys
|
||||
{
|
||||
void *Mmap(uptr base, u32 size)
|
||||
{
|
||||
u8 *Mem;
|
||||
Mem = (u8*)mmap((uptr*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
if (Mem == MAP_FAILED) Console::Notice("Mmap Failed!");
|
||||
|
||||
return Mem;
|
||||
}
|
||||
|
||||
void Munmap(uptr base, u32 size)
|
||||
{
|
||||
munmap((uptr*)base, size);
|
||||
}
|
||||
|
||||
void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution )
|
||||
{
|
||||
int lnxmode = 0;
|
||||
|
||||
// make sure size is aligned to the system page size:
|
||||
size = (size + m_pagemask) & ~m_pagemask;
|
||||
|
||||
switch( mode )
|
||||
{
|
||||
case Protect_NoAccess: break;
|
||||
case Protect_ReadOnly: lnxmode = PROT_READ; break;
|
||||
case Protect_ReadWrite: lnxmode = PROT_READ | PROT_WRITE; break;
|
||||
}
|
||||
|
||||
if( allowExecution ) lnxmode |= PROT_EXEC;
|
||||
mprotect( baseaddr, size, lnxmode );
|
||||
}
|
||||
}
|
|
@ -22,8 +22,6 @@
|
|||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "CDVD.h"
|
||||
|
||||
void InitCPUTicks()
|
||||
{
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ix86/ix86.h"
|
||||
#include "Threading.h"
|
||||
|
||||
// Note: assuming multicore is safer because it forces the interlocked routines to use
|
||||
// the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not
|
||||
|
@ -169,28 +169,4 @@ namespace Threading
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
__forceinline void pcsx2_InterlockedExchange64(volatile s64* Target, s64 Value)
|
||||
{
|
||||
__asm__ __volatile__(
|
||||
".intel_syntax noprefix\n"
|
||||
"lock xchg [%0], rax\n"
|
||||
".att_syntax\n" : : "r"(Target), "a"(Value) : "memory"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__forceinline s64 pcsx2_InterlockedCompareExchange64(volatile s64* dest, s64 exch, s64 comp)
|
||||
{
|
||||
s64 old;
|
||||
__asm__ __volatile__(
|
||||
"lock; cmpxchgq %q2, %q1"
|
||||
: "=a" (old)
|
||||
: "r" (exch), "m" (*dest), "a" (comp)
|
||||
);
|
||||
return old;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
#include "PrecompiledHeader.h"
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef UTILITIES_PRECOMPILED_HEADER
|
||||
#define UTILITIES_PRECOMPILED_HEADER
|
||||
|
||||
#include "Dependencies.h"
|
||||
|
||||
using std::string;
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
#include "MemcpyFast.h"
|
||||
#include "Console.h"
|
||||
#include "Exceptions.h"
|
||||
#include "SafeArray.h"
|
||||
#include "General.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -17,7 +17,8 @@
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "SafeArray.h"
|
||||
|
||||
const wxRect wxDefaultRect( wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Splits a string into parts and adds the parts into the given SafeList.
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "RedtapeWindows.h"
|
||||
#include "cdvd.h"
|
||||
|
||||
static LARGE_INTEGER lfreq;
|
||||
|
|
@ -19,9 +19,9 @@
|
|||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "RedtapeWindows.h"
|
||||
#include "x86emitter/tools.h"
|
||||
#include "Threading.h"
|
||||
|
||||
#include "System.h"
|
||||
#include "ix86/ix86_types.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "implement.h" // win32 pthreads implementations.
|
||||
|
@ -53,7 +53,7 @@ namespace Threading
|
|||
LogicalCoresPerPhysicalCPU = CPUs;
|
||||
|
||||
cpuinfo.PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
|
||||
ptw32_smp_system = ( cpuinfo.LogicalCores > 1 ) ? TRUE : FALSE;
|
||||
//ptw32_smp_system = ( cpuinfo.LogicalCores > 1 ) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
__forceinline void Timeslice()
|
||||
|
@ -77,13 +77,13 @@ namespace Threading
|
|||
{
|
||||
jASSUME( itsme != NULL );
|
||||
|
||||
pthread_win32_thread_attach_np();
|
||||
//pthread_win32_thread_attach_np();
|
||||
|
||||
Thread& owner = *((Thread*)itsme);
|
||||
owner.m_returncode = owner.Callback();
|
||||
owner.m_terminated = true;
|
||||
|
||||
pthread_win32_thread_detach_np();
|
||||
//pthread_win32_thread_detach_np();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -98,14 +98,13 @@ namespace Threading
|
|||
|
||||
__forceinline long pcsx2_InterlockedExchange( volatile long* target, long srcval )
|
||||
{
|
||||
// Use the pthreads-win32 implementation...
|
||||
return ptw32_InterlockedExchange( target, srcval );
|
||||
return _InterlockedExchange( target, srcval );
|
||||
}
|
||||
|
||||
__forceinline long pcsx2_InterlockedCompareExchange( volatile long* target, long srcval, long comp )
|
||||
{
|
||||
// Use the pthreads-win32 implementation...
|
||||
return ptw32_InterlockedCompareExchange( target, srcval, comp );
|
||||
return _InterlockedCompareExchange( target, srcval, comp );
|
||||
}
|
||||
|
||||
__forceinline long pcsx2_InterlockedExchangeAdd( volatile long* target, long srcval )
|
|
@ -16,8 +16,8 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Win32.h"
|
||||
#include "../PrecompiledHeader.h"
|
||||
#include "Utilities/RedtapeWindows.h"
|
||||
#include <winnt.h>
|
||||
|
||||
namespace HostSys
|
|
@ -27,8 +27,6 @@
|
|||
// zerofrog(@gmail.com)
|
||||
// and added to by arcum42@gmail.com
|
||||
.intel_syntax noprefix
|
||||
.extern g_EEFreezeRegs
|
||||
.extern FreezeMMXRegs_
|
||||
.extern _mmx_backup
|
||||
|
||||
// mmx memcmp implementation, size has to be a multiple of 8
|
||||
|
@ -227,20 +225,12 @@ memcmp_End:
|
|||
|
||||
.global memxor_mmx
|
||||
memxor_mmx:
|
||||
// make sure mmx regs are stored
|
||||
// FreezeMMXRegs(1);
|
||||
cmp dword ptr [g_EEFreezeRegs], 0
|
||||
je memxor_mmx_begin
|
||||
push 1
|
||||
call FreezeMMXRegs_
|
||||
add esp, 4
|
||||
|
||||
memxor_mmx_begin:
|
||||
push esi
|
||||
mov MEMXOR_SRC1, dword ptr [esp+8]
|
||||
mov MEMXOR_SRC2, dword ptr [esp+12]
|
||||
mov MEMXOR_SIZE, dword ptr [esp+16]
|
||||
cmp MEMXOR_SIZE, 64
|
||||
push esi
|
||||
mov MEMXOR_SRC1, dword ptr [esp+8]
|
||||
mov MEMXOR_SRC2, dword ptr [esp+12]
|
||||
mov MEMXOR_SIZE, dword ptr [esp+16]
|
||||
cmp MEMXOR_SIZE, 64
|
||||
jl memxor_Setup4
|
||||
|
||||
movq mm0, [MEMXOR_SRC2]
|
|
@ -31,7 +31,7 @@
|
|||
3dsdk.support@amd.com
|
||||
******************************************************************************/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "..\PrecompiledHeader.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4414)
|
||||
|
@ -72,19 +72,13 @@ MEMCPY_AMD.CPP
|
|||
// This is faster than using software prefetch. The technique is great for
|
||||
// getting maximum read bandwidth, especially in DDR memory systems.
|
||||
|
||||
#include "Misc.h"
|
||||
|
||||
// Inline assembly syntax for use with Visual C++
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#ifdef _DEBUG
|
||||
#ifdef PCSX2_DEBUG
|
||||
extern u8 g_globalMMXSaved;
|
||||
|
||||
void checkregs()
|
||||
{
|
||||
if( g_EEFreezeRegs ) assert( g_globalMMXSaved );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -772,7 +766,6 @@ End:
|
|||
// returns the xor of all elements, cmpsize has to be mult of 8
|
||||
void memxor_mmx(void* dst, const void* src1, int cmpsize)
|
||||
{
|
||||
FreezeMMXRegs(1);
|
||||
assert( (cmpsize&7) == 0 );
|
||||
|
||||
__asm {
|
||||
|
@ -875,7 +868,6 @@ Setup1:
|
|||
End:
|
||||
emms
|
||||
}
|
||||
FreezeMMXRegs(0);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,202 +1,202 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ix86_legacy_internal.h"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// 3DNOW instructions [Anyone caught dead using these will be re-killed]
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/* femms */
|
||||
emitterT void FEMMS( void )
|
||||
{
|
||||
xWrite16( 0x0E0F );
|
||||
}
|
||||
|
||||
emitterT void PFCMPEQMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0xB0 );
|
||||
}
|
||||
|
||||
emitterT void PFCMPGTMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0xA0 );
|
||||
}
|
||||
|
||||
emitterT void PFCMPGEMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x90 );
|
||||
}
|
||||
|
||||
emitterT void PFADDMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x9E );
|
||||
}
|
||||
|
||||
emitterT void PFADDRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x9E );
|
||||
}
|
||||
|
||||
emitterT void PFSUBMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x9A );
|
||||
}
|
||||
|
||||
emitterT void PFSUBRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x9A );
|
||||
}
|
||||
|
||||
emitterT void PFMULMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0xB4 );
|
||||
}
|
||||
|
||||
emitterT void PFMULRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xB4 );
|
||||
}
|
||||
|
||||
emitterT void PFRCPMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x96 );
|
||||
}
|
||||
|
||||
emitterT void PFRCPRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x96 );
|
||||
}
|
||||
|
||||
emitterT void PFRCPIT1RtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xA6 );
|
||||
}
|
||||
|
||||
emitterT void PFRCPIT2RtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xB6 );
|
||||
}
|
||||
|
||||
emitterT void PFRSQRTRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x97 );
|
||||
}
|
||||
|
||||
emitterT void PFRSQIT1RtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xA7 );
|
||||
}
|
||||
|
||||
emitterT void PF2IDMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x1D );
|
||||
}
|
||||
|
||||
emitterT void PF2IDRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x1D );
|
||||
}
|
||||
|
||||
emitterT void PI2FDMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x0D );
|
||||
}
|
||||
|
||||
emitterT void PI2FDRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x0D );
|
||||
}
|
||||
|
||||
emitterT void PFMAXMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0xA4 );
|
||||
}
|
||||
|
||||
emitterT void PFMAXRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xA4 );
|
||||
}
|
||||
|
||||
emitterT void PFMINMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x94 );
|
||||
}
|
||||
|
||||
emitterT void PFMINRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x94 );
|
||||
}
|
||||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "legacy_internal.h"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// 3DNOW instructions [Anyone caught dead using these will be re-killed]
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/* femms */
|
||||
emitterT void FEMMS( void )
|
||||
{
|
||||
xWrite16( 0x0E0F );
|
||||
}
|
||||
|
||||
emitterT void PFCMPEQMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0xB0 );
|
||||
}
|
||||
|
||||
emitterT void PFCMPGTMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0xA0 );
|
||||
}
|
||||
|
||||
emitterT void PFCMPGEMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x90 );
|
||||
}
|
||||
|
||||
emitterT void PFADDMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x9E );
|
||||
}
|
||||
|
||||
emitterT void PFADDRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x9E );
|
||||
}
|
||||
|
||||
emitterT void PFSUBMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x9A );
|
||||
}
|
||||
|
||||
emitterT void PFSUBRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x9A );
|
||||
}
|
||||
|
||||
emitterT void PFMULMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0xB4 );
|
||||
}
|
||||
|
||||
emitterT void PFMULRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xB4 );
|
||||
}
|
||||
|
||||
emitterT void PFRCPMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x96 );
|
||||
}
|
||||
|
||||
emitterT void PFRCPRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x96 );
|
||||
}
|
||||
|
||||
emitterT void PFRCPIT1RtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xA6 );
|
||||
}
|
||||
|
||||
emitterT void PFRCPIT2RtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xB6 );
|
||||
}
|
||||
|
||||
emitterT void PFRSQRTRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x97 );
|
||||
}
|
||||
|
||||
emitterT void PFRSQIT1RtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xA7 );
|
||||
}
|
||||
|
||||
emitterT void PF2IDMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x1D );
|
||||
}
|
||||
|
||||
emitterT void PF2IDRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x1D );
|
||||
}
|
||||
|
||||
emitterT void PI2FDMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x0D );
|
||||
}
|
||||
|
||||
emitterT void PI2FDRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x0D );
|
||||
}
|
||||
|
||||
emitterT void PFMAXMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0xA4 );
|
||||
}
|
||||
|
||||
emitterT void PFMAXRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0xA4 );
|
||||
}
|
||||
|
||||
emitterT void PFMINMtoR( x86IntRegType to, uptr from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 0, to, DISP32 );
|
||||
xWrite32( from );
|
||||
xWrite8( 0x94 );
|
||||
}
|
||||
|
||||
emitterT void PFMINRtoR( x86IntRegType to, x86IntRegType from )
|
||||
{
|
||||
xWrite16( 0x0F0F );
|
||||
ModRM( 3, to, from );
|
||||
xWrite8( 0x94 );
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
#include "PrecompiledHeader.h"
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef EMITTER_PRECOMPILED_HEADER
|
||||
#define EMITTER_PRECOMPILED_HEADER
|
||||
|
||||
#include "Pcsx2Defs.h"
|
||||
|
||||
#include <wx/string.h>
|
||||
#include <wx/tokenzr.h>
|
||||
#include <wx/gdicmn.h> // for wxPoint/wxRect stuff
|
||||
#include <wx/intl.h>
|
||||
#include <wx/log.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cstring> // string.h under c++
|
||||
#include <cstdio> // stdio.h under c++
|
||||
#include <cstdlib>
|
||||
|
||||
using std::string;
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
#include "Utilities/Console.h"
|
||||
#include "Utilities/Exceptions.h"
|
||||
#include "Utilities/General.h"
|
||||
#include "Utilities/MemcpyFast.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -1,450 +1,401 @@
|
|||
/* Cpudetection lib
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "System.h"
|
||||
#include "ix86_legacy_internal.h"
|
||||
|
||||
#include "RedtapeWindows.h"
|
||||
|
||||
using namespace x86Emitter;
|
||||
|
||||
#if defined (_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void __cpuid(int* CPUInfo, int InfoType);
|
||||
unsigned __int64 __rdtsc();
|
||||
#ifndef __INTEL_COMPILER
|
||||
# pragma intrinsic(__cpuid)
|
||||
# pragma intrinsic(__rdtsc)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
CAPABILITIES cpucaps;
|
||||
CPUINFO cpuinfo;
|
||||
|
||||
#define cpuid(cmd,a,b,c,d) \
|
||||
__asm__ __volatile__("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
|
||||
: "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "0" (cmd), "c" (0))
|
||||
|
||||
extern s32 iCpuId( u32 cmd, u32 *regs )
|
||||
{
|
||||
int flag=1;
|
||||
|
||||
#if defined (_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
__asm
|
||||
{
|
||||
xor ecx, ecx; /* ecx should be zero for CPUID(4) */
|
||||
}
|
||||
__cpuid( (int*)regs, cmd );
|
||||
|
||||
return 0;
|
||||
|
||||
#elif defined (_MSC_VER)
|
||||
__asm
|
||||
{
|
||||
push ebx;
|
||||
push edi;
|
||||
|
||||
pushfd;
|
||||
pop eax;
|
||||
mov edx, eax;
|
||||
xor eax, 1 << 21;
|
||||
push eax;
|
||||
popfd;
|
||||
pushfd;
|
||||
pop eax;
|
||||
xor eax, edx;
|
||||
mov flag, eax;
|
||||
}
|
||||
if ( ! flag )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
__asm
|
||||
{
|
||||
mov eax, cmd;
|
||||
xor ecx, ecx; /* ecx should be zero for CPUID(4) */
|
||||
cpuid;
|
||||
mov edi, [regs]
|
||||
mov [edi], eax;
|
||||
mov [edi+4], ebx;
|
||||
mov [edi+8], ecx;
|
||||
mov [edi+12], edx;
|
||||
|
||||
pop edi;
|
||||
pop ebx;
|
||||
}
|
||||
return 0;
|
||||
|
||||
#else
|
||||
|
||||
// GCC Assembly Code -->
|
||||
|
||||
// see if we can use cpuid
|
||||
__asm__ __volatile__ (
|
||||
"sub $0x18, %%esp\n"
|
||||
"pushf\n"
|
||||
"pop %%eax\n"
|
||||
"mov %%eax, %%edx\n"
|
||||
"xor $0x200000, %%eax\n"
|
||||
"push %%eax\n"
|
||||
"popf\n"
|
||||
"pushf\n"
|
||||
"pop %%eax\n"
|
||||
"xor %%edx, %%eax\n"
|
||||
"mov %%eax, %[flag]\n"
|
||||
"add $0x18, %%esp\n"
|
||||
"cmpl $0x0,%%eax\n"
|
||||
"jne 1f\n"
|
||||
"mov $0xffffffff, %%eax\n"
|
||||
"leave\n"
|
||||
"ret\n"
|
||||
"1:\n"
|
||||
: [flag]"=r"(flag) :
|
||||
);
|
||||
|
||||
cpuid(cmd, regs[0], regs[1], regs[2], regs[3]);
|
||||
return 0;
|
||||
|
||||
#endif // _MSC_VER
|
||||
}
|
||||
|
||||
u64 GetCPUTick( void )
|
||||
{
|
||||
#if defined (_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
return __rdtsc();
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
__asm rdtsc;
|
||||
|
||||
#else
|
||||
|
||||
u32 _a, _d;
|
||||
__asm__ __volatile__ ("rdtsc" : "=a"(_a), "=d"(_d));
|
||||
return (u64)_a | ((u64)_d << 32);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Note: This function doesn't support GCC/Linux. Looking online it seems the only
|
||||
// way to simulate the Micrsoft SEH model is to use unix signals, and the 'sigaction'
|
||||
// function specifically. Maybe a project for a linux developer at a later date. :)
|
||||
#ifdef _MSC_VER
|
||||
static bool _test_instruction( void* pfnCall )
|
||||
{
|
||||
__try {
|
||||
((void (*)())pfnCall)();
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static char* bool_to_char( bool testcond )
|
||||
{
|
||||
return testcond ? "true" : "false";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined __LINUX__
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
s64 CPUSpeedHz( int time )
|
||||
{
|
||||
int timeStart,
|
||||
timeStop;
|
||||
s64 startTick,
|
||||
endTick;
|
||||
|
||||
if( ! cpucaps.hasTimeStampCounter )
|
||||
{
|
||||
return 0; //check if function is supported
|
||||
}
|
||||
|
||||
// Align the cpu execution to a timeGetTime boundary.
|
||||
// Without this the result could be skewed by up to several milliseconds.
|
||||
|
||||
do { timeStart = timeGetTime( );
|
||||
} while( timeGetTime( ) == timeStart );
|
||||
|
||||
do
|
||||
{
|
||||
timeStop = timeGetTime( );
|
||||
startTick = GetCPUTick( );
|
||||
} while( ( timeStop - timeStart ) < 1 );
|
||||
|
||||
timeStart = timeStop;
|
||||
do
|
||||
{
|
||||
timeStop = timeGetTime();
|
||||
endTick = GetCPUTick();
|
||||
}
|
||||
while( ( timeStop - timeStart ) < time );
|
||||
|
||||
return (s64)( endTick - startTick );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
int arr[] = {
|
||||
0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865,
|
||||
0x51203229,0x20646175,0x20555043,0x20202020 ,
|
||||
0x20202020,0x20402020,0x36362e32,0x7a4847
|
||||
};
|
||||
|
||||
void cpudetectInit()
|
||||
{
|
||||
u32 regs[ 4 ];
|
||||
u32 cmds;
|
||||
int cputype=0; // Cpu type
|
||||
//AMD 64 STUFF
|
||||
u32 x86_64_8BITBRANDID;
|
||||
u32 x86_64_12BITBRANDID;
|
||||
int num;
|
||||
char str[50];
|
||||
|
||||
memzero_obj( cpuinfo.x86ID );
|
||||
cpuinfo.x86Family = 0;
|
||||
cpuinfo.x86Model = 0;
|
||||
cpuinfo.x86PType = 0;
|
||||
cpuinfo.x86StepID = 0;
|
||||
cpuinfo.x86Flags = 0;
|
||||
cpuinfo.x86EFlags = 0;
|
||||
|
||||
if ( iCpuId( 0, regs ) == -1 ) return;
|
||||
|
||||
cmds = regs[ 0 ];
|
||||
((u32*)cpuinfo.x86ID)[ 0 ] = regs[ 1 ];
|
||||
((u32*)cpuinfo.x86ID)[ 1 ] = regs[ 3 ];
|
||||
((u32*)cpuinfo.x86ID)[ 2 ] = regs[ 2 ];
|
||||
|
||||
// Hack - prevents reg[2] & reg[3] from being optimized out of existance!
|
||||
num = sprintf(str, "\tx86Flags = %8.8x %8.8x\n", regs[3], regs[2]);
|
||||
|
||||
u32 LogicalCoresPerPhysicalCPU = 0;
|
||||
u32 PhysicalCoresPerPhysicalCPU = 1;
|
||||
|
||||
if ( cmds >= 0x00000001 )
|
||||
{
|
||||
if ( iCpuId( 0x00000001, regs ) != -1 )
|
||||
{
|
||||
cpuinfo.x86StepID = regs[ 0 ] & 0xf;
|
||||
cpuinfo.x86Model = (regs[ 0 ] >> 4) & 0xf;
|
||||
cpuinfo.x86Family = (regs[ 0 ] >> 8) & 0xf;
|
||||
cpuinfo.x86PType = (regs[ 0 ] >> 12) & 0x3;
|
||||
LogicalCoresPerPhysicalCPU = ( regs[1] >> 16 ) & 0xff;
|
||||
x86_64_8BITBRANDID = regs[1] & 0xff;
|
||||
cpuinfo.x86Flags = regs[ 3 ];
|
||||
cpuinfo.x86Flags2 = regs[ 2 ];
|
||||
}
|
||||
}
|
||||
/* detect multicore for intel cpu */
|
||||
if ((cmds >= 0x00000004) && !strcmp("GenuineIntel",cpuinfo.x86ID))
|
||||
{
|
||||
if ( iCpuId( 0x00000004, regs ) != -1 )
|
||||
{
|
||||
PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f;
|
||||
}
|
||||
}
|
||||
|
||||
if ( iCpuId( 0x80000000, regs ) != -1 )
|
||||
{
|
||||
cmds = regs[ 0 ];
|
||||
if ( cmds >= 0x80000001 )
|
||||
{
|
||||
if ( iCpuId( 0x80000001, regs ) != -1 )
|
||||
{
|
||||
x86_64_12BITBRANDID = regs[1] & 0xfff;
|
||||
cpuinfo.x86EFlags2 = regs[ 2 ];
|
||||
cpuinfo.x86EFlags = regs[ 3 ];
|
||||
|
||||
}
|
||||
}
|
||||
/* detect multicore for amd cpu */
|
||||
if ((cmds >= 0x80000008) && !strcmp("AuthenticAMD",cpuinfo.x86ID))
|
||||
{
|
||||
if ( iCpuId( 0x80000008, regs ) != -1 )
|
||||
{
|
||||
PhysicalCoresPerPhysicalCPU += ( regs[2] ) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(cpuinfo.x86PType)
|
||||
{
|
||||
case 0:
|
||||
strcpy( cpuinfo.x86Type, "Standard OEM");
|
||||
break;
|
||||
case 1:
|
||||
strcpy( cpuinfo.x86Type, "Overdrive");
|
||||
break;
|
||||
case 2:
|
||||
strcpy( cpuinfo.x86Type, "Dual");
|
||||
break;
|
||||
case 3:
|
||||
strcpy( cpuinfo.x86Type, "Reserved");
|
||||
break;
|
||||
default:
|
||||
strcpy( cpuinfo.x86Type, "Unknown");
|
||||
break;
|
||||
}
|
||||
if ( cpuinfo.x86ID[ 0 ] == 'G' ){ cputype=0;}//trick lines but if you know a way better ;p
|
||||
if ( cpuinfo.x86ID[ 0 ] == 'A' ){ cputype=1;}
|
||||
|
||||
memzero_obj( cpuinfo.x86Fam );
|
||||
iCpuId( 0x80000002, (u32*)cpuinfo.x86Fam);
|
||||
iCpuId( 0x80000003, (u32*)(cpuinfo.x86Fam+16));
|
||||
iCpuId( 0x80000004, (u32*)(cpuinfo.x86Fam+32));
|
||||
|
||||
//capabilities
|
||||
cpucaps.hasFloatingPointUnit = ( cpuinfo.x86Flags >> 0 ) & 1;
|
||||
cpucaps.hasVirtual8086ModeEnhancements = ( cpuinfo.x86Flags >> 1 ) & 1;
|
||||
cpucaps.hasDebuggingExtensions = ( cpuinfo.x86Flags >> 2 ) & 1;
|
||||
cpucaps.hasPageSizeExtensions = ( cpuinfo.x86Flags >> 3 ) & 1;
|
||||
cpucaps.hasTimeStampCounter = ( cpuinfo.x86Flags >> 4 ) & 1;
|
||||
cpucaps.hasModelSpecificRegisters = ( cpuinfo.x86Flags >> 5 ) & 1;
|
||||
cpucaps.hasPhysicalAddressExtension = ( cpuinfo.x86Flags >> 6 ) & 1;
|
||||
cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 7 ) & 1;
|
||||
cpucaps.hasCOMPXCHG8BInstruction = ( cpuinfo.x86Flags >> 8 ) & 1;
|
||||
cpucaps.hasAdvancedProgrammableInterruptController = ( cpuinfo.x86Flags >> 9 ) & 1;
|
||||
cpucaps.hasSEPFastSystemCall = ( cpuinfo.x86Flags >> 11 ) & 1;
|
||||
cpucaps.hasMemoryTypeRangeRegisters = ( cpuinfo.x86Flags >> 12 ) & 1;
|
||||
cpucaps.hasPTEGlobalFlag = ( cpuinfo.x86Flags >> 13 ) & 1;
|
||||
cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 14 ) & 1;
|
||||
cpucaps.hasConditionalMoveAndCompareInstructions = ( cpuinfo.x86Flags >> 15 ) & 1;
|
||||
cpucaps.hasFGPageAttributeTable = ( cpuinfo.x86Flags >> 16 ) & 1;
|
||||
cpucaps.has36bitPageSizeExtension = ( cpuinfo.x86Flags >> 17 ) & 1;
|
||||
cpucaps.hasProcessorSerialNumber = ( cpuinfo.x86Flags >> 18 ) & 1;
|
||||
cpucaps.hasCFLUSHInstruction = ( cpuinfo.x86Flags >> 19 ) & 1;
|
||||
cpucaps.hasDebugStore = ( cpuinfo.x86Flags >> 21 ) & 1;
|
||||
cpucaps.hasACPIThermalMonitorAndClockControl = ( cpuinfo.x86Flags >> 22 ) & 1;
|
||||
cpucaps.hasMultimediaExtensions = ( cpuinfo.x86Flags >> 23 ) & 1; //mmx
|
||||
cpucaps.hasFastStreamingSIMDExtensionsSaveRestore = ( cpuinfo.x86Flags >> 24 ) & 1;
|
||||
cpucaps.hasStreamingSIMDExtensions = ( cpuinfo.x86Flags >> 25 ) & 1; //sse
|
||||
cpucaps.hasStreamingSIMD2Extensions = ( cpuinfo.x86Flags >> 26 ) & 1; //sse2
|
||||
cpucaps.hasSelfSnoop = ( cpuinfo.x86Flags >> 27 ) & 1;
|
||||
cpucaps.hasMultiThreading = ( cpuinfo.x86Flags >> 28 ) & 1;
|
||||
cpucaps.hasThermalMonitor = ( cpuinfo.x86Flags >> 29 ) & 1;
|
||||
cpucaps.hasIntel64BitArchitecture = ( cpuinfo.x86Flags >> 30 ) & 1;
|
||||
|
||||
//that is only for AMDs
|
||||
cpucaps.hasMultimediaExtensionsExt = ( cpuinfo.x86EFlags >> 22 ) & 1; //mmx2
|
||||
cpucaps.hasAMD64BitArchitecture = ( cpuinfo.x86EFlags >> 29 ) & 1; //64bit cpu
|
||||
cpucaps.has3DNOWInstructionExtensionsExt = ( cpuinfo.x86EFlags >> 30 ) & 1; //3dnow+
|
||||
cpucaps.has3DNOWInstructionExtensions = ( cpuinfo.x86EFlags >> 31 ) & 1; //3dnow
|
||||
cpucaps.hasStreamingSIMD4ExtensionsA = ( cpuinfo.x86EFlags2 >> 6 ) & 1; //INSERTQ / EXTRQ / MOVNT
|
||||
|
||||
|
||||
cpuinfo.cpuspeed = (u32)(CPUSpeedHz( 400 ) / 400000 );
|
||||
|
||||
// --> SSE3 / SSSE3 / SSE4.1 / SSE 4.2 detection <--
|
||||
|
||||
cpucaps.hasStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 0 ) & 1; //sse3
|
||||
cpucaps.hasSupplementalStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 9 ) & 1; //ssse3
|
||||
cpucaps.hasStreamingSIMD4Extensions = ( cpuinfo.x86Flags2 >> 19 ) & 1; //sse4.1
|
||||
cpucaps.hasStreamingSIMD4Extensions2 = ( cpuinfo.x86Flags2 >> 20 ) & 1; //sse4.2
|
||||
|
||||
// Can the SSE3 / SSE4.1 bits be trusted? Using an instruction test is a very "complete"
|
||||
// approach to ensuring the bit is accurate, and at least one reported case of a Q9550 not
|
||||
// having SSE 4.1 set but still supporting it properly is fixed by this --air
|
||||
|
||||
#ifdef _MSC_VER
|
||||
u8* recSSE = (u8*)HostSys::Mmap( NULL, 0x1000 );
|
||||
if( recSSE != NULL )
|
||||
{
|
||||
xSetPtr( recSSE );
|
||||
xMOVSLDUP( xmm1, xmm0 );
|
||||
RET();
|
||||
|
||||
u8* funcSSSE3 = xGetPtr();
|
||||
xPABS.W( xmm0, xmm1 );
|
||||
RET();
|
||||
|
||||
u8* funcSSE41 = xGetPtr();
|
||||
xBLEND.VPD( xmm1, xmm0 );
|
||||
RET();
|
||||
|
||||
bool sse3_result = _test_instruction( recSSE ); // sse3
|
||||
bool ssse3_result = _test_instruction( funcSSSE3 );
|
||||
bool sse41_result = _test_instruction( funcSSE41 );
|
||||
|
||||
HostSys::Munmap( recSSE, 0x1000 );
|
||||
|
||||
// Test for and log any irregularities here.
|
||||
// We take the instruction test result over cpuid since (in theory) it should be a
|
||||
// more reliable gauge of the cpu's actual ability.
|
||||
|
||||
if( sse3_result != !!cpucaps.hasStreamingSIMD3Extensions )
|
||||
{
|
||||
Console::Notice( "SSE3 Detection Inconsistency: cpuid=%s, test_result=%s",
|
||||
params bool_to_char( !!cpucaps.hasStreamingSIMD3Extensions ), bool_to_char( sse3_result ) );
|
||||
|
||||
cpucaps.hasStreamingSIMD3Extensions = sse3_result;
|
||||
}
|
||||
|
||||
if( ssse3_result != !!cpucaps.hasSupplementalStreamingSIMD3Extensions )
|
||||
{
|
||||
Console::Notice( "SSSE3 Detection Inconsistency: cpuid=%s, test_result=%s",
|
||||
params bool_to_char( !!cpucaps.hasSupplementalStreamingSIMD3Extensions ), bool_to_char( ssse3_result ) );
|
||||
|
||||
cpucaps.hasSupplementalStreamingSIMD3Extensions = ssse3_result;
|
||||
}
|
||||
|
||||
if( sse41_result != !!cpucaps.hasStreamingSIMD4Extensions )
|
||||
{
|
||||
Console::Notice( "SSE4 Detection Inconsistency: cpuid=%s, test_result=%s",
|
||||
params bool_to_char( !!cpucaps.hasStreamingSIMD4Extensions ), bool_to_char( sse41_result ) );
|
||||
|
||||
cpucaps.hasStreamingSIMD4Extensions = sse41_result;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
Console::Notice(
|
||||
"Notice: Could not allocate memory for SSE3/4 detection.\n"
|
||||
"\tRelying on CPUID results. [this is not an error]"
|
||||
);
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////
|
||||
// Core Counting!
|
||||
|
||||
if( !cpucaps.hasMultiThreading || LogicalCoresPerPhysicalCPU == 0 )
|
||||
LogicalCoresPerPhysicalCPU = 1;
|
||||
|
||||
// This will assign values into cpuinfo.LogicalCores and PhysicalCores
|
||||
Threading::CountLogicalCores( LogicalCoresPerPhysicalCPU, PhysicalCoresPerPhysicalCPU );
|
||||
}
|
||||
|
||||
/* Cpudetection lib
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "internal.h"
|
||||
#include "tools.h"
|
||||
#include "Utilities/RedtapeWindows.h"
|
||||
#include "Utilities/Threading.h"
|
||||
|
||||
using namespace x86Emitter;
|
||||
|
||||
CAPABILITIES cpucaps;
|
||||
CPUINFO cpuinfo;
|
||||
|
||||
static s32 iCpuId( u32 cmd, u32 *regs )
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
__asm
|
||||
{
|
||||
xor ecx, ecx; // ecx should be zero for CPUID(4)
|
||||
}
|
||||
#else
|
||||
__asm__ ( "xor ecx, ecx" );
|
||||
#endif
|
||||
|
||||
__cpuid( (int*)regs, cmd );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u64 GetRdtsc( void )
|
||||
{
|
||||
return __rdtsc();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Note: This function doesn't support GCC/Linux. Looking online it seems the only
|
||||
// way to simulate the Microsoft SEH model is to use unix signals, and the 'sigaction'
|
||||
// function specifically. Maybe a project for a linux developer at a later date. :)
|
||||
//
|
||||
#ifdef _MSC_VER
|
||||
static bool _test_instruction( void* pfnCall )
|
||||
{
|
||||
__try {
|
||||
((void (*)())pfnCall)();
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static char* bool_to_char( bool testcond )
|
||||
{
|
||||
return testcond ? "true" : "false";
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __LINUX__
|
||||
# include <sys/time.h>
|
||||
# include <errno.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
static HANDLE s_threadId = NULL;
|
||||
static DWORD s_oldmask = ERROR_INVALID_PARAMETER;
|
||||
#endif
|
||||
|
||||
static void SetSingleAffinity()
|
||||
{
|
||||
#ifdef _WINDOWS_
|
||||
// Assign a single CPU thread affinity to ensure rdtsc() accuracy.
|
||||
// (rdtsc for each CPU/core can differ, causing skewed results)
|
||||
|
||||
DWORD_PTR availProcCpus, availSysCpus;
|
||||
if( !GetProcessAffinityMask( GetCurrentProcess(), &availProcCpus, &availSysCpus ) ) return;
|
||||
|
||||
int i;
|
||||
for( i=0; i<32; ++i )
|
||||
{
|
||||
if( availProcCpus & (1<<i) ) break;
|
||||
}
|
||||
|
||||
HANDLE s_threadId = GetCurrentThread();
|
||||
DWORD s_oldmask = SetThreadAffinityMask( s_threadId, (1UL<<i) );
|
||||
|
||||
if( s_oldmask == ERROR_INVALID_PARAMETER )
|
||||
{
|
||||
Console::Notice(
|
||||
"CpuDetect: SetThreadAffinityMask failed...\n"
|
||||
"\tSystem Affinity : 0x%08x"
|
||||
"\tProcess Affinity: 0x%08x"
|
||||
"\tAttempted Thread Affinity CPU: i",
|
||||
params availProcCpus, availSysCpus, i
|
||||
);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
static s64 CPUSpeedHz( u64 time )
|
||||
{
|
||||
u64 timeStart, timeStop;
|
||||
s64 startTick, endTick;
|
||||
|
||||
if( ! cpucaps.hasTimeStampCounter )
|
||||
return 0; //check if function is supported
|
||||
|
||||
SetSingleAffinity();
|
||||
|
||||
// Align the cpu execution to a cpuTick boundary.
|
||||
|
||||
do { timeStart = GetCPUTicks();
|
||||
} while( GetCPUTicks() == timeStart );
|
||||
|
||||
do
|
||||
{
|
||||
timeStop = GetCPUTicks( );
|
||||
startTick = GetRdtsc( );
|
||||
} while( ( timeStop - timeStart ) == 0 );
|
||||
|
||||
timeStart = timeStop;
|
||||
do
|
||||
{
|
||||
timeStop = GetCPUTicks();
|
||||
endTick = GetRdtsc();
|
||||
}
|
||||
while( ( timeStop - timeStart ) < time );
|
||||
|
||||
#ifdef _WINDOWS_
|
||||
if( s_oldmask != ERROR_INVALID_PARAMETER )
|
||||
SetThreadAffinityMask( s_threadId, s_oldmask );
|
||||
#endif
|
||||
|
||||
return (s64)( endTick - startTick );
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
int arr[] = {
|
||||
0x65746e49, 0x2952286c, 0x726f4320, 0x4d542865,
|
||||
0x51203229,0x20646175,0x20555043,0x20202020 ,
|
||||
0x20202020,0x20402020,0x36362e32,0x7a4847
|
||||
};
|
||||
|
||||
void cpudetectInit()
|
||||
{
|
||||
u32 regs[ 4 ];
|
||||
u32 cmds;
|
||||
int cputype=0; // Cpu type
|
||||
//AMD 64 STUFF
|
||||
u32 x86_64_8BITBRANDID;
|
||||
u32 x86_64_12BITBRANDID;
|
||||
int num;
|
||||
char str[50];
|
||||
|
||||
memzero_obj( cpuinfo.x86ID );
|
||||
cpuinfo.x86Family = 0;
|
||||
cpuinfo.x86Model = 0;
|
||||
cpuinfo.x86PType = 0;
|
||||
cpuinfo.x86StepID = 0;
|
||||
cpuinfo.x86Flags = 0;
|
||||
cpuinfo.x86EFlags = 0;
|
||||
|
||||
if ( iCpuId( 0, regs ) == -1 ) return;
|
||||
|
||||
cmds = regs[ 0 ];
|
||||
((u32*)cpuinfo.x86ID)[ 0 ] = regs[ 1 ];
|
||||
((u32*)cpuinfo.x86ID)[ 1 ] = regs[ 3 ];
|
||||
((u32*)cpuinfo.x86ID)[ 2 ] = regs[ 2 ];
|
||||
|
||||
// Hack - prevents reg[2] & reg[3] from being optimized out of existance!
|
||||
num = sprintf(str, "\tx86Flags = %8.8x %8.8x\n", regs[3], regs[2]);
|
||||
|
||||
u32 LogicalCoresPerPhysicalCPU = 0;
|
||||
u32 PhysicalCoresPerPhysicalCPU = 1;
|
||||
|
||||
if ( cmds >= 0x00000001 )
|
||||
{
|
||||
if ( iCpuId( 0x00000001, regs ) != -1 )
|
||||
{
|
||||
cpuinfo.x86StepID = regs[ 0 ] & 0xf;
|
||||
cpuinfo.x86Model = (regs[ 0 ] >> 4) & 0xf;
|
||||
cpuinfo.x86Family = (regs[ 0 ] >> 8) & 0xf;
|
||||
cpuinfo.x86PType = (regs[ 0 ] >> 12) & 0x3;
|
||||
LogicalCoresPerPhysicalCPU = ( regs[1] >> 16 ) & 0xff;
|
||||
x86_64_8BITBRANDID = regs[ 1 ] & 0xff;
|
||||
cpuinfo.x86Flags = regs[ 3 ];
|
||||
cpuinfo.x86Flags2 = regs[ 2 ];
|
||||
}
|
||||
}
|
||||
/* detect multicore for intel cpu */
|
||||
if ((cmds >= 0x00000004) && !strcmp("GenuineIntel",cpuinfo.x86ID))
|
||||
{
|
||||
if ( iCpuId( 0x00000004, regs ) != -1 )
|
||||
{
|
||||
PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f;
|
||||
}
|
||||
}
|
||||
|
||||
if ( iCpuId( 0x80000000, regs ) != -1 )
|
||||
{
|
||||
cmds = regs[ 0 ];
|
||||
if ( cmds >= 0x80000001 )
|
||||
{
|
||||
if ( iCpuId( 0x80000001, regs ) != -1 )
|
||||
{
|
||||
x86_64_12BITBRANDID = regs[1] & 0xfff;
|
||||
cpuinfo.x86EFlags2 = regs[ 2 ];
|
||||
cpuinfo.x86EFlags = regs[ 3 ];
|
||||
|
||||
}
|
||||
}
|
||||
/* detect multicore for amd cpu */
|
||||
if ((cmds >= 0x80000008) && !strcmp("AuthenticAMD",cpuinfo.x86ID))
|
||||
{
|
||||
if ( iCpuId( 0x80000008, regs ) != -1 )
|
||||
{
|
||||
PhysicalCoresPerPhysicalCPU += ( regs[2] ) & 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(cpuinfo.x86PType)
|
||||
{
|
||||
case 0:
|
||||
strcpy( cpuinfo.x86Type, "Standard OEM");
|
||||
break;
|
||||
case 1:
|
||||
strcpy( cpuinfo.x86Type, "Overdrive");
|
||||
break;
|
||||
case 2:
|
||||
strcpy( cpuinfo.x86Type, "Dual");
|
||||
break;
|
||||
case 3:
|
||||
strcpy( cpuinfo.x86Type, "Reserved");
|
||||
break;
|
||||
default:
|
||||
strcpy( cpuinfo.x86Type, "Unknown");
|
||||
break;
|
||||
}
|
||||
if ( cpuinfo.x86ID[ 0 ] == 'G' ){ cputype=0;}//trick lines but if you know a way better ;p
|
||||
if ( cpuinfo.x86ID[ 0 ] == 'A' ){ cputype=1;}
|
||||
|
||||
memzero_obj( cpuinfo.x86Fam );
|
||||
iCpuId( 0x80000002, (u32*)cpuinfo.x86Fam);
|
||||
iCpuId( 0x80000003, (u32*)(cpuinfo.x86Fam+16));
|
||||
iCpuId( 0x80000004, (u32*)(cpuinfo.x86Fam+32));
|
||||
|
||||
//capabilities
|
||||
cpucaps.hasFloatingPointUnit = ( cpuinfo.x86Flags >> 0 ) & 1;
|
||||
cpucaps.hasVirtual8086ModeEnhancements = ( cpuinfo.x86Flags >> 1 ) & 1;
|
||||
cpucaps.hasDebuggingExtensions = ( cpuinfo.x86Flags >> 2 ) & 1;
|
||||
cpucaps.hasPageSizeExtensions = ( cpuinfo.x86Flags >> 3 ) & 1;
|
||||
cpucaps.hasTimeStampCounter = ( cpuinfo.x86Flags >> 4 ) & 1;
|
||||
cpucaps.hasModelSpecificRegisters = ( cpuinfo.x86Flags >> 5 ) & 1;
|
||||
cpucaps.hasPhysicalAddressExtension = ( cpuinfo.x86Flags >> 6 ) & 1;
|
||||
cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 7 ) & 1;
|
||||
cpucaps.hasCOMPXCHG8BInstruction = ( cpuinfo.x86Flags >> 8 ) & 1;
|
||||
cpucaps.hasAdvancedProgrammableInterruptController = ( cpuinfo.x86Flags >> 9 ) & 1;
|
||||
cpucaps.hasSEPFastSystemCall = ( cpuinfo.x86Flags >> 11 ) & 1;
|
||||
cpucaps.hasMemoryTypeRangeRegisters = ( cpuinfo.x86Flags >> 12 ) & 1;
|
||||
cpucaps.hasPTEGlobalFlag = ( cpuinfo.x86Flags >> 13 ) & 1;
|
||||
cpucaps.hasMachineCheckArchitecture = ( cpuinfo.x86Flags >> 14 ) & 1;
|
||||
cpucaps.hasConditionalMoveAndCompareInstructions = ( cpuinfo.x86Flags >> 15 ) & 1;
|
||||
cpucaps.hasFGPageAttributeTable = ( cpuinfo.x86Flags >> 16 ) & 1;
|
||||
cpucaps.has36bitPageSizeExtension = ( cpuinfo.x86Flags >> 17 ) & 1;
|
||||
cpucaps.hasProcessorSerialNumber = ( cpuinfo.x86Flags >> 18 ) & 1;
|
||||
cpucaps.hasCFLUSHInstruction = ( cpuinfo.x86Flags >> 19 ) & 1;
|
||||
cpucaps.hasDebugStore = ( cpuinfo.x86Flags >> 21 ) & 1;
|
||||
cpucaps.hasACPIThermalMonitorAndClockControl = ( cpuinfo.x86Flags >> 22 ) & 1;
|
||||
cpucaps.hasMultimediaExtensions = ( cpuinfo.x86Flags >> 23 ) & 1; //mmx
|
||||
cpucaps.hasFastStreamingSIMDExtensionsSaveRestore = ( cpuinfo.x86Flags >> 24 ) & 1;
|
||||
cpucaps.hasStreamingSIMDExtensions = ( cpuinfo.x86Flags >> 25 ) & 1; //sse
|
||||
cpucaps.hasStreamingSIMD2Extensions = ( cpuinfo.x86Flags >> 26 ) & 1; //sse2
|
||||
cpucaps.hasSelfSnoop = ( cpuinfo.x86Flags >> 27 ) & 1;
|
||||
cpucaps.hasMultiThreading = ( cpuinfo.x86Flags >> 28 ) & 1;
|
||||
cpucaps.hasThermalMonitor = ( cpuinfo.x86Flags >> 29 ) & 1;
|
||||
cpucaps.hasIntel64BitArchitecture = ( cpuinfo.x86Flags >> 30 ) & 1;
|
||||
|
||||
//that is only for AMDs
|
||||
cpucaps.hasMultimediaExtensionsExt = ( cpuinfo.x86EFlags >> 22 ) & 1; //mmx2
|
||||
cpucaps.hasAMD64BitArchitecture = ( cpuinfo.x86EFlags >> 29 ) & 1; //64bit cpu
|
||||
cpucaps.has3DNOWInstructionExtensionsExt = ( cpuinfo.x86EFlags >> 30 ) & 1; //3dnow+
|
||||
cpucaps.has3DNOWInstructionExtensions = ( cpuinfo.x86EFlags >> 31 ) & 1; //3dnow
|
||||
cpucaps.hasStreamingSIMD4ExtensionsA = ( cpuinfo.x86EFlags2 >> 6 ) & 1; //INSERTQ / EXTRQ / MOVNT
|
||||
|
||||
InitCPUTicks();
|
||||
u64 span = GetTickFrequency();
|
||||
|
||||
if( (span % 1000) < 400 ) // helps minimize rounding errors
|
||||
cpuinfo.cpuspeed = (u32)( CPUSpeedHz( span / 1000 ) / 1000 );
|
||||
else
|
||||
cpuinfo.cpuspeed = (u32)( CPUSpeedHz( span / 500 ) / 2000 );
|
||||
|
||||
// --> SSE3 / SSSE3 / SSE4.1 / SSE 4.2 detection <--
|
||||
|
||||
cpucaps.hasStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 0 ) & 1; //sse3
|
||||
cpucaps.hasSupplementalStreamingSIMD3Extensions = ( cpuinfo.x86Flags2 >> 9 ) & 1; //ssse3
|
||||
cpucaps.hasStreamingSIMD4Extensions = ( cpuinfo.x86Flags2 >> 19 ) & 1; //sse4.1
|
||||
cpucaps.hasStreamingSIMD4Extensions2 = ( cpuinfo.x86Flags2 >> 20 ) & 1; //sse4.2
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SIMD Instruction Support Detection
|
||||
//
|
||||
// Can the SSE3 / SSE4.1 bits be trusted? Using an instruction test is a very "complete"
|
||||
// approach to ensuring the instruction set is supported, and at least one reported case
|
||||
// of a Q9550 not having it's SSE 4.1 bit set but still supporting it properly is fixed
|
||||
// by this --air
|
||||
// (note: the user who reported the case later fixed the problem by doing a CMOS reset)
|
||||
//
|
||||
// Linux support note: Linux/GCC doesn't have SEH-style exceptions which allow handling of
|
||||
// CPU-level exceptions (__try/__except in msvc) so this code is disabled on GCC, and
|
||||
// detection relies on the CPUID bits alone.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
u8* recSSE = (u8*)HostSys::Mmap( NULL, 0x1000 );
|
||||
if( recSSE != NULL )
|
||||
{
|
||||
xSetPtr( recSSE );
|
||||
xMOVSLDUP( xmm1, xmm0 );
|
||||
xRET();
|
||||
|
||||
u8* funcSSSE3 = xGetPtr();
|
||||
xPABS.W( xmm0, xmm1 );
|
||||
xRET();
|
||||
|
||||
u8* funcSSE41 = xGetPtr();
|
||||
xBLEND.VPD( xmm1, xmm0 );
|
||||
xRET();
|
||||
|
||||
bool sse3_result = _test_instruction( recSSE ); // sse3
|
||||
bool ssse3_result = _test_instruction( funcSSSE3 );
|
||||
bool sse41_result = _test_instruction( funcSSE41 );
|
||||
|
||||
HostSys::Munmap( recSSE, 0x1000 );
|
||||
|
||||
// Test for and log any irregularities here.
|
||||
// We take the instruction test result over cpuid since (in theory) it should be a
|
||||
// more reliable gauge of the cpu's actual ability. But since a difference in bit
|
||||
// and actual ability may represent a cmos/bios problem, we report it to the user.
|
||||
|
||||
if( sse3_result != !!cpucaps.hasStreamingSIMD3Extensions )
|
||||
{
|
||||
Console::Notice( "SSE3 Detection Inconsistency: cpuid=%s, test_result=%s",
|
||||
params bool_to_char( !!cpucaps.hasStreamingSIMD3Extensions ), bool_to_char( sse3_result ) );
|
||||
|
||||
cpucaps.hasStreamingSIMD3Extensions = sse3_result;
|
||||
}
|
||||
|
||||
if( ssse3_result != !!cpucaps.hasSupplementalStreamingSIMD3Extensions )
|
||||
{
|
||||
Console::Notice( "SSSE3 Detection Inconsistency: cpuid=%s, test_result=%s",
|
||||
params bool_to_char( !!cpucaps.hasSupplementalStreamingSIMD3Extensions ), bool_to_char( ssse3_result ) );
|
||||
|
||||
cpucaps.hasSupplementalStreamingSIMD3Extensions = ssse3_result;
|
||||
}
|
||||
|
||||
if( sse41_result != !!cpucaps.hasStreamingSIMD4Extensions )
|
||||
{
|
||||
Console::Notice( "SSE4 Detection Inconsistency: cpuid=%s, test_result=%s",
|
||||
params bool_to_char( !!cpucaps.hasStreamingSIMD4Extensions ), bool_to_char( sse41_result ) );
|
||||
|
||||
cpucaps.hasStreamingSIMD4Extensions = sse41_result;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Console::Notice(
|
||||
"Notice: Could not allocate memory for SSE3/4 detection.\n"
|
||||
"\tRelying on CPUID results. [this is not an error]"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Core Counting!
|
||||
|
||||
if( !cpucaps.hasMultiThreading || LogicalCoresPerPhysicalCPU == 0 )
|
||||
LogicalCoresPerPhysicalCPU = 1;
|
||||
|
||||
// This will assign values into cpuinfo.LogicalCores and PhysicalCores
|
||||
Threading::CountLogicalCores( LogicalCoresPerPhysicalCPU, PhysicalCoresPerPhysicalCPU );
|
||||
}
|
||||
|
|
@ -1,276 +1,276 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "ix86_legacy_internal.h"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// FPU instructions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/* fild m32 to fpu reg stack */
|
||||
emitterT void FILD32( u32 from )
|
||||
{
|
||||
xWrite8( 0xDB );
|
||||
ModRM( 0, 0x0, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fistp m32 from fpu reg stack */
|
||||
emitterT void FISTP32( u32 from )
|
||||
{
|
||||
xWrite8( 0xDB );
|
||||
ModRM( 0, 0x3, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fld m32 to fpu reg stack */
|
||||
emitterT void FLD32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x0, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
// fld st(i)
|
||||
emitterT void FLD(int st) { xWrite16(0xc0d9+(st<<8)); }
|
||||
emitterT void FLD1() { xWrite16(0xe8d9); }
|
||||
emitterT void FLDL2E() { xWrite16(0xead9); }
|
||||
|
||||
/* fst m32 from fpu reg stack */
|
||||
emitterT void FST32( u32 to )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x2, DISP32 );
|
||||
xWrite32( MEMADDR(to, 4) );
|
||||
}
|
||||
|
||||
/* fstp m32 from fpu reg stack */
|
||||
emitterT void FSTP32( u32 to )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x3, DISP32 );
|
||||
xWrite32( MEMADDR(to, 4) );
|
||||
}
|
||||
|
||||
// fstp st(i)
|
||||
emitterT void FSTP(int st) { xWrite16(0xd8dd+(st<<8)); }
|
||||
|
||||
/* fldcw fpu control word from m16 */
|
||||
emitterT void FLDCW( u32 from )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x5, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fnstcw fpu control word to m16 */
|
||||
emitterT void FNSTCW( u32 to )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x7, DISP32 );
|
||||
xWrite32( MEMADDR(to, 4) );
|
||||
}
|
||||
|
||||
emitterT void FNSTSWtoAX() { xWrite16(0xE0DF); }
|
||||
emitterT void FXAM() { xWrite16(0xe5d9); }
|
||||
emitterT void FDECSTP() { xWrite16(0xf6d9); }
|
||||
emitterT void FRNDINT() { xWrite16(0xfcd9); }
|
||||
emitterT void FXCH(int st) { xWrite16(0xc8d9+(st<<8)); }
|
||||
emitterT void F2XM1() { xWrite16(0xf0d9); }
|
||||
emitterT void FSCALE() { xWrite16(0xfdd9); }
|
||||
emitterT void FPATAN(void) { xWrite16(0xf3d9); }
|
||||
emitterT void FSIN(void) { xWrite16(0xfed9); }
|
||||
|
||||
/* fadd ST(src) to fpu reg stack ST(0) */
|
||||
emitterT void FADD32Rto0( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
xWrite8( 0xC0 + src );
|
||||
}
|
||||
|
||||
/* fadd ST(0) to fpu reg stack ST(src) */
|
||||
emitterT void FADD320toR( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDC );
|
||||
xWrite8( 0xC0 + src );
|
||||
}
|
||||
|
||||
/* fsub ST(src) to fpu reg stack ST(0) */
|
||||
emitterT void FSUB32Rto0( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
xWrite8( 0xE0 + src );
|
||||
}
|
||||
|
||||
/* fsub ST(0) to fpu reg stack ST(src) */
|
||||
emitterT void FSUB320toR( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDC );
|
||||
xWrite8( 0xE8 + src );
|
||||
}
|
||||
|
||||
/* fsubp -> substract ST(0) from ST(1), store in ST(1) and POP stack */
|
||||
emitterT void FSUBP( void )
|
||||
{
|
||||
xWrite8( 0xDE );
|
||||
xWrite8( 0xE9 );
|
||||
}
|
||||
|
||||
/* fmul ST(src) to fpu reg stack ST(0) */
|
||||
emitterT void FMUL32Rto0( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
xWrite8( 0xC8 + src );
|
||||
}
|
||||
|
||||
/* fmul ST(0) to fpu reg stack ST(src) */
|
||||
emitterT void FMUL320toR( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDC );
|
||||
xWrite8( 0xC8 + src );
|
||||
}
|
||||
|
||||
/* fdiv ST(src) to fpu reg stack ST(0) */
|
||||
emitterT void FDIV32Rto0( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
xWrite8( 0xF0 + src );
|
||||
}
|
||||
|
||||
/* fdiv ST(0) to fpu reg stack ST(src) */
|
||||
emitterT void FDIV320toR( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDC );
|
||||
xWrite8( 0xF8 + src );
|
||||
}
|
||||
|
||||
emitterT void FDIV320toRP( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDE );
|
||||
xWrite8( 0xF8 + src );
|
||||
}
|
||||
|
||||
/* fadd m32 to fpu reg stack */
|
||||
emitterT void FADD32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x0, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fsub m32 to fpu reg stack */
|
||||
emitterT void FSUB32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x4, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fmul m32 to fpu reg stack */
|
||||
emitterT void FMUL32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x1, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fdiv m32 to fpu reg stack */
|
||||
emitterT void FDIV32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x6, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fabs fpu reg stack */
|
||||
emitterT void FABS( void )
|
||||
{
|
||||
xWrite16( 0xE1D9 );
|
||||
}
|
||||
|
||||
/* fsqrt fpu reg stack */
|
||||
emitterT void FSQRT( void )
|
||||
{
|
||||
xWrite16( 0xFAD9 );
|
||||
}
|
||||
|
||||
/* fchs fpu reg stack */
|
||||
emitterT void FCHS( void )
|
||||
{
|
||||
xWrite16( 0xE0D9 );
|
||||
}
|
||||
|
||||
/* fcomi st, st(i) */
|
||||
emitterT void FCOMI( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDB );
|
||||
xWrite8( 0xF0 + src );
|
||||
}
|
||||
|
||||
/* fcomip st, st(i) */
|
||||
emitterT void FCOMIP( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDF );
|
||||
xWrite8( 0xF0 + src );
|
||||
}
|
||||
|
||||
/* fucomi st, st(i) */
|
||||
emitterT void FUCOMI( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDB );
|
||||
xWrite8( 0xE8 + src );
|
||||
}
|
||||
|
||||
/* fucomip st, st(i) */
|
||||
emitterT void FUCOMIP( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDF );
|
||||
xWrite8( 0xE8 + src );
|
||||
}
|
||||
|
||||
/* fcom m32 to fpu reg stack */
|
||||
emitterT void FCOM32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x2, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fcomp m32 to fpu reg stack */
|
||||
emitterT void FCOMP32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x3, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
#define FCMOV32( low, high ) \
|
||||
{ \
|
||||
xWrite8( low ); \
|
||||
xWrite8( high + from ); \
|
||||
}
|
||||
|
||||
emitterT void FCMOVB32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC0 ); }
|
||||
emitterT void FCMOVE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC8 ); }
|
||||
emitterT void FCMOVBE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD0 ); }
|
||||
emitterT void FCMOVU32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD8 ); }
|
||||
emitterT void FCMOVNB32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC0 ); }
|
||||
emitterT void FCMOVNE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC8 ); }
|
||||
emitterT void FCMOVNBE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD0 ); }
|
||||
emitterT void FCMOVNU32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD8 ); }
|
||||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "legacy_internal.h"
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// FPU instructions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
/* fild m32 to fpu reg stack */
|
||||
emitterT void FILD32( u32 from )
|
||||
{
|
||||
xWrite8( 0xDB );
|
||||
ModRM( 0, 0x0, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fistp m32 from fpu reg stack */
|
||||
emitterT void FISTP32( u32 from )
|
||||
{
|
||||
xWrite8( 0xDB );
|
||||
ModRM( 0, 0x3, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fld m32 to fpu reg stack */
|
||||
emitterT void FLD32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x0, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
// fld st(i)
|
||||
emitterT void FLD(int st) { xWrite16(0xc0d9+(st<<8)); }
|
||||
emitterT void FLD1() { xWrite16(0xe8d9); }
|
||||
emitterT void FLDL2E() { xWrite16(0xead9); }
|
||||
|
||||
/* fst m32 from fpu reg stack */
|
||||
emitterT void FST32( u32 to )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x2, DISP32 );
|
||||
xWrite32( MEMADDR(to, 4) );
|
||||
}
|
||||
|
||||
/* fstp m32 from fpu reg stack */
|
||||
emitterT void FSTP32( u32 to )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x3, DISP32 );
|
||||
xWrite32( MEMADDR(to, 4) );
|
||||
}
|
||||
|
||||
// fstp st(i)
|
||||
emitterT void FSTP(int st) { xWrite16(0xd8dd+(st<<8)); }
|
||||
|
||||
/* fldcw fpu control word from m16 */
|
||||
emitterT void FLDCW( u32 from )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x5, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fnstcw fpu control word to m16 */
|
||||
emitterT void FNSTCW( u32 to )
|
||||
{
|
||||
xWrite8( 0xD9 );
|
||||
ModRM( 0, 0x7, DISP32 );
|
||||
xWrite32( MEMADDR(to, 4) );
|
||||
}
|
||||
|
||||
emitterT void FNSTSWtoAX() { xWrite16(0xE0DF); }
|
||||
emitterT void FXAM() { xWrite16(0xe5d9); }
|
||||
emitterT void FDECSTP() { xWrite16(0xf6d9); }
|
||||
emitterT void FRNDINT() { xWrite16(0xfcd9); }
|
||||
emitterT void FXCH(int st) { xWrite16(0xc8d9+(st<<8)); }
|
||||
emitterT void F2XM1() { xWrite16(0xf0d9); }
|
||||
emitterT void FSCALE() { xWrite16(0xfdd9); }
|
||||
emitterT void FPATAN(void) { xWrite16(0xf3d9); }
|
||||
emitterT void FSIN(void) { xWrite16(0xfed9); }
|
||||
|
||||
/* fadd ST(src) to fpu reg stack ST(0) */
|
||||
emitterT void FADD32Rto0( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
xWrite8( 0xC0 + src );
|
||||
}
|
||||
|
||||
/* fadd ST(0) to fpu reg stack ST(src) */
|
||||
emitterT void FADD320toR( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDC );
|
||||
xWrite8( 0xC0 + src );
|
||||
}
|
||||
|
||||
/* fsub ST(src) to fpu reg stack ST(0) */
|
||||
emitterT void FSUB32Rto0( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
xWrite8( 0xE0 + src );
|
||||
}
|
||||
|
||||
/* fsub ST(0) to fpu reg stack ST(src) */
|
||||
emitterT void FSUB320toR( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDC );
|
||||
xWrite8( 0xE8 + src );
|
||||
}
|
||||
|
||||
/* fsubp -> substract ST(0) from ST(1), store in ST(1) and POP stack */
|
||||
emitterT void FSUBP( void )
|
||||
{
|
||||
xWrite8( 0xDE );
|
||||
xWrite8( 0xE9 );
|
||||
}
|
||||
|
||||
/* fmul ST(src) to fpu reg stack ST(0) */
|
||||
emitterT void FMUL32Rto0( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
xWrite8( 0xC8 + src );
|
||||
}
|
||||
|
||||
/* fmul ST(0) to fpu reg stack ST(src) */
|
||||
emitterT void FMUL320toR( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDC );
|
||||
xWrite8( 0xC8 + src );
|
||||
}
|
||||
|
||||
/* fdiv ST(src) to fpu reg stack ST(0) */
|
||||
emitterT void FDIV32Rto0( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
xWrite8( 0xF0 + src );
|
||||
}
|
||||
|
||||
/* fdiv ST(0) to fpu reg stack ST(src) */
|
||||
emitterT void FDIV320toR( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDC );
|
||||
xWrite8( 0xF8 + src );
|
||||
}
|
||||
|
||||
emitterT void FDIV320toRP( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDE );
|
||||
xWrite8( 0xF8 + src );
|
||||
}
|
||||
|
||||
/* fadd m32 to fpu reg stack */
|
||||
emitterT void FADD32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x0, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fsub m32 to fpu reg stack */
|
||||
emitterT void FSUB32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x4, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fmul m32 to fpu reg stack */
|
||||
emitterT void FMUL32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x1, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fdiv m32 to fpu reg stack */
|
||||
emitterT void FDIV32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x6, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fabs fpu reg stack */
|
||||
emitterT void FABS( void )
|
||||
{
|
||||
xWrite16( 0xE1D9 );
|
||||
}
|
||||
|
||||
/* fsqrt fpu reg stack */
|
||||
emitterT void FSQRT( void )
|
||||
{
|
||||
xWrite16( 0xFAD9 );
|
||||
}
|
||||
|
||||
/* fchs fpu reg stack */
|
||||
emitterT void FCHS( void )
|
||||
{
|
||||
xWrite16( 0xE0D9 );
|
||||
}
|
||||
|
||||
/* fcomi st, st(i) */
|
||||
emitterT void FCOMI( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDB );
|
||||
xWrite8( 0xF0 + src );
|
||||
}
|
||||
|
||||
/* fcomip st, st(i) */
|
||||
emitterT void FCOMIP( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDF );
|
||||
xWrite8( 0xF0 + src );
|
||||
}
|
||||
|
||||
/* fucomi st, st(i) */
|
||||
emitterT void FUCOMI( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDB );
|
||||
xWrite8( 0xE8 + src );
|
||||
}
|
||||
|
||||
/* fucomip st, st(i) */
|
||||
emitterT void FUCOMIP( x86IntRegType src )
|
||||
{
|
||||
xWrite8( 0xDF );
|
||||
xWrite8( 0xE8 + src );
|
||||
}
|
||||
|
||||
/* fcom m32 to fpu reg stack */
|
||||
emitterT void FCOM32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x2, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
/* fcomp m32 to fpu reg stack */
|
||||
emitterT void FCOMP32( u32 from )
|
||||
{
|
||||
xWrite8( 0xD8 );
|
||||
ModRM( 0, 0x3, DISP32 );
|
||||
xWrite32( MEMADDR(from, 4) );
|
||||
}
|
||||
|
||||
#define FCMOV32( low, high ) \
|
||||
{ \
|
||||
xWrite8( low ); \
|
||||
xWrite8( high + from ); \
|
||||
}
|
||||
|
||||
emitterT void FCMOVB32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC0 ); }
|
||||
emitterT void FCMOVE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xC8 ); }
|
||||
emitterT void FCMOVBE32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD0 ); }
|
||||
emitterT void FCMOVU32( x86IntRegType from ) { FCMOV32( 0xDA, 0xD8 ); }
|
||||
emitterT void FCMOVNB32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC0 ); }
|
||||
emitterT void FCMOVNE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xC8 ); }
|
||||
emitterT void FCMOVNBE32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD0 ); }
|
||||
emitterT void FCMOVNU32( x86IntRegType from ) { FCMOV32( 0xDB, 0xD8 ); }
|
|
@ -32,9 +32,7 @@
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "System.h"
|
||||
#include "ix86_internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
namespace x86Emitter {
|
||||
|
||||
|
@ -73,6 +71,34 @@ xSmartJump::~xSmartJump()
|
|||
m_baseptr = NULL; // just in case (sometimes helps in debugging too)
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Emits a 32 bit jump, and returns a pointer to the 32 bit displacement.
|
||||
// (displacements should be assigned relative to the end of the jump instruction,
|
||||
// or in other words *(retval+1) )
|
||||
__emitinline s32* xJcc32( JccComparisonType comparison, s32 displacement )
|
||||
{
|
||||
if( comparison == Jcc_Unconditional )
|
||||
xWrite8( 0xe9 );
|
||||
else
|
||||
{
|
||||
xWrite8( 0x0f );
|
||||
xWrite8( 0x80 | comparison );
|
||||
}
|
||||
xWrite<s32>( displacement );
|
||||
|
||||
return ((s32*)xGetPtr()) - 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Emits a 32 bit jump, and returns a pointer to the 8 bit displacement.
|
||||
// (displacements should be assigned relative to the end of the jump instruction,
|
||||
// or in other words *(retval+1) )
|
||||
__emitinline s8* xJcc8( JccComparisonType comparison, s8 displacement )
|
||||
{
|
||||
xWrite8( (comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison) );
|
||||
xWrite<s8>( displacement );
|
||||
return (s8*)xGetPtr() - 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Writes a jump at the current x86Ptr, which targets a pre-established target address.
|
||||
|
@ -84,32 +110,26 @@ xSmartJump::~xSmartJump()
|
|||
__emitinline void Internal::xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward )
|
||||
{
|
||||
// Calculate the potential j8 displacement first, assuming an instruction length of 2:
|
||||
sptr displacement8 = (sptr)target - ((sptr)xGetPtr() + 2);
|
||||
sptr displacement8 = (sptr)target - (sptr)(xGetPtr() + 2);
|
||||
|
||||
const int slideVal = slideForward ? ((comparison == Jcc_Unconditional) ? 3 : 4) : 0;
|
||||
displacement8 -= slideVal;
|
||||
|
||||
// if the following assert fails it means we accidentally used slideForard on a backward
|
||||
// jump (which is an invalid operation since there's nothing to slide forward).
|
||||
if( slideForward ) jASSUME( displacement8 >= 0 );
|
||||
if( slideForward )
|
||||
{
|
||||
// jASSUME has an else statement in it that would be abiguous without the brackets.
|
||||
jASSUME( displacement8 >= 0 );
|
||||
}
|
||||
|
||||
if( is_s8( displacement8 ) )
|
||||
{
|
||||
xWrite8( (comparison == Jcc_Unconditional) ? 0xeb : (0x70 | comparison) );
|
||||
xWrite<s8>( displacement8 );
|
||||
}
|
||||
xJcc8( comparison, displacement8 );
|
||||
else
|
||||
{
|
||||
// Perform a 32 bit jump instead. :(
|
||||
|
||||
if( comparison == Jcc_Unconditional )
|
||||
xWrite8( 0xe9 );
|
||||
else
|
||||
{
|
||||
xWrite8( 0x0f );
|
||||
xWrite8( 0x80 | comparison );
|
||||
}
|
||||
xWrite<s32>( (sptr)target - ((sptr)xGetPtr() + 4) );
|
||||
s32* bah = xJcc32( comparison );
|
||||
*bah = (s32)target - (s32)xGetPtr();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -17,9 +17,7 @@
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "System.h"
|
||||
#include "ix86_internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
namespace x86Emitter {
|
||||
|
||||
|
@ -90,27 +88,27 @@ const SimdImpl_MoveSSE<0x66,true> xMOVAPD;
|
|||
const SimdImpl_MoveSSE<0x66,false> xMOVUPD;
|
||||
#endif
|
||||
|
||||
const MovhlImplAll<0x16> xMOVH;
|
||||
const MovhlImplAll<0x12> xMOVL;
|
||||
const MovhlImpl_RtoR<0x16> xMOVLH;
|
||||
const MovhlImpl_RtoR<0x12> xMOVHL;
|
||||
const MovhlImplAll<0x16> xMOVH;
|
||||
const MovhlImplAll<0x12> xMOVL;
|
||||
const MovhlImpl_RtoR<0x16> xMOVLH;
|
||||
const MovhlImpl_RtoR<0x12> xMOVHL;
|
||||
|
||||
const SimdImpl_AndNot xANDN;
|
||||
const SimdImpl_COMI<true> xCOMI;
|
||||
const SimdImpl_COMI<false> xUCOMI;
|
||||
const SimdImpl_rSqrt<0x53> xRCP;
|
||||
const SimdImpl_rSqrt<0x52> xRSQRT;
|
||||
const SimdImpl_Sqrt<0x51> xSQRT;
|
||||
|
||||
const SimdImpl_MinMax<0x5f> xMAX;
|
||||
const SimdImpl_MinMax<0x5d> xMIN;
|
||||
const SimdImpl_Shuffle<0xc6> xSHUF;
|
||||
|
||||
const SimdImpl_DestRegEither<0x66,0xdb> xPAND;
|
||||
const SimdImpl_DestRegEither<0x66,0xdf> xPANDN;
|
||||
const SimdImpl_DestRegEither<0x66,0xeb> xPOR;
|
||||
const SimdImpl_DestRegEither<0x66,0xef> xPXOR;
|
||||
|
||||
const SimdImpl_AndNot xANDN;
|
||||
|
||||
const SimdImpl_UcomI<0x66,0x2e> xUCOMI;
|
||||
const SimdImpl_rSqrt<0x53> xRCP;
|
||||
const SimdImpl_rSqrt<0x52> xRSQRT;
|
||||
const SimdImpl_Sqrt<0x51> xSQRT;
|
||||
|
||||
const SimdImpl_MinMax<0x5f> xMAX;
|
||||
const SimdImpl_MinMax<0x5d> xMIN;
|
||||
const SimdImpl_Shuffle<0xc6> xSHUF;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// [SSE-4.1] Performs a bitwise AND of dest against src, and sets the ZF flag
|
||||
|
@ -238,19 +236,15 @@ __emitinline void xLDMXCSR( const u32* src )
|
|||
//
|
||||
|
||||
__forceinline void xMOVDZX( const xRegisterSSE& to, const xRegister32& from ) { xOpWrite0F( 0x66, 0x6e, to, from ); }
|
||||
__forceinline void xMOVDZX( const xRegisterSSE& to, const void* src ) { xOpWrite0F( 0x66, 0x6e, to, src ); }
|
||||
__forceinline void xMOVDZX( const xRegisterSSE& to, const ModSibBase& src ) { xOpWrite0F( 0x66, 0x6e, to, src ); }
|
||||
|
||||
__forceinline void xMOVDZX( const xRegisterMMX& to, const xRegister32& from ) { xOpWrite0F( 0x6e, to, from ); }
|
||||
__forceinline void xMOVDZX( const xRegisterMMX& to, const void* src ) { xOpWrite0F( 0x6e, to, src ); }
|
||||
__forceinline void xMOVDZX( const xRegisterMMX& to, const ModSibBase& src ) { xOpWrite0F( 0x6e, to, src ); }
|
||||
|
||||
__forceinline void xMOVD( const xRegister32& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, to ); }
|
||||
__forceinline void xMOVD( void* dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, dest ); }
|
||||
__forceinline void xMOVD( const ModSibBase& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x7e, from, dest ); }
|
||||
|
||||
__forceinline void xMOVD( const xRegister32& to, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, to ); }
|
||||
__forceinline void xMOVD( void* dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, dest ); }
|
||||
__forceinline void xMOVD( const ModSibBase& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7e, from, dest ); }
|
||||
|
||||
|
||||
|
@ -268,14 +262,10 @@ __forceinline void xMOVQZX( const xRegisterSSE& to, const void* src ) { xOpWri
|
|||
|
||||
// Moves lower quad of XMM to ptr64 (no bits are cleared)
|
||||
__forceinline void xMOVQ( const ModSibBase& dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd6, from, dest ); }
|
||||
// Moves lower quad of XMM to ptr64 (no bits are cleared)
|
||||
__forceinline void xMOVQ( void* dest, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xd6, from, dest ); }
|
||||
|
||||
__forceinline void xMOVQ( const xRegisterMMX& to, const xRegisterMMX& from ) { if( to != from ) xOpWrite0F( 0x6f, to, from ); }
|
||||
__forceinline void xMOVQ( const xRegisterMMX& to, const ModSibBase& src ) { xOpWrite0F( 0x6f, to, src ); }
|
||||
__forceinline void xMOVQ( const xRegisterMMX& to, const void* src ) { xOpWrite0F( 0x6f, to, src ); }
|
||||
__forceinline void xMOVQ( const ModSibBase& dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7f, from, dest ); }
|
||||
__forceinline void xMOVQ( void* dest, const xRegisterMMX& from ) { xOpWrite0F( 0x7f, from, dest ); }
|
||||
|
||||
// This form of xMOVQ is Intel's adeptly named 'MOVQ2DQ'
|
||||
__forceinline void xMOVQ( const xRegisterSSE& to, const xRegisterMMX& from ) { xOpWrite0F( 0xf3, 0xd6, to, from ); }
|
||||
|
@ -295,9 +285,7 @@ __forceinline void xMOVQ( const xRegisterMMX& to, const xRegisterSSE& from )
|
|||
|
||||
#define IMPLEMENT_xMOVS( ssd, prefix ) \
|
||||
__forceinline void xMOV##ssd( const xRegisterSSE& to, const xRegisterSSE& from ) { if( to != from ) xOpWrite0F( prefix, 0x10, to, from ); } \
|
||||
__forceinline void xMOV##ssd##ZX( const xRegisterSSE& to, const void* from ) { xOpWrite0F( prefix, 0x10, to, from ); } \
|
||||
__forceinline void xMOV##ssd##ZX( const xRegisterSSE& to, const ModSibBase& from ) { xOpWrite0F( prefix, 0x10, to, from ); } \
|
||||
__forceinline void xMOV##ssd( const void* to, const xRegisterSSE& from ) { xOpWrite0F( prefix, 0x11, from, to ); } \
|
||||
__forceinline void xMOV##ssd( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( prefix, 0x11, from, to ); }
|
||||
|
||||
IMPLEMENT_xMOVS( SS, 0xf3 )
|
||||
|
@ -307,27 +295,17 @@ IMPLEMENT_xMOVS( SD, 0xf2 )
|
|||
// Non-temporal movs only support a register as a target (ie, load form only, no stores)
|
||||
//
|
||||
|
||||
__forceinline void xMOVNTDQA( const xRegisterSSE& to, const void* from )
|
||||
{
|
||||
xWrite32( 0x2A380f66 );
|
||||
EmitSibMagic( to.Id, from );
|
||||
}
|
||||
|
||||
__forceinline void xMOVNTDQA( const xRegisterSSE& to, const ModSibBase& from )
|
||||
{
|
||||
xWrite32( 0x2A380f66 );
|
||||
EmitSibMagic( to.Id, from );
|
||||
}
|
||||
|
||||
__forceinline void xMOVNTDQ( void* to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xe7, from, to ); }
|
||||
__forceinline void xMOVNTDQA( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0xe7, from, to ); }
|
||||
|
||||
__forceinline void xMOVNTPD( void* to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x2b, from, to ); }
|
||||
__forceinline void xMOVNTPD( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x66, 0x2b, from, to ); }
|
||||
__forceinline void xMOVNTPS( void* to, const xRegisterSSE& from ) { xOpWrite0F( 0x2b, from, to ); }
|
||||
__forceinline void xMOVNTPS( const ModSibBase& to, const xRegisterSSE& from ) { xOpWrite0F( 0x2b, from, to ); }
|
||||
|
||||
__forceinline void xMOVNTQ( void* to, const xRegisterMMX& from ) { xOpWrite0F( 0xe7, from, to ); }
|
||||
__forceinline void xMOVNTQ( const ModSibBase& to, const xRegisterMMX& from ) { xOpWrite0F( 0xe7, from, to ); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
@ -382,7 +360,6 @@ __forceinline void xPALIGNR( const xRegisterMMX& to, const xRegisterMMX& from, u
|
|||
// with 0.0 if set to 1.
|
||||
//
|
||||
__emitinline void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); }
|
||||
__emitinline void xINSERTPS( const xRegisterSSE& to, const u32* from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); }
|
||||
__emitinline void xINSERTPS( const xRegisterSSE& to, const ModSibStrict<u32>& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x213a, to, from, imm8 ); }
|
||||
|
||||
// [SSE-4.1] Extract a single-precision floating-point value from src at an offset
|
||||
|
@ -390,7 +367,6 @@ __emitinline void xINSERTPS( const xRegisterSSE& to, const ModSibStrict<u32>& fr
|
|||
// is stored into the low 32-bits of dest (or at a 32-bit memory pointer).
|
||||
//
|
||||
__emitinline void xEXTRACTPS( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x173a, to, from, imm8 ); }
|
||||
__emitinline void xEXTRACTPS( u32* dest, const xRegisterSSE& from, u8 imm8 ) { xOpWrite0F( 0x66, 0x173a, from, dest, imm8 ); }
|
||||
__emitinline void xEXTRACTPS( const ModSibStrict<u32>& dest, const xRegisterSSE& from, u8 imm8 ){ xOpWrite0F( 0x66, 0x173a, from, dest, imm8 ); }
|
||||
|
||||
}
|
|
@ -17,9 +17,8 @@
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "System.h"
|
||||
#include "ix86.h"
|
||||
#include "internal.h"
|
||||
#include "tools.h"
|
||||
|
||||
// used to make sure regs don't get changed while in recompiler
|
||||
// use FreezeMMXRegs, FreezeXMMRegs
|
||||
|
@ -27,64 +26,12 @@
|
|||
u8 g_globalMMXSaved = 0;
|
||||
u8 g_globalXMMSaved = 0;
|
||||
|
||||
PCSX2_ALIGNED16( static u64 g_globalMMXData[8] );
|
||||
PCSX2_ALIGNED16( static u64 g_globalXMMData[2*iREGCNT_XMM] );
|
||||
|
||||
namespace x86Emitter
|
||||
{
|
||||
void xStoreReg( const xRegisterSSE& src )
|
||||
{
|
||||
xMOVDQA( &g_globalXMMData[src.Id*2], src );
|
||||
}
|
||||
|
||||
void xRestoreReg( const xRegisterSSE& dest )
|
||||
{
|
||||
xMOVDQA( dest, &g_globalXMMData[dest.Id*2] );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// SetCPUState -- for assignment of SSE roundmodes and clampmodes.
|
||||
|
||||
u32 g_sseMXCSR = DEFAULT_sseMXCSR;
|
||||
u32 g_sseVUMXCSR = DEFAULT_sseVUMXCSR;
|
||||
|
||||
void SetCPUState(u32 sseMXCSR, u32 sseVUMXCSR)
|
||||
{
|
||||
//Msgbox::Alert("SetCPUState: Config.sseMXCSR = %x; Config.sseVUMXCSR = %x \n", Config.sseMXCSR, Config.sseVUMXCSR);
|
||||
// SSE STATE //
|
||||
// WARNING: do not touch unless you know what you are doing
|
||||
|
||||
sseMXCSR &= 0xffff; // clear the upper 16 bits since they shouldn't be set
|
||||
sseVUMXCSR &= 0xffff;
|
||||
|
||||
if( !cpucaps.hasStreamingSIMD2Extensions )
|
||||
{
|
||||
// SSE1 cpus do not support Denormals Are Zero flag (throws an exception
|
||||
// if we don't mask them off)
|
||||
|
||||
sseMXCSR &= ~0x0040;
|
||||
sseVUMXCSR &= ~0x0040;
|
||||
}
|
||||
|
||||
g_sseMXCSR = sseMXCSR;
|
||||
g_sseVUMXCSR = sseVUMXCSR;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__asm ldmxcsr g_sseMXCSR; // set the new sse control
|
||||
#else
|
||||
__asm__("ldmxcsr %[g_sseMXCSR]" : : [g_sseMXCSR]"m"(g_sseMXCSR) );
|
||||
#endif
|
||||
//g_sseVUMXCSR = g_sseMXCSR|0x6000;
|
||||
}
|
||||
PCSX2_ALIGNED16( u64 g_globalMMXData[8] );
|
||||
PCSX2_ALIGNED16( u64 g_globalXMMData[2*iREGCNT_XMM] );
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// MMX Register Freezing
|
||||
#ifndef __INTEL_COMPILER
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
//
|
||||
|
||||
__forceinline void FreezeRegs(int save)
|
||||
{
|
||||
|
@ -92,14 +39,16 @@ __forceinline void FreezeRegs(int save)
|
|||
FreezeMMXRegs(save);
|
||||
}
|
||||
|
||||
__forceinline void FreezeMMXRegs_(int save)
|
||||
__forceinline void FreezeMMXRegs(int save)
|
||||
{
|
||||
//DevCon::Notice("FreezeMMXRegs_(%d); [%d]\n", save, g_globalMMXSaved);
|
||||
assert( g_EEFreezeRegs );
|
||||
if( !g_EEFreezeRegs ) return;
|
||||
|
||||
if( save ) {
|
||||
//DevCon::Notice("FreezeMMXRegs_(%d); [%d]\n", save, g_globalMMXSaved);
|
||||
|
||||
if( save )
|
||||
{
|
||||
g_globalMMXSaved++;
|
||||
if( g_globalMMXSaved>1 )
|
||||
if( g_globalMMXSaved > 1 )
|
||||
{
|
||||
//DevCon::Notice("MMX Already Saved!\n");
|
||||
return;
|
||||
|
@ -178,10 +127,12 @@ __forceinline void FreezeMMXRegs_(int save)
|
|||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// XMM Register Freezing
|
||||
__forceinline void FreezeXMMRegs_(int save)
|
||||
//
|
||||
__forceinline void FreezeXMMRegs(int save)
|
||||
{
|
||||
if( !g_EEFreezeRegs ) return;
|
||||
|
||||
//DevCon::Notice("FreezeXMMRegs_(%d); [%d]\n", save, g_globalXMMSaved);
|
||||
assert( g_EEFreezeRegs );
|
||||
|
||||
if( save )
|
||||
{
|
||||
|
@ -264,7 +215,4 @@ __forceinline void FreezeXMMRegs_(int save)
|
|||
#endif // _MSC_VER
|
||||
}
|
||||
}
|
||||
#ifndef __INTEL_COMPILER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -32,9 +32,11 @@
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "internal.h"
|
||||
|
||||
// defined in tools.cpp
|
||||
PCSX2_ALIGNED16_EXTERN( u64 g_globalXMMData[2*iREGCNT_XMM] );
|
||||
|
||||
#include "System.h"
|
||||
#include "ix86_internal.h"
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Notes on Thread Local Storage:
|
||||
|
@ -96,6 +98,7 @@ const xAddressIndexer<u8> ptr8;
|
|||
// ------------------------------------------------------------------------
|
||||
|
||||
template< typename OperandType > const xRegisterBase<OperandType> xRegisterBase<OperandType>::Empty;
|
||||
|
||||
const xAddressReg xAddressReg::Empty;
|
||||
|
||||
const xRegisterSSE
|
||||
|
@ -113,14 +116,14 @@ const xRegisterMMX
|
|||
const xAddressReg
|
||||
eax( 0 ), ebx( 3 ),
|
||||
ecx( 1 ), edx( 2 ),
|
||||
esi( 6 ), edi( 7 ),
|
||||
ebp( 5 ), esp( 4 );
|
||||
esp( 4 ), ebp( 5 ),
|
||||
esi( 6 ), edi( 7 );
|
||||
|
||||
const xRegister16
|
||||
ax( 0 ), bx( 3 ),
|
||||
cx( 1 ), dx( 2 ),
|
||||
si( 6 ), di( 7 ),
|
||||
bp( 5 ), sp( 4 );
|
||||
sp( 4 ), bp( 5 ),
|
||||
si( 6 ), di( 7 );
|
||||
|
||||
const xRegister8
|
||||
al( 0 ),
|
||||
|
@ -130,10 +133,53 @@ const xRegister8
|
|||
|
||||
const xRegisterCL cl;
|
||||
|
||||
const char *const x86_regnames_gpr8[8] =
|
||||
{
|
||||
"al", "cl", "dl", "bl",
|
||||
"ah", "ch", "dh", "bh"
|
||||
};
|
||||
|
||||
const char *const x86_regnames_gpr16[8] =
|
||||
{
|
||||
"ax", "cx", "dx", "bx",
|
||||
"sp", "bp", "si", "di"
|
||||
};
|
||||
|
||||
const char *const x86_regnames_gpr32[8] =
|
||||
{
|
||||
"eax", "ecx", "edx", "ebx",
|
||||
"esp", "ebp", "esi", "edi"
|
||||
};
|
||||
|
||||
const char *const x86_regnames_sse[8] =
|
||||
{
|
||||
"xmm0", "xmm1", "xmm2", "xmm3",
|
||||
"xmm4", "xmm5", "xmm6", "xmm7"
|
||||
};
|
||||
|
||||
const char *const x86_regnames_mmx[8] =
|
||||
{
|
||||
"mm0", "mm1", "mm2", "mm3",
|
||||
"mm4", "mm5", "mm6", "mm7"
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
|
||||
template< typename T >
|
||||
const char* xGetRegName( const xRegister<T>& src )
|
||||
{
|
||||
if( src.IsEmpty() ) return "empty";
|
||||
switch( sizeof(T) )
|
||||
{
|
||||
case 1: return tbl_regnames_gpr8[ src.Id ];
|
||||
case 2: return tbl_regnames_gpr16[ src.Id ];
|
||||
case 4: return tbl_regnames_gpr32[ src.Id ];
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Performance note: VC++ wants to use byte/word register form for the following
|
||||
// ModRM/SibSB constructors when we use xWrite<u8>, and furthermore unrolls the
|
||||
|
@ -201,11 +247,6 @@ namespace Internal
|
|||
xOpWrite0F( 0, opcode, instId, sib );
|
||||
}
|
||||
|
||||
__emitinline void xOpWrite0F( u16 opcode, int instId, const void* data )
|
||||
{
|
||||
xOpWrite0F( 0, opcode, instId, data );
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// returns TRUE if this instruction requires SIB to be encoded, or FALSE if the
|
||||
|
@ -674,11 +715,9 @@ __emitinline void xPUSH( const ModSibBase& from )
|
|||
}
|
||||
|
||||
__forceinline void xPOP( xRegister32 from ) { xWrite8( 0x58 | from.Id ); }
|
||||
__forceinline void xPOP( void* from ) { xPOP( ptr[from] ); }
|
||||
|
||||
__forceinline void xPUSH( u32 imm ) { xWrite8( 0x68 ); xWrite32( imm ); }
|
||||
__forceinline void xPUSH( xRegister32 from ) { xWrite8( 0x50 | from.Id ); }
|
||||
__forceinline void xPUSH( void* from ) { xPUSH( ptr[from] ); }
|
||||
|
||||
// pushes the EFLAGS register onto the stack
|
||||
__forceinline void xPUSHFD() { xWrite8( 0x9C ); }
|
||||
|
@ -710,4 +749,14 @@ __emitinline void xBSWAP( const xRegister32& to )
|
|||
xWrite8( 0xC8 | to.Id );
|
||||
}
|
||||
|
||||
__emitinline void xStoreReg( const xRegisterSSE& src )
|
||||
{
|
||||
xMOVDQA( &g_globalXMMData[src.Id*2], src );
|
||||
}
|
||||
|
||||
__emitinline void xRestoreReg( const xRegisterSSE& dest )
|
||||
{
|
||||
xMOVDQA( dest, &g_globalXMMData[dest.Id*2] );
|
||||
}
|
||||
|
||||
}
|
|
@ -2,17 +2,13 @@
|
|||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="debug"
|
||||
Name="CodeGen_Debug"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
PreprocessorDefinitions="PCSX2_DEBUG"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
RuntimeLibrary="3"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="CodeGen_Devel"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
EnableFiberSafeOptimizations="true"
|
||||
PreprocessorDefinitions="PCSX2_DEVEL;PCSX2_DEVBUILD;NDEBUG"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="false"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -2,7 +2,7 @@
|
|||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="GlobalOptimizations"
|
||||
Name="CodeGen_Release"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
@ -11,9 +11,12 @@
|
|||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
EnableFiberSafeOptimizations="true"
|
||||
WholeProgramOptimization="true"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
StringPooling="true"
|
||||
MinimalRebuild="true"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="false"
|
||||
/>
|
||||
<Tool
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="windows-1250"?>
|
||||
<VisualStudioPropertySheet
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="CommonLibrary"
|
||||
OutputDirectory="..\..\deps\$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(SvnRootDir)\common\include\$(ProjectName)";"$(SvnRootDir)\common\include";"$(SvnRootDir)\3rdparty\wxWidgets\include""
|
||||
PreprocessorDefinitions="__WIN32__;WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE"
|
||||
StructMemberAlignment="5"
|
||||
RuntimeTypeInfo="false"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
/>
|
||||
<UserMacro
|
||||
Name="ProjectRootDir"
|
||||
Value="$(ProjectDir)\..\.."
|
||||
/>
|
||||
<UserMacro
|
||||
Name="SvnRootDir"
|
||||
Value="$(ProjectRootDir)\.."
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
|
@ -5,16 +5,12 @@
|
|||
Name="w32pthreads"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(SvnRootDir)\3rdparty""
|
||||
PreprocessorDefinitions="PTW32_STATIC_LIB;WIN32_PTHREADS;__CLEANUP_SEH"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""$(SvnRootDir)\3rdparty\w32pthreads\include""
|
||||
PreprocessorDefinitions="WIN32_PTHREADS;__CLEANUP_SEH"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="pthreads.lib Ws2_32.lib"
|
||||
AdditionalDependencies="w32pthreads.lib"
|
||||
/>
|
||||
</VisualStudioPropertySheet>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
../3rdparty/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,103 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IopCommon.h"
|
||||
|
||||
#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
|
||||
#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
|
||||
|
||||
struct cdvdRTC {
|
||||
u8 status;
|
||||
u8 second;
|
||||
u8 minute;
|
||||
u8 hour;
|
||||
u8 pad;
|
||||
u8 day;
|
||||
u8 month;
|
||||
u8 year;
|
||||
};
|
||||
|
||||
struct cdvdStruct {
|
||||
u8 nCommand;
|
||||
u8 Ready;
|
||||
u8 Error;
|
||||
u8 PwOff;
|
||||
u8 Status;
|
||||
u8 Type;
|
||||
u8 sCommand;
|
||||
u8 sDataIn;
|
||||
u8 sDataOut;
|
||||
u8 HowTo;
|
||||
|
||||
u8 Param[32];
|
||||
u8 Result[32];
|
||||
|
||||
u8 ParamC;
|
||||
u8 ParamP;
|
||||
u8 ResultC;
|
||||
u8 ResultP;
|
||||
|
||||
u8 CBlockIndex;
|
||||
u8 COffset;
|
||||
u8 CReadWrite;
|
||||
u8 CNumBlocks;
|
||||
|
||||
int RTCcount;
|
||||
cdvdRTC RTC;
|
||||
|
||||
u32 Sector;
|
||||
int nSectors;
|
||||
int Readed; // change to bool. --arcum42
|
||||
int Reading; // same here.
|
||||
int ReadMode;
|
||||
int BlockSize; // Total bytes transfered at 1x speed
|
||||
int Speed;
|
||||
int RetryCnt;
|
||||
int RetryCntP;
|
||||
int RErr;
|
||||
int SpindlCtrl;
|
||||
|
||||
u8 Key[16];
|
||||
u8 KeyXor;
|
||||
u8 decSet;
|
||||
|
||||
u8 mg_buffer[65536];
|
||||
int mg_size;
|
||||
int mg_maxsize;
|
||||
int mg_datatype;//0-data(encrypted); 1-header
|
||||
u8 mg_kbit[16];//last BIT key 'seen'
|
||||
u8 mg_kcon[16];//last content key 'seen'
|
||||
|
||||
u8 Action; // the currently scheduled emulated action
|
||||
u32 SeekToSector; // Holds the destination sector during seek operations.
|
||||
u32 ReadTime; // Avg. time to read one block of data (in Iop cycles)
|
||||
bool Spinning; // indicates if the Cdvd is spinning or needs a spinup delay
|
||||
};
|
||||
|
||||
extern void cdvdReset();
|
||||
extern void cdvdVsync();
|
||||
extern void cdvdActionInterrupt();
|
||||
extern void cdvdReadInterrupt();
|
||||
|
||||
// We really should not have a function with the exact same name as a callback except for case!
|
||||
extern void cdvdNewDiskCB();
|
||||
extern u8 cdvdRead(u8 key);
|
||||
extern void cdvdWrite(u8 key, u8 rt);
|
||||
|
|
@ -15,79 +15,9 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __CDVD_H__
|
||||
#define __CDVD_H__
|
||||
|
||||
#include "IopCommon.h"
|
||||
|
||||
struct cdvdRTC {
|
||||
u8 status;
|
||||
u8 second;
|
||||
u8 minute;
|
||||
u8 hour;
|
||||
u8 pad;
|
||||
u8 day;
|
||||
u8 month;
|
||||
u8 year;
|
||||
};
|
||||
|
||||
struct cdvdStruct {
|
||||
u8 nCommand;
|
||||
u8 Ready;
|
||||
u8 Error;
|
||||
u8 PwOff;
|
||||
u8 Status;
|
||||
u8 Type;
|
||||
u8 sCommand;
|
||||
u8 sDataIn;
|
||||
u8 sDataOut;
|
||||
u8 HowTo;
|
||||
|
||||
u8 Param[32];
|
||||
u8 Result[32];
|
||||
|
||||
u8 ParamC;
|
||||
u8 ParamP;
|
||||
u8 ResultC;
|
||||
u8 ResultP;
|
||||
|
||||
u8 CBlockIndex;
|
||||
u8 COffset;
|
||||
u8 CReadWrite;
|
||||
u8 CNumBlocks;
|
||||
|
||||
int RTCcount;
|
||||
cdvdRTC RTC;
|
||||
|
||||
u32 Sector;
|
||||
int nSectors;
|
||||
int Readed; // change to bool. --arcum42
|
||||
int Reading; // same here.
|
||||
int ReadMode;
|
||||
int BlockSize; // Total bytes transfered at 1x speed
|
||||
int Speed;
|
||||
int RetryCnt;
|
||||
int RetryCntP;
|
||||
int RErr;
|
||||
int SpindlCtrl;
|
||||
|
||||
u8 Key[16];
|
||||
u8 KeyXor;
|
||||
u8 decSet;
|
||||
|
||||
u8 mg_buffer[65536];
|
||||
int mg_size;
|
||||
int mg_maxsize;
|
||||
int mg_datatype;//0-data(encrypted); 1-header
|
||||
u8 mg_kbit[16];//last BIT key 'seen'
|
||||
u8 mg_kcon[16];//last content key 'seen'
|
||||
|
||||
u8 Action; // the currently scheduled emulated action
|
||||
u32 SeekToSector; // Holds the destination sector during seek operations.
|
||||
u32 ReadTime; // Avg. time to read one block of data (in Iop cycles)
|
||||
bool Spinning; // indicates if the Cdvd is spinning or needs a spinup delay
|
||||
};
|
||||
|
||||
#ifndef __CDVD_INTERNAL_H__
|
||||
#define __CDVD_INTERNAL_H__
|
||||
|
||||
/*
|
||||
Interrupts - values are flag bits.
|
||||
|
@ -191,7 +121,6 @@ static const uint tbl_ContigiousSeekDelta[3] =
|
|||
static const uint PSX_CD_READSPEED = 153600; // 1 Byte Time @ x1 (150KB = cd x 1)
|
||||
static const uint PSX_DVD_READSPEED = 1382400 + 256000; // normal is 1 Byte Time @ x1 (1350KB = dvd x 1).
|
||||
|
||||
|
||||
// Legacy Note: FullSeek timing causes many games to load very slow, but it likely not the real problem.
|
||||
// Games breaking with it set to PSXCLK*40 : "wrath unleashed" and "Shijou Saikyou no Deshi Kenichi".
|
||||
|
||||
|
@ -301,15 +230,4 @@ static NVMLayout nvmlayouts[NVM_FORMAT_MAX] =
|
|||
{0x146, 0x270, 0x2B0, 0x200, 0x1C8, 0x1E0, 0x1B0, 0x180, 0x198}, // eeproms from bios v1.70 and up
|
||||
};
|
||||
|
||||
#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */
|
||||
#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */
|
||||
|
||||
void cdvdReset();
|
||||
void cdvdVsync();
|
||||
extern void cdvdActionInterrupt();
|
||||
extern void cdvdReadInterrupt();
|
||||
void cdvdNewDiskCB();
|
||||
u8 cdvdRead(u8 key);
|
||||
void cdvdWrite(u8 key, u8 rt);
|
||||
|
||||
#endif /* __CDVD_H__ */
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue