early-access version 2687
This commit is contained in:
parent
cd45d7e9d5
commit
8aa17b7ffc
251 changed files with 4148 additions and 1023 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 2686.
|
This is the source code for early-access 2687.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
7
externals/dynarmic/externals/CMakeLists.txt
vendored
7
externals/dynarmic/externals/CMakeLists.txt
vendored
|
@ -19,10 +19,11 @@ if (NOT TARGET fmt AND NOT TARGET fmt::fmt)
|
||||||
add_subdirectory(fmt)
|
add_subdirectory(fmt)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# mp
|
# mcl
|
||||||
|
|
||||||
add_library(mp INTERFACE)
|
if (NOT TARGET merry::mcl)
|
||||||
target_include_directories(mp INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/mp/include>)
|
add_subdirectory(mcl)
|
||||||
|
endif()
|
||||||
|
|
||||||
# robin-map
|
# robin-map
|
||||||
|
|
||||||
|
|
6
externals/dynarmic/externals/README.md
vendored
6
externals/dynarmic/externals/README.md
vendored
|
@ -4,7 +4,7 @@ This repository uses subtrees to manage some of its externals.
|
||||||
|
|
||||||
```
|
```
|
||||||
git remote add externals-fmt https://github.com/fmtlib/fmt.git --no-tags
|
git remote add externals-fmt https://github.com/fmtlib/fmt.git --no-tags
|
||||||
git remote add externals-mp https://github.com/MerryMage/mp.git --no-tags
|
git remote add externals-mcl https://github.com/merryhime/mcl.git --no-tags
|
||||||
git remote add externals-robin-map https://github.com/Tessil/robin-map.git --no-tags
|
git remote add externals-robin-map https://github.com/Tessil/robin-map.git --no-tags
|
||||||
git remote add externals-vixl https://git.linaro.org/arm/vixl.git --no-tags
|
git remote add externals-vixl https://git.linaro.org/arm/vixl.git --no-tags
|
||||||
git remote add externals-xbyak https://github.com/herumi/xbyak.git --no-tags
|
git remote add externals-xbyak https://github.com/herumi/xbyak.git --no-tags
|
||||||
|
@ -18,14 +18,14 @@ Change `<ref>` to refer to the appropriate git reference.
|
||||||
|
|
||||||
```
|
```
|
||||||
git fetch externals-fmt
|
git fetch externals-fmt
|
||||||
git fetch externals-mp
|
git fetch externals-mcl
|
||||||
git fetch externals-robin-map
|
git fetch externals-robin-map
|
||||||
git fetch externals-vixl
|
git fetch externals-vixl
|
||||||
git fetch externals-xbyak
|
git fetch externals-xbyak
|
||||||
git fetch externals-zycore
|
git fetch externals-zycore
|
||||||
git fetch externals-zydis
|
git fetch externals-zydis
|
||||||
git subtree pull --squash --prefix=externals/fmt externals-fmt <ref>
|
git subtree pull --squash --prefix=externals/fmt externals-fmt <ref>
|
||||||
git subtree pull --squash --prefix=externals/mp externals-mp <ref>
|
git subtree pull --squash --prefix=externals/mcl externals-mcl <ref>
|
||||||
git subtree pull --squash --prefix=externals/robin-map externals-robin-map <ref>
|
git subtree pull --squash --prefix=externals/robin-map externals-robin-map <ref>
|
||||||
git subtree pull --squash --prefix=externals/vixl/vixl externals-vixl <ref>
|
git subtree pull --squash --prefix=externals/vixl/vixl externals-vixl <ref>
|
||||||
git subtree pull --squash --prefix=externals/xbyak externals-xbyak <ref>
|
git subtree pull --squash --prefix=externals/xbyak externals-xbyak <ref>
|
||||||
|
|
218
externals/dynarmic/externals/mcl/.clang-format
vendored
Executable file
218
externals/dynarmic/externals/mcl/.clang-format
vendored
Executable file
|
@ -0,0 +1,218 @@
|
||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveMacros: None
|
||||||
|
AlignConsecutiveAssignments: None
|
||||||
|
AlignConsecutiveBitFields: None
|
||||||
|
AlignConsecutiveDeclarations: None
|
||||||
|
AlignConsecutiveMacros: None
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: AlignAfterOperator
|
||||||
|
AlignTrailingComments: true
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: true
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: false
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
BreakBeforeBinaryOperators: All
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BreakBeforeConceptDeclarations: true
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakConstructorInitializersBeforeComma: true
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 0
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||||
|
ConstructorInitializerIndentWidth: 8
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DeriveLineEnding: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
# EmptyLineAfterAccessModifier: Leave
|
||||||
|
EmptyLineBeforeAccessModifier: Always
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^<mach/'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^<windows.h>'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '(^<signal.h>)|(^<sys/ucontext.h>)|(^<ucontext.h>)'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^<([^\.])*>$'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^<.*\.'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 4
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: '([-_](test|unittest))?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
# IndentAccessModifiers: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentExternBlock: NoIndent
|
||||||
|
IndentGotoLabels: false
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
IndentRequires: false
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
# InsertTrailingCommas: None
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
NamespaceMacros:
|
||||||
|
ObjCBinPackProtocolList: Never
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 1
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 200
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PointerAlignment: Left
|
||||||
|
RawStringFormats:
|
||||||
|
- Language: Cpp
|
||||||
|
Delimiters:
|
||||||
|
- cc
|
||||||
|
- CC
|
||||||
|
- cpp
|
||||||
|
- Cpp
|
||||||
|
- CPP
|
||||||
|
- 'c++'
|
||||||
|
- 'C++'
|
||||||
|
CanonicalDelimiter: ''
|
||||||
|
BasedOnStyle: google
|
||||||
|
- Language: TextProto
|
||||||
|
Delimiters:
|
||||||
|
- pb
|
||||||
|
- PB
|
||||||
|
- proto
|
||||||
|
- PROTO
|
||||||
|
EnclosingFunctions:
|
||||||
|
- EqualsProto
|
||||||
|
- EquivToProto
|
||||||
|
- PARSE_PARTIAL_TEXT_PROTO
|
||||||
|
- PARSE_TEST_PROTO
|
||||||
|
- PARSE_TEXT_PROTO
|
||||||
|
- ParseTextOrDie
|
||||||
|
- ParseTextProtoOrDie
|
||||||
|
- ParseTestProto
|
||||||
|
- ParsePartialTestProto
|
||||||
|
CanonicalDelimiter: ''
|
||||||
|
BasedOnStyle: google
|
||||||
|
ReflowComments: true
|
||||||
|
# ShortNamespaceLines: 5
|
||||||
|
SortIncludes: true
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInConditionalStatement: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
# SpacesInLineCommentPrefix: -1
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Latest
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TabWidth: 4
|
||||||
|
TypenameMacros:
|
||||||
|
UseCRLF: false
|
||||||
|
UseTab: Never
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- STRINGIZE
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
- FCODE
|
||||||
|
- ICODE
|
||||||
|
...
|
||||||
|
|
2
externals/dynarmic/externals/mcl/.gitignore
vendored
Executable file
2
externals/dynarmic/externals/mcl/.gitignore
vendored
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
*build*/
|
||||||
|
.DS_Store
|
126
externals/dynarmic/externals/mcl/CMakeLists.txt
vendored
Executable file
126
externals/dynarmic/externals/mcl/CMakeLists.txt
vendored
Executable file
|
@ -0,0 +1,126 @@
|
||||||
|
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
project(mcl LANGUAGES CXX VERSION 0.1.5)
|
||||||
|
|
||||||
|
# Project options
|
||||||
|
option(MCL_WARNINGS_AS_ERRORS "Warnings as errors" ON)
|
||||||
|
|
||||||
|
# Default to a Release build
|
||||||
|
if (NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||||
|
message(STATUS "Defaulting to a Release build")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set hard requirements for C++
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
# Warn on CMake API deprecations
|
||||||
|
set(CMAKE_WARN_DEPRECATED ON)
|
||||||
|
|
||||||
|
# Disable in-source builds
|
||||||
|
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
|
||||||
|
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||||
|
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
|
||||||
|
message(SEND_ERROR "In-source builds are not allowed.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add the module directory to the list of paths
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules")
|
||||||
|
|
||||||
|
# Compiler flags
|
||||||
|
if (MSVC)
|
||||||
|
set(MCL_CXX_FLAGS
|
||||||
|
/std:c++latest
|
||||||
|
/experimental:external
|
||||||
|
/external:W0
|
||||||
|
/external:anglebrackets
|
||||||
|
/W4
|
||||||
|
/w44263 # Non-virtual member function hides base class virtual function
|
||||||
|
/w44265 # Class has virtual functions, but destructor is not virtual
|
||||||
|
/w44456 # Declaration of 'var' hides previous local declaration
|
||||||
|
/w44457 # Declaration of 'var' hides function parameter
|
||||||
|
/w44458 # Declaration of 'var' hides class member
|
||||||
|
/w44459 # Declaration of 'var' hides global definition
|
||||||
|
/w44946 # Reinterpret-cast between related types
|
||||||
|
/wd4592 # Symbol will be dynamically initialized (implementation limitation)
|
||||||
|
/permissive- # Stricter C++ standards conformance
|
||||||
|
/MP
|
||||||
|
/Zi
|
||||||
|
/Zo
|
||||||
|
/EHsc
|
||||||
|
/Zc:externConstexpr # Allows external linkage for variables declared "extern constexpr", as the standard permits.
|
||||||
|
/Zc:inline # Omits inline functions from object-file output.
|
||||||
|
/Zc:throwingNew # Assumes new (without std::nothrow) never returns null.
|
||||||
|
/volatile:iso # Use strict standard-abiding volatile semantics
|
||||||
|
/bigobj # Increase number of sections in .obj files
|
||||||
|
/DNOMINMAX)
|
||||||
|
|
||||||
|
if (MCL_WARNINGS_AS_ERRORS)
|
||||||
|
list(APPEND MCL_CXX_FLAGS /WX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (CMAKE_VS_PLATFORM_TOOLSET MATCHES "LLVM-vs[0-9]+")
|
||||||
|
list(APPEND MCL_CXX_FLAGS
|
||||||
|
-Qunused-arguments
|
||||||
|
-Wno-missing-braces)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(MCL_CXX_FLAGS
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wcast-qual
|
||||||
|
-pedantic
|
||||||
|
-pedantic-errors
|
||||||
|
-Wfatal-errors
|
||||||
|
-Wno-missing-braces)
|
||||||
|
|
||||||
|
if (MCL_WARNINGS_AS_ERRORS)
|
||||||
|
list(APPEND MCL_CXX_FLAGS -Werror)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
|
if (NOT TARGET Catch2::Catch2)
|
||||||
|
find_package(Catch2 QUIET)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT TARGET fmt::fmt)
|
||||||
|
find_package(fmt REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Project files
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
|
if (TARGET Catch2::Catch2)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Install instructions
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
|
install(TARGETS mcl EXPORT mclTargets)
|
||||||
|
install(EXPORT mclTargets
|
||||||
|
NAMESPACE merry::
|
||||||
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mcl"
|
||||||
|
)
|
||||||
|
|
||||||
|
configure_package_config_file(CMakeModules/mclConfig.cmake.in
|
||||||
|
mclConfig.cmake
|
||||||
|
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mcl"
|
||||||
|
)
|
||||||
|
write_basic_package_version_file(mclConfigVersion.cmake
|
||||||
|
COMPATIBILITY SameMajorVersion
|
||||||
|
)
|
||||||
|
install(FILES
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/mclConfig.cmake"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/mclConfigVersion.cmake"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mcl"
|
||||||
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY include/ TYPE INCLUDE FILES_MATCHING PATTERN "*.hpp")
|
17
externals/dynarmic/externals/mcl/CMakeModules/CreateTargetDirectoryGroups.cmake
vendored
Executable file
17
externals/dynarmic/externals/mcl/CMakeModules/CreateTargetDirectoryGroups.cmake
vendored
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
# This function should be passed a name of an existing target. It will automatically generate
|
||||||
|
# file groups following the directory hierarchy, so that the layout of the files in IDEs matches the
|
||||||
|
# one in the filesystem.
|
||||||
|
function(create_target_directory_groups target_name)
|
||||||
|
# Place any files that aren't in the source list in a separate group so that they don't get in
|
||||||
|
# the way.
|
||||||
|
source_group("Other Files" REGULAR_EXPRESSION ".")
|
||||||
|
|
||||||
|
get_target_property(target_sources "${target_name}" SOURCES)
|
||||||
|
|
||||||
|
foreach(file_name IN LISTS target_sources)
|
||||||
|
get_filename_component(dir_name "${file_name}" PATH)
|
||||||
|
# Group names use '\' as a separator even though the entire rest of CMake uses '/'...
|
||||||
|
string(REPLACE "/" "\\" group_name "${dir_name}")
|
||||||
|
source_group("${group_name}" FILES "${file_name}")
|
||||||
|
endforeach()
|
||||||
|
endfunction()
|
56
externals/dynarmic/externals/mcl/CMakeModules/DetectArchitecture.cmake
vendored
Executable file
56
externals/dynarmic/externals/mcl/CMakeModules/DetectArchitecture.cmake
vendored
Executable file
|
@ -0,0 +1,56 @@
|
||||||
|
include(CheckSymbolExists)
|
||||||
|
|
||||||
|
function(detect_architecture symbol arch)
|
||||||
|
if (NOT DEFINED ARCHITECTURE)
|
||||||
|
set(CMAKE_REQUIRED_QUIET YES)
|
||||||
|
check_symbol_exists("${symbol}" "" DETECT_ARCHITECTURE_${arch})
|
||||||
|
unset(CMAKE_REQUIRED_QUIET)
|
||||||
|
|
||||||
|
if (DETECT_ARCHITECTURE_${arch})
|
||||||
|
set(ARCHITECTURE "${arch}" PARENT_SCOPE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
unset(DETECT_ARCHITECTURE_${arch} CACHE)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
detect_architecture("__ARM64__" arm64)
|
||||||
|
detect_architecture("__aarch64__" arm64)
|
||||||
|
detect_architecture("_M_ARM64" arm64)
|
||||||
|
|
||||||
|
detect_architecture("__arm__" arm32)
|
||||||
|
detect_architecture("__TARGET_ARCH_ARM" arm32)
|
||||||
|
detect_architecture("_M_ARM" arm32)
|
||||||
|
|
||||||
|
detect_architecture("__x86_64" x86_64)
|
||||||
|
detect_architecture("__x86_64__" x86_64)
|
||||||
|
detect_architecture("__amd64" x86_64)
|
||||||
|
detect_architecture("_M_X64" x86_64)
|
||||||
|
|
||||||
|
detect_architecture("__i386" x86_32)
|
||||||
|
detect_architecture("__i386__" x86_32)
|
||||||
|
detect_architecture("_M_IX86" x86_32)
|
||||||
|
|
||||||
|
detect_architecture("__ia64" ia64)
|
||||||
|
detect_architecture("__ia64__" ia64)
|
||||||
|
detect_architecture("_M_IA64" ia64)
|
||||||
|
|
||||||
|
detect_architecture("__mips" mips)
|
||||||
|
detect_architecture("__mips__" mips)
|
||||||
|
detect_architecture("_M_MRX000" mips)
|
||||||
|
|
||||||
|
detect_architecture("__ppc64__" ppc64)
|
||||||
|
detect_architecture("__powerpc64__" ppc64)
|
||||||
|
|
||||||
|
detect_architecture("__ppc__" ppc32)
|
||||||
|
detect_architecture("__ppc" ppc32)
|
||||||
|
detect_architecture("__powerpc__" ppc32)
|
||||||
|
detect_architecture("_ARCH_COM" ppc32)
|
||||||
|
detect_architecture("_ARCH_PWR" ppc32)
|
||||||
|
detect_architecture("_ARCH_PPC" ppc32)
|
||||||
|
detect_architecture("_M_MPPC" ppc32)
|
||||||
|
detect_architecture("_M_PPC" ppc32)
|
||||||
|
|
||||||
|
detect_architecture("__riscv" riscv)
|
||||||
|
|
||||||
|
detect_architecture("__EMSCRIPTEN__" wasm)
|
5
externals/dynarmic/externals/mcl/CMakeModules/mclConfig.cmake.in
vendored
Executable file
5
externals/dynarmic/externals/mcl/CMakeModules/mclConfig.cmake.in
vendored
Executable file
|
@ -0,0 +1,5 @@
|
||||||
|
@PACKAGE_INIT@
|
||||||
|
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||||
|
|
||||||
|
check_required_components(@PROJECT_NAME@)
|
21
externals/dynarmic/externals/mcl/LICENSE
vendored
Executable file
21
externals/dynarmic/externals/mcl/LICENSE
vendored
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 merryhime
|
||||||
|
|
||||||
|
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.
|
17
externals/dynarmic/externals/mcl/README
vendored
Executable file
17
externals/dynarmic/externals/mcl/README
vendored
Executable file
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
oooo
|
||||||
|
`888
|
||||||
|
ooo. .oo. .oo. .ooooo. 888
|
||||||
|
`888P"Y88bP"Y88b d88' `"Y8 888
|
||||||
|
888 888 888 888 888
|
||||||
|
888 888 888 888 .o8 888
|
||||||
|
o888o o888o o888o `Y8bod8P' o888o
|
||||||
|
|
||||||
|
|
||||||
|
.-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-. .-.-.
|
||||||
|
/ / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \ / / \ \
|
||||||
|
`-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`-' `-`
|
||||||
|
|
||||||
|
A collection of C++20 utilities which is common to a number of merry's projects.
|
||||||
|
|
||||||
|
MIT licensed.
|
61
externals/dynarmic/externals/mcl/include/mcl/assert.hpp
vendored
Executable file
61
externals/dynarmic/externals/mcl/include/mcl/assert.hpp
vendored
Executable file
|
@ -0,0 +1,61 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include "mcl/hint/assume.hpp"
|
||||||
|
|
||||||
|
namespace mcl::detail {
|
||||||
|
|
||||||
|
[[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args);
|
||||||
|
|
||||||
|
template<typename... Ts>
|
||||||
|
[[noreturn]] void assert_terminate(fmt::string_view msg, Ts... args) {
|
||||||
|
assert_terminate_impl(msg, fmt::make_format_args(args...));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl::detail
|
||||||
|
|
||||||
|
#define UNREACHABLE() ASSERT_FALSE("Unreachable code!")
|
||||||
|
|
||||||
|
#define ASSERT(expr) \
|
||||||
|
[&] { \
|
||||||
|
if (std::is_constant_evaluated()) { \
|
||||||
|
if (!(expr)) { \
|
||||||
|
throw std::logic_error{"ASSERT failed at compile time"}; \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
if (!(expr)) [[unlikely]] { \
|
||||||
|
::mcl::detail::assert_terminate(#expr); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}()
|
||||||
|
|
||||||
|
#define ASSERT_MSG(expr, ...) \
|
||||||
|
[&] { \
|
||||||
|
if (std::is_constant_evaluated()) { \
|
||||||
|
if (!(expr)) { \
|
||||||
|
throw std::logic_error{"ASSERT_MSG failed at compile time"}; \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
if (!(expr)) [[unlikely]] { \
|
||||||
|
::mcl::detail::assert_terminate(#expr "\nMessage: " __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}()
|
||||||
|
|
||||||
|
#define ASSERT_FALSE(...) ::mcl::detail::assert_terminate("false\nMessage: " __VA_ARGS__)
|
||||||
|
|
||||||
|
#if defined(NDEBUG) || defined(MCL_IGNORE_ASSERTS)
|
||||||
|
# define DEBUG_ASSERT(expr) ASSUME(expr)
|
||||||
|
# define DEBUG_ASSERT_MSG(expr, ...) ASSUME(expr)
|
||||||
|
#else
|
||||||
|
# define DEBUG_ASSERT(expr) ASSERT(expr)
|
||||||
|
# define DEBUG_ASSERT_MSG(expr, ...) ASSERT_MSG(expr, __VA_ARGS__)
|
||||||
|
#endif
|
54
externals/dynarmic/externals/mcl/include/mcl/bit/bit_count.hpp
vendored
Executable file
54
externals/dynarmic/externals/mcl/include/mcl/bit/bit_count.hpp
vendored
Executable file
|
@ -0,0 +1,54 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
|
#include "mcl/bitsizeof.hpp"
|
||||||
|
#include "mcl/concepts/bit_integral.hpp"
|
||||||
|
#include "mcl/stdint.hpp"
|
||||||
|
|
||||||
|
namespace mcl::bit {
|
||||||
|
|
||||||
|
template<BitIntegral T>
|
||||||
|
inline size_t count_ones(T x) {
|
||||||
|
return std::bitset<bitsizeof<T>>(x).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr size_t count_leading_zeros(T x) {
|
||||||
|
size_t result = bitsizeof<T>;
|
||||||
|
while (x != 0) {
|
||||||
|
x >>= 1;
|
||||||
|
result--;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr int highest_set_bit(T x) {
|
||||||
|
int result = -1;
|
||||||
|
while (x != 0) {
|
||||||
|
x >>= 1;
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr size_t lowest_set_bit(T x) {
|
||||||
|
if (x == 0) {
|
||||||
|
return bitsizeof<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t result = 0;
|
||||||
|
while ((x & 1) == 0) {
|
||||||
|
x >>= 1;
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl::bit
|
203
externals/dynarmic/externals/mcl/include/mcl/bit/bit_field.hpp
vendored
Executable file
203
externals/dynarmic/externals/mcl/include/mcl/bit/bit_field.hpp
vendored
Executable file
|
@ -0,0 +1,203 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/assert.hpp"
|
||||||
|
#include "mcl/bitsizeof.hpp"
|
||||||
|
#include "mcl/concepts/bit_integral.hpp"
|
||||||
|
#include "mcl/stdint.hpp"
|
||||||
|
|
||||||
|
namespace mcl::bit {
|
||||||
|
|
||||||
|
/// Create a mask with `count` number of one bits.
|
||||||
|
template<size_t count, BitIntegral T>
|
||||||
|
constexpr T ones() {
|
||||||
|
static_assert(count <= bitsizeof<T>, "count larger than bitsize of T");
|
||||||
|
|
||||||
|
if constexpr (count == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return static_cast<T>(~static_cast<T>(0)) >> (bitsizeof<T> - count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a mask with `count` number of one bits.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T ones(size_t count) {
|
||||||
|
ASSERT_MSG(count <= bitsizeof<T>, "count larger than bitsize of T");
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return static_cast<T>(~static_cast<T>(0)) >> (bitsizeof<T> - count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
|
||||||
|
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||||
|
constexpr T mask() {
|
||||||
|
static_assert(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
|
||||||
|
static_assert(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
|
||||||
|
static_assert(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
|
||||||
|
|
||||||
|
return ones<end_bit - begin_bit + 1, T>() << begin_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a mask of type T for bits [begin_bit, end_bit] inclusive.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T mask(size_t begin_bit, size_t end_bit) {
|
||||||
|
ASSERT_MSG(begin_bit <= end_bit, "invalid bit range (position of beginning bit cannot be greater than that of end bit)");
|
||||||
|
ASSERT_MSG(begin_bit < bitsizeof<T>, "begin_bit must be smaller than size of T");
|
||||||
|
ASSERT_MSG(end_bit < bitsizeof<T>, "end_bit must be smaller than size of T");
|
||||||
|
|
||||||
|
return ones<T>(end_bit - begin_bit + 1) << begin_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract bits [begin_bit, end_bit] inclusive from value of type T.
|
||||||
|
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||||
|
constexpr T get_bits(T value) {
|
||||||
|
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||||
|
return (value & m) >> begin_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract bits [begin_bit, end_bit] inclusive from value of type T.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T get_bits(size_t begin_bit, size_t end_bit, T value) {
|
||||||
|
const T m = mask<T>(begin_bit, end_bit);
|
||||||
|
return (value & m) >> begin_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears bits [begin_bit, end_bit] inclusive of value of type T.
|
||||||
|
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||||
|
constexpr T clear_bits(T value) {
|
||||||
|
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||||
|
return value & ~m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears bits [begin_bit, end_bit] inclusive of value of type T.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T clear_bits(size_t begin_bit, size_t end_bit, T value) {
|
||||||
|
const T m = mask<T>(begin_bit, end_bit);
|
||||||
|
return value & ~m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
|
||||||
|
template<size_t begin_bit, size_t end_bit, BitIntegral T>
|
||||||
|
constexpr T set_bits(T value, T new_bits) {
|
||||||
|
constexpr T m = mask<begin_bit, end_bit, T>();
|
||||||
|
return (value & ~m) | ((new_bits << begin_bit) & m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifies bits [begin_bit, end_bit] inclusive of value of type T.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T set_bits(size_t begin_bit, size_t end_bit, T value, T new_bits) {
|
||||||
|
const T m = mask<T>(begin_bit, end_bit);
|
||||||
|
return (value & ~m) | ((new_bits << begin_bit) & m);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract bit at bit_position from value of type T.
|
||||||
|
template<size_t bit_position, BitIntegral T>
|
||||||
|
constexpr bool get_bit(T value) {
|
||||||
|
constexpr T m = mask<bit_position, bit_position, T>();
|
||||||
|
return (value & m) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extract bit at bit_position from value of type T.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr bool get_bit(size_t bit_position, T value) {
|
||||||
|
const T m = mask<T>(bit_position, bit_position);
|
||||||
|
return (value & m) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears bit at bit_position of value of type T.
|
||||||
|
template<size_t bit_position, BitIntegral T>
|
||||||
|
constexpr T clear_bit(T value) {
|
||||||
|
constexpr T m = mask<bit_position, bit_position, T>();
|
||||||
|
return value & ~m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears bit at bit_position of value of type T.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T clear_bit(size_t bit_position, T value) {
|
||||||
|
const T m = mask<T>(bit_position, bit_position);
|
||||||
|
return value & ~m;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifies bit at bit_position of value of type T.
|
||||||
|
template<size_t bit_position, BitIntegral T>
|
||||||
|
constexpr T set_bit(T value, bool new_bit) {
|
||||||
|
constexpr T m = mask<bit_position, bit_position, T>();
|
||||||
|
return (value & ~m) | (new_bit ? m : static_cast<T>(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifies bit at bit_position of value of type T.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T set_bit(size_t bit_position, T value, bool new_bit) {
|
||||||
|
const T m = mask<T>(bit_position, bit_position);
|
||||||
|
return (value & ~m) | (new_bit ? m : static_cast<T>(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
|
||||||
|
template<size_t bit_count, BitIntegral T>
|
||||||
|
constexpr T sign_extend(T value) {
|
||||||
|
static_assert(bit_count != 0, "cannot sign-extend zero-sized value");
|
||||||
|
|
||||||
|
constexpr T m = ones<bit_count, T>();
|
||||||
|
if (get_bit<bit_count - 1, T>(value)) {
|
||||||
|
return value | ~m;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sign-extends a value that has bit_count bits to the full bitwidth of type T.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T sign_extend(size_t bit_count, T value) {
|
||||||
|
ASSERT_MSG(bit_count != 0, "cannot sign-extend zero-sized value");
|
||||||
|
|
||||||
|
const T m = ones<T>(bit_count);
|
||||||
|
if (get_bit<T>(bit_count - 1, value)) {
|
||||||
|
return value | ~m;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replicate an element across a value of type T.
|
||||||
|
template<size_t element_size, BitIntegral T>
|
||||||
|
constexpr T replicate_element(T value) {
|
||||||
|
static_assert(element_size <= bitsizeof<T>, "element_size is too large");
|
||||||
|
static_assert(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
|
||||||
|
|
||||||
|
if constexpr (element_size == bitsizeof<T>) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return replicate_element<element_size * 2, T>(static_cast<T>(value | (value << element_size)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replicate an element of type U across a value of type T.
|
||||||
|
template<BitIntegral U, BitIntegral T>
|
||||||
|
constexpr T replicate_element(T value) {
|
||||||
|
static_assert(bitsizeof<U> <= bitsizeof<T>, "element_size is too large");
|
||||||
|
|
||||||
|
return replicate_element<bitsizeof<U>, T>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Replicate an element across a value of type T.
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T replicate_element(size_t element_size, T value) {
|
||||||
|
ASSERT_MSG(element_size <= bitsizeof<T>, "element_size is too large");
|
||||||
|
ASSERT_MSG(bitsizeof<T> % element_size == 0, "bitsize of T not divisible by element_size");
|
||||||
|
|
||||||
|
if (element_size == bitsizeof<T>) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return replicate_element<T>(element_size * 2, static_cast<T>(value | (value << element_size)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr bool most_significant_bit(T value) {
|
||||||
|
return get_bit<bitsizeof<T> - 1, T>(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl::bit
|
31
externals/dynarmic/externals/mcl/include/mcl/bit/rotate.hpp
vendored
Executable file
31
externals/dynarmic/externals/mcl/include/mcl/bit/rotate.hpp
vendored
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/bitsizeof.hpp"
|
||||||
|
#include "mcl/concepts/bit_integral.hpp"
|
||||||
|
#include "mcl/stdint.hpp"
|
||||||
|
|
||||||
|
namespace mcl::bit {
|
||||||
|
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T rotate_right(T x, size_t amount) {
|
||||||
|
amount %= bitsizeof<T>;
|
||||||
|
if (amount == 0) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
return static_cast<T>((x >> amount) | (x << (bitsizeof<T> - amount)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<BitIntegral T>
|
||||||
|
constexpr T rotate_left(T x, size_t amount) {
|
||||||
|
amount %= bitsizeof<T>;
|
||||||
|
if (amount == 0) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
return static_cast<T>((x << amount) | (x >> (bitsizeof<T> - amount)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl::bit
|
50
externals/dynarmic/externals/mcl/include/mcl/bit/swap.hpp
vendored
Executable file
50
externals/dynarmic/externals/mcl/include/mcl/bit/swap.hpp
vendored
Executable file
|
@ -0,0 +1,50 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/concepts/bit_integral.hpp"
|
||||||
|
|
||||||
|
namespace mcl::bit {
|
||||||
|
|
||||||
|
constexpr u16 swap_bytes_16(u16 value) {
|
||||||
|
return static_cast<u16>(u32{value} >> 8 | u32{value} << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr u32 swap_bytes_32(u32 value) {
|
||||||
|
return ((value & 0xff000000u) >> 24)
|
||||||
|
| ((value & 0x00ff0000u) >> 8)
|
||||||
|
| ((value & 0x0000ff00u) << 8)
|
||||||
|
| ((value & 0x000000ffu) << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr u64 swap_bytes_64(u64 value) {
|
||||||
|
return ((value & 0xff00000000000000ull) >> 56)
|
||||||
|
| ((value & 0x00ff000000000000ull) >> 40)
|
||||||
|
| ((value & 0x0000ff0000000000ull) >> 24)
|
||||||
|
| ((value & 0x000000ff00000000ull) >> 8)
|
||||||
|
| ((value & 0x00000000ff000000ull) << 8)
|
||||||
|
| ((value & 0x0000000000ff0000ull) << 24)
|
||||||
|
| ((value & 0x000000000000ff00ull) << 40)
|
||||||
|
| ((value & 0x00000000000000ffull) << 56);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr u32 swap_halves_32(u32 value) {
|
||||||
|
return ((value & 0xffff0000u) >> 16)
|
||||||
|
| ((value & 0x0000ffffu) << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr u64 swap_halves_64(u64 value) {
|
||||||
|
return ((value & 0xffff000000000000ull) >> 48)
|
||||||
|
| ((value & 0x0000ffff00000000ull) >> 16)
|
||||||
|
| ((value & 0x00000000ffff0000ull) << 16)
|
||||||
|
| ((value & 0x000000000000ffffull) << 48);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr u64 swap_words_64(u64 value) {
|
||||||
|
return ((value & 0xffffffff00000000ull) >> 32)
|
||||||
|
| ((value & 0x00000000ffffffffull) << 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl::bit
|
36
externals/dynarmic/externals/mcl/include/mcl/bit_cast.hpp
vendored
Executable file
36
externals/dynarmic/externals/mcl/include/mcl/bit_cast.hpp
vendored
Executable file
|
@ -0,0 +1,36 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
/// Reinterpret objects of one type as another by bit-casting between object representations.
|
||||||
|
template<class Dest, class Source>
|
||||||
|
inline Dest bit_cast(const Source& source) noexcept {
|
||||||
|
static_assert(sizeof(Dest) == sizeof(Source), "size of destination and source objects must be equal");
|
||||||
|
static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable.");
|
||||||
|
static_assert(std::is_trivially_copyable_v<Source>, "source type must be trivially copyable");
|
||||||
|
|
||||||
|
std::aligned_storage_t<sizeof(Dest), alignof(Dest)> dest;
|
||||||
|
std::memcpy(&dest, &source, sizeof(dest));
|
||||||
|
return reinterpret_cast<Dest&>(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reinterpret objects of any arbitrary type as another type by bit-casting between object representations.
|
||||||
|
/// Note that here we do not verify if source pointed to by source_ptr has enough bytes to read from.
|
||||||
|
template<class Dest, class SourcePtr>
|
||||||
|
inline Dest bit_cast_pointee(const SourcePtr source_ptr) noexcept {
|
||||||
|
static_assert(sizeof(SourcePtr) == sizeof(void*), "source pointer must have size of a pointer");
|
||||||
|
static_assert(std::is_trivially_copyable_v<Dest>, "destination type must be trivially copyable.");
|
||||||
|
|
||||||
|
std::aligned_storage_t<sizeof(Dest), alignof(Dest)> dest;
|
||||||
|
std::memcpy(&dest, bit_cast<void*>(source_ptr), sizeof(dest));
|
||||||
|
return reinterpret_cast<Dest&>(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl
|
15
externals/dynarmic/externals/mcl/include/mcl/bitsizeof.hpp
vendored
Executable file
15
externals/dynarmic/externals/mcl/include/mcl/bitsizeof.hpp
vendored
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr std::size_t bitsizeof = CHAR_BIT * sizeof(T);
|
||||||
|
|
||||||
|
} // namespace mcl
|
16
externals/dynarmic/externals/mcl/include/mcl/concepts/bit_integral.hpp
vendored
Executable file
16
externals/dynarmic/externals/mcl/include/mcl/concepts/bit_integral.hpp
vendored
Executable file
|
@ -0,0 +1,16 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/concepts/is_any_of.hpp"
|
||||||
|
#include "mcl/stdint.hpp"
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
/// Integral upon which bit operations can be safely performed.
|
||||||
|
template<typename T>
|
||||||
|
concept BitIntegral = IsAnyOf<T, u8, u16, u32, u64, uptr, size_t>;
|
||||||
|
|
||||||
|
} // namespace mcl
|
14
externals/dynarmic/externals/mcl/include/mcl/concepts/is_any_of.hpp
vendored
Executable file
14
externals/dynarmic/externals/mcl/include/mcl/concepts/is_any_of.hpp
vendored
Executable file
|
@ -0,0 +1,14 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/concepts/same_as.hpp"
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
template<typename T, typename... U>
|
||||||
|
concept IsAnyOf = (SameAs<T, U> || ...);
|
||||||
|
|
||||||
|
} // namespace mcl
|
19
externals/dynarmic/externals/mcl/include/mcl/concepts/same_as.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/concepts/same_as.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
concept SameHelper = std::is_same_v<T, U>;
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
concept SameAs = detail::SameHelper<T, U> && detail::SameHelper<U, T>;
|
||||||
|
|
||||||
|
} // namespace mcl
|
378
externals/dynarmic/externals/mcl/include/mcl/container/intrusive_list.hpp
vendored
Executable file
378
externals/dynarmic/externals/mcl/include/mcl/container/intrusive_list.hpp
vendored
Executable file
|
@ -0,0 +1,378 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "mcl/assert.hpp"
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class intrusive_list;
|
||||||
|
template<typename T>
|
||||||
|
class intrusive_list_iterator;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class intrusive_list_node {
|
||||||
|
public:
|
||||||
|
bool is_sentinel() const {
|
||||||
|
return is_sentinel_;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
intrusive_list_node* next = nullptr;
|
||||||
|
intrusive_list_node* prev = nullptr;
|
||||||
|
bool is_sentinel_ = false;
|
||||||
|
|
||||||
|
friend class intrusive_list<T>;
|
||||||
|
friend class intrusive_list_iterator<T>;
|
||||||
|
friend class intrusive_list_iterator<const T>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class intrusive_list_sentinel final : public intrusive_list_node<T> {
|
||||||
|
using intrusive_list_node<T>::next;
|
||||||
|
using intrusive_list_node<T>::prev;
|
||||||
|
using intrusive_list_node<T>::is_sentinel_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
intrusive_list_sentinel() {
|
||||||
|
next = this;
|
||||||
|
prev = this;
|
||||||
|
is_sentinel_ = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class intrusive_list_iterator {
|
||||||
|
public:
|
||||||
|
using iterator_category = std::bidirectional_iterator_tag;
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using value_type = T;
|
||||||
|
using pointer = value_type*;
|
||||||
|
using const_pointer = const value_type*;
|
||||||
|
using reference = value_type&;
|
||||||
|
using const_reference = const value_type&;
|
||||||
|
|
||||||
|
// If value_type is const, we want "const intrusive_list_node<value_type>", not "intrusive_list_node<const value_type>"
|
||||||
|
using node_type = std::conditional_t<std::is_const<value_type>::value,
|
||||||
|
const intrusive_list_node<std::remove_const_t<value_type>>,
|
||||||
|
intrusive_list_node<value_type>>;
|
||||||
|
using node_pointer = node_type*;
|
||||||
|
using node_reference = node_type&;
|
||||||
|
|
||||||
|
intrusive_list_iterator() = default;
|
||||||
|
intrusive_list_iterator(const intrusive_list_iterator& other) = default;
|
||||||
|
intrusive_list_iterator& operator=(const intrusive_list_iterator& other) = default;
|
||||||
|
|
||||||
|
explicit intrusive_list_iterator(node_pointer list_node)
|
||||||
|
: node(list_node) {
|
||||||
|
}
|
||||||
|
explicit intrusive_list_iterator(pointer data)
|
||||||
|
: node(data) {
|
||||||
|
}
|
||||||
|
explicit intrusive_list_iterator(reference data)
|
||||||
|
: node(&data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
intrusive_list_iterator& operator++() {
|
||||||
|
node = node->next;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
intrusive_list_iterator& operator--() {
|
||||||
|
node = node->prev;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
intrusive_list_iterator operator++(int) {
|
||||||
|
intrusive_list_iterator it(*this);
|
||||||
|
++*this;
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
intrusive_list_iterator operator--(int) {
|
||||||
|
intrusive_list_iterator it(*this);
|
||||||
|
--*this;
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const intrusive_list_iterator& other) const {
|
||||||
|
return node == other.node;
|
||||||
|
}
|
||||||
|
bool operator!=(const intrusive_list_iterator& other) const {
|
||||||
|
return !operator==(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
reference operator*() const {
|
||||||
|
DEBUG_ASSERT(!node->is_sentinel());
|
||||||
|
return static_cast<reference>(*node);
|
||||||
|
}
|
||||||
|
pointer operator->() const {
|
||||||
|
return std::addressof(operator*());
|
||||||
|
}
|
||||||
|
|
||||||
|
node_pointer AsNodePointer() const {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class intrusive_list<T>;
|
||||||
|
node_pointer node = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class intrusive_list {
|
||||||
|
public:
|
||||||
|
using difference_type = std::ptrdiff_t;
|
||||||
|
using size_type = std::size_t;
|
||||||
|
using value_type = T;
|
||||||
|
using pointer = value_type*;
|
||||||
|
using const_pointer = const value_type*;
|
||||||
|
using reference = value_type&;
|
||||||
|
using const_reference = const value_type&;
|
||||||
|
using iterator = intrusive_list_iterator<value_type>;
|
||||||
|
using const_iterator = intrusive_list_iterator<const value_type>;
|
||||||
|
using reverse_iterator = std::reverse_iterator<iterator>;
|
||||||
|
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a node at the given location indicated by an iterator.
|
||||||
|
*
|
||||||
|
* @param location The location to insert the node.
|
||||||
|
* @param new_node The node to add.
|
||||||
|
*/
|
||||||
|
iterator insert(iterator location, pointer new_node) {
|
||||||
|
return insert_before(location, new_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a node at the given location, moving the previous
|
||||||
|
* node occupant ahead of the one inserted.
|
||||||
|
*
|
||||||
|
* @param location The location to insert the new node.
|
||||||
|
* @param new_node The node to insert into the list.
|
||||||
|
*/
|
||||||
|
iterator insert_before(iterator location, pointer new_node) {
|
||||||
|
auto existing_node = location.AsNodePointer();
|
||||||
|
|
||||||
|
new_node->next = existing_node;
|
||||||
|
new_node->prev = existing_node->prev;
|
||||||
|
existing_node->prev->next = new_node;
|
||||||
|
existing_node->prev = new_node;
|
||||||
|
|
||||||
|
return iterator(new_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a new node into the list ahead of the position indicated.
|
||||||
|
*
|
||||||
|
* @param position Location to insert the node in front of.
|
||||||
|
* @param new_node The node to be inserted into the list.
|
||||||
|
*/
|
||||||
|
iterator insert_after(iterator position, pointer new_node) {
|
||||||
|
if (empty())
|
||||||
|
return insert(begin(), new_node);
|
||||||
|
|
||||||
|
return insert(++position, new_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an entry to the start of the list.
|
||||||
|
* @param node Node to add to the list.
|
||||||
|
*/
|
||||||
|
void push_front(pointer node) {
|
||||||
|
insert(begin(), node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an entry to the end of the list
|
||||||
|
* @param node Node to add to the list.
|
||||||
|
*/
|
||||||
|
void push_back(pointer node) {
|
||||||
|
insert(end(), node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erases the node at the front of the list.
|
||||||
|
* @note Must not be called on an empty list.
|
||||||
|
*/
|
||||||
|
void pop_front() {
|
||||||
|
DEBUG_ASSERT(!empty());
|
||||||
|
erase(begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erases the node at the back of the list.
|
||||||
|
* @note Must not be called on an empty list.
|
||||||
|
*/
|
||||||
|
void pop_back() {
|
||||||
|
DEBUG_ASSERT(!empty());
|
||||||
|
erase(--end());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a node from this list
|
||||||
|
* @param it An iterator that points to the node to remove from list.
|
||||||
|
*/
|
||||||
|
pointer remove(iterator& it) {
|
||||||
|
DEBUG_ASSERT(it != end());
|
||||||
|
|
||||||
|
pointer node = &*it++;
|
||||||
|
|
||||||
|
node->prev->next = node->next;
|
||||||
|
node->next->prev = node->prev;
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
node->next = nullptr;
|
||||||
|
node->prev = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a node from this list
|
||||||
|
* @param it A constant iterator that points to the node to remove from list.
|
||||||
|
*/
|
||||||
|
pointer remove(const iterator& it) {
|
||||||
|
iterator copy = it;
|
||||||
|
return remove(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a node from this list.
|
||||||
|
* @param node A pointer to the node to remove.
|
||||||
|
*/
|
||||||
|
pointer remove(pointer node) {
|
||||||
|
return remove(iterator(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a node from this list.
|
||||||
|
* @param node A reference to the node to remove.
|
||||||
|
*/
|
||||||
|
pointer remove(reference node) {
|
||||||
|
return remove(iterator(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is this list empty?
|
||||||
|
* @returns true if there are no nodes in this list.
|
||||||
|
*/
|
||||||
|
bool empty() const {
|
||||||
|
return root->next == root.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the total number of elements within this list.
|
||||||
|
* @return the number of elements in this list.
|
||||||
|
*/
|
||||||
|
size_type size() const {
|
||||||
|
return static_cast<size_type>(std::distance(begin(), end()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a reference to the node at the front of the list.
|
||||||
|
* @note Must not be called on an empty list.
|
||||||
|
*/
|
||||||
|
reference front() {
|
||||||
|
DEBUG_ASSERT(!empty());
|
||||||
|
return *begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a constant reference to the node at the front of the list.
|
||||||
|
* @note Must not be called on an empty list.
|
||||||
|
*/
|
||||||
|
const_reference front() const {
|
||||||
|
DEBUG_ASSERT(!empty());
|
||||||
|
return *begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a reference to the node at the back of the list.
|
||||||
|
* @note Must not be called on an empty list.
|
||||||
|
*/
|
||||||
|
reference back() {
|
||||||
|
DEBUG_ASSERT(!empty());
|
||||||
|
return *--end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves a constant reference to the node at the back of the list.
|
||||||
|
* @note Must not be called on an empty list.
|
||||||
|
*/
|
||||||
|
const_reference back() const {
|
||||||
|
DEBUG_ASSERT(!empty());
|
||||||
|
return *--end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterator interface
|
||||||
|
iterator begin() { return iterator(root->next); }
|
||||||
|
const_iterator begin() const { return const_iterator(root->next); }
|
||||||
|
const_iterator cbegin() const { return begin(); }
|
||||||
|
|
||||||
|
iterator end() { return iterator(root.get()); }
|
||||||
|
const_iterator end() const { return const_iterator(root.get()); }
|
||||||
|
const_iterator cend() const { return end(); }
|
||||||
|
|
||||||
|
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
||||||
|
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
||||||
|
const_reverse_iterator crbegin() const { return rbegin(); }
|
||||||
|
|
||||||
|
reverse_iterator rend() { return reverse_iterator(begin()); }
|
||||||
|
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
|
||||||
|
const_reverse_iterator crend() const { return rend(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erases a node from the list, indicated by an iterator.
|
||||||
|
* @param it The iterator that points to the node to erase.
|
||||||
|
*/
|
||||||
|
iterator erase(iterator it) {
|
||||||
|
remove(it);
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erases a node from this list.
|
||||||
|
* @param node A pointer to the node to erase from this list.
|
||||||
|
*/
|
||||||
|
iterator erase(pointer node) {
|
||||||
|
return erase(iterator(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erases a node from this list.
|
||||||
|
* @param node A reference to the node to erase from this list.
|
||||||
|
*/
|
||||||
|
iterator erase(reference node) {
|
||||||
|
return erase(iterator(node));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchanges contents of this list with another list instance.
|
||||||
|
* @param other The other list to swap with.
|
||||||
|
*/
|
||||||
|
void swap(intrusive_list& other) noexcept {
|
||||||
|
root.swap(other.root);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<intrusive_list_node<T>> root = std::make_shared<intrusive_list_sentinel<T>>();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exchanges contents of an intrusive list with another intrusive list.
|
||||||
|
* @tparam T The type of data being kept track of by the lists.
|
||||||
|
* @param lhs The first list.
|
||||||
|
* @param rhs The second list.
|
||||||
|
*/
|
||||||
|
template<typename T>
|
||||||
|
void swap(intrusive_list<T>& lhs, intrusive_list<T>& rhs) noexcept {
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl
|
13
externals/dynarmic/externals/mcl/include/mcl/hint/assume.hpp
vendored
Executable file
13
externals/dynarmic/externals/mcl/include/mcl/hint/assume.hpp
vendored
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(__clang) || defined(__GNUC__)
|
||||||
|
# define ASSUME(expr) [&] { if (!(expr)) __builtin_unreachable(); }()
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
# define ASSUME(expr) __assume(expr)
|
||||||
|
#else
|
||||||
|
# define ASSUME(expr)
|
||||||
|
#endif
|
34
externals/dynarmic/externals/mcl/include/mcl/iterator/reverse.hpp
vendored
Executable file
34
externals/dynarmic/externals/mcl/include/mcl/iterator/reverse.hpp
vendored
Executable file
|
@ -0,0 +1,34 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace mcl::iterator {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct reverse_adapter {
|
||||||
|
T& iterable;
|
||||||
|
|
||||||
|
constexpr auto begin() {
|
||||||
|
using namespace std;
|
||||||
|
return rbegin(iterable);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr auto end() {
|
||||||
|
using namespace std;
|
||||||
|
return rend(iterable);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
constexpr detail::reverse_adapter<T> reverse(T&& iterable) {
|
||||||
|
return detail::reverse_adapter<T>{iterable};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl::iterator
|
13
externals/dynarmic/externals/mcl/include/mcl/macro/anonymous_variable.hpp
vendored
Executable file
13
externals/dynarmic/externals/mcl/include/mcl/macro/anonymous_variable.hpp
vendored
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mcl/macro/concatenate_tokens.hpp>
|
||||||
|
|
||||||
|
#ifdef __COUNTER__
|
||||||
|
# define ANONYMOUS_VARIABLE(str) CONCATENATE_TOKENS(str, __COUNTER__)
|
||||||
|
#else
|
||||||
|
# define ANONYMOUS_VARIABLE(str) CONCATENATE_TOKENS(str, __LINE__)
|
||||||
|
#endif
|
40
externals/dynarmic/externals/mcl/include/mcl/macro/architecture.hpp
vendored
Executable file
40
externals/dynarmic/externals/mcl/include/mcl/macro/architecture.hpp
vendored
Executable file
|
@ -0,0 +1,40 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(__ARM64__) || defined(__aarch64__) || defined(_M_ARM64)
|
||||||
|
# define MCL_ARCHITECTURE arm64
|
||||||
|
# define MCL_ARCHITECTURE_ARM64 1
|
||||||
|
#elif defined(__arm__) || defined(__TARGET_ARCH_ARM) || defined(_M_ARM)
|
||||||
|
# define MCL_ARCHITECTURE arm32
|
||||||
|
# define MCL_ARCHITECTURE_ARM32 1
|
||||||
|
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
|
||||||
|
# define MCL_ARCHITECTURE x86_64
|
||||||
|
# define MCL_ARCHITECTURE_X86_64 1
|
||||||
|
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
|
||||||
|
# define MCL_ARCHITECTURE x86_32
|
||||||
|
# define MCL_ARCHITECTURE_X86_32 1
|
||||||
|
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
|
||||||
|
# define MCL_ARCHITECTURE ia64
|
||||||
|
# define MCL_ARCHITECTURE_IA64 1
|
||||||
|
#elif defined(__mips) || defined(__mips__) || defined(_M_MRX000)
|
||||||
|
# define MCL_ARCHITECTURE mips
|
||||||
|
# define MCL_ARCHITECTURE_MIPS 1
|
||||||
|
#elif defined(__ppc64__) || defined(__powerpc64__)
|
||||||
|
# define MCL_ARCHITECTURE ppc64
|
||||||
|
# define MCL_ARCHITECTURE_PPC64 1
|
||||||
|
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) || defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_M_MPPC) || defined(_M_PPC)
|
||||||
|
# define MCL_ARCHITECTURE ppc32
|
||||||
|
# define MCL_ARCHITECTURE_PPC32 1
|
||||||
|
#elif defined(__riscv)
|
||||||
|
# define MCL_ARCHITECTURE riscv
|
||||||
|
# define MCL_ARCHITECTURE_RISCV 1
|
||||||
|
#elif defined(__EMSCRIPTEN__)
|
||||||
|
# define MCL_ARCHITECTURE wasm
|
||||||
|
# define MCL_ARCHITECTURE_WASM 1
|
||||||
|
#else
|
||||||
|
# define MCL_ARCHITECTURE generic
|
||||||
|
# define MCL_ARCHITECTURE_GENERIC 1
|
||||||
|
#endif
|
8
externals/dynarmic/externals/mcl/include/mcl/macro/concatenate_tokens.hpp
vendored
Executable file
8
externals/dynarmic/externals/mcl/include/mcl/macro/concatenate_tokens.hpp
vendored
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define CONCATENATE_TOKENS(x, y) CONCATENATE_TOKENS_IMPL(x, y)
|
||||||
|
#define CONCATENATE_TOKENS_IMPL(x, y) x##y
|
25
externals/dynarmic/externals/mcl/include/mcl/mp/metafunction/apply.hpp
vendored
Executable file
25
externals/dynarmic/externals/mcl/include/mcl/mp/metafunction/apply.hpp
vendored
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<template<class...> class F, class L>
|
||||||
|
struct apply_impl;
|
||||||
|
|
||||||
|
template<template<class...> class F, template<class...> class LT, class... Es>
|
||||||
|
struct apply_impl<F, LT<Es...>> {
|
||||||
|
using type = F<Es...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Invokes metafunction F where the arguments are all the members of list L
|
||||||
|
template<template<class...> class F, class L>
|
||||||
|
using apply = typename detail::apply_impl<F, L>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
18
externals/dynarmic/externals/mcl/include/mcl/mp/metafunction/bind.hpp
vendored
Executable file
18
externals/dynarmic/externals/mcl/include/mcl/mp/metafunction/bind.hpp
vendored
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Binds the first sizeof...(A) arguments of metafunction F with arguments A
|
||||||
|
template<template<class...> class F, class... As>
|
||||||
|
struct bind {
|
||||||
|
template<class... Rs>
|
||||||
|
using type = F<As..., Rs...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
||||||
|
|
||||||
|
#define MCL_MP_BIND(...) ::mcl::mp::bind<__VA_ARGS__>::template type
|
22
externals/dynarmic/externals/mcl/include/mcl/mp/metafunction/identity.hpp
vendored
Executable file
22
externals/dynarmic/externals/mcl/include/mcl/mp/metafunction/identity.hpp
vendored
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct identity_impl {
|
||||||
|
using type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Identity metafunction
|
||||||
|
template<class T>
|
||||||
|
using identity = typename identity_impl<T>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
25
externals/dynarmic/externals/mcl/include/mcl/mp/metafunction/map.hpp
vendored
Executable file
25
externals/dynarmic/externals/mcl/include/mcl/mp/metafunction/map.hpp
vendored
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<template<class...> class F, class L>
|
||||||
|
struct map_impl;
|
||||||
|
|
||||||
|
template<template<class...> class F, template<class...> class LT, class... Es>
|
||||||
|
struct map_impl<F, LT<Es...>> {
|
||||||
|
using type = LT<F<Es>...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Applies each element of list L to metafunction F
|
||||||
|
template<template<class...> class F, class L>
|
||||||
|
using map = typename detail::map_impl<F, L>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/bit_and.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/bit_and.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Bitwise and of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
using bit_and = lift_value<(Vs::value & ...)>;
|
||||||
|
|
||||||
|
/// Bitwise and of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr auto bit_and_v = (Vs::value & ...);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/bit_not.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/bit_not.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Bitwise not of metavalue V
|
||||||
|
template<class V>
|
||||||
|
using bit_not = lift_value<~V::value>;
|
||||||
|
|
||||||
|
/// Bitwise not of metavalue V
|
||||||
|
template<class V>
|
||||||
|
constexpr auto bit_not_v = ~V::value;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/bit_or.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/bit_or.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Bitwise or of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
using bit_or = lift_value<(Vs::value | ...)>;
|
||||||
|
|
||||||
|
/// Bitwise or of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr auto bit_or_v = (Vs::value | ...);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/bit_xor.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/bit_xor.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Bitwise xor of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
using bit_xor = lift_value<(Vs::value ^ ...)>;
|
||||||
|
|
||||||
|
/// Bitwise xor of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr auto bit_xor_v = (Vs::value ^ ...);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
42
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/conjunction.hpp
vendored
Executable file
42
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/conjunction.hpp
vendored
Executable file
|
@ -0,0 +1,42 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/logic_if.hpp"
|
||||||
|
#include "mcl/mp/metavalue/value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class...>
|
||||||
|
struct conjunction_impl;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct conjunction_impl<> {
|
||||||
|
using type = false_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V>
|
||||||
|
struct conjunction_impl<V> {
|
||||||
|
using type = V;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V1, class... Vs>
|
||||||
|
struct conjunction_impl<V1, Vs...> {
|
||||||
|
using type = logic_if<V1, typename conjunction_impl<Vs...>::type, V1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Conjunction of metavalues Vs with short-circuiting and type preservation.
|
||||||
|
template<class... Vs>
|
||||||
|
using conjunction = typename detail::conjunction_impl<Vs...>::type;
|
||||||
|
|
||||||
|
/// Conjunction of metavalues Vs with short-circuiting and type preservation.
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr auto conjunction_v = conjunction<Vs...>::value;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
42
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/disjunction.hpp
vendored
Executable file
42
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/disjunction.hpp
vendored
Executable file
|
@ -0,0 +1,42 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/logic_if.hpp"
|
||||||
|
#include "mcl/mp/metavalue/value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class...>
|
||||||
|
struct disjunction_impl;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct disjunction_impl<> {
|
||||||
|
using type = false_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V>
|
||||||
|
struct disjunction_impl<V> {
|
||||||
|
using type = V;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class V1, class... Vs>
|
||||||
|
struct disjunction_impl<V1, Vs...> {
|
||||||
|
using type = logic_if<V1, V1, typename disjunction_impl<Vs...>::type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Disjunction of metavalues Vs with short-circuiting and type preservation.
|
||||||
|
template<class... Vs>
|
||||||
|
using disjunction = typename detail::disjunction_impl<Vs...>::type;
|
||||||
|
|
||||||
|
/// Disjunction of metavalues Vs with short-circuiting and type preservation.
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr auto disjunction_v = disjunction<Vs...>::value;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
15
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/lift_value.hpp
vendored
Executable file
15
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/lift_value.hpp
vendored
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Lifts a value into a type (a metavalue)
|
||||||
|
template<auto V>
|
||||||
|
using lift_value = std::integral_constant<decltype(V), V>;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/logic_and.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/logic_and.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Logical conjunction of metavalues Vs without short-circuiting or type presevation.
|
||||||
|
template<class... Vs>
|
||||||
|
using logic_and = bool_value<(true && ... && Vs::value)>;
|
||||||
|
|
||||||
|
/// Logical conjunction of metavalues Vs without short-circuiting or type presevation.
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr bool logic_and_v = (true && ... && Vs::value);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
21
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/logic_if.hpp
vendored
Executable file
21
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/logic_if.hpp
vendored
Executable file
|
@ -0,0 +1,21 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Conditionally select between types T and F based on boolean metavalue V
|
||||||
|
template<class V, class T, class F>
|
||||||
|
using logic_if = std::conditional_t<bool(V::value), T, F>;
|
||||||
|
|
||||||
|
/// Conditionally select between metavalues T and F based on boolean metavalue V
|
||||||
|
template<class V, class TV, class FV>
|
||||||
|
constexpr auto logic_if_v = logic_if<V, TV, FV>::value;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/logic_not.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/logic_not.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Logical negation of metavalue V.
|
||||||
|
template<class V>
|
||||||
|
using logic_not = bool_value<!bool(V::value)>;
|
||||||
|
|
||||||
|
/// Logical negation of metavalue V.
|
||||||
|
template<class V>
|
||||||
|
constexpr bool logic_not_v = !bool(V::value);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/logic_or.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/logic_or.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Logical disjunction of metavalues Vs without short-circuiting or type presevation.
|
||||||
|
template<class... Vs>
|
||||||
|
using logic_or = bool_value<(false || ... || Vs::value)>;
|
||||||
|
|
||||||
|
/// Logical disjunction of metavalues Vs without short-circuiting or type presevation.
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr bool logic_or_v = (false || ... || Vs::value);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/product.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/product.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Product of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
using product = lift_value<(Vs::value * ...)>;
|
||||||
|
|
||||||
|
/// Product of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr auto product_v = (Vs::value * ...);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/sum.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/sum.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Sum of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
using sum = lift_value<(Vs::value + ...)>;
|
||||||
|
|
||||||
|
/// Sum of metavalues Vs
|
||||||
|
template<class... Vs>
|
||||||
|
constexpr auto sum_v = (Vs::value + ...);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
30
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/value.hpp
vendored
Executable file
30
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/value.hpp
vendored
Executable file
|
@ -0,0 +1,30 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// A metavalue (of type VT and value v).
|
||||||
|
template<class VT, VT v>
|
||||||
|
using value = std::integral_constant<VT, v>;
|
||||||
|
|
||||||
|
/// A metavalue of type size_t (and value v).
|
||||||
|
template<size_t v>
|
||||||
|
using size_value = value<size_t, v>;
|
||||||
|
|
||||||
|
/// A metavalue of type bool (and value v). (Aliases to std::bool_constant.)
|
||||||
|
template<bool v>
|
||||||
|
using bool_value = value<bool, v>;
|
||||||
|
|
||||||
|
/// true metavalue (Aliases to std::true_type).
|
||||||
|
using true_type = bool_value<true>;
|
||||||
|
|
||||||
|
/// false metavalue (Aliases to std::false_type).
|
||||||
|
using false_type = bool_value<false>;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
15
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/value_cast.hpp
vendored
Executable file
15
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/value_cast.hpp
vendored
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Casts a metavalue from one type to another
|
||||||
|
template<class T, class V>
|
||||||
|
using value_cast = std::integral_constant<T, static_cast<T>(V::value)>;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
15
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/value_equal.hpp
vendored
Executable file
15
externals/dynarmic/externals/mcl/include/mcl/mp/metavalue/value_equal.hpp
vendored
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Do two metavalues contain the same value?
|
||||||
|
template<class V1, class V2>
|
||||||
|
using value_equal = std::bool_constant<V1::value == V2::value>;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
19
externals/dynarmic/externals/mcl/include/mcl/mp/misc/argument_count.hpp
vendored
Executable file
19
externals/dynarmic/externals/mcl/include/mcl/mp/misc/argument_count.hpp
vendored
Executable file
|
@ -0,0 +1,19 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/lift_value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Metafunction that returns the number of arguments it has
|
||||||
|
template<typename... Ts>
|
||||||
|
using argument_count = lift_value<sizeof...(Ts)>;
|
||||||
|
|
||||||
|
/// Metafunction that returns the number of arguments it has
|
||||||
|
template<typename... Ts>
|
||||||
|
constexpr auto argument_count_v = sizeof...(Ts);
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
25
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/append.hpp
vendored
Executable file
25
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/append.hpp
vendored
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class... L>
|
||||||
|
struct append_impl;
|
||||||
|
|
||||||
|
template<template<class...> class LT, class... E1s, class... E2s>
|
||||||
|
struct append_impl<LT<E1s...>, E2s...> {
|
||||||
|
using type = LT<E1s..., E2s...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Append items E to list L
|
||||||
|
template<class L, class... Es>
|
||||||
|
using append = typename detail::append_impl<L, Es...>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
47
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/cartesian_product.hpp
vendored
Executable file
47
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/cartesian_product.hpp
vendored
Executable file
|
@ -0,0 +1,47 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metafunction/bind.hpp"
|
||||||
|
#include "mcl/mp/metafunction/map.hpp"
|
||||||
|
#include "mcl/mp/typelist/append.hpp"
|
||||||
|
#include "mcl/mp/typelist/concat.hpp"
|
||||||
|
#include "mcl/mp/typelist/list.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class... Ls>
|
||||||
|
struct cartesian_product_impl;
|
||||||
|
|
||||||
|
template<class RL>
|
||||||
|
struct cartesian_product_impl<RL> {
|
||||||
|
using type = RL;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class LT, class... REs, class... E2s>
|
||||||
|
struct cartesian_product_impl<LT<REs...>, LT<E2s...>> {
|
||||||
|
using type = concat<
|
||||||
|
map<MCL_MP_BIND(append, REs), list<E2s...>>...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class RL, class L2, class L3, class... Ls>
|
||||||
|
struct cartesian_product_impl<RL, L2, L3, Ls...> {
|
||||||
|
using type = typename cartesian_product_impl<
|
||||||
|
typename cartesian_product_impl<RL, L2>::type,
|
||||||
|
L3,
|
||||||
|
Ls...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Produces the cartesian product of a set of lists
|
||||||
|
/// For example:
|
||||||
|
/// cartesian_product<list<A, B>, list<D, E>> == list<list<A, D>, list<A, E>, list<B, D>, list<B, E>
|
||||||
|
template<typename L1, typename... Ls>
|
||||||
|
using cartesian_product = typename detail::cartesian_product_impl<map<list, L1>, Ls...>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
94
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/concat.hpp
vendored
Executable file
94
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/concat.hpp
vendored
Executable file
|
@ -0,0 +1,94 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/typelist/list.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class... Ls>
|
||||||
|
struct concat_impl;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct concat_impl<> {
|
||||||
|
using type = list<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class L>
|
||||||
|
struct concat_impl<L> {
|
||||||
|
using type = L;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class LT, class... E1s, class... E2s, class... Ls>
|
||||||
|
struct concat_impl<LT<E1s...>, LT<E2s...>, Ls...> {
|
||||||
|
using type = typename concat_impl<LT<E1s..., E2s...>, Ls...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<template<class...> class LT,
|
||||||
|
class... E1s,
|
||||||
|
class... E2s,
|
||||||
|
class... E3s,
|
||||||
|
class... E4s,
|
||||||
|
class... E5s,
|
||||||
|
class... E6s,
|
||||||
|
class... E7s,
|
||||||
|
class... E8s,
|
||||||
|
class... E9s,
|
||||||
|
class... E10s,
|
||||||
|
class... E11s,
|
||||||
|
class... E12s,
|
||||||
|
class... E13s,
|
||||||
|
class... E14s,
|
||||||
|
class... E15s,
|
||||||
|
class... E16s,
|
||||||
|
class... Ls>
|
||||||
|
struct concat_impl<
|
||||||
|
LT<E1s...>,
|
||||||
|
LT<E2s...>,
|
||||||
|
LT<E3s...>,
|
||||||
|
LT<E4s...>,
|
||||||
|
LT<E5s...>,
|
||||||
|
LT<E6s...>,
|
||||||
|
LT<E7s...>,
|
||||||
|
LT<E8s...>,
|
||||||
|
LT<E9s...>,
|
||||||
|
LT<E10s...>,
|
||||||
|
LT<E11s...>,
|
||||||
|
LT<E12s...>,
|
||||||
|
LT<E13s...>,
|
||||||
|
LT<E14s...>,
|
||||||
|
LT<E15s...>,
|
||||||
|
LT<E16s...>,
|
||||||
|
Ls...> {
|
||||||
|
using type = typename concat_impl<
|
||||||
|
LT<
|
||||||
|
E1s...,
|
||||||
|
E2s...,
|
||||||
|
E3s...,
|
||||||
|
E4s...,
|
||||||
|
E5s...,
|
||||||
|
E6s...,
|
||||||
|
E7s...,
|
||||||
|
E8s...,
|
||||||
|
E9s...,
|
||||||
|
E10s...,
|
||||||
|
E11s...,
|
||||||
|
E12s...,
|
||||||
|
E13s...,
|
||||||
|
E14s...,
|
||||||
|
E15s...,
|
||||||
|
E16s...>,
|
||||||
|
Ls...>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Concatenate lists together
|
||||||
|
template<class... Ls>
|
||||||
|
using concat = typename detail::concat_impl<Ls...>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
23
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/contains.hpp
vendored
Executable file
23
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/contains.hpp
vendored
Executable file
|
@ -0,0 +1,23 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/value.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Does list L contain an element which is same as type T?
|
||||||
|
template<class L, class T>
|
||||||
|
struct contains;
|
||||||
|
|
||||||
|
template<template<class...> class LT, class... Ts, class T>
|
||||||
|
struct contains<LT<Ts...>, T>
|
||||||
|
: bool_value<(false || ... || std::is_same_v<Ts, T>)> {};
|
||||||
|
|
||||||
|
/// Does list L contain an element which is same as type T?
|
||||||
|
template<class L, class T>
|
||||||
|
constexpr bool contains_v = contains<L, T>::value;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
33
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/drop.hpp
vendored
Executable file
33
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/drop.hpp
vendored
Executable file
|
@ -0,0 +1,33 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<size_t N, class L>
|
||||||
|
struct drop_impl;
|
||||||
|
|
||||||
|
template<size_t N, template<class...> class LT>
|
||||||
|
struct drop_impl<N, LT<>> {
|
||||||
|
using type = LT<>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<size_t N, template<class...> class LT, class E1, class... Es>
|
||||||
|
struct drop_impl<N, LT<E1, Es...>> {
|
||||||
|
using type = std::conditional_t<N == 0, LT<E1, Es...>, typename drop_impl<N - 1, LT<Es...>>::type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Drops the first N elements of list L
|
||||||
|
template<std::size_t N, class L>
|
||||||
|
using drop = typename detail::drop_impl<N, L>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
18
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/get.hpp
vendored
Executable file
18
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/get.hpp
vendored
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#include "mcl/mp/metafunction/apply.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Get element I from list L
|
||||||
|
template<std::size_t I, class L>
|
||||||
|
using get = std::tuple_element_t<I, apply<std::tuple, L>>;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
25
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/head.hpp
vendored
Executable file
25
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/head.hpp
vendored
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class L>
|
||||||
|
struct head_impl;
|
||||||
|
|
||||||
|
template<template<class...> class LT, class E1, class... Es>
|
||||||
|
struct head_impl<LT<E1, Es...>> {
|
||||||
|
using type = E1;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Gets the tail/cdr/all-but-the-first-element of list L
|
||||||
|
template<class L>
|
||||||
|
using head = typename detail::head_impl<L>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
20
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/length.hpp
vendored
Executable file
20
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/length.hpp
vendored
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metafunction/apply.hpp"
|
||||||
|
#include "mcl/mp/misc/argument_count.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Length of list L
|
||||||
|
template<class L>
|
||||||
|
using length = apply<argument_count, L>;
|
||||||
|
|
||||||
|
/// Length of list L
|
||||||
|
template<class L>
|
||||||
|
constexpr auto length_v = length<L>::value;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
29
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/lift_sequence.hpp
vendored
Executable file
29
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/lift_sequence.hpp
vendored
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "mcl/mp/typelist/list.hpp"
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class VL>
|
||||||
|
struct lift_sequence_impl;
|
||||||
|
|
||||||
|
template<class T, template<class, T...> class VLT, T... values>
|
||||||
|
struct lift_sequence_impl<VLT<T, values...>> {
|
||||||
|
using type = list<std::integral_constant<T, values>...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Lifts values in value list VL to create a type list.
|
||||||
|
template<class VL>
|
||||||
|
using lift_sequence = typename detail::lift_sequence_impl<VL>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
13
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/list.hpp
vendored
Executable file
13
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/list.hpp
vendored
Executable file
|
@ -0,0 +1,13 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Contains a list of types
|
||||||
|
template<class... E>
|
||||||
|
struct list {};
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
24
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/lower_to_tuple.hpp
vendored
Executable file
24
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/lower_to_tuple.hpp
vendored
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
/// Converts a list of metavalues to a tuple.
|
||||||
|
template<class L>
|
||||||
|
struct lower_to_tuple;
|
||||||
|
|
||||||
|
template<template<class...> class LT, class... Es>
|
||||||
|
struct lower_to_tuple<LT<Es...>> {
|
||||||
|
static constexpr auto value = std::make_tuple(static_cast<typename Es::value_type>(Es::value)...);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Converts a list of metavalues to a tuple.
|
||||||
|
template<class L>
|
||||||
|
constexpr auto lower_to_tuple_v = lower_to_tuple<L>::value;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
25
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/prepend.hpp
vendored
Executable file
25
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/prepend.hpp
vendored
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class... L>
|
||||||
|
struct prepend_impl;
|
||||||
|
|
||||||
|
template<template<class...> class LT, class... E1s, class... E2s>
|
||||||
|
struct prepend_impl<LT<E1s...>, E2s...> {
|
||||||
|
using type = LT<E2s..., E1s...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Prepend items E to list L
|
||||||
|
template<class L, class... Es>
|
||||||
|
using prepend = typename detail::prepend_impl<L, Es...>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
25
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/tail.hpp
vendored
Executable file
25
externals/dynarmic/externals/mcl/include/mcl/mp/typelist/tail.hpp
vendored
Executable file
|
@ -0,0 +1,25 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace mcl::mp {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class L>
|
||||||
|
struct tail_impl;
|
||||||
|
|
||||||
|
template<template<class...> class LT, class E1, class... Es>
|
||||||
|
struct tail_impl<LT<E1, Es...>> {
|
||||||
|
using type = LT<Es...>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Gets the first type of list L
|
||||||
|
template<class L>
|
||||||
|
using tail = typename detail::tail_impl<L>::type;
|
||||||
|
|
||||||
|
} // namespace mcl::mp
|
85
externals/dynarmic/externals/mcl/include/mcl/scope_exit.hpp
vendored
Executable file
85
externals/dynarmic/externals/mcl/include/mcl/scope_exit.hpp
vendored
Executable file
|
@ -0,0 +1,85 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <mcl/macro/anonymous_variable.hpp>
|
||||||
|
|
||||||
|
namespace mcl::detail {
|
||||||
|
|
||||||
|
struct scope_exit_tag {};
|
||||||
|
struct scope_fail_tag {};
|
||||||
|
struct scope_success_tag {};
|
||||||
|
|
||||||
|
template<typename Function>
|
||||||
|
class scope_exit final {
|
||||||
|
public:
|
||||||
|
explicit scope_exit(Function&& fn)
|
||||||
|
: function(std::move(fn)) {}
|
||||||
|
~scope_exit() noexcept {
|
||||||
|
function();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Function function;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Function>
|
||||||
|
class scope_fail final {
|
||||||
|
public:
|
||||||
|
explicit scope_fail(Function&& fn)
|
||||||
|
: function(std::move(fn)), exception_count(std::uncaught_exceptions()) {}
|
||||||
|
~scope_fail() noexcept {
|
||||||
|
if (std::uncaught_exceptions() > exception_count) {
|
||||||
|
function();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Function function;
|
||||||
|
int exception_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Function>
|
||||||
|
class scope_success final {
|
||||||
|
public:
|
||||||
|
explicit scope_success(Function&& fn)
|
||||||
|
: function(std::move(fn)), exception_count(std::uncaught_exceptions()) {}
|
||||||
|
~scope_success() {
|
||||||
|
if (std::uncaught_exceptions() <= exception_count) {
|
||||||
|
function();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Function function;
|
||||||
|
int exception_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
// We use ->* here as it has the highest precedence of the operators we can use.
|
||||||
|
|
||||||
|
template<typename Function>
|
||||||
|
auto operator->*(scope_exit_tag, Function&& function) {
|
||||||
|
return scope_exit<std::decay_t<Function>>{std::forward<Function>(function)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Function>
|
||||||
|
auto operator->*(scope_fail_tag, Function&& function) {
|
||||||
|
return scope_fail<std::decay_t<Function>>{std::forward<Function>(function)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Function>
|
||||||
|
auto operator->*(scope_success_tag, Function&& function) {
|
||||||
|
return scope_success<std::decay_t<Function>>{std::forward<Function>(function)};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl::detail
|
||||||
|
|
||||||
|
#define SCOPE_EXIT auto ANONYMOUS_VARIABLE(MCL_SCOPE_EXIT_VAR_) = ::mcl::detail::scope_exit_tag{}->*[&]() noexcept
|
||||||
|
#define SCOPE_FAIL auto ANONYMOUS_VARIABLE(MCL_SCOPE_FAIL_VAR_) = ::mcl::detail::scope_fail_tag{}->*[&]() noexcept
|
||||||
|
#define SCOPE_SUCCESS auto ANONYMOUS_VARIABLE(MCL_SCOPE_FAIL_VAR_) = ::mcl::detail::scope_success_tag{}->*[&]()
|
27
externals/dynarmic/externals/mcl/include/mcl/stdint.hpp
vendored
Executable file
27
externals/dynarmic/externals/mcl/include/mcl/stdint.hpp
vendored
Executable file
|
@ -0,0 +1,27 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
using u8 = std::uint8_t;
|
||||||
|
using u16 = std::uint16_t;
|
||||||
|
using u32 = std::uint32_t;
|
||||||
|
using u64 = std::uint64_t;
|
||||||
|
using uptr = std::uintptr_t;
|
||||||
|
|
||||||
|
using s8 = std::int8_t;
|
||||||
|
using s16 = std::int16_t;
|
||||||
|
using s32 = std::int32_t;
|
||||||
|
using s64 = std::int64_t;
|
||||||
|
using sptr = std::intptr_t;
|
||||||
|
|
||||||
|
using size_t = std::size_t;
|
||||||
|
|
||||||
|
using f32 = float;
|
||||||
|
using f64 = double;
|
||||||
|
static_assert(sizeof(f32) == sizeof(u32), "f32 must be 32 bits wide");
|
||||||
|
static_assert(sizeof(f64) == sizeof(u64), "f64 must be 64 bits wide");
|
70
externals/dynarmic/externals/mcl/include/mcl/type_traits/function_info.hpp
vendored
Executable file
70
externals/dynarmic/externals/mcl/include/mcl/type_traits/function_info.hpp
vendored
Executable file
|
@ -0,0 +1,70 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#include "mcl/mp/typelist/list.hpp"
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
struct function_info : function_info<decltype(&F::operator())> {};
|
||||||
|
|
||||||
|
template<class R, class... As>
|
||||||
|
struct function_info<R(As...)> {
|
||||||
|
using return_type = R;
|
||||||
|
using parameter_list = mp::list<As...>;
|
||||||
|
static constexpr std::size_t parameter_count = sizeof...(As);
|
||||||
|
|
||||||
|
using equivalent_function_type = R(As...);
|
||||||
|
|
||||||
|
template<std::size_t I>
|
||||||
|
struct parameter {
|
||||||
|
static_assert(I < parameter_count, "Non-existent parameter");
|
||||||
|
using type = std::tuple_element_t<I, std::tuple<As...>>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class R, class... As>
|
||||||
|
struct function_info<R (*)(As...)> : function_info<R(As...)> {};
|
||||||
|
|
||||||
|
template<class C, class R, class... As>
|
||||||
|
struct function_info<R (C::*)(As...)> : function_info<R(As...)> {
|
||||||
|
using class_type = C;
|
||||||
|
|
||||||
|
using equivalent_function_type_with_class = R(C*, As...);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class C, class R, class... As>
|
||||||
|
struct function_info<R (C::*)(As...) const> : function_info<R(As...)> {
|
||||||
|
using class_type = C;
|
||||||
|
|
||||||
|
using equivalent_function_type_with_class = R(C*, As...);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
constexpr size_t parameter_count_v = function_info<F>::parameter_count;
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
using parameter_list = typename function_info<F>::parameter_list;
|
||||||
|
|
||||||
|
template<class F, std::size_t I>
|
||||||
|
using get_parameter = typename function_info<F>::template parameter<I>::type;
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
using equivalent_function_type = typename function_info<F>::equivalent_function_type;
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
using equivalent_function_type_with_class = typename function_info<F>::equivalent_function_type_with_class;
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
using return_type = typename function_info<F>::return_type;
|
||||||
|
|
||||||
|
template<class F>
|
||||||
|
using class_type = typename function_info<F>::class_type;
|
||||||
|
|
||||||
|
} // namespace mcl
|
48
externals/dynarmic/externals/mcl/include/mcl/type_traits/integer_of_size.hpp
vendored
Executable file
48
externals/dynarmic/externals/mcl/include/mcl/type_traits/integer_of_size.hpp
vendored
Executable file
|
@ -0,0 +1,48 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/stdint.hpp"
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<size_t size>
|
||||||
|
struct integer_of_size_impl {};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct integer_of_size_impl<8> {
|
||||||
|
using unsigned_type = u8;
|
||||||
|
using signed_type = s8;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct integer_of_size_impl<16> {
|
||||||
|
using unsigned_type = u16;
|
||||||
|
using signed_type = s16;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct integer_of_size_impl<32> {
|
||||||
|
using unsigned_type = u32;
|
||||||
|
using signed_type = s32;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct integer_of_size_impl<64> {
|
||||||
|
using unsigned_type = u64;
|
||||||
|
using signed_type = s64;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template<size_t size>
|
||||||
|
using unsigned_integer_of_size = typename detail::integer_of_size_impl<size>::unsigned_type;
|
||||||
|
|
||||||
|
template<size_t size>
|
||||||
|
using signed_integer_of_size = typename detail::integer_of_size_impl<size>::signed_type;
|
||||||
|
|
||||||
|
} // namespace mcl
|
22
externals/dynarmic/externals/mcl/include/mcl/type_traits/is_instance_of_template.hpp
vendored
Executable file
22
externals/dynarmic/externals/mcl/include/mcl/type_traits/is_instance_of_template.hpp
vendored
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "mcl/mp/metavalue/value.hpp"
|
||||||
|
|
||||||
|
namespace mcl {
|
||||||
|
|
||||||
|
/// Is type T an instance of template class C?
|
||||||
|
template<template<class...> class, class>
|
||||||
|
struct is_instance_of_template : mp::false_type {};
|
||||||
|
|
||||||
|
template<template<class...> class C, class... As>
|
||||||
|
struct is_instance_of_template<C, C<As...>> : mp::true_type {};
|
||||||
|
|
||||||
|
/// Is type T an instance of template class C?
|
||||||
|
template<template<class...> class C, class T>
|
||||||
|
constexpr bool is_instance_of_template_v = is_instance_of_template<C, T>::value;
|
||||||
|
|
||||||
|
} // namespace mcl
|
69
externals/dynarmic/externals/mcl/src/CMakeLists.txt
vendored
Executable file
69
externals/dynarmic/externals/mcl/src/CMakeLists.txt
vendored
Executable file
|
@ -0,0 +1,69 @@
|
||||||
|
add_library(mcl
|
||||||
|
../include/mcl/assert.hpp
|
||||||
|
../include/mcl/bit/bit_count.hpp
|
||||||
|
../include/mcl/bit/bit_field.hpp
|
||||||
|
../include/mcl/bit/rotate.hpp
|
||||||
|
../include/mcl/bit/swap.hpp
|
||||||
|
../include/mcl/bit_cast.hpp
|
||||||
|
../include/mcl/bitsizeof.hpp
|
||||||
|
../include/mcl/concepts/bit_integral.hpp
|
||||||
|
../include/mcl/concepts/is_any_of.hpp
|
||||||
|
../include/mcl/concepts/same_as.hpp
|
||||||
|
../include/mcl/container/intrusive_list.hpp
|
||||||
|
../include/mcl/hint/assume.hpp
|
||||||
|
../include/mcl/iterator/reverse.hpp
|
||||||
|
../include/mcl/macro/anonymous_variable.hpp
|
||||||
|
../include/mcl/macro/architecture.hpp
|
||||||
|
../include/mcl/macro/concatenate_tokens.hpp
|
||||||
|
../include/mcl/mp/metafunction/apply.hpp
|
||||||
|
../include/mcl/mp/metafunction/bind.hpp
|
||||||
|
../include/mcl/mp/metafunction/identity.hpp
|
||||||
|
../include/mcl/mp/metafunction/map.hpp
|
||||||
|
../include/mcl/mp/metavalue/bit_and.hpp
|
||||||
|
../include/mcl/mp/metavalue/bit_not.hpp
|
||||||
|
../include/mcl/mp/metavalue/bit_or.hpp
|
||||||
|
../include/mcl/mp/metavalue/bit_xor.hpp
|
||||||
|
../include/mcl/mp/metavalue/conjunction.hpp
|
||||||
|
../include/mcl/mp/metavalue/disjunction.hpp
|
||||||
|
../include/mcl/mp/metavalue/lift_value.hpp
|
||||||
|
../include/mcl/mp/metavalue/logic_and.hpp
|
||||||
|
../include/mcl/mp/metavalue/logic_if.hpp
|
||||||
|
../include/mcl/mp/metavalue/logic_not.hpp
|
||||||
|
../include/mcl/mp/metavalue/logic_or.hpp
|
||||||
|
../include/mcl/mp/metavalue/product.hpp
|
||||||
|
../include/mcl/mp/metavalue/sum.hpp
|
||||||
|
../include/mcl/mp/metavalue/value.hpp
|
||||||
|
../include/mcl/mp/metavalue/value_cast.hpp
|
||||||
|
../include/mcl/mp/metavalue/value_equal.hpp
|
||||||
|
../include/mcl/mp/misc/argument_count.hpp
|
||||||
|
../include/mcl/mp/typelist/append.hpp
|
||||||
|
../include/mcl/mp/typelist/cartesian_product.hpp
|
||||||
|
../include/mcl/mp/typelist/concat.hpp
|
||||||
|
../include/mcl/mp/typelist/contains.hpp
|
||||||
|
../include/mcl/mp/typelist/drop.hpp
|
||||||
|
../include/mcl/mp/typelist/get.hpp
|
||||||
|
../include/mcl/mp/typelist/head.hpp
|
||||||
|
../include/mcl/mp/typelist/length.hpp
|
||||||
|
../include/mcl/mp/typelist/lift_sequence.hpp
|
||||||
|
../include/mcl/mp/typelist/list.hpp
|
||||||
|
../include/mcl/mp/typelist/lower_to_tuple.hpp
|
||||||
|
../include/mcl/mp/typelist/prepend.hpp
|
||||||
|
../include/mcl/mp/typelist/tail.hpp
|
||||||
|
../include/mcl/scope_exit.hpp
|
||||||
|
../include/mcl/stdint.hpp
|
||||||
|
../include/mcl/type_traits/function_info.hpp
|
||||||
|
../include/mcl/type_traits/integer_of_size.hpp
|
||||||
|
../include/mcl/type_traits/is_instance_of_template.hpp
|
||||||
|
assert.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(mcl
|
||||||
|
PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||||
|
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||||
|
)
|
||||||
|
target_compile_options(mcl PRIVATE ${MCL_CXX_FLAGS})
|
||||||
|
target_link_libraries(mcl PUBLIC $<BUILD_INTERFACE:fmt::fmt>)
|
||||||
|
add_library(merry::mcl ALIAS mcl)
|
||||||
|
|
||||||
|
include(CreateTargetDirectoryGroups)
|
||||||
|
create_target_directory_groups(mcl)
|
20
externals/dynarmic/externals/mcl/src/assert.cpp
vendored
Executable file
20
externals/dynarmic/externals/mcl/src/assert.cpp
vendored
Executable file
|
@ -0,0 +1,20 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include "mcl/assert.hpp"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
namespace mcl::detail {
|
||||||
|
|
||||||
|
[[noreturn]] void assert_terminate_impl(fmt::string_view msg, fmt::format_args args) {
|
||||||
|
fmt::print(stderr, "assertion failed: ");
|
||||||
|
fmt::vprint(stderr, msg, args);
|
||||||
|
std::terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mcl::detail
|
15
externals/dynarmic/externals/mcl/tests/CMakeLists.txt
vendored
Executable file
15
externals/dynarmic/externals/mcl/tests/CMakeLists.txt
vendored
Executable file
|
@ -0,0 +1,15 @@
|
||||||
|
add_executable(mcl-tests
|
||||||
|
bit/bit_field_tests.cpp
|
||||||
|
main.cpp
|
||||||
|
mp/metavalue_tests.cpp
|
||||||
|
mp/typelist_tests.cpp
|
||||||
|
type_traits/type_traits_tests.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(mcl-tests PUBLIC .)
|
||||||
|
target_compile_options(mcl-tests PRIVATE ${STAMINA_CXX_FLAGS})
|
||||||
|
target_link_libraries(mcl-tests PRIVATE Catch2::Catch2 mcl)
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
include(Catch)
|
||||||
|
catch_discover_tests(mcl-tests)
|
||||||
|
enable_testing()
|
41
externals/dynarmic/externals/mcl/tests/bit/bit_field_tests.cpp
vendored
Executable file
41
externals/dynarmic/externals/mcl/tests/bit/bit_field_tests.cpp
vendored
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
#include <mcl/bit/bit_field.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("mcl::bit::ones", "[bit]") {
|
||||||
|
const std::array cases{
|
||||||
|
std::make_tuple<size_t, u8>(0, 0x00),
|
||||||
|
std::make_tuple<size_t, u8>(1, 0x01),
|
||||||
|
std::make_tuple<size_t, u8>(2, 0x03),
|
||||||
|
std::make_tuple<size_t, u8>(3, 0x07),
|
||||||
|
std::make_tuple<size_t, u8>(4, 0x0f),
|
||||||
|
std::make_tuple<size_t, u8>(5, 0x1f),
|
||||||
|
std::make_tuple<size_t, u8>(6, 0x3f),
|
||||||
|
std::make_tuple<size_t, u8>(7, 0x7f),
|
||||||
|
std::make_tuple<size_t, u8>(8, 0xff),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto [count, expected] : cases) {
|
||||||
|
REQUIRE(mcl::bit::ones<u8>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<u16>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<u32>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<u64>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<uptr>(count) == expected);
|
||||||
|
REQUIRE(mcl::bit::ones<size_t>(count) == expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(mcl::bit::ones<3, u8>() == 0x7);
|
||||||
|
static_assert(mcl::bit::ones<15, u16>() == 0x7fff);
|
||||||
|
static_assert(mcl::bit::ones<16, u16>() == 0xffff);
|
||||||
|
static_assert(mcl::bit::ones<31, u32>() == 0x7fff'ffff);
|
||||||
|
static_assert(mcl::bit::ones<32, u32>() == 0xffff'ffff);
|
||||||
|
static_assert(mcl::bit::ones<63, u64>() == 0x7fff'ffff'ffff'ffff);
|
||||||
|
static_assert(mcl::bit::ones<64, u64>() == 0xffff'ffff'ffff'ffff);
|
6
externals/dynarmic/externals/mcl/tests/main.cpp
vendored
Executable file
6
externals/dynarmic/externals/mcl/tests/main.cpp
vendored
Executable file
|
@ -0,0 +1,6 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#define CATCH_CONFIG_MAIN
|
||||||
|
#include "catch2/catch.hpp"
|
90
externals/dynarmic/externals/mcl/tests/mp/metavalue_tests.cpp
vendored
Executable file
90
externals/dynarmic/externals/mcl/tests/mp/metavalue_tests.cpp
vendored
Executable file
|
@ -0,0 +1,90 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <mcl/mp/metavalue/bit_and.hpp>
|
||||||
|
#include <mcl/mp/metavalue/bit_not.hpp>
|
||||||
|
#include <mcl/mp/metavalue/bit_or.hpp>
|
||||||
|
#include <mcl/mp/metavalue/bit_xor.hpp>
|
||||||
|
#include <mcl/mp/metavalue/conjunction.hpp>
|
||||||
|
#include <mcl/mp/metavalue/disjunction.hpp>
|
||||||
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
|
#include <mcl/mp/metavalue/logic_and.hpp>
|
||||||
|
#include <mcl/mp/metavalue/logic_not.hpp>
|
||||||
|
#include <mcl/mp/metavalue/logic_or.hpp>
|
||||||
|
#include <mcl/mp/metavalue/product.hpp>
|
||||||
|
#include <mcl/mp/metavalue/sum.hpp>
|
||||||
|
#include <mcl/mp/metavalue/value.hpp>
|
||||||
|
#include <mcl/mp/metavalue/value_cast.hpp>
|
||||||
|
#include <mcl/mp/metavalue/value_equal.hpp>
|
||||||
|
|
||||||
|
using namespace mcl::mp;
|
||||||
|
|
||||||
|
// bit_and
|
||||||
|
|
||||||
|
static_assert(bit_and<lift_value<3>, lift_value<1>>::value == 1);
|
||||||
|
|
||||||
|
// bit_not
|
||||||
|
|
||||||
|
static_assert(bit_not<lift_value<0>>::value == ~0);
|
||||||
|
|
||||||
|
// bit_or
|
||||||
|
|
||||||
|
static_assert(bit_or<lift_value<1>, lift_value<3>>::value == 3);
|
||||||
|
|
||||||
|
// bit_xor
|
||||||
|
|
||||||
|
static_assert(bit_xor<lift_value<1>, lift_value<3>>::value == 2);
|
||||||
|
|
||||||
|
// conjunction
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<conjunction<std::true_type>, std::true_type>);
|
||||||
|
static_assert(std::is_same_v<conjunction<std::true_type, lift_value<0>>, lift_value<0>>);
|
||||||
|
static_assert(std::is_same_v<conjunction<std::true_type, lift_value<42>, std::true_type>, std::true_type>);
|
||||||
|
|
||||||
|
// disjunction
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<disjunction<std::true_type>, std::true_type>);
|
||||||
|
static_assert(std::is_same_v<disjunction<std::false_type, lift_value<0>>, lift_value<0>>);
|
||||||
|
static_assert(std::is_same_v<disjunction<std::false_type, lift_value<42>, std::true_type>, lift_value<42>>);
|
||||||
|
|
||||||
|
// lift_value
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<lift_value<3>, std::integral_constant<int, 3>>);
|
||||||
|
static_assert(std::is_same_v<lift_value<false>, std::false_type>);
|
||||||
|
|
||||||
|
// logic_and
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<logic_and<>, std::true_type>);
|
||||||
|
static_assert(std::is_same_v<logic_and<std::true_type>, std::true_type>);
|
||||||
|
static_assert(std::is_same_v<logic_and<lift_value<1>>, std::true_type>);
|
||||||
|
static_assert(std::is_same_v<logic_and<std::true_type, std::false_type>, std::false_type>);
|
||||||
|
|
||||||
|
// logic_not
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<logic_not<std::false_type>, std::true_type>);
|
||||||
|
|
||||||
|
// logic_or
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<logic_or<>, std::false_type>);
|
||||||
|
static_assert(std::is_same_v<logic_or<std::true_type>, std::true_type>);
|
||||||
|
static_assert(std::is_same_v<logic_or<lift_value<0>>, std::false_type>);
|
||||||
|
static_assert(std::is_same_v<logic_or<std::true_type, std::false_type>, std::true_type>);
|
||||||
|
|
||||||
|
// product
|
||||||
|
|
||||||
|
static_assert(product<lift_value<1>, lift_value<2>, lift_value<3>, lift_value<4>>::value == 24);
|
||||||
|
|
||||||
|
// sum
|
||||||
|
|
||||||
|
static_assert(sum<lift_value<1>, lift_value<2>, lift_value<3>, lift_value<4>>::value == 10);
|
||||||
|
|
||||||
|
// value_cast
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<value_cast<int, std::true_type>, std::integral_constant<int, 1>>);
|
||||||
|
|
||||||
|
// value_equal
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<value_equal<std::true_type, std::integral_constant<int, 1>>, std::true_type>);
|
104
externals/dynarmic/externals/mcl/tests/mp/typelist_tests.cpp
vendored
Executable file
104
externals/dynarmic/externals/mcl/tests/mp/typelist_tests.cpp
vendored
Executable file
|
@ -0,0 +1,104 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <mcl/mp/metavalue/value.hpp>
|
||||||
|
#include <mcl/mp/typelist/append.hpp>
|
||||||
|
#include <mcl/mp/typelist/cartesian_product.hpp>
|
||||||
|
#include <mcl/mp/typelist/concat.hpp>
|
||||||
|
#include <mcl/mp/typelist/contains.hpp>
|
||||||
|
#include <mcl/mp/typelist/drop.hpp>
|
||||||
|
#include <mcl/mp/typelist/get.hpp>
|
||||||
|
#include <mcl/mp/typelist/head.hpp>
|
||||||
|
#include <mcl/mp/typelist/length.hpp>
|
||||||
|
#include <mcl/mp/typelist/lift_sequence.hpp>
|
||||||
|
#include <mcl/mp/typelist/list.hpp>
|
||||||
|
#include <mcl/mp/typelist/lower_to_tuple.hpp>
|
||||||
|
#include <mcl/mp/typelist/prepend.hpp>
|
||||||
|
#include <mcl/mp/typelist/tail.hpp>
|
||||||
|
|
||||||
|
using namespace mcl::mp;
|
||||||
|
|
||||||
|
// append
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<append<list<int, bool>, double>, list<int, bool, double>>);
|
||||||
|
static_assert(std::is_same_v<append<list<>, int, int>, list<int, int>>);
|
||||||
|
|
||||||
|
// cartesian_product
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same_v<
|
||||||
|
cartesian_product<list<int, bool>, list<double, float>, list<char, unsigned>>,
|
||||||
|
list<
|
||||||
|
list<int, double, char>,
|
||||||
|
list<int, double, unsigned>,
|
||||||
|
list<int, float, char>,
|
||||||
|
list<int, float, unsigned>,
|
||||||
|
list<bool, double, char>,
|
||||||
|
list<bool, double, unsigned>,
|
||||||
|
list<bool, float, char>,
|
||||||
|
list<bool, float, unsigned>>>);
|
||||||
|
|
||||||
|
// concat
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<concat<list<int, bool>, list<double>>, list<int, bool, double>>);
|
||||||
|
static_assert(std::is_same_v<concat<list<>, list<int>, list<int>>, list<int, int>>);
|
||||||
|
|
||||||
|
// contains
|
||||||
|
|
||||||
|
static_assert(contains_v<list<int>, int>);
|
||||||
|
static_assert(!contains_v<list<>, int>);
|
||||||
|
static_assert(!contains_v<list<double>, int>);
|
||||||
|
static_assert(contains_v<list<double, int>, int>);
|
||||||
|
|
||||||
|
// drop
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<list<>, drop<3, list<int, int>>>);
|
||||||
|
static_assert(std::is_same_v<list<>, drop<3, list<int, int, int>>>);
|
||||||
|
static_assert(std::is_same_v<list<int>, drop<3, list<int, int, int, int>>>);
|
||||||
|
static_assert(std::is_same_v<list<double>, drop<3, list<int, int, int, double>>>);
|
||||||
|
static_assert(std::is_same_v<list<int, double, bool>, drop<0, list<int, double, bool>>>);
|
||||||
|
|
||||||
|
// get
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<get<0, list<int, double>>, int>);
|
||||||
|
static_assert(std::is_same_v<get<1, list<int, double>>, double>);
|
||||||
|
|
||||||
|
// head
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<head<list<int, double>>, int>);
|
||||||
|
static_assert(std::is_same_v<head<list<int>>, int>);
|
||||||
|
|
||||||
|
// length
|
||||||
|
|
||||||
|
static_assert(length_v<list<>> == 0);
|
||||||
|
static_assert(length_v<list<int>> == 1);
|
||||||
|
static_assert(length_v<list<int, int, int>> == 3);
|
||||||
|
|
||||||
|
// lift_sequence
|
||||||
|
|
||||||
|
static_assert(
|
||||||
|
std::is_same_v<
|
||||||
|
lift_sequence<std::make_index_sequence<3>>,
|
||||||
|
list<size_value<0>, size_value<1>, size_value<2>>>);
|
||||||
|
|
||||||
|
// lower_to_tuple
|
||||||
|
|
||||||
|
static_assert(lower_to_tuple_v<list<size_value<0>, size_value<1>, size_value<2>>> == std::tuple<std::size_t, std::size_t, std::size_t>(0, 1, 2));
|
||||||
|
static_assert(lower_to_tuple_v<list<std::true_type, std::false_type>> == std::make_tuple(true, false));
|
||||||
|
|
||||||
|
// prepend
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<prepend<list<int, int>, double>, list<double, int, int>>);
|
||||||
|
static_assert(std::is_same_v<prepend<list<>, double>, list<double>>);
|
||||||
|
static_assert(std::is_same_v<prepend<list<int>, double, bool>, list<double, bool, int>>);
|
||||||
|
|
||||||
|
// tail
|
||||||
|
|
||||||
|
static_assert(std::is_same_v<tail<list<int, double>>, list<double>>);
|
||||||
|
static_assert(std::is_same_v<tail<list<int>>, list<>>);
|
39
externals/dynarmic/externals/mcl/tests/type_traits/type_traits_tests.cpp
vendored
Executable file
39
externals/dynarmic/externals/mcl/tests/type_traits/type_traits_tests.cpp
vendored
Executable file
|
@ -0,0 +1,39 @@
|
||||||
|
// This file is part of the mcl project.
|
||||||
|
// Copyright (c) 2022 merryhime
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
|
#include <mcl/type_traits/is_instance_of_template.hpp>
|
||||||
|
|
||||||
|
using namespace mcl;
|
||||||
|
|
||||||
|
// function_info
|
||||||
|
|
||||||
|
struct Bar {
|
||||||
|
int frob(double a) { return a; }
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(parameter_count_v<void()> == 0);
|
||||||
|
static_assert(parameter_count_v<void(int, int, int)> == 3);
|
||||||
|
static_assert(std::is_same_v<get_parameter<void (*)(bool, int, double), 2>, double>);
|
||||||
|
static_assert(std::is_same_v<equivalent_function_type<void (*)(bool, int, double)>, void(bool, int, double)>);
|
||||||
|
static_assert(std::is_same_v<return_type<void (*)(bool, int, double)>, void>);
|
||||||
|
static_assert(std::is_same_v<equivalent_function_type<decltype(&Bar::frob)>, int(double)>);
|
||||||
|
static_assert(std::is_same_v<class_type<decltype(&Bar::frob)>, Bar>);
|
||||||
|
|
||||||
|
// is_instance_of_template
|
||||||
|
|
||||||
|
template<class, class...>
|
||||||
|
class Foo {};
|
||||||
|
|
||||||
|
template<class, class>
|
||||||
|
class Pair {};
|
||||||
|
|
||||||
|
static_assert(is_instance_of_template_v<std::tuple, std::tuple<int, bool>>);
|
||||||
|
static_assert(!is_instance_of_template_v<std::tuple, bool>);
|
||||||
|
static_assert(is_instance_of_template_v<Foo, Foo<bool>>);
|
||||||
|
static_assert(is_instance_of_template_v<Pair, Pair<bool, int>>);
|
||||||
|
static_assert(!is_instance_of_template_v<Pair, Foo<bool, int>>);
|
13
externals/dynarmic/src/dynarmic/CMakeLists.txt
vendored
13
externals/dynarmic/src/dynarmic/CMakeLists.txt
vendored
|
@ -1,9 +1,5 @@
|
||||||
add_library(dynarmic
|
add_library(dynarmic
|
||||||
common/assert.cpp
|
|
||||||
common/assert.h
|
|
||||||
common/bit_util.h
|
|
||||||
common/cast_util.h
|
common/cast_util.h
|
||||||
common/common_types.h
|
|
||||||
common/crypto/aes.cpp
|
common/crypto/aes.cpp
|
||||||
common/crypto/aes.h
|
common/crypto/aes.h
|
||||||
common/crypto/crc32.cpp
|
common/crypto/crc32.cpp
|
||||||
|
@ -46,18 +42,14 @@ add_library(dynarmic
|
||||||
common/fp/unpacked.cpp
|
common/fp/unpacked.cpp
|
||||||
common/fp/unpacked.h
|
common/fp/unpacked.h
|
||||||
common/fp/util.h
|
common/fp/util.h
|
||||||
common/intrusive_list.h
|
|
||||||
common/iterator_util.h
|
|
||||||
common/llvm_disassemble.cpp
|
common/llvm_disassemble.cpp
|
||||||
common/llvm_disassemble.h
|
common/llvm_disassemble.h
|
||||||
common/lut_from_list.h
|
common/lut_from_list.h
|
||||||
common/macro_util.h
|
|
||||||
common/math_util.cpp
|
common/math_util.cpp
|
||||||
common/math_util.h
|
common/math_util.h
|
||||||
common/memory_pool.cpp
|
common/memory_pool.cpp
|
||||||
common/memory_pool.h
|
common/memory_pool.h
|
||||||
common/safe_ops.h
|
common/safe_ops.h
|
||||||
common/scope_exit.h
|
|
||||||
common/spin_lock.h
|
common/spin_lock.h
|
||||||
common/string_util.h
|
common/string_util.h
|
||||||
common/u128.cpp
|
common/u128.cpp
|
||||||
|
@ -385,10 +377,11 @@ set_target_properties(dynarmic PROPERTIES
|
||||||
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
target_compile_options(dynarmic PRIVATE ${DYNARMIC_CXX_FLAGS})
|
||||||
# $<BUILD_INTERFACE:> required because of https://gitlab.kitware.com/cmake/cmake/-/issues/15415
|
# $<BUILD_INTERFACE:> required because of https://gitlab.kitware.com/cmake/cmake/-/issues/15415
|
||||||
target_link_libraries(dynarmic
|
target_link_libraries(dynarmic
|
||||||
|
PUBLIC
|
||||||
|
$<BUILD_INTERFACE:merry::mcl>
|
||||||
PRIVATE
|
PRIVATE
|
||||||
$<BUILD_INTERFACE:boost>
|
$<BUILD_INTERFACE:boost>
|
||||||
$<BUILD_INTERFACE:fmt::fmt>
|
$<BUILD_INTERFACE:fmt::fmt>
|
||||||
$<BUILD_INTERFACE:mp>
|
|
||||||
tsl::robin_map
|
tsl::robin_map
|
||||||
$<BUILD_INTERFACE:xbyak>
|
$<BUILD_INTERFACE:xbyak>
|
||||||
$<BUILD_INTERFACE:Zydis>
|
$<BUILD_INTERFACE:Zydis>
|
||||||
|
@ -401,7 +394,7 @@ if (DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT)
|
||||||
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
|
target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
|
||||||
endif()
|
endif()
|
||||||
if (DYNARMIC_IGNORE_ASSERTS)
|
if (DYNARMIC_IGNORE_ASSERTS)
|
||||||
target_compile_definitions(dynarmic PRIVATE DYNARMIC_IGNORE_ASSERTS=1)
|
target_compile_definitions(dynarmic PRIVATE MCL_IGNORE_ASSERTS=1)
|
||||||
endif()
|
endif()
|
||||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||||
target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)
|
target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)
|
||||||
|
|
|
@ -11,6 +11,10 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
|
#include <mcl/assert.hpp>
|
||||||
|
#include <mcl/bit/bit_field.hpp>
|
||||||
|
#include <mcl/scope_exit.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||||
#include "dynarmic/backend/x64/abi.h"
|
#include "dynarmic/backend/x64/abi.h"
|
||||||
|
@ -20,10 +24,6 @@
|
||||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||||
#include "dynarmic/backend/x64/perf_map.h"
|
#include "dynarmic/backend/x64/perf_map.h"
|
||||||
#include "dynarmic/backend/x64/stack_layout.h"
|
#include "dynarmic/backend/x64/stack_layout.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/bit_util.h"
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/common/scope_exit.h"
|
|
||||||
#include "dynarmic/common/variant_util.h"
|
#include "dynarmic/common/variant_util.h"
|
||||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||||
#include "dynarmic/frontend/A32/a32_types.h"
|
#include "dynarmic/frontend/A32/a32_types.h"
|
||||||
|
@ -626,10 +626,10 @@ void A32EmitX64::EmitA32SetGEFlagsCompressed(A32EmitContext& ctx, IR::Inst* inst
|
||||||
if (args[0].IsImmediate()) {
|
if (args[0].IsImmediate()) {
|
||||||
const u32 imm = args[0].GetImmediateU32();
|
const u32 imm = args[0].GetImmediateU32();
|
||||||
u32 ge = 0;
|
u32 ge = 0;
|
||||||
ge |= Common::Bit<19>(imm) ? 0xFF000000 : 0;
|
ge |= mcl::bit::get_bit<19>(imm) ? 0xFF000000 : 0;
|
||||||
ge |= Common::Bit<18>(imm) ? 0x00FF0000 : 0;
|
ge |= mcl::bit::get_bit<18>(imm) ? 0x00FF0000 : 0;
|
||||||
ge |= Common::Bit<17>(imm) ? 0x0000FF00 : 0;
|
ge |= mcl::bit::get_bit<17>(imm) ? 0x0000FF00 : 0;
|
||||||
ge |= Common::Bit<16>(imm) ? 0x000000FF : 0;
|
ge |= mcl::bit::get_bit<16>(imm) ? 0x000000FF : 0;
|
||||||
|
|
||||||
code.mov(dword[r15 + offsetof(A32JitState, cpsr_ge)], ge);
|
code.mov(dword[r15 + offsetof(A32JitState, cpsr_ge)], ge);
|
||||||
} else if (code.HasHostFeature(HostFeature::FastBMI2)) {
|
} else if (code.HasHostFeature(HostFeature::FastBMI2)) {
|
||||||
|
@ -689,8 +689,8 @@ void A32EmitX64::EmitA32BXWritePC(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
if (arg.IsImmediate()) {
|
if (arg.IsImmediate()) {
|
||||||
const u32 new_pc = arg.GetImmediateU32();
|
const u32 new_pc = arg.GetImmediateU32();
|
||||||
const u32 mask = Common::Bit<0>(new_pc) ? 0xFFFFFFFE : 0xFFFFFFFC;
|
const u32 mask = mcl::bit::get_bit<0>(new_pc) ? 0xFFFFFFFE : 0xFFFFFFFC;
|
||||||
const u32 new_upper = upper_without_t | (Common::Bit<0>(new_pc) ? 1 : 0);
|
const u32 new_upper = upper_without_t | (mcl::bit::get_bit<0>(new_pc) ? 1 : 0);
|
||||||
|
|
||||||
code.mov(MJitStateReg(A32::Reg::PC), new_pc & mask);
|
code.mov(MJitStateReg(A32::Reg::PC), new_pc & mask);
|
||||||
code.mov(dword[r15 + offsetof(A32JitState, upper_location_descriptor)], new_upper);
|
code.mov(dword[r15 + offsetof(A32JitState, upper_location_descriptor)], new_upper);
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
||||||
|
|
|
@ -8,6 +8,10 @@
|
||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
|
#include <mcl/assert.hpp>
|
||||||
|
#include <mcl/bit_cast.hpp>
|
||||||
|
#include <mcl/scope_exit.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
#include "dynarmic/backend/x64/a32_emit_x64.h"
|
||||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||||
|
@ -15,11 +19,7 @@
|
||||||
#include "dynarmic/backend/x64/callback.h"
|
#include "dynarmic/backend/x64/callback.h"
|
||||||
#include "dynarmic/backend/x64/devirtualize.h"
|
#include "dynarmic/backend/x64/devirtualize.h"
|
||||||
#include "dynarmic/backend/x64/jitstate_info.h"
|
#include "dynarmic/backend/x64/jitstate_info.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/atomic.h"
|
#include "dynarmic/common/atomic.h"
|
||||||
#include "dynarmic/common/cast_util.h"
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/common/scope_exit.h"
|
|
||||||
#include "dynarmic/common/x64_disassemble.h"
|
#include "dynarmic/common/x64_disassemble.h"
|
||||||
#include "dynarmic/frontend/A32/translate/a32_translate.h"
|
#include "dynarmic/frontend/A32/translate/a32_translate.h"
|
||||||
#include "dynarmic/interface/A32/a32.h"
|
#include "dynarmic/interface/A32/a32.h"
|
||||||
|
@ -44,10 +44,10 @@ static RunCodeCallbacks GenRunCodeCallbacks(A32::UserCallbacks* cb, CodePtr (*Lo
|
||||||
static std::function<void(BlockOfCode&)> GenRCP(const A32::UserConfig& conf) {
|
static std::function<void(BlockOfCode&)> GenRCP(const A32::UserConfig& conf) {
|
||||||
return [conf](BlockOfCode& code) {
|
return [conf](BlockOfCode& code) {
|
||||||
if (conf.page_table) {
|
if (conf.page_table) {
|
||||||
code.mov(code.r14, Common::BitCast<u64>(conf.page_table));
|
code.mov(code.r14, mcl::bit_cast<u64>(conf.page_table));
|
||||||
}
|
}
|
||||||
if (conf.fastmem_pointer) {
|
if (conf.fastmem_pointer) {
|
||||||
code.mov(code.r13, Common::BitCast<u64>(conf.fastmem_pointer));
|
code.mov(code.r13, mcl::bit_cast<u64>(conf.fastmem_pointer));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,12 @@
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||||
|
|
||||||
|
#include <mcl/assert.hpp>
|
||||||
|
#include <mcl/bit/bit_field.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/bit_util.h"
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
#include "dynarmic/frontend/A32/a32_location_descriptor.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
@ -57,13 +58,13 @@ u32 A32JitState::Cpsr() const {
|
||||||
// Q flag
|
// Q flag
|
||||||
cpsr |= cpsr_q ? 1 << 27 : 0;
|
cpsr |= cpsr_q ? 1 << 27 : 0;
|
||||||
// GE flags
|
// GE flags
|
||||||
cpsr |= Common::Bit<31>(cpsr_ge) ? 1 << 19 : 0;
|
cpsr |= mcl::bit::get_bit<31>(cpsr_ge) ? 1 << 19 : 0;
|
||||||
cpsr |= Common::Bit<23>(cpsr_ge) ? 1 << 18 : 0;
|
cpsr |= mcl::bit::get_bit<23>(cpsr_ge) ? 1 << 18 : 0;
|
||||||
cpsr |= Common::Bit<15>(cpsr_ge) ? 1 << 17 : 0;
|
cpsr |= mcl::bit::get_bit<15>(cpsr_ge) ? 1 << 17 : 0;
|
||||||
cpsr |= Common::Bit<7>(cpsr_ge) ? 1 << 16 : 0;
|
cpsr |= mcl::bit::get_bit<7>(cpsr_ge) ? 1 << 16 : 0;
|
||||||
// E flag, T flag
|
// E flag, T flag
|
||||||
cpsr |= Common::Bit<1>(upper_location_descriptor) ? 1 << 9 : 0;
|
cpsr |= mcl::bit::get_bit<1>(upper_location_descriptor) ? 1 << 9 : 0;
|
||||||
cpsr |= Common::Bit<0>(upper_location_descriptor) ? 1 << 5 : 0;
|
cpsr |= mcl::bit::get_bit<0>(upper_location_descriptor) ? 1 << 5 : 0;
|
||||||
// IT state
|
// IT state
|
||||||
cpsr |= static_cast<u32>(upper_location_descriptor & 0b11111100'00000000);
|
cpsr |= static_cast<u32>(upper_location_descriptor & 0b11111100'00000000);
|
||||||
cpsr |= static_cast<u32>(upper_location_descriptor & 0b00000011'00000000) << 17;
|
cpsr |= static_cast<u32>(upper_location_descriptor & 0b00000011'00000000) << 17;
|
||||||
|
@ -77,18 +78,18 @@ void A32JitState::SetCpsr(u32 cpsr) {
|
||||||
// NZCV flags
|
// NZCV flags
|
||||||
cpsr_nzcv = NZCV::ToX64(cpsr);
|
cpsr_nzcv = NZCV::ToX64(cpsr);
|
||||||
// Q flag
|
// Q flag
|
||||||
cpsr_q = Common::Bit<27>(cpsr) ? 1 : 0;
|
cpsr_q = mcl::bit::get_bit<27>(cpsr) ? 1 : 0;
|
||||||
// GE flags
|
// GE flags
|
||||||
cpsr_ge = 0;
|
cpsr_ge = 0;
|
||||||
cpsr_ge |= Common::Bit<19>(cpsr) ? 0xFF000000 : 0;
|
cpsr_ge |= mcl::bit::get_bit<19>(cpsr) ? 0xFF000000 : 0;
|
||||||
cpsr_ge |= Common::Bit<18>(cpsr) ? 0x00FF0000 : 0;
|
cpsr_ge |= mcl::bit::get_bit<18>(cpsr) ? 0x00FF0000 : 0;
|
||||||
cpsr_ge |= Common::Bit<17>(cpsr) ? 0x0000FF00 : 0;
|
cpsr_ge |= mcl::bit::get_bit<17>(cpsr) ? 0x0000FF00 : 0;
|
||||||
cpsr_ge |= Common::Bit<16>(cpsr) ? 0x000000FF : 0;
|
cpsr_ge |= mcl::bit::get_bit<16>(cpsr) ? 0x000000FF : 0;
|
||||||
|
|
||||||
upper_location_descriptor &= 0xFFFF0000;
|
upper_location_descriptor &= 0xFFFF0000;
|
||||||
// E flag, T flag
|
// E flag, T flag
|
||||||
upper_location_descriptor |= Common::Bit<9>(cpsr) ? 2 : 0;
|
upper_location_descriptor |= mcl::bit::get_bit<9>(cpsr) ? 2 : 0;
|
||||||
upper_location_descriptor |= Common::Bit<5>(cpsr) ? 1 : 0;
|
upper_location_descriptor |= mcl::bit::get_bit<5>(cpsr) ? 1 : 0;
|
||||||
// IT state
|
// IT state
|
||||||
upper_location_descriptor |= (cpsr >> 0) & 0b11111100'00000000;
|
upper_location_descriptor |= (cpsr >> 0) & 0b11111100'00000000;
|
||||||
upper_location_descriptor |= (cpsr >> 17) & 0b00000011'00000000;
|
upper_location_descriptor |= (cpsr >> 17) & 0b00000011'00000000;
|
||||||
|
@ -197,7 +198,7 @@ void A32JitState::SetFpscr(u32 FPSCR) {
|
||||||
// Cumulative flags IDC, IOC, IXC, UFC, OFC, DZC
|
// Cumulative flags IDC, IOC, IXC, UFC, OFC, DZC
|
||||||
fpsr_exc = FPSCR & 0x9F;
|
fpsr_exc = FPSCR & 0x9F;
|
||||||
|
|
||||||
if (Common::Bit<24>(FPSCR)) {
|
if (mcl::bit::get_bit<24>(FPSCR)) {
|
||||||
// VFP Flush to Zero
|
// VFP Flush to Zero
|
||||||
guest_MXCSR |= (1 << 15); // SSE Flush to Zero
|
guest_MXCSR |= (1 << 15); // SSE Flush to Zero
|
||||||
guest_MXCSR |= (1 << 6); // SSE Denormals are Zero
|
guest_MXCSR |= (1 << 6); // SSE Denormals are Zero
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,10 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/assert.hpp>
|
||||||
|
#include <mcl/scope_exit.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a64_jitstate.h"
|
#include "dynarmic/backend/x64/a64_jitstate.h"
|
||||||
#include "dynarmic/backend/x64/abi.h"
|
#include "dynarmic/backend/x64/abi.h"
|
||||||
|
@ -17,10 +20,6 @@
|
||||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||||
#include "dynarmic/backend/x64/perf_map.h"
|
#include "dynarmic/backend/x64/perf_map.h"
|
||||||
#include "dynarmic/backend/x64/stack_layout.h"
|
#include "dynarmic/backend/x64/stack_layout.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/bit_util.h"
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/common/scope_exit.h"
|
|
||||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||||
#include "dynarmic/frontend/A64/a64_types.h"
|
#include "dynarmic/frontend/A64/a64_types.h"
|
||||||
#include "dynarmic/ir/basic_block.h"
|
#include "dynarmic/ir/basic_block.h"
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <fmt/ostream.h>
|
#include <fmt/ostream.h>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a64_emit_x64.h"
|
#include "dynarmic/backend/x64/a64_emit_x64.h"
|
||||||
|
|
|
@ -8,15 +8,16 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
|
#include <mcl/assert.hpp>
|
||||||
|
#include <mcl/bit_cast.hpp>
|
||||||
|
#include <mcl/scope_exit.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a64_emit_x64.h"
|
#include "dynarmic/backend/x64/a64_emit_x64.h"
|
||||||
#include "dynarmic/backend/x64/a64_jitstate.h"
|
#include "dynarmic/backend/x64/a64_jitstate.h"
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/devirtualize.h"
|
#include "dynarmic/backend/x64/devirtualize.h"
|
||||||
#include "dynarmic/backend/x64/jitstate_info.h"
|
#include "dynarmic/backend/x64/jitstate_info.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/atomic.h"
|
#include "dynarmic/common/atomic.h"
|
||||||
#include "dynarmic/common/scope_exit.h"
|
|
||||||
#include "dynarmic/common/x64_disassemble.h"
|
#include "dynarmic/common/x64_disassemble.h"
|
||||||
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
#include "dynarmic/frontend/A64/translate/a64_translate.h"
|
||||||
#include "dynarmic/interface/A64/a64.h"
|
#include "dynarmic/interface/A64/a64.h"
|
||||||
|
@ -39,10 +40,10 @@ static RunCodeCallbacks GenRunCodeCallbacks(A64::UserCallbacks* cb, CodePtr (*Lo
|
||||||
static std::function<void(BlockOfCode&)> GenRCP(const A64::UserConfig& conf) {
|
static std::function<void(BlockOfCode&)> GenRCP(const A64::UserConfig& conf) {
|
||||||
return [conf](BlockOfCode& code) {
|
return [conf](BlockOfCode& code) {
|
||||||
if (conf.page_table) {
|
if (conf.page_table) {
|
||||||
code.mov(code.r14, Common::BitCast<u64>(conf.page_table));
|
code.mov(code.r14, mcl::bit_cast<u64>(conf.page_table));
|
||||||
}
|
}
|
||||||
if (conf.fastmem_pointer) {
|
if (conf.fastmem_pointer) {
|
||||||
code.mov(code.r13, Common::BitCast<u64>(conf.fastmem_pointer));
|
code.mov(code.r13, mcl::bit_cast<u64>(conf.fastmem_pointer));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a64_jitstate.h"
|
#include "dynarmic/backend/x64/a64_jitstate.h"
|
||||||
|
|
||||||
#include "dynarmic/common/bit_util.h"
|
#include <mcl/bit/bit_field.hpp>
|
||||||
|
|
||||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
@ -65,7 +66,7 @@ void A64JitState::SetFpcr(u32 value) {
|
||||||
const std::array<u32, 4> MXCSR_RMode{0x0, 0x4000, 0x2000, 0x6000};
|
const std::array<u32, 4> MXCSR_RMode{0x0, 0x4000, 0x2000, 0x6000};
|
||||||
guest_MXCSR |= MXCSR_RMode[(value >> 22) & 0x3];
|
guest_MXCSR |= MXCSR_RMode[(value >> 22) & 0x3];
|
||||||
|
|
||||||
if (Common::Bit<24>(value)) {
|
if (mcl::bit::get_bit<24>(value)) {
|
||||||
guest_MXCSR |= (1 << 15); // SSE Flush to Zero
|
guest_MXCSR |= (1 << 15); // SSE Flush to Zero
|
||||||
guest_MXCSR |= (1 << 6); // SSE Denormals are Zero
|
guest_MXCSR |= (1 << 6); // SSE Denormals are Zero
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <mcl/iterator/reverse.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/common/iterator_util.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ void ABI_PopRegistersAndAdjustStack(BlockOfCode& code, size_t frame_size, const
|
||||||
code.add(rsp, u32(frame_info.stack_subtraction));
|
code.add(rsp, u32(frame_info.stack_subtraction));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (HostLoc gpr : Common::Reverse(regs)) {
|
for (HostLoc gpr : mcl::iterator::reverse(regs)) {
|
||||||
if (HostLocIsGPR(gpr)) {
|
if (HostLocIsGPR(gpr)) {
|
||||||
code.pop(HostLocToReg64(gpr));
|
code.pop(HostLocToReg64(gpr));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,9 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/hostloc.h"
|
#include "dynarmic/backend/x64/hostloc.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <mcl/assert.hpp>
|
||||||
|
#include <mcl/bit/bit_field.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/a32_jitstate.h"
|
#include "dynarmic/backend/x64/a32_jitstate.h"
|
||||||
|
@ -22,8 +24,6 @@
|
||||||
#include "dynarmic/backend/x64/hostloc.h"
|
#include "dynarmic/backend/x64/hostloc.h"
|
||||||
#include "dynarmic/backend/x64/perf_map.h"
|
#include "dynarmic/backend/x64/perf_map.h"
|
||||||
#include "dynarmic/backend/x64/stack_layout.h"
|
#include "dynarmic/backend/x64/stack_layout.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/bit_util.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
|
@ -52,6 +52,41 @@ constexpr size_t CONSTANT_POOL_SIZE = 2 * 1024 * 1024;
|
||||||
|
|
||||||
class CustomXbyakAllocator : public Xbyak::Allocator {
|
class CustomXbyakAllocator : public Xbyak::Allocator {
|
||||||
public:
|
public:
|
||||||
|
#ifndef _WIN32
|
||||||
|
static constexpr size_t PAGE_SIZE = 4096;
|
||||||
|
|
||||||
|
// Can't subclass Xbyak::MmapAllocator because it is not a pure interface
|
||||||
|
// and doesn't expose its construtor
|
||||||
|
uint8_t* alloc(size_t size) override {
|
||||||
|
// Waste a page to store the size
|
||||||
|
size += PAGE_SIZE;
|
||||||
|
|
||||||
|
# if defined(MAP_ANONYMOUS)
|
||||||
|
int mode = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||||
|
# elif defined(MAP_ANON)
|
||||||
|
int mode = MAP_PRIVATE | MAP_ANON;
|
||||||
|
# else
|
||||||
|
# error "not supported"
|
||||||
|
# endif
|
||||||
|
# ifdef MAP_JIT
|
||||||
|
mode |= MAP_JIT;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
void* p = mmap(nullptr, size, PROT_READ | PROT_WRITE, mode, -1, 0);
|
||||||
|
if (p == MAP_FAILED) {
|
||||||
|
throw Xbyak::Error(Xbyak::ERR_CANT_ALLOC);
|
||||||
|
}
|
||||||
|
std::memcpy(p, &size, sizeof(size_t));
|
||||||
|
return static_cast<uint8_t*>(p) + PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void free(uint8_t* p) override {
|
||||||
|
size_t size;
|
||||||
|
std::memcpy(&size, p - PAGE_SIZE, sizeof(size_t));
|
||||||
|
munmap(p - PAGE_SIZE, size);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
|
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
|
||||||
bool useProtect() const override { return false; }
|
bool useProtect() const override { return false; }
|
||||||
#endif
|
#endif
|
||||||
|
@ -134,8 +169,8 @@ HostFeature GetHostFeatures() {
|
||||||
if (cpu_info.has(Cpu::tAMD)) {
|
if (cpu_info.has(Cpu::tAMD)) {
|
||||||
std::array<u32, 4> data{};
|
std::array<u32, 4> data{};
|
||||||
cpu_info.getCpuid(1, data.data());
|
cpu_info.getCpuid(1, data.data());
|
||||||
const u32 family_base = Common::Bits<8, 11>(data[0]);
|
const u32 family_base = mcl::bit::get_bits<8, 11>(data[0]);
|
||||||
const u32 family_extended = Common::Bits<20, 27>(data[0]);
|
const u32 family_extended = mcl::bit::get_bits<20, 27>(data[0]);
|
||||||
const u32 family = family_base + family_extended;
|
const u32 family = family_base + family_extended;
|
||||||
if (family >= 0x19)
|
if (family >= 0x19)
|
||||||
features |= HostFeature::FastBMI2;
|
features |= HostFeature::FastBMI2;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
#include <xbyak/xbyak_util.h>
|
#include <xbyak/xbyak_util.h>
|
||||||
|
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
#include "dynarmic/backend/x64/host_feature.h"
|
#include "dynarmic/backend/x64/host_feature.h"
|
||||||
#include "dynarmic/backend/x64/jitstate_info.h"
|
#include "dynarmic/backend/x64/jitstate_info.h"
|
||||||
#include "dynarmic/common/cast_util.h"
|
#include "dynarmic/common/cast_util.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/interface/halt_reason.h"
|
#include "dynarmic/interface/halt_reason.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
|
@ -7,10 +7,9 @@
|
||||||
|
|
||||||
#include <boost/icl/interval_map.hpp>
|
#include <boost/icl/interval_map.hpp>
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/icl/interval_set.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
#include <tsl/robin_set.h>
|
#include <tsl/robin_set.h>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
template<typename ProgramCounterType>
|
template<typename ProgramCounterType>
|
||||||
|
|
|
@ -8,10 +8,9 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
using RegList = std::vector<Xbyak::Reg64>;
|
using RegList = std::vector<Xbyak::Reg64>;
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include <mcl/assert.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,10 @@
|
||||||
#include <bit>
|
#include <bit>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
#include <tsl/robin_map.h>
|
#include <tsl/robin_map.h>
|
||||||
#include <xbyak/xbyak.h>
|
#include <xbyak/xbyak.h>
|
||||||
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
class BlockOfCode;
|
class BlockOfCode;
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include "dynarmic/common/bit_util.h"
|
#include <mcl/bit/bit_field.hpp>
|
||||||
#include "dynarmic/common/common_types.h"
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
#include "dynarmic/common/fp/rounding_mode.h"
|
#include "dynarmic/common/fp/rounding_mode.h"
|
||||||
|
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
@ -124,14 +125,14 @@ constexpr u32 FixupLUT(FpFixup src_qnan = FpFixup::A,
|
||||||
FpFixup src_pos = FpFixup::A,
|
FpFixup src_pos = FpFixup::A,
|
||||||
FpFixup src_neg = FpFixup::A) {
|
FpFixup src_neg = FpFixup::A) {
|
||||||
u32 fixup_lut = 0;
|
u32 fixup_lut = 0;
|
||||||
fixup_lut = Common::ModifyBits<0, 3, u32>(fixup_lut, static_cast<u32>(src_qnan));
|
fixup_lut = mcl::bit::set_bits<0, 3, u32>(fixup_lut, static_cast<u32>(src_qnan));
|
||||||
fixup_lut = Common::ModifyBits<4, 7, u32>(fixup_lut, static_cast<u32>(src_snan));
|
fixup_lut = mcl::bit::set_bits<4, 7, u32>(fixup_lut, static_cast<u32>(src_snan));
|
||||||
fixup_lut = Common::ModifyBits<8, 11, u32>(fixup_lut, static_cast<u32>(src_zero));
|
fixup_lut = mcl::bit::set_bits<8, 11, u32>(fixup_lut, static_cast<u32>(src_zero));
|
||||||
fixup_lut = Common::ModifyBits<12, 15, u32>(fixup_lut, static_cast<u32>(src_posone));
|
fixup_lut = mcl::bit::set_bits<12, 15, u32>(fixup_lut, static_cast<u32>(src_posone));
|
||||||
fixup_lut = Common::ModifyBits<16, 19, u32>(fixup_lut, static_cast<u32>(src_neginf));
|
fixup_lut = mcl::bit::set_bits<16, 19, u32>(fixup_lut, static_cast<u32>(src_neginf));
|
||||||
fixup_lut = Common::ModifyBits<20, 23, u32>(fixup_lut, static_cast<u32>(src_posinf));
|
fixup_lut = mcl::bit::set_bits<20, 23, u32>(fixup_lut, static_cast<u32>(src_posinf));
|
||||||
fixup_lut = Common::ModifyBits<24, 27, u32>(fixup_lut, static_cast<u32>(src_pos));
|
fixup_lut = mcl::bit::set_bits<24, 27, u32>(fixup_lut, static_cast<u32>(src_pos));
|
||||||
fixup_lut = Common::ModifyBits<28, 31, u32>(fixup_lut, static_cast<u32>(src_neg));
|
fixup_lut = mcl::bit::set_bits<28, 31, u32>(fixup_lut, static_cast<u32>(src_neg));
|
||||||
return fixup_lut;
|
return fixup_lut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,8 +154,8 @@ enum class FpRangeSign : u8 {
|
||||||
// Generates 8-bit immediate LUT for vrange instruction
|
// Generates 8-bit immediate LUT for vrange instruction
|
||||||
constexpr u8 FpRangeLUT(FpRangeSelect range_select, FpRangeSign range_sign) {
|
constexpr u8 FpRangeLUT(FpRangeSelect range_select, FpRangeSign range_sign) {
|
||||||
u8 range_lut = 0;
|
u8 range_lut = 0;
|
||||||
range_lut = Common::ModifyBits<0, 1, u8>(range_lut, static_cast<u8>(range_select));
|
range_lut = mcl::bit::set_bits<0, 1, u8>(range_lut, static_cast<u8>(range_select));
|
||||||
range_lut = Common::ModifyBits<2, 3, u8>(range_lut, static_cast<u8>(range_sign));
|
range_lut = mcl::bit::set_bits<2, 3, u8>(range_lut, static_cast<u8>(range_sign));
|
||||||
return range_lut;
|
return range_lut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <mp/traits/function_info.h>
|
#include <mcl/bit_cast.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
#include <mcl/type_traits/function_info.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/callback.h"
|
#include "dynarmic/backend/x64/callback.h"
|
||||||
#include "dynarmic/common/cast_util.h"
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
|
|
||||||
namespace Dynarmic {
|
namespace Dynarmic {
|
||||||
namespace Backend::X64 {
|
namespace Backend::X64 {
|
||||||
|
@ -32,25 +32,25 @@ struct ThunkBuilder<R (C::*)(Args...), mfp> {
|
||||||
} // namespace impl
|
} // namespace impl
|
||||||
|
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
ArgCallback DevirtualizeGeneric(mp::class_type<decltype(mfp)>* this_) {
|
ArgCallback DevirtualizeGeneric(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
return ArgCallback{&impl::ThunkBuilder<decltype(mfp), mfp>::Thunk, reinterpret_cast<u64>(this_)};
|
return ArgCallback{&impl::ThunkBuilder<decltype(mfp), mfp>::Thunk, reinterpret_cast<u64>(this_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
ArgCallback DevirtualizeWindows(mp::class_type<decltype(mfp)>* this_) {
|
ArgCallback DevirtualizeWindows(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
static_assert(sizeof(mfp) == 8);
|
static_assert(sizeof(mfp) == 8);
|
||||||
return ArgCallback{Common::BitCast<u64>(mfp), reinterpret_cast<u64>(this_)};
|
return ArgCallback{mcl::bit_cast<u64>(mfp), reinterpret_cast<u64>(this_)};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
ArgCallback DevirtualizeItanium(mp::class_type<decltype(mfp)>* this_) {
|
ArgCallback DevirtualizeItanium(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
struct MemberFunctionPointer {
|
struct MemberFunctionPointer {
|
||||||
/// For a non-virtual function, this is a simple function pointer.
|
/// For a non-virtual function, this is a simple function pointer.
|
||||||
/// For a virtual function, it is (1 + virtual table offset in bytes).
|
/// For a virtual function, it is (1 + virtual table offset in bytes).
|
||||||
u64 ptr;
|
u64 ptr;
|
||||||
/// The required adjustment to `this`, prior to the call.
|
/// The required adjustment to `this`, prior to the call.
|
||||||
u64 adj;
|
u64 adj;
|
||||||
} mfp_struct = Common::BitCast<MemberFunctionPointer>(mfp);
|
} mfp_struct = mcl::bit_cast<MemberFunctionPointer>(mfp);
|
||||||
|
|
||||||
static_assert(sizeof(MemberFunctionPointer) == 16);
|
static_assert(sizeof(MemberFunctionPointer) == 16);
|
||||||
static_assert(sizeof(MemberFunctionPointer) == sizeof(mfp));
|
static_assert(sizeof(MemberFunctionPointer) == sizeof(mfp));
|
||||||
|
@ -58,14 +58,14 @@ ArgCallback DevirtualizeItanium(mp::class_type<decltype(mfp)>* this_) {
|
||||||
u64 fn_ptr = mfp_struct.ptr;
|
u64 fn_ptr = mfp_struct.ptr;
|
||||||
u64 this_ptr = reinterpret_cast<u64>(this_) + mfp_struct.adj;
|
u64 this_ptr = reinterpret_cast<u64>(this_) + mfp_struct.adj;
|
||||||
if (mfp_struct.ptr & 1) {
|
if (mfp_struct.ptr & 1) {
|
||||||
u64 vtable = Common::BitCastPointee<u64>(this_ptr);
|
u64 vtable = mcl::bit_cast_pointee<u64>(this_ptr);
|
||||||
fn_ptr = Common::BitCastPointee<u64>(vtable + fn_ptr - 1);
|
fn_ptr = mcl::bit_cast_pointee<u64>(vtable + fn_ptr - 1);
|
||||||
}
|
}
|
||||||
return ArgCallback{fn_ptr, this_ptr};
|
return ArgCallback{fn_ptr, this_ptr};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp>
|
template<auto mfp>
|
||||||
ArgCallback Devirtualize(mp::class_type<decltype(mfp)>* this_) {
|
ArgCallback Devirtualize(mcl::class_type<decltype(mfp)>* this_) {
|
||||||
#if defined(__APPLE__) || defined(linux) || defined(__linux) || defined(__linux__)
|
#if defined(__APPLE__) || defined(linux) || defined(__linux) || defined(__linux__)
|
||||||
return DevirtualizeItanium<mfp>(this_);
|
return DevirtualizeItanium<mfp>(this_);
|
||||||
#elif defined(__MINGW64__)
|
#elif defined(__MINGW64__)
|
||||||
|
|
|
@ -7,16 +7,16 @@
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
#include <mcl/assert.hpp>
|
||||||
|
#include <mcl/bit/bit_field.hpp>
|
||||||
|
#include <mcl/scope_exit.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
#include <tsl/robin_set.h>
|
#include <tsl/robin_set.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/nzcv_util.h"
|
#include "dynarmic/backend/x64/nzcv_util.h"
|
||||||
#include "dynarmic/backend/x64/perf_map.h"
|
#include "dynarmic/backend/x64/perf_map.h"
|
||||||
#include "dynarmic/backend/x64/stack_layout.h"
|
#include "dynarmic/backend/x64/stack_layout.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/bit_util.h"
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/common/scope_exit.h"
|
|
||||||
#include "dynarmic/common/variant_util.h"
|
#include "dynarmic/common/variant_util.h"
|
||||||
#include "dynarmic/ir/basic_block.h"
|
#include "dynarmic/ir/basic_block.h"
|
||||||
#include "dynarmic/ir/microinstruction.h"
|
#include "dynarmic/ir/microinstruction.h"
|
||||||
|
@ -164,10 +164,10 @@ void EmitX64::EmitNZCVFromPackedFlags(EmitContext& ctx, IR::Inst* inst) {
|
||||||
if (args[0].IsImmediate()) {
|
if (args[0].IsImmediate()) {
|
||||||
const Xbyak::Reg32 nzcv = ctx.reg_alloc.ScratchGpr().cvt32();
|
const Xbyak::Reg32 nzcv = ctx.reg_alloc.ScratchGpr().cvt32();
|
||||||
u32 value = 0;
|
u32 value = 0;
|
||||||
value |= Common::Bit<31>(args[0].GetImmediateU32()) ? (1 << 15) : 0;
|
value |= mcl::bit::get_bit<31>(args[0].GetImmediateU32()) ? (1 << 15) : 0;
|
||||||
value |= Common::Bit<30>(args[0].GetImmediateU32()) ? (1 << 14) : 0;
|
value |= mcl::bit::get_bit<30>(args[0].GetImmediateU32()) ? (1 << 14) : 0;
|
||||||
value |= Common::Bit<29>(args[0].GetImmediateU32()) ? (1 << 8) : 0;
|
value |= mcl::bit::get_bit<29>(args[0].GetImmediateU32()) ? (1 << 8) : 0;
|
||||||
value |= Common::Bit<28>(args[0].GetImmediateU32()) ? (1 << 0) : 0;
|
value |= mcl::bit::get_bit<28>(args[0].GetImmediateU32()) ? (1 << 0) : 0;
|
||||||
code.mov(nzcv, value);
|
code.mov(nzcv, value);
|
||||||
ctx.reg_alloc.DefineValue(inst, nzcv);
|
ctx.reg_alloc.DefineValue(inst, nzcv);
|
||||||
} else if (code.HasHostFeature(HostFeature::FastBMI2)) {
|
} else if (code.HasHostFeature(HostFeature::FastBMI2)) {
|
||||||
|
@ -204,44 +204,44 @@ Xbyak::Label EmitX64::EmitCond(IR::Cond cond) {
|
||||||
// add al, 0x7F restores OF
|
// add al, 0x7F restores OF
|
||||||
|
|
||||||
switch (cond) {
|
switch (cond) {
|
||||||
case IR::Cond::EQ: //z
|
case IR::Cond::EQ: // z
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.jz(pass);
|
code.jz(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::NE: //!z
|
case IR::Cond::NE: //! z
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.jnz(pass);
|
code.jnz(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::CS: //c
|
case IR::Cond::CS: // c
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.jc(pass);
|
code.jc(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::CC: //!c
|
case IR::Cond::CC: //! c
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.jnc(pass);
|
code.jnc(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::MI: //n
|
case IR::Cond::MI: // n
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.js(pass);
|
code.js(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::PL: //!n
|
case IR::Cond::PL: //! n
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.jns(pass);
|
code.jns(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::VS: //v
|
case IR::Cond::VS: // v
|
||||||
code.cmp(al, 0x81);
|
code.cmp(al, 0x81);
|
||||||
code.jo(pass);
|
code.jo(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::VC: //!v
|
case IR::Cond::VC: //! v
|
||||||
code.cmp(al, 0x81);
|
code.cmp(al, 0x81);
|
||||||
code.jno(pass);
|
code.jno(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::HI: //c & !z
|
case IR::Cond::HI: // c & !z
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmc();
|
code.cmc();
|
||||||
code.ja(pass);
|
code.ja(pass);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::LS: //!c | z
|
case IR::Cond::LS: //! c | z
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmc();
|
code.cmc();
|
||||||
code.jna(pass);
|
code.jna(pass);
|
||||||
|
|
|
@ -11,13 +11,13 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <mcl/bitsizeof.hpp>
|
||||||
#include <tsl/robin_map.h>
|
#include <tsl/robin_map.h>
|
||||||
#include <tsl/robin_set.h>
|
#include <tsl/robin_set.h>
|
||||||
#include <xbyak/xbyak_util.h>
|
#include <xbyak/xbyak_util.h>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/exception_handler.h"
|
#include "dynarmic/backend/x64/exception_handler.h"
|
||||||
#include "dynarmic/backend/x64/reg_alloc.h"
|
#include "dynarmic/backend/x64/reg_alloc.h"
|
||||||
#include "dynarmic/common/bit_util.h"
|
|
||||||
#include "dynarmic/common/fp/fpcr.h"
|
#include "dynarmic/common/fp/fpcr.h"
|
||||||
#include "dynarmic/ir/location_descriptor.h"
|
#include "dynarmic/ir/location_descriptor.h"
|
||||||
#include "dynarmic/ir/terminal.h"
|
#include "dynarmic/ir/terminal.h"
|
||||||
|
@ -41,10 +41,10 @@ using A64FullVectorWidth = std::integral_constant<size_t, 128>;
|
||||||
// relative to the size of a vector register. e.g. T = u32 would result
|
// relative to the size of a vector register. e.g. T = u32 would result
|
||||||
// in a std::array<u32, 4>.
|
// in a std::array<u32, 4>.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using VectorArray = std::array<T, A64FullVectorWidth::value / Common::BitSize<T>()>;
|
using VectorArray = std::array<T, A64FullVectorWidth::value / mcl::bitsizeof<T>>;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using HalfVectorArray = std::array<T, A64FullVectorWidth::value / Common::BitSize<T>() / 2>;
|
using HalfVectorArray = std::array<T, A64FullVectorWidth::value / mcl::bitsizeof<T> / 2>;
|
||||||
|
|
||||||
struct EmitContext {
|
struct EmitContext {
|
||||||
EmitContext(RegAlloc& reg_alloc, IR::Block& block);
|
EmitContext(RegAlloc& reg_alloc, IR::Block& block);
|
||||||
|
|
|
@ -3,10 +3,11 @@
|
||||||
* SPDX-License-Identifier: 0BSD
|
* SPDX-License-Identifier: 0BSD
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/abi.h"
|
#include "dynarmic/backend/x64/abi.h"
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/emit_x64.h"
|
#include "dynarmic/backend/x64/emit_x64.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/common/crypto/aes.h"
|
#include "dynarmic/common/crypto/aes.h"
|
||||||
#include "dynarmic/ir/microinstruction.h"
|
#include "dynarmic/ir/microinstruction.h"
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <mcl/assert.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/emit_x64.h"
|
#include "dynarmic/backend/x64/emit_x64.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/ir/basic_block.h"
|
#include "dynarmic/ir/basic_block.h"
|
||||||
#include "dynarmic/ir/microinstruction.h"
|
#include "dynarmic/ir/microinstruction.h"
|
||||||
#include "dynarmic/ir/opcodes.h"
|
#include "dynarmic/ir/opcodes.h"
|
||||||
|
@ -146,44 +147,44 @@ static void EmitConditionalSelect(BlockOfCode& code, EmitContext& ctx, IR::Inst*
|
||||||
// add al, 0x7F restores OF
|
// add al, 0x7F restores OF
|
||||||
|
|
||||||
switch (args[0].GetImmediateCond()) {
|
switch (args[0].GetImmediateCond()) {
|
||||||
case IR::Cond::EQ: //z
|
case IR::Cond::EQ: // z
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmovz(else_, then_);
|
code.cmovz(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::NE: //!z
|
case IR::Cond::NE: //! z
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmovnz(else_, then_);
|
code.cmovnz(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::CS: //c
|
case IR::Cond::CS: // c
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmovc(else_, then_);
|
code.cmovc(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::CC: //!c
|
case IR::Cond::CC: //! c
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmovnc(else_, then_);
|
code.cmovnc(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::MI: //n
|
case IR::Cond::MI: // n
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmovs(else_, then_);
|
code.cmovs(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::PL: //!n
|
case IR::Cond::PL: //! n
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmovns(else_, then_);
|
code.cmovns(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::VS: //v
|
case IR::Cond::VS: // v
|
||||||
code.cmp(nzcv.cvt8(), 0x81);
|
code.cmp(nzcv.cvt8(), 0x81);
|
||||||
code.cmovo(else_, then_);
|
code.cmovo(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::VC: //!v
|
case IR::Cond::VC: //! v
|
||||||
code.cmp(nzcv.cvt8(), 0x81);
|
code.cmp(nzcv.cvt8(), 0x81);
|
||||||
code.cmovno(else_, then_);
|
code.cmovno(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::HI: //c & !z
|
case IR::Cond::HI: // c & !z
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmc();
|
code.cmc();
|
||||||
code.cmova(else_, then_);
|
code.cmova(else_, then_);
|
||||||
break;
|
break;
|
||||||
case IR::Cond::LS: //!c | z
|
case IR::Cond::LS: //! c | z
|
||||||
code.sahf();
|
code.sahf();
|
||||||
code.cmc();
|
code.cmc();
|
||||||
code.cmovna(else_, then_);
|
code.cmovna(else_, then_);
|
||||||
|
|
|
@ -7,20 +7,20 @@
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include <mp/metavalue/lift_value.h>
|
#include <mcl/assert.hpp>
|
||||||
#include <mp/traits/integer_of_size.h>
|
#include <mcl/mp/metavalue/lift_value.hpp>
|
||||||
#include <mp/typelist/cartesian_product.h>
|
#include <mcl/mp/typelist/cartesian_product.hpp>
|
||||||
#include <mp/typelist/lift_sequence.h>
|
#include <mcl/mp/typelist/lift_sequence.hpp>
|
||||||
#include <mp/typelist/list.h>
|
#include <mcl/mp/typelist/list.hpp>
|
||||||
#include <mp/typelist/lower_to_tuple.h>
|
#include <mcl/mp/typelist/lower_to_tuple.hpp>
|
||||||
|
#include <mcl/stdint.hpp>
|
||||||
|
#include <mcl/type_traits/integer_of_size.hpp>
|
||||||
|
|
||||||
#include "dynarmic/backend/x64/abi.h"
|
#include "dynarmic/backend/x64/abi.h"
|
||||||
#include "dynarmic/backend/x64/block_of_code.h"
|
#include "dynarmic/backend/x64/block_of_code.h"
|
||||||
#include "dynarmic/backend/x64/constants.h"
|
#include "dynarmic/backend/x64/constants.h"
|
||||||
#include "dynarmic/backend/x64/emit_x64.h"
|
#include "dynarmic/backend/x64/emit_x64.h"
|
||||||
#include "dynarmic/common/assert.h"
|
|
||||||
#include "dynarmic/common/cast_util.h"
|
#include "dynarmic/common/cast_util.h"
|
||||||
#include "dynarmic/common/common_types.h"
|
|
||||||
#include "dynarmic/common/fp/fpcr.h"
|
#include "dynarmic/common/fp/fpcr.h"
|
||||||
#include "dynarmic/common/fp/fpsr.h"
|
#include "dynarmic/common/fp/fpsr.h"
|
||||||
#include "dynarmic/common/fp/info.h"
|
#include "dynarmic/common/fp/info.h"
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
namespace Dynarmic::Backend::X64 {
|
namespace Dynarmic::Backend::X64 {
|
||||||
|
|
||||||
using namespace Xbyak::util;
|
using namespace Xbyak::util;
|
||||||
|
namespace mp = mcl::mp;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -173,7 +174,7 @@ void PostProcessNaN(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm tmp) {
|
||||||
// We allow for the case where op1 and result are the same register. We do not read from op1 once result is written to.
|
// We allow for the case where op1 and result are the same register. We do not read from op1 once result is written to.
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, Xbyak::Xmm op2, Xbyak::Reg64 tmp, Xbyak::Label end) {
|
void EmitPostProcessNaNs(BlockOfCode& code, Xbyak::Xmm result, Xbyak::Xmm op1, Xbyak::Xmm op2, Xbyak::Reg64 tmp, Xbyak::Label end) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT exponent_mask = FP::FPInfo<FPT>::exponent_mask;
|
constexpr FPT exponent_mask = FP::FPInfo<FPT>::exponent_mask;
|
||||||
constexpr FPT mantissa_msb = FP::FPInfo<FPT>::mantissa_msb;
|
constexpr FPT mantissa_msb = FP::FPInfo<FPT>::mantissa_msb;
|
||||||
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
||||||
|
@ -267,7 +268,7 @@ void FPTwoOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
||||||
|
|
||||||
template<size_t fsize, typename Function>
|
template<size_t fsize, typename Function>
|
||||||
void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -324,7 +325,7 @@ void FPThreeOp(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, Function fn)
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void FPAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void FPAbs(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
|
constexpr FPT non_sign_mask = FP::FPInfo<FPT>::sign_mask - FPT(1u);
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
@ -350,7 +351,7 @@ void EmitX64::EmitFPAbs64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
void FPNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
void FPNeg(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
|
constexpr FPT sign_mask = FP::FPInfo<FPT>::sign_mask;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
@ -440,7 +441,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize, bool is_max>
|
template<size_t fsize, bool is_max>
|
||||||
static void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
constexpr FPT default_nan = FP::FPInfo<FPT>::DefaultNaN();
|
constexpr FPT default_nan = FP::FPInfo<FPT>::DefaultNaN();
|
||||||
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
constexpr u8 mantissa_msb_bit = static_cast<u8>(FP::FPInfo<FPT>::explicit_mantissa_width - 1);
|
||||||
|
|
||||||
|
@ -592,7 +593,7 @@ void EmitX64::EmitFPMul64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -697,7 +698,7 @@ void EmitX64::EmitFPMulAdd64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPMulX(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -755,7 +756,7 @@ void EmitX64::EmitFPMulX64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRecipEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
if constexpr (fsize != 16) {
|
if constexpr (fsize != 16) {
|
||||||
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
||||||
|
@ -801,7 +802,7 @@ void EmitX64::EmitFPRecipEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
ctx.reg_alloc.HostCall(inst, args[0]);
|
ctx.reg_alloc.HostCall(inst, args[0]);
|
||||||
|
@ -824,7 +825,7 @@ void EmitX64::EmitFPRecipExponent64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -949,7 +950,7 @@ static void EmitFPRound(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, siz
|
||||||
constexpr size_t fsize = std::get<0>(t);
|
constexpr size_t fsize = std::get<0>(t);
|
||||||
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
||||||
constexpr bool exact = std::get<2>(t);
|
constexpr bool exact = std::get<2>(t);
|
||||||
using InputSize = mp::unsigned_integer_of_size<fsize>;
|
using InputSize = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
return FP::FPRoundInt<InputSize>(static_cast<InputSize>(input), fpcr, rounding_mode, exact, fpsr);
|
return FP::FPRoundInt<InputSize>(static_cast<InputSize>(input), fpcr, rounding_mode, exact, fpsr);
|
||||||
})};
|
})};
|
||||||
|
@ -977,7 +978,7 @@ void EmitX64::EmitFPRoundInt64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
if constexpr (fsize != 16) {
|
if constexpr (fsize != 16) {
|
||||||
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
if (ctx.HasOptimization(OptimizationFlag::Unsafe_ReducedErrorFP)) {
|
||||||
|
@ -1156,7 +1157,7 @@ void EmitX64::EmitFPRSqrtEstimate64(EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
|
||||||
template<size_t fsize>
|
template<size_t fsize>
|
||||||
static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
|
||||||
|
@ -1589,7 +1590,7 @@ static void EmitFPToFixed(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
constexpr auto t = mp::lower_to_tuple_v<decltype(args)>;
|
constexpr auto t = mp::lower_to_tuple_v<decltype(args)>;
|
||||||
constexpr size_t fbits = std::get<0>(t);
|
constexpr size_t fbits = std::get<0>(t);
|
||||||
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
constexpr FP::RoundingMode rounding_mode = std::get<1>(t);
|
||||||
using FPT = mp::unsigned_integer_of_size<fsize>;
|
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||||
|
|
||||||
return FP::FPToFixed<FPT>(isize, static_cast<FPT>(input), fbits, unsigned_, fpcr, rounding_mode, fpsr);
|
return FP::FPToFixed<FPT>(isize, static_cast<FPT>(input), fbits, unsigned_, fpcr, rounding_mode, fpsr);
|
||||||
})};
|
})};
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue