mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-20 14:05:45 +00:00
Compare commits
25 commits
8b64b28111
...
1960804696
Author | SHA1 | Date | |
---|---|---|---|
|
1960804696 | ||
|
c07df11609 | ||
|
ac89ffae9f | ||
|
fc8d7004d2 | ||
|
2aab37b516 | ||
|
108daeeb39 | ||
|
a538126eb7 | ||
|
d7574b2878 | ||
|
e9ca3f4c06 | ||
|
a8564a09b7 | ||
|
2e092010e6 | ||
|
be59b4f15f | ||
|
2be7df287a | ||
|
492903cc7a | ||
|
f99488fe3e | ||
|
7b23cd0df4 | ||
![]() |
fe4f5a3860 | ||
|
a0a208db57 | ||
![]() |
c47f6615d3 | ||
|
1cd51d6545 | ||
|
5091759a47 | ||
|
03351a4f8b | ||
|
55a7797378 | ||
|
d5c58342e0 | ||
|
ae02310bdf |
136 changed files with 6142 additions and 6484 deletions
|
@ -36,15 +36,16 @@ case "$1" in
|
|||
ARCH=armv9
|
||||
ARCH_FLAGS="-march=armv9-a -mtune=generic -w"
|
||||
;;
|
||||
*)
|
||||
echo "Invalid target $1 specified, must be one of amd64, steamdeck, allyx, rog-ally, legacy, aarch64, armv9"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
export ARCH_FLAGS="$ARCH_FLAGS -O3"
|
||||
|
||||
NPROC="$2"
|
||||
if [ -z "$NPROC" ]; then
|
||||
NPROC="$(nproc)"
|
||||
else
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ "$1" != "" ]; then shift; fi
|
||||
|
@ -60,11 +61,27 @@ if [ "$DEVEL" != "true" ]; then
|
|||
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DENABLE_QT_UPDATE_CHECKER=ON)
|
||||
fi
|
||||
|
||||
if [ "$USE_WEBENGINE" = "true" ]; then
|
||||
WEBENGINE=ON
|
||||
else
|
||||
WEBENGINE=OFF
|
||||
fi
|
||||
|
||||
if [ "$USE_MULTIMEDIA" = "false" ]; then
|
||||
MULTIMEDIA=OFF
|
||||
else
|
||||
MULTIMEDIA=ON
|
||||
fi
|
||||
|
||||
if [ -z "$BUILD_TYPE" ]; then
|
||||
export BUILD_TYPE="Release"
|
||||
fi
|
||||
|
||||
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" $@)
|
||||
|
||||
mkdir -p build && cd build
|
||||
cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
|
||||
-DENABLE_QT_TRANSLATION=ON \
|
||||
-DUSE_DISCORD_PRESENCE=ON \
|
||||
-DCMAKE_CXX_FLAGS="$ARCH_FLAGS" \
|
||||
|
@ -74,8 +91,8 @@ cmake .. -G Ninja \
|
|||
-DYUZU_USE_BUNDLED_SDL2=OFF \
|
||||
-DYUZU_USE_EXTERNAL_SDL2=ON \
|
||||
-DYUZU_TESTS=OFF \
|
||||
-DYUZU_USE_QT_MULTIMEDIA=ON \
|
||||
-DYUZU_USE_QT_WEB_ENGINE=ON \
|
||||
-DYUZU_USE_QT_MULTIMEDIA=$MULTIMEDIA \
|
||||
-DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \
|
||||
-DYUZU_USE_FASTER_LD=ON \
|
||||
-DYUZU_ENABLE_LTO=ON \
|
||||
"${EXTRA_CMAKE_FLAGS[@]}"
|
||||
|
|
|
@ -17,16 +17,32 @@ else
|
|||
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" -DYUZU_USE_BUNDLED_QT=OFF)
|
||||
fi
|
||||
|
||||
if [ -z "$BUILD_TYPE" ]; then
|
||||
export BUILD_TYPE="Release"
|
||||
fi
|
||||
|
||||
if [ "$WINDEPLOYQT" == "" ]; then
|
||||
echo "You must supply the WINDEPLOYQT environment variable."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$USE_WEBENGINE" = "true" ]; then
|
||||
WEBENGINE=ON
|
||||
else
|
||||
WEBENGINE=OFF
|
||||
fi
|
||||
|
||||
if [ "$USE_MULTIMEDIA" = "false" ]; then
|
||||
MULTIMEDIA=OFF
|
||||
else
|
||||
MULTIMEDIA=ON
|
||||
fi
|
||||
|
||||
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" $@)
|
||||
|
||||
mkdir -p build && cd build
|
||||
cmake .. -G Ninja \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
|
||||
-DENABLE_QT_TRANSLATION=ON \
|
||||
-DUSE_DISCORD_PRESENCE=ON \
|
||||
-DYUZU_USE_BUNDLED_SDL2=OFF \
|
||||
|
@ -34,8 +50,8 @@ cmake .. -G Ninja \
|
|||
-DYUZU_TESTS=OFF \
|
||||
-DYUZU_CMD=OFF \
|
||||
-DYUZU_ROOM_STANDALONE=OFF \
|
||||
-DYUZU_USE_QT_MULTIMEDIA=ON \
|
||||
-DYUZU_USE_QT_WEB_ENGINE=ON \
|
||||
-DYUZU_USE_QT_MULTIMEDIA=$MULTIMEDIA \
|
||||
-DYUZU_USE_QT_WEB_ENGINE=$WEBENGINE \
|
||||
-DYUZU_ENABLE_LTO=ON \
|
||||
"${EXTRA_CMAKE_FLAGS[@]}"
|
||||
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -33,6 +33,7 @@ CMakeLists.txt.user*
|
|||
|
||||
# Visual Studio CMake settings
|
||||
CMakeSettings.json
|
||||
.cache/
|
||||
|
||||
# OSX global filetypes
|
||||
# Created by Finder or Spotlight in directories for various OS functionality (indexing, etc)
|
||||
|
@ -51,4 +52,3 @@ Thumbs.db
|
|||
eden-windows-msvc
|
||||
artifacts
|
||||
*.AppImage*
|
||||
*.patch
|
||||
|
|
80
.patch/quazip/0001-strict.patch
Normal file
80
.patch/quazip/0001-strict.patch
Normal file
|
@ -0,0 +1,80 @@
|
|||
diff --git a/quazip/quazipdir.cpp b/quazip/quazipdir.cpp
|
||||
index d43f1c1..eb24bf1 100644
|
||||
--- a/quazip/quazipdir.cpp
|
||||
+++ b/quazip/quazipdir.cpp
|
||||
@@ -293,8 +293,8 @@ bool QuaZipDirComparator::operator()(const QuaZipFileInfo64 &info1,
|
||||
}
|
||||
|
||||
template<typename TFileInfoList>
|
||||
-bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters,
|
||||
- QDir::Filters filter, QDir::SortFlags sort, TFileInfoList &result) const
|
||||
+bool QuaZipDirPrivate::entryInfoList(QStringList _nameFilters,
|
||||
+ QDir::Filters _filter, QDir::SortFlags sort, TFileInfoList &result) const
|
||||
{
|
||||
QString basePath = simplePath();
|
||||
if (!basePath.isEmpty())
|
||||
@@ -305,12 +305,12 @@ bool QuaZipDirPrivate::entryInfoList(QStringList nameFilters,
|
||||
if (!zip->goToFirstFile()) {
|
||||
return zip->getZipError() == UNZ_OK;
|
||||
}
|
||||
- QDir::Filters fltr = filter;
|
||||
+ QDir::Filters fltr = _filter;
|
||||
if (fltr == QDir::NoFilter)
|
||||
fltr = this->filter;
|
||||
if (fltr == QDir::NoFilter)
|
||||
fltr = QDir::AllEntries;
|
||||
- QStringList nmfltr = nameFilters;
|
||||
+ QStringList nmfltr = _nameFilters;
|
||||
if (nmfltr.isEmpty())
|
||||
nmfltr = this->nameFilters;
|
||||
QSet<QString> dirsFound;
|
||||
diff --git a/quazip/quazipfile.cpp b/quazip/quazipfile.cpp
|
||||
index 4a5f2f9..f7865f5 100644
|
||||
--- a/quazip/quazipfile.cpp
|
||||
+++ b/quazip/quazipfile.cpp
|
||||
@@ -241,14 +241,14 @@ void QuaZipFile::setFileName(const QString& fileName, QuaZip::CaseSensitivity cs
|
||||
p->caseSensitivity=cs;
|
||||
}
|
||||
|
||||
-void QuaZipFilePrivate::setZipError(int zipError) const
|
||||
+void QuaZipFilePrivate::setZipError(int _zipError) const
|
||||
{
|
||||
QuaZipFilePrivate *fakeThis = const_cast<QuaZipFilePrivate*>(this); // non-const
|
||||
- fakeThis->zipError=zipError;
|
||||
- if(zipError==UNZ_OK)
|
||||
+ fakeThis->zipError = _zipError;
|
||||
+ if(_zipError == UNZ_OK)
|
||||
q->setErrorString(QString());
|
||||
else
|
||||
- q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(zipError));
|
||||
+ q->setErrorString(QuaZipFile::tr("ZIP/UNZIP API error %1").arg(_zipError));
|
||||
}
|
||||
|
||||
bool QuaZipFile::open(OpenMode mode)
|
||||
diff --git a/quazip/unzip.c b/quazip/unzip.c
|
||||
index a39365d..ee7b487 100644
|
||||
--- a/quazip/unzip.c
|
||||
+++ b/quazip/unzip.c
|
||||
@@ -1054,7 +1054,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
/* ZIP64 extra fields */
|
||||
if (headerId == 0x0001)
|
||||
{
|
||||
- uLong uL;
|
||||
+ uLong _uL;
|
||||
|
||||
if(file_info.uncompressed_size == (ZPOS64_T)0xFFFFFFFFu)
|
||||
{
|
||||
@@ -1078,7 +1078,7 @@ local int unz64local_GetCurrentFileInfoInternal (unzFile file,
|
||||
if(file_info.disk_num_start == 0xFFFFFFFFu)
|
||||
{
|
||||
/* Disk Start Number */
|
||||
- if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
|
||||
+ if (unz64local_getLong(&s->z_filefunc, s->filestream, &_uL) != UNZ_OK)
|
||||
err=UNZ_ERRNO;
|
||||
}
|
||||
|
||||
@@ -2151,3 +2151,4 @@ int ZEXPORT unzClearFlags(unzFile file, unsigned flags)
|
||||
s->flags &= ~flags;
|
||||
return UNZ_OK;
|
||||
}
|
||||
+
|
26
.patch/quazip/0002-oldstyle.patch
Normal file
26
.patch/quazip/0002-oldstyle.patch
Normal file
|
@ -0,0 +1,26 @@
|
|||
diff --git a/quazip/minizip_crypt.h b/quazip/minizip_crypt.h
|
||||
index 2e833f7..ea9d277 100644
|
||||
--- a/quazip/minizip_crypt.h
|
||||
+++ b/quazip/minizip_crypt.h
|
||||
@@ -90,13 +90,14 @@ static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t FAR
|
||||
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
|
||||
# endif
|
||||
|
||||
-static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting)
|
||||
- const char *passwd; /* password string */
|
||||
- unsigned char *buf; /* where to write header */
|
||||
- int bufSize;
|
||||
- unsigned long* pkeys;
|
||||
- const z_crc_t FAR * pcrc_32_tab;
|
||||
- unsigned long crcForCrypting;
|
||||
+static int crypthead(
|
||||
+ const char *passwd, /* password string */
|
||||
+ unsigned char *buf, /* where to write header */
|
||||
+ int bufSize,
|
||||
+ unsigned long* pkeys,
|
||||
+ const z_crc_t FAR * pcrc_32_tab,
|
||||
+ unsigned long crcForCrypting
|
||||
+)
|
||||
{
|
||||
int n; /* index in random header */
|
||||
int t; /* temporary */
|
19
.patch/quazip/0003-predecls.patch
Normal file
19
.patch/quazip/0003-predecls.patch
Normal file
|
@ -0,0 +1,19 @@
|
|||
diff --git a/quazip/zip.c b/quazip/zip.c
|
||||
index 7788b88..f4e21aa 100644
|
||||
--- a/quazip/zip.c
|
||||
+++ b/quazip/zip.c
|
||||
@@ -645,6 +645,14 @@ local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib
|
||||
return relativeOffset;
|
||||
}
|
||||
|
||||
+// compilers hate this ONE SIMPLE TRICK!
|
||||
+static int LoadCentralDirectoryRecord(zip64_internal* pziinit);
|
||||
+static int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local, uLong version_to_extract);
|
||||
+static int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip);
|
||||
+static int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip);
|
||||
+static int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip);
|
||||
+static int Write_GlobalComment(zip64_internal* zi, const char* global_comment);
|
||||
+
|
||||
int LoadCentralDirectoryRecord(zip64_internal* pziinit)
|
||||
{
|
||||
int err=ZIP_OK;
|
400
.patch/quazip/0004-qt6-only.patch
Normal file
400
.patch/quazip/0004-qt6-only.patch
Normal file
|
@ -0,0 +1,400 @@
|
|||
"Debloats" QuaZip by removing some unneeded stuff (Qt <6, bzip2, emscripten...)
|
||||
|
||||
This is completely optional.
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index b376fb2..4aac4ec 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -3,64 +3,16 @@ cmake_minimum_required(VERSION 3.15...3.18)
|
||||
|
||||
project(QuaZip VERSION 1.5)
|
||||
|
||||
-include(cmake/clone-repo.cmake)
|
||||
-
|
||||
set(QUAZIP_LIB_VERSION ${QuaZip_VERSION})
|
||||
set(QUAZIP_LIB_SOVERSION 1.5.0)
|
||||
|
||||
-if(EMSCRIPTEN)
|
||||
- #option(ZLIB_INCLUDE "Path to include dir" "")
|
||||
- #option(ZLIB_LIBRARY "Path to library dir" "")
|
||||
- option(BUILD_SHARED_LIBS "" OFF)
|
||||
- option(QUAZIP_INSTALL "" OFF)
|
||||
- option(QUAZIP_USE_QT_ZLIB "" OFF)
|
||||
- option(QUAZIP_ENABLE_TESTS "Build QuaZip tests" OFF)
|
||||
-else()
|
||||
- option(BUILD_SHARED_LIBS "" ON)
|
||||
- option(QUAZIP_INSTALL "" ON)
|
||||
- option(QUAZIP_USE_QT_ZLIB "" OFF)
|
||||
- option(QUAZIP_ENABLE_TESTS "Build QuaZip tests" OFF)
|
||||
-endif()
|
||||
+option(BUILD_SHARED_LIBS "" ON)
|
||||
+option(QUAZIP_INSTALL "" ON)
|
||||
+option(QUAZIP_ENABLE_TESTS "Build QuaZip tests" OFF)
|
||||
|
||||
OPTION(ZLIB_CONST "Sets ZLIB_CONST preprocessor definition" OFF)
|
||||
|
||||
-# Make BZIP2 optional
|
||||
-option(QUAZIP_BZIP2 "Enables BZIP2 compression" ON)
|
||||
-option(QUAZIP_BZIP2_STDIO "Output BZIP2 errors to stdio" ON)
|
||||
-
|
||||
-option(QUAZIP_FETCH_LIBS "Enables fetching third-party libraries if not found" ${WIN32})
|
||||
-option(QUAZIP_FORCE_FETCH_LIBS "Enables fetching third-party libraries always" OFF)
|
||||
-
|
||||
-if (QUAZIP_USE_QT_ZLIB AND BUILD_SHARED_LIBS)
|
||||
- message(FATAL_ERROR "Using BUILD_SHARED_LIBS=ON together with QUAZIP_USE_QT_ZLIB=ON is not supported." )
|
||||
-endif()
|
||||
-
|
||||
-# Set the default value of `${QUAZIP_QT_MAJOR_VERSION}`.
|
||||
-# We search quietly for Qt6, Qt5 and Qt4 in that order.
|
||||
-# Qt6 and Qt5 provide config files for CMake.
|
||||
-# Qt4 relies on `FindQt4.cmake`.
|
||||
-find_package(
|
||||
- QT NAMES Qt6 Qt5
|
||||
- QUIET COMPONENTS Core
|
||||
-)
|
||||
-if (NOT QT_FOUND)
|
||||
- find_package(Qt4 QUIET COMPONENTS QtCore)
|
||||
- if (Qt4_FOUND)
|
||||
- set(QT_VERSION_MAJOR 4)
|
||||
- else()
|
||||
- # If neither 6, 5 nor 4 are found, we default to 5.
|
||||
- # The setup will fail further down.
|
||||
- set(QT_VERSION_MAJOR 5)
|
||||
- endif()
|
||||
-endif()
|
||||
-
|
||||
-set(QUAZIP_QT_MAJOR_VERSION ${QT_VERSION_MAJOR} CACHE STRING "Qt version to use (4, 5 or 6), defaults to ${QT_VERSION_MAJOR}")
|
||||
-
|
||||
-if (QUAZIP_QT_MAJOR_VERSION EQUAL 6)
|
||||
- set(CMAKE_CXX_STANDARD 17)
|
||||
-else()
|
||||
- set(CMAKE_CXX_STANDARD 14)
|
||||
-endif()
|
||||
+set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE RELEASE)
|
||||
@@ -77,92 +29,17 @@ set(QUAZIP_LIB_TARGET_NAME QuaZip)
|
||||
set(QUAZIP_DIR_NAME QuaZip-Qt${QUAZIP_QT_MAJOR_VERSION}-${QUAZIP_LIB_VERSION})
|
||||
set(QUAZIP_PACKAGE_NAME QuaZip-Qt${QUAZIP_QT_MAJOR_VERSION})
|
||||
|
||||
-message(STATUS "QUAZIP_QT_MAJOR_VERSION set to ${QUAZIP_QT_MAJOR_VERSION}")
|
||||
-message(STATUS "CMAKE_CXX_STANDARD set to ${CMAKE_CXX_STANDARD}")
|
||||
-
|
||||
-if(QUAZIP_QT_MAJOR_VERSION EQUAL 6)
|
||||
- find_package(Qt6 REQUIRED COMPONENTS Core Core5Compat
|
||||
- OPTIONAL_COMPONENTS Network Test)
|
||||
- message(STATUS "Found Qt version ${Qt6_VERSION} at ${Qt6_DIR}")
|
||||
- set(QUAZIP_QT_ZLIB_COMPONENT BundledZLIB)
|
||||
- set(QUAZIP_QT_ZLIB_HEADER_COMPONENT ZlibPrivate)
|
||||
- set(QUAZIP_LIB_LIBRARIES Qt6::Core Qt6::Core5Compat)
|
||||
- set(QUAZIP_TEST_QT_LIBRARIES Qt6::Core Qt6::Core5Compat Qt6::Network Qt6::Test)
|
||||
- set(QUAZIP_PKGCONFIG_REQUIRES "zlib, Qt6Core")
|
||||
-elseif(QUAZIP_QT_MAJOR_VERSION EQUAL 5)
|
||||
- find_package(Qt5 REQUIRED COMPONENTS Core
|
||||
- OPTIONAL_COMPONENTS Network Test)
|
||||
- message(STATUS "Found Qt version ${Qt5_VERSION} at ${Qt5_DIR}")
|
||||
- set(QUAZIP_QT_ZLIB_COMPONENT Zlib)
|
||||
- set(QUAZIP_LIB_LIBRARIES Qt5::Core)
|
||||
- set(QUAZIP_TEST_QT_LIBRARIES Qt5::Core Qt5::Network Qt5::Test)
|
||||
- set(QUAZIP_PKGCONFIG_REQUIRES "zlib, Qt5Core")
|
||||
-elseif(QUAZIP_QT_MAJOR_VERSION EQUAL 4)
|
||||
- find_package(Qt4 4.5.0 REQUIRED COMPONENTS QtCore
|
||||
- OPTIONAL_COMPONENTS QtNetwork QtTest)
|
||||
- set(QUAZIP_QT_ZLIB_COMPONENT Zlib)
|
||||
- set(QUAZIP_LIB_LIBRARIES Qt4::QtCore)
|
||||
- set(QUAZIP_TEST_QT_LIBRARIES Qt4::QtCore Qt4::QtNetwork Qt4::QtTest)
|
||||
- set(QUAZIP_PKGCONFIG_REQUIRES "zlib, QtCore")
|
||||
-else()
|
||||
- message(FATAL_ERROR "Qt version ${QUAZIP_QT_MAJOR_VERSION} is not supported")
|
||||
-endif()
|
||||
-
|
||||
-message(STATUS "Using Qt version ${QUAZIP_QT_MAJOR_VERSION}")
|
||||
-
|
||||
-set(QUAZIP_QT_ZLIB_USED OFF)
|
||||
-if(QUAZIP_USE_QT_ZLIB)
|
||||
- find_package(Qt${QUAZIP_QT_MAJOR_VERSION} OPTIONAL_COMPONENTS ${QUAZIP_QT_ZLIB_COMPONENT})
|
||||
- set(QUAZIP_QT_ZLIB_COMPONENT_FOUND Qt${QUAZIP_QT_MAJOR_VERSION}${QUAZIP_QT_ZLIB_COMPONENT}_FOUND)
|
||||
- if (DEFINED QUAZIP_QT_ZLIB_HEADER_COMPONENT)
|
||||
- find_package(Qt${QUAZIP_QT_MAJOR_VERSION} OPTIONAL_COMPONENTS ${QUAZIP_QT_ZLIB_HEADER_COMPONENT})
|
||||
- set(QUAZIP_QT_ZLIB_HEADER_COMPONENT_FOUND Qt${QUAZIP_QT_MAJOR_VERSION}${QUAZIP_QT_ZLIB_HEADER_COMPONENT}_FOUND)
|
||||
- else()
|
||||
- set(QUAZIP_QT_ZLIB_HEADER_COMPONENT_FOUND ON)
|
||||
- endif()
|
||||
- if(QUAZIP_QT_ZLIB_COMPONENT_FOUND AND QUAZIP_QT_ZLIB_HEADER_COMPONENT_FOUND)
|
||||
- message(STATUS "Qt component ${QUAZIP_QT_ZLIB_COMPONENT} found")
|
||||
- set(QUAZIP_LIB_LIBRARIES ${QUAZIP_LIB_LIBRARIES} Qt${QUAZIP_QT_MAJOR_VERSION}::${QUAZIP_QT_ZLIB_COMPONENT})
|
||||
- if(DEFINED QUAZIP_QT_ZLIB_HEADER_COMPONENT)
|
||||
- message(STATUS "Qt component ${QUAZIP_QT_ZLIB_HEADER_COMPONENT} found")
|
||||
- set(QUAZIP_LIB_LIBRARIES ${QUAZIP_LIB_LIBRARIES} Qt${QUAZIP_QT_MAJOR_VERSION}::${QUAZIP_QT_ZLIB_HEADER_COMPONENT})
|
||||
- endif()
|
||||
- set(QUAZIP_QT_ZLIB_USED ON)
|
||||
- else()
|
||||
- message(FATAL_ERROR "QUAZIP_USE_QT_ZLIB was set but bundled zlib was not found. Terminating to prevent accidental linking to system libraries.")
|
||||
- endif()
|
||||
-endif()
|
||||
-
|
||||
-if(QUAZIP_QT_ZLIB_USED AND QUAZIP_QT_ZLIB_COMPONENT STREQUAL BundledZLIB)
|
||||
- # Qt's new BundledZLIB uses z-prefix in zlib
|
||||
- add_compile_definitions(Z_PREFIX)
|
||||
-endif()
|
||||
-
|
||||
-if(NOT QUAZIP_QT_ZLIB_USED)
|
||||
-
|
||||
- if(EMSCRIPTEN)
|
||||
- if(NOT DEFINED ZLIB_LIBRARY)
|
||||
- message(WARNING "ZLIB_LIBRARY is not set")
|
||||
- endif()
|
||||
+find_package(Qt6 REQUIRED COMPONENTS Core Core5Compat
|
||||
+ OPTIONAL_COMPONENTS Network Test)
|
||||
+message(STATUS "Found Qt version ${Qt6_VERSION} at ${Qt6_DIR}")
|
||||
+set(QUAZIP_QT_ZLIB_COMPONENT BundledZLIB)
|
||||
+set(QUAZIP_QT_ZLIB_HEADER_COMPONENT ZlibPrivate)
|
||||
+set(QUAZIP_LIB_LIBRARIES Qt6::Core Qt6::Core5Compat)
|
||||
+set(QUAZIP_TEST_QT_LIBRARIES Qt6::Core Qt6::Core5Compat Qt6::Network Qt6::Test)
|
||||
+set(QUAZIP_PKGCONFIG_REQUIRES "zlib, Qt6Core")
|
||||
|
||||
- if(NOT DEFINED ZLIB_INCLUDE)
|
||||
- message(WARNING "ZLIB_INCLUDE is not set")
|
||||
- else()
|
||||
- include_directories(${ZLIB_INCLUDE})
|
||||
- endif()
|
||||
-
|
||||
- if(NOT DEFINED ZCONF_INCLUDE)
|
||||
- message(WARNING "ZCONF_INCLUDE is not set")
|
||||
- else()
|
||||
- include_directories(${ZCONF_INCLUDE})
|
||||
- endif()
|
||||
-
|
||||
- set(QUAZIP_LIB_LIBRARIES ${QUAZIP_LIB_LIBRARIES} ${ZLIB_LIBRARY})
|
||||
- else()
|
||||
- find_package(ZLIB REQUIRED)
|
||||
- set(QUAZIP_LIB_LIBRARIES ${QUAZIP_LIB_LIBRARIES} ZLIB::ZLIB)
|
||||
- endif()
|
||||
-endif()
|
||||
+find_package(ZLIB REQUIRED)
|
||||
+set(QUAZIP_LIB_LIBRARIES ${QUAZIP_LIB_LIBRARIES} ZLIB::ZLIB)
|
||||
|
||||
if (ZLIB_CONST)
|
||||
add_compile_definitions(ZLIB_CONST)
|
||||
@@ -173,65 +50,4 @@ set(QUAZIP_INC)
|
||||
set(QUAZIP_LIB)
|
||||
set(QUAZIP_LBD)
|
||||
|
||||
-if(QUAZIP_BZIP2)
|
||||
- # Check if bzip2 is present
|
||||
- set(QUAZIP_BZIP2 ON)
|
||||
-
|
||||
- if(NOT QUAZIP_FORCE_FETCH_LIBS)
|
||||
- find_package(BZip2 QUIET)
|
||||
- endif()
|
||||
-
|
||||
- if(BZIP2_FOUND AND NOT QUAZIP_FORCE_FETCH_LIBS)
|
||||
- message(STATUS "Using BZIP2 ${BZIP2_VERSION_STRING}")
|
||||
-
|
||||
- list(APPEND QUAZIP_INC ${BZIP2_INCLUDE_DIRS})
|
||||
- list(APPEND QUAZIP_LIB ${BZIP2_LIBRARIES})
|
||||
- list(APPEND QUAZIP_LBD ${BZIP2_LIBRARY_DIRS})
|
||||
-
|
||||
- set(PC_PRIVATE_LIBS "${PC_PRIVATE_LIBS} -lbzip2")
|
||||
- elseif(QUAZIP_FETCH_LIBS)
|
||||
- clone_repo(bzip2 https://sourceware.org/git/bzip2.git)
|
||||
-
|
||||
- # BZip2 repository does not support cmake so we have to create
|
||||
- # the bzip2 library ourselves
|
||||
- set(BZIP2_SRC
|
||||
- ${BZIP2_SOURCE_DIR}/blocksort.c
|
||||
- ${BZIP2_SOURCE_DIR}/bzlib.c
|
||||
- ${BZIP2_SOURCE_DIR}/compress.c
|
||||
- ${BZIP2_SOURCE_DIR}/crctable.c
|
||||
- ${BZIP2_SOURCE_DIR}/decompress.c
|
||||
- ${BZIP2_SOURCE_DIR}/huffman.c
|
||||
- ${BZIP2_SOURCE_DIR}/randtable.c)
|
||||
-
|
||||
- set(BZIP2_HDR
|
||||
- ${BZIP2_SOURCE_DIR}/bzlib.h
|
||||
- ${BZIP2_SOURCE_DIR}/bzlib_private.h)
|
||||
-
|
||||
- add_library(bzip2 STATIC ${BZIP2_SRC} ${BZIP2_HDR})
|
||||
-
|
||||
- if(NOT QUAZIP_BZIP2_STDIO)
|
||||
- target_compile_definitions(bzip2 PRIVATE -DBZ_NO_STDIO)
|
||||
- endif()
|
||||
-
|
||||
- list(APPEND QUAZIP_DEP bzip2)
|
||||
- list(APPEND QUAZIP_LIB bzip2)
|
||||
- list(APPEND QUAZIP_INC ${BZIP2_SOURCE_DIR})
|
||||
- else()
|
||||
- message(STATUS "BZip2 library not found")
|
||||
-
|
||||
- set(QUAZIP_BZIP2 OFF)
|
||||
- endif()
|
||||
-
|
||||
- if(QUAZIP_BZIP2)
|
||||
- find_package(BZip2)
|
||||
- add_compile_definitions(HAVE_BZIP2)
|
||||
- endif()
|
||||
-endif()
|
||||
-
|
||||
add_subdirectory(quazip)
|
||||
-
|
||||
-if(QUAZIP_ENABLE_TESTS)
|
||||
- message(STATUS "Building QuaZip tests")
|
||||
- enable_testing()
|
||||
- add_subdirectory(qztest)
|
||||
-endif()
|
||||
diff --git a/quazip/CMakeLists.txt b/quazip/CMakeLists.txt
|
||||
index 6cfdf4e..66bc4cb 100644
|
||||
--- a/quazip/CMakeLists.txt
|
||||
+++ b/quazip/CMakeLists.txt
|
||||
@@ -46,10 +46,6 @@ set(QUAZIP_INCLUDE_PATH ${QUAZIP_DIR_NAME}/quazip)
|
||||
set(QUAZIP_INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake)
|
||||
set(QUAZIP_PKGCONFIG_NAME quazip${QuaZip_VERSION_MAJOR}-qt${QUAZIP_QT_MAJOR_VERSION})
|
||||
|
||||
-if(EMSCRIPTEN)
|
||||
- set(BUILD_SHARED_LIBS OFF)
|
||||
-endif()
|
||||
-
|
||||
add_library(${QUAZIP_LIB_TARGET_NAME} ${QUAZIP_SOURCES})
|
||||
add_library(QuaZip::QuaZip ALIAS ${QUAZIP_LIB_TARGET_NAME})
|
||||
|
||||
diff --git a/quazip/quazip_qt_compat.h b/quazip/quazip_qt_compat.h
|
||||
index 0dde011..41f9dd1 100644
|
||||
--- a/quazip/quazip_qt_compat.h
|
||||
+++ b/quazip/quazip_qt_compat.h
|
||||
@@ -14,16 +14,11 @@
|
||||
|
||||
// Legacy encodings are still everywhere, but the Qt team decided we
|
||||
// don't need them anymore and moved them out of Core in Qt 6.
|
||||
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
-# include <QtCore5Compat/QTextCodec>
|
||||
-#else
|
||||
-# include <QtCore/QTextCodec>
|
||||
-#endif
|
||||
+#include <QtCore5Compat/QTextCodec>
|
||||
|
||||
// QSaveFile terribly breaks the is-a idiom (Liskov substitution principle):
|
||||
// QSaveFile is-a QIODevice, but it makes close() private and aborts
|
||||
// if you call it through the base class. Hence this ugly hack:
|
||||
-#if (QT_VERSION >= 0x050100)
|
||||
#include <QtCore/QSaveFile>
|
||||
inline bool quazip_close(QIODevice *device) {
|
||||
QSaveFile *file = qobject_cast<QSaveFile*>(device);
|
||||
@@ -34,74 +29,35 @@ inline bool quazip_close(QIODevice *device) {
|
||||
device->close();
|
||||
return true;
|
||||
}
|
||||
-#else
|
||||
-inline bool quazip_close(QIODevice *device) {
|
||||
- device->close();
|
||||
- return true;
|
||||
-}
|
||||
-#endif
|
||||
|
||||
-// this is yet another stupid move and deprecation
|
||||
-#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
using Qt::SkipEmptyParts;
|
||||
-#else
|
||||
-#include <QtCore/QString>
|
||||
-const auto SkipEmptyParts = QString::SplitBehavior::SkipEmptyParts;
|
||||
-#endif
|
||||
|
||||
// and yet another... (why didn't they just make qSort delegate to std::sort?)
|
||||
#include <QtCore/QList>
|
||||
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 2, 0))
|
||||
#include <algorithm>
|
||||
template<typename T, typename C>
|
||||
inline void quazip_sort(T begin, T end, C comparator) {
|
||||
std::sort(begin, end, comparator);
|
||||
}
|
||||
-#else
|
||||
-#include <QtCore/QtAlgorithms>
|
||||
-template<typename T, typename C>
|
||||
-inline void quazip_sort(T begin, T end, C comparator) {
|
||||
- qSort(begin, end, comparator);
|
||||
-}
|
||||
-#endif
|
||||
|
||||
// this is a stupid rename...
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QFileInfo>
|
||||
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
|
||||
inline QDateTime quazip_ctime(const QFileInfo &fi) {
|
||||
return fi.birthTime();
|
||||
}
|
||||
-#else
|
||||
-inline QDateTime quazip_ctime(const QFileInfo &fi) {
|
||||
- return fi.created();
|
||||
-}
|
||||
-#endif
|
||||
|
||||
// this is just a slightly better alternative
|
||||
#include <QtCore/QFileInfo>
|
||||
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
|
||||
inline bool quazip_is_symlink(const QFileInfo &fi) {
|
||||
return fi.isSymbolicLink();
|
||||
}
|
||||
-#else
|
||||
-inline bool quazip_is_symlink(const QFileInfo &fi) {
|
||||
- // also detects *.lnk on Windows, but better than nothing
|
||||
- return fi.isSymLink();
|
||||
-}
|
||||
-#endif
|
||||
|
||||
// I'm not even sure what this one is, but nevertheless
|
||||
#include <QtCore/QFileInfo>
|
||||
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||
inline QString quazip_symlink_target(const QFileInfo &fi) {
|
||||
return fi.symLinkTarget();
|
||||
}
|
||||
-#else
|
||||
-inline QString quazip_symlink_target(const QFileInfo &fi) {
|
||||
- return fi.readLink(); // What's the difference? I've no idea.
|
||||
-}
|
||||
-#endif
|
||||
|
||||
// deprecation
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
@@ -125,40 +81,19 @@ inline QDateTime quazip_since_epoch_ntfs() {
|
||||
|
||||
// this is not a deprecation but an improvement, for a change
|
||||
#include <QtCore/QDateTime>
|
||||
-#if (QT_VERSION >= 0x040700)
|
||||
inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) {
|
||||
QDateTime base = quazip_since_epoch_ntfs();
|
||||
return base.msecsTo(time) * 10000 + fineTicks;
|
||||
}
|
||||
-#else
|
||||
-inline quint64 quazip_ntfs_ticks(const QDateTime &time, int fineTicks) {
|
||||
- QDateTime base = quazip_since_epoch_ntfs();
|
||||
- QDateTime utc = time.toUTC();
|
||||
- return (static_cast<qint64>(base.date().daysTo(utc.date()))
|
||||
- * Q_INT64_C(86400000)
|
||||
- + static_cast<qint64>(base.time().msecsTo(utc.time())))
|
||||
- * Q_INT64_C(10000) + fineTicks;
|
||||
-}
|
||||
-#endif
|
||||
|
||||
// yet another improvement...
|
||||
#include <QtCore/QDateTime>
|
||||
-#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0) // Yay! Finally a way to get time as qint64!
|
||||
inline qint64 quazip_to_time64_t(const QDateTime &time) {
|
||||
return time.toSecsSinceEpoch();
|
||||
}
|
||||
-#else
|
||||
-inline qint64 quazip_to_time64_t(const QDateTime &time) {
|
||||
- return static_cast<qint64>(time.toTime_t()); // 32 bits only, but better than nothing
|
||||
-}
|
||||
-#endif
|
||||
|
||||
#include <QtCore/QTextStream>
|
||||
-// and another stupid move
|
||||
-#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
|
||||
const auto quazip_endl = Qt::endl;
|
||||
-#else
|
||||
-const auto quazip_endl = endl;
|
||||
-#endif
|
||||
|
||||
#endif // QUAZIP_QT_COMPAT_H
|
||||
+
|
|
@ -29,10 +29,10 @@ elseif (TARGET SDL2::SDL2-shared)
|
|||
endif()
|
||||
|
||||
# Set bundled sdl2/qt as dependent options.
|
||||
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
|
||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" OFF "ENABLE_SDL2;NOT MSVC" OFF)
|
||||
else()
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" ON "ENABLE_SDL2;NOT MSVC" OFF)
|
||||
|
@ -60,7 +60,7 @@ endif()
|
|||
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" OFF)
|
||||
else()
|
||||
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON)
|
||||
option(YUZU_USE_EXTERNAL_VULKAN_HEADERS "Use Vulkan-Headers from externals" ON)
|
||||
endif()
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
|
@ -79,6 +79,8 @@ option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
|
|||
|
||||
option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF)
|
||||
|
||||
set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundled Qt libraries")
|
||||
|
||||
option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
|
||||
|
||||
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
||||
|
@ -465,12 +467,10 @@ if (ENABLE_QT)
|
|||
list(APPEND CMAKE_PREFIX_PATH "${Qt6_DIR}")
|
||||
endif()
|
||||
|
||||
# QT6 Multimedia pulls in unneeded audio systems (ALSA, Pulseaudio) for FreeBSD
|
||||
# ALSA is the default sound system on Linux, but FreeBSD uses OSS which works well enough
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent)
|
||||
else()
|
||||
find_package(Qt6 REQUIRED COMPONENTS Widgets Multimedia Concurrent)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Widgets Concurrent)
|
||||
|
||||
if (YUZU_USE_QT_MULTIMEDIA)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Multimedia)
|
||||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
|
|
24
CMakeModules/CPM.cmake
Normal file
24
CMakeModules/CPM.cmake
Normal file
|
@ -0,0 +1,24 @@
|
|||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors
|
||||
|
||||
set(CPM_DOWNLOAD_VERSION 0.42.0)
|
||||
set(CPM_HASH_SUM "2020b4fc42dba44817983e06342e682ecfc3d2f484a581f11cc5731fbe4dce8a")
|
||||
|
||||
if(CPM_SOURCE_CACHE)
|
||||
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
||||
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
|
||||
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
||||
else()
|
||||
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
|
||||
endif()
|
||||
|
||||
# Expand relative path. This is important if the provided path contains a tilde (~)
|
||||
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
|
||||
|
||||
file(DOWNLOAD
|
||||
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
|
||||
${CPM_DOWNLOAD_LOCATION} EXPECTED_HASH SHA256=${CPM_HASH_SUM}
|
||||
)
|
||||
|
||||
include(${CPM_DOWNLOAD_LOCATION})
|
|
@ -94,7 +94,7 @@ function(determine_qt_parameters target host_out type_out arch_out arch_path_out
|
|||
else()
|
||||
set(host "linux")
|
||||
set(type "desktop")
|
||||
set(arch "gcc_64")
|
||||
set(arch "linux_gcc_64")
|
||||
set(arch_path "linux")
|
||||
endif()
|
||||
|
||||
|
@ -133,12 +133,26 @@ function(download_qt_configuration prefix_out target host type arch arch_path ba
|
|||
set(install_args ${install_args} install-tool --outputdir ${base_path} ${host} desktop ${target})
|
||||
else()
|
||||
set(prefix "${base_path}/${target}/${arch_path}")
|
||||
set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} -m qt3d qt5compat qtactiveqt qtcharts qtconnectivity qtdatavis3d qtgraphs qtgrpc qthttpserver qtimageformats qtlanguageserver qtlocation qtlottie qtmultimedia qtnetworkauth qtpdf qtpositioning qtquick3d qtquick3dphysics qtquickeffectmaker qtquicktimeline qtremoteobjects qtscxml qtsensors qtserialbus qtserialport qtshadertools qtspeech qtvirtualkeyboard qtwebchannel qtwebengine qtwebsockets qtwebview)
|
||||
set(install_args ${install_args} install-qt --outputdir ${base_path} ${host} ${type} ${target} ${arch} -m qtbase)
|
||||
|
||||
if (YUZU_USE_QT_MULTIMEDIA)
|
||||
set(install_args ${install_args} qtmultimedia)
|
||||
endif()
|
||||
|
||||
if (YUZU_USE_QT_WEB_ENGINE)
|
||||
set(install_args ${install_args} qtpositioning qtwebchannel qtwebengine)
|
||||
endif()
|
||||
|
||||
if (NOT ${YUZU_QT_MIRROR} STREQUAL "")
|
||||
message(STATUS "Using Qt mirror ${YUZU_QT_MIRROR}")
|
||||
set(install_args ${install_args} -b ${YUZU_QT_MIRROR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
message(STATUS "Install Args ${install_args}")
|
||||
if (NOT EXISTS "${prefix}")
|
||||
message(STATUS "Downloading Qt binaries for ${target}:${host}:${type}:${arch}:${arch_path}")
|
||||
set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.2.1")
|
||||
set(AQT_PREBUILD_BASE_URL "https://github.com/miurahr/aqtinstall/releases/download/v3.3.0")
|
||||
if (WIN32)
|
||||
set(aqt_path "${base_path}/aqt.exe")
|
||||
if (NOT EXISTS "${aqt_path}")
|
||||
|
|
6
externals/dynarmic/CMakeLists.txt
vendored
6
externals/dynarmic/CMakeLists.txt
vendored
|
@ -98,8 +98,7 @@ else()
|
|||
-Wextra
|
||||
-Wcast-qual
|
||||
-pedantic
|
||||
-Wno-missing-braces
|
||||
-Wstack-usage=4096)
|
||||
-Wno-missing-braces)
|
||||
|
||||
if (ARCHITECTURE STREQUAL "x86_64")
|
||||
list(APPEND DYNARMIC_CXX_FLAGS -mtune=core2)
|
||||
|
@ -123,12 +122,15 @@ else()
|
|||
# GCC knows that the variable is actually a Reg64. isMEM() will never return true for a
|
||||
# Reg64, but GCC doesn't know that.
|
||||
list(APPEND DYNARMIC_CXX_FLAGS -Wno-array-bounds)
|
||||
list(APPEND DYNARMIC_CXX_FLAGS -Wstack-usage=4096)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "[Cc]lang")
|
||||
# Bracket depth determines maximum size of a fold expression in Clang since 9c9974c3ccb6.
|
||||
# And this in turns limits the size of a std::array.
|
||||
list(APPEND DYNARMIC_CXX_FLAGS -fbracket-depth=1024)
|
||||
# Clang mistakenly blames CMake for using unused arguments during compilation
|
||||
list(APPEND DYNARMIC_CXX_FLAGS -Wno-unused-command-line-argument)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
105
externals/dynarmic/src/dynarmic/CMakeLists.txt
vendored
105
externals/dynarmic/src/dynarmic/CMakeLists.txt
vendored
|
@ -125,52 +125,6 @@ if ("A32" IN_LIST DYNARMIC_FRONTENDS)
|
|||
frontend/A32/translate/a32_translate.h
|
||||
frontend/A32/translate/conditional_state.cpp
|
||||
frontend/A32/translate/conditional_state.h
|
||||
frontend/A32/translate/impl/a32_branch.cpp
|
||||
frontend/A32/translate/impl/a32_crc32.cpp
|
||||
frontend/A32/translate/impl/a32_exception_generating.cpp
|
||||
frontend/A32/translate/impl/a32_translate_impl.cpp
|
||||
frontend/A32/translate/impl/a32_translate_impl.h
|
||||
frontend/A32/translate/impl/asimd_load_store_structures.cpp
|
||||
frontend/A32/translate/impl/asimd_misc.cpp
|
||||
frontend/A32/translate/impl/asimd_one_reg_modified_immediate.cpp
|
||||
frontend/A32/translate/impl/asimd_three_regs.cpp
|
||||
frontend/A32/translate/impl/asimd_two_regs_misc.cpp
|
||||
frontend/A32/translate/impl/asimd_two_regs_scalar.cpp
|
||||
frontend/A32/translate/impl/asimd_two_regs_shift.cpp
|
||||
frontend/A32/translate/impl/barrier.cpp
|
||||
frontend/A32/translate/impl/coprocessor.cpp
|
||||
frontend/A32/translate/impl/data_processing.cpp
|
||||
frontend/A32/translate/impl/divide.cpp
|
||||
frontend/A32/translate/impl/extension.cpp
|
||||
frontend/A32/translate/impl/hint.cpp
|
||||
frontend/A32/translate/impl/load_store.cpp
|
||||
frontend/A32/translate/impl/misc.cpp
|
||||
frontend/A32/translate/impl/multiply.cpp
|
||||
frontend/A32/translate/impl/packing.cpp
|
||||
frontend/A32/translate/impl/parallel.cpp
|
||||
frontend/A32/translate/impl/reversal.cpp
|
||||
frontend/A32/translate/impl/saturated.cpp
|
||||
frontend/A32/translate/impl/status_register_access.cpp
|
||||
frontend/A32/translate/impl/synchronization.cpp
|
||||
frontend/A32/translate/impl/thumb16.cpp
|
||||
frontend/A32/translate/impl/thumb32_branch.cpp
|
||||
frontend/A32/translate/impl/thumb32_control.cpp
|
||||
frontend/A32/translate/impl/thumb32_coprocessor.cpp
|
||||
frontend/A32/translate/impl/thumb32_data_processing_modified_immediate.cpp
|
||||
frontend/A32/translate/impl/thumb32_data_processing_plain_binary_immediate.cpp
|
||||
frontend/A32/translate/impl/thumb32_data_processing_register.cpp
|
||||
frontend/A32/translate/impl/thumb32_data_processing_shifted_register.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_byte.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_halfword.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_store_dual.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_store_multiple.cpp
|
||||
frontend/A32/translate/impl/thumb32_load_word.cpp
|
||||
frontend/A32/translate/impl/thumb32_long_multiply.cpp
|
||||
frontend/A32/translate/impl/thumb32_misc.cpp
|
||||
frontend/A32/translate/impl/thumb32_multiply.cpp
|
||||
frontend/A32/translate/impl/thumb32_parallel.cpp
|
||||
frontend/A32/translate/impl/thumb32_store_single_data_item.cpp
|
||||
frontend/A32/translate/impl/vfp.cpp
|
||||
frontend/A32/translate/translate_arm.cpp
|
||||
frontend/A32/translate/translate_thumb.cpp
|
||||
interface/A32/a32.h
|
||||
|
@ -194,65 +148,6 @@ if ("A64" IN_LIST DYNARMIC_FRONTENDS)
|
|||
frontend/A64/decoder/a64.inc
|
||||
frontend/A64/translate/a64_translate.cpp
|
||||
frontend/A64/translate/a64_translate.h
|
||||
frontend/A64/translate/impl/a64_branch.cpp
|
||||
frontend/A64/translate/impl/a64_exception_generating.cpp
|
||||
frontend/A64/translate/impl/data_processing_addsub.cpp
|
||||
frontend/A64/translate/impl/data_processing_bitfield.cpp
|
||||
frontend/A64/translate/impl/data_processing_conditional_compare.cpp
|
||||
frontend/A64/translate/impl/data_processing_conditional_select.cpp
|
||||
frontend/A64/translate/impl/data_processing_crc32.cpp
|
||||
frontend/A64/translate/impl/data_processing_logical.cpp
|
||||
frontend/A64/translate/impl/data_processing_multiply.cpp
|
||||
frontend/A64/translate/impl/data_processing_pcrel.cpp
|
||||
frontend/A64/translate/impl/data_processing_register.cpp
|
||||
frontend/A64/translate/impl/data_processing_shift.cpp
|
||||
frontend/A64/translate/impl/floating_point_compare.cpp
|
||||
frontend/A64/translate/impl/floating_point_conditional_compare.cpp
|
||||
frontend/A64/translate/impl/floating_point_conditional_select.cpp
|
||||
frontend/A64/translate/impl/floating_point_conversion_fixed_point.cpp
|
||||
frontend/A64/translate/impl/floating_point_conversion_integer.cpp
|
||||
frontend/A64/translate/impl/floating_point_data_processing_one_register.cpp
|
||||
frontend/A64/translate/impl/floating_point_data_processing_three_register.cpp
|
||||
frontend/A64/translate/impl/floating_point_data_processing_two_register.cpp
|
||||
frontend/A64/translate/impl/impl.cpp
|
||||
frontend/A64/translate/impl/impl.h
|
||||
frontend/A64/translate/impl/load_store_exclusive.cpp
|
||||
frontend/A64/translate/impl/load_store_load_literal.cpp
|
||||
frontend/A64/translate/impl/load_store_multiple_structures.cpp
|
||||
frontend/A64/translate/impl/load_store_no_allocate_pair.cpp
|
||||
frontend/A64/translate/impl/load_store_register_immediate.cpp
|
||||
frontend/A64/translate/impl/load_store_register_pair.cpp
|
||||
frontend/A64/translate/impl/load_store_register_register_offset.cpp
|
||||
frontend/A64/translate/impl/load_store_register_unprivileged.cpp
|
||||
frontend/A64/translate/impl/load_store_single_structure.cpp
|
||||
frontend/A64/translate/impl/move_wide.cpp
|
||||
frontend/A64/translate/impl/simd_across_lanes.cpp
|
||||
frontend/A64/translate/impl/simd_aes.cpp
|
||||
frontend/A64/translate/impl/simd_copy.cpp
|
||||
frontend/A64/translate/impl/simd_crypto_four_register.cpp
|
||||
frontend/A64/translate/impl/simd_crypto_three_register.cpp
|
||||
frontend/A64/translate/impl/simd_extract.cpp
|
||||
frontend/A64/translate/impl/simd_modified_immediate.cpp
|
||||
frontend/A64/translate/impl/simd_permute.cpp
|
||||
frontend/A64/translate/impl/simd_scalar_pairwise.cpp
|
||||
frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp
|
||||
frontend/A64/translate/impl/simd_scalar_three_same.cpp
|
||||
frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp
|
||||
frontend/A64/translate/impl/simd_scalar_x_indexed_element.cpp
|
||||
frontend/A64/translate/impl/simd_sha.cpp
|
||||
frontend/A64/translate/impl/simd_sha512.cpp
|
||||
frontend/A64/translate/impl/simd_shift_by_immediate.cpp
|
||||
frontend/A64/translate/impl/simd_table_lookup.cpp
|
||||
frontend/A64/translate/impl/simd_three_different.cpp
|
||||
frontend/A64/translate/impl/simd_three_same.cpp
|
||||
frontend/A64/translate/impl/simd_three_same_extra.cpp
|
||||
frontend/A64/translate/impl/simd_two_register_misc.cpp
|
||||
frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp
|
||||
frontend/A64/translate/impl/sys_dc.cpp
|
||||
frontend/A64/translate/impl/sys_ic.cpp
|
||||
frontend/A64/translate/impl/system.cpp
|
||||
frontend/A64/translate/impl/system_flag_format.cpp
|
||||
frontend/A64/translate/impl/system_flag_manipulation.cpp
|
||||
interface/A64/a64.h
|
||||
interface/A64/config.h
|
||||
ir/opt/a64_callback_config_pass.cpp
|
||||
|
|
|
@ -59,13 +59,12 @@ constexpr RegisterList ToRegList(oaknut::Reg reg) {
|
|||
}
|
||||
|
||||
if (reg.index() == 31) {
|
||||
throw std::out_of_range("ZR not allowed in reg list");
|
||||
ASSERT_FALSE("ZR not allowed in reg list");
|
||||
}
|
||||
|
||||
if (reg.index() == -1) {
|
||||
return RegisterList{1} << 31;
|
||||
}
|
||||
|
||||
return RegisterList{1} << reg.index();
|
||||
}
|
||||
|
||||
|
|
|
@ -14,29 +14,26 @@ namespace Dynarmic::Backend::RV64 {
|
|||
|
||||
class CodeBlock {
|
||||
public:
|
||||
explicit CodeBlock(std::size_t size)
|
||||
: memsize(size) {
|
||||
explicit CodeBlock(std::size_t size) noexcept : memsize(size) {
|
||||
mem = (u8*)mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
|
||||
|
||||
if (mem == nullptr)
|
||||
throw std::bad_alloc{};
|
||||
ASSERT_FALSE("out of memory");
|
||||
}
|
||||
|
||||
~CodeBlock() {
|
||||
~CodeBlock() noexcept {
|
||||
if (mem == nullptr)
|
||||
return;
|
||||
|
||||
munmap(mem, memsize);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T ptr() const {
|
||||
T ptr() const noexcept {
|
||||
static_assert(std::is_pointer_v<T> || std::is_same_v<T, uptr> || std::is_same_v<T, sptr>);
|
||||
return reinterpret_cast<T>(mem);
|
||||
}
|
||||
|
||||
protected:
|
||||
u8* mem;
|
||||
u8* mem = nullptr;
|
||||
size_t memsize = 0;
|
||||
};
|
||||
} // namespace Dynarmic::Backend::RV64
|
||||
|
|
|
@ -124,35 +124,36 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
|
|||
|
||||
EmitCondPrelude(ctx);
|
||||
|
||||
for (auto iter = block.begin(); iter != block.end(); ++iter) {
|
||||
IR::Inst* inst = &*iter;
|
||||
|
||||
// Call the relevant Emit* member function.
|
||||
switch (inst->GetOpcode()) {
|
||||
#define OPCODE(name, type, ...) \
|
||||
case IR::Opcode::name: \
|
||||
A32EmitX64::Emit##name(ctx, inst); \
|
||||
break;
|
||||
#define A32OPC(name, type, ...) \
|
||||
case IR::Opcode::A32##name: \
|
||||
A32EmitX64::EmitA32##name(ctx, inst); \
|
||||
break;
|
||||
auto const loop_all_inst = [this, &block, &ctx](auto const func) {
|
||||
for (auto iter = block.begin(); iter != block.end(); ++iter) [[likely]] {
|
||||
auto* inst = &*iter;
|
||||
// Call the relevant Emit* member function.
|
||||
switch (inst->GetOpcode()) {
|
||||
#define OPCODE(name, type, ...) \
|
||||
case IR::Opcode::name: \
|
||||
A32EmitX64::Emit##name(ctx, inst); \
|
||||
break;
|
||||
#define A32OPC(name, type, ...) \
|
||||
case IR::Opcode::A32##name: \
|
||||
A32EmitX64::EmitA32##name(ctx, inst);\
|
||||
break;
|
||||
#define A64OPC(...)
|
||||
#include "dynarmic/ir/opcodes.inc"
|
||||
#undef OPCODE
|
||||
#undef A32OPC
|
||||
#undef A64OPC
|
||||
|
||||
default:
|
||||
ASSERT_FALSE("Invalid opcode: {}", inst->GetOpcode());
|
||||
break;
|
||||
default: [[unlikely]] ASSERT_FALSE("Invalid opcode: {}", inst->GetOpcode());
|
||||
}
|
||||
reg_alloc.EndOfAllocScope();
|
||||
func(reg_alloc);
|
||||
}
|
||||
|
||||
reg_alloc.EndOfAllocScope();
|
||||
|
||||
if (conf.very_verbose_debugging_output) {
|
||||
};
|
||||
if (!conf.very_verbose_debugging_output) [[likely]] {
|
||||
loop_all_inst([](auto&) { /*noop*/ });
|
||||
} else [[unlikely]] {
|
||||
loop_all_inst([this](auto& reg_alloc) {
|
||||
EmitVerboseDebuggingOutput(reg_alloc);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reg_alloc.AssertNoMoreUses();
|
||||
|
@ -229,7 +230,7 @@ void A32EmitX64::GenTerminalHandlers() {
|
|||
terminal_handler_pop_rsb_hint = code.getCurr<const void*>();
|
||||
calculate_location_descriptor();
|
||||
code.mov(eax, dword[r15 + offsetof(A32JitState, rsb_ptr)]);
|
||||
code.sub(eax, 1);
|
||||
code.dec(eax);
|
||||
code.and_(eax, u32(A32JitState::RSBPtrMask));
|
||||
code.mov(dword[r15 + offsetof(A32JitState, rsb_ptr)], eax);
|
||||
code.cmp(rbx, qword[r15 + offsetof(A32JitState, rsb_location_descriptors) + rax * sizeof(u64)]);
|
||||
|
|
|
@ -198,18 +198,19 @@ void A64EmitX64::GenTerminalHandlers() {
|
|||
code.or_(rbx, rcx);
|
||||
};
|
||||
|
||||
Xbyak::Label fast_dispatch_cache_miss, rsb_cache_miss;
|
||||
Xbyak::Label fast_dispatch_cache_miss;
|
||||
Xbyak::Label rsb_cache_miss;
|
||||
|
||||
code.align();
|
||||
terminal_handler_pop_rsb_hint = code.getCurr<const void*>();
|
||||
calculate_location_descriptor();
|
||||
code.mov(eax, dword[r15 + offsetof(A64JitState, rsb_ptr)]);
|
||||
code.sub(eax, 1);
|
||||
code.dec(eax);
|
||||
code.and_(eax, u32(A64JitState::RSBPtrMask));
|
||||
code.mov(dword[r15 + offsetof(A64JitState, rsb_ptr)], eax);
|
||||
code.cmp(rbx, qword[r15 + offsetof(A64JitState, rsb_location_descriptors) + rax * sizeof(u64)]);
|
||||
if (conf.HasOptimization(OptimizationFlag::FastDispatch)) {
|
||||
code.jne(rsb_cache_miss);
|
||||
code.jne(rsb_cache_miss, code.T_NEAR);
|
||||
} else {
|
||||
code.jne(code.GetReturnFromRunCodeAddress());
|
||||
}
|
||||
|
|
|
@ -33,13 +33,13 @@ void A64EmitX64::GenMemory128Accessors() {
|
|||
#ifdef _WIN32
|
||||
Devirtualize<&A64::UserCallbacks::MemoryRead128>(conf.callbacks).EmitCallWithReturnPointer(code, [&](Xbyak::Reg64 return_value_ptr, [[maybe_unused]] RegList args) {
|
||||
code.mov(code.ABI_PARAM3, code.ABI_PARAM2);
|
||||
code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (8 + 16 + ABI_SHADOW_SPACE)]);
|
||||
code.lea(return_value_ptr, ptr[rsp + ABI_SHADOW_SPACE]);
|
||||
});
|
||||
code.movups(xmm1, xword[code.ABI_RETURN]);
|
||||
code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
||||
#else
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
Devirtualize<&A64::UserCallbacks::MemoryRead128>(conf.callbacks).EmitCall(code);
|
||||
if (code.HasHostFeature(HostFeature::SSE41)) {
|
||||
code.movq(xmm1, code.ABI_RETURN);
|
||||
|
@ -57,13 +57,13 @@ void A64EmitX64::GenMemory128Accessors() {
|
|||
code.align();
|
||||
memory_write_128 = code.getCurr<void (*)()>();
|
||||
#ifdef _WIN32
|
||||
code.sub(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (8 + 16 + ABI_SHADOW_SPACE)]);
|
||||
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]);
|
||||
code.movaps(xword[code.ABI_PARAM3], xmm1);
|
||||
Devirtualize<&A64::UserCallbacks::MemoryWrite128>(conf.callbacks).EmitCall(code);
|
||||
code.add(rsp, 8 + 16 + ABI_SHADOW_SPACE);
|
||||
#else
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
if (code.HasHostFeature(HostFeature::SSE41)) {
|
||||
code.movq(code.ABI_PARAM3, xmm1);
|
||||
code.pextrq(code.ABI_PARAM4, xmm1, 1);
|
||||
|
@ -81,7 +81,7 @@ void A64EmitX64::GenMemory128Accessors() {
|
|||
code.align();
|
||||
memory_exclusive_write_128 = code.getCurr<void (*)()>();
|
||||
#ifdef _WIN32
|
||||
code.sub(rsp, 8 + 32 + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (8 + 32 + ABI_SHADOW_SPACE)]);
|
||||
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE]);
|
||||
code.lea(code.ABI_PARAM4, ptr[rsp + ABI_SHADOW_SPACE + 16]);
|
||||
code.movaps(xword[code.ABI_PARAM3], xmm1);
|
||||
|
@ -89,7 +89,7 @@ void A64EmitX64::GenMemory128Accessors() {
|
|||
Devirtualize<&A64::UserCallbacks::MemoryWriteExclusive128>(conf.callbacks).EmitCall(code);
|
||||
code.add(rsp, 8 + 32 + ABI_SHADOW_SPACE);
|
||||
#else
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
if (code.HasHostFeature(HostFeature::SSE41)) {
|
||||
code.movq(code.ABI_PARAM3, xmm1);
|
||||
code.pextrq(code.ABI_PARAM4, xmm1, 1);
|
||||
|
@ -131,8 +131,8 @@ void A64EmitX64::GenFastmemFallbacks() {
|
|||
{64, Devirtualize<&A64::UserCallbacks::MemoryWriteExclusive64>(conf.callbacks)},
|
||||
}};
|
||||
|
||||
for (bool ordered : {false, true}) {
|
||||
for (int vaddr_idx : idxes) {
|
||||
for (auto const ordered : {false, true}) {
|
||||
for (auto const vaddr_idx : idxes) {
|
||||
if (vaddr_idx == 4 || vaddr_idx == 15) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,8 @@ public:
|
|||
uint8_t* alloc(size_t size) override {
|
||||
void* p = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_READWRITE);
|
||||
if (p == nullptr) {
|
||||
throw Xbyak::Error(Xbyak::ERR_CANT_ALLOC);
|
||||
using Xbyak::Error;
|
||||
XBYAK_THROW(Xbyak::ERR_CANT_ALLOC);
|
||||
}
|
||||
return static_cast<uint8_t*>(p);
|
||||
}
|
||||
|
@ -95,7 +96,8 @@ public:
|
|||
|
||||
void* p = mmap(nullptr, size, PROT_READ | PROT_WRITE, mode, -1, 0);
|
||||
if (p == MAP_FAILED) {
|
||||
throw Xbyak::Error(Xbyak::ERR_CANT_ALLOC);
|
||||
using Xbyak::Error;
|
||||
XBYAK_THROW(Xbyak::ERR_CANT_ALLOC);
|
||||
}
|
||||
std::memcpy(p, &size, sizeof(size_t));
|
||||
return static_cast<uint8_t*>(p) + DYNARMIC_PAGE_SIZE;
|
||||
|
@ -514,7 +516,8 @@ size_t BlockOfCode::GetTotalCodeSize() const {
|
|||
|
||||
void* BlockOfCode::AllocateFromCodeSpace(size_t alloc_size) {
|
||||
if (size_ + alloc_size >= maxSize_) {
|
||||
throw Xbyak::Error(Xbyak::ERR_CODE_IS_TOO_BIG);
|
||||
using Xbyak::Error;
|
||||
XBYAK_THROW(Xbyak::ERR_CODE_IS_TOO_BIG);
|
||||
}
|
||||
|
||||
EnsureMemoryCommitted(alloc_size);
|
||||
|
|
|
@ -104,7 +104,7 @@ void EmitX64::PushRSBHelper(Xbyak::Reg64 loc_desc_reg, Xbyak::Reg64 index_reg, I
|
|||
}
|
||||
|
||||
void EmitX64::EmitVerboseDebuggingOutput(RegAlloc& reg_alloc) {
|
||||
code.sub(rsp, sizeof(RegisterData));
|
||||
code.lea(rsp, ptr[rsp - sizeof(RegisterData)]);
|
||||
code.stmxcsr(dword[rsp + offsetof(RegisterData, mxcsr)]);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (rsp.getIdx() == i) {
|
||||
|
@ -223,7 +223,7 @@ void EmitX64::EmitGetNZCVFromOp(EmitContext& ctx, IR::Inst* inst) {
|
|||
const Xbyak::Reg value = ctx.reg_alloc.UseGpr(args[0]).changeBit(bitsize);
|
||||
code.test(value, value);
|
||||
code.lahf();
|
||||
code.mov(al, 0);
|
||||
code.xor_(al, al);
|
||||
ctx.reg_alloc.DefineValue(inst, nzcv);
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,6 @@ void EmitX64::EmitNZCVFromPackedFlags(EmitContext& ctx, IR::Inst* inst) {
|
|||
code.shr(nzcv, 28);
|
||||
code.imul(nzcv, nzcv, NZCV::to_x64_multiplier);
|
||||
code.and_(nzcv, NZCV::x64_mask);
|
||||
|
||||
ctx.reg_alloc.DefineValue(inst, nzcv);
|
||||
}
|
||||
}
|
||||
|
@ -331,10 +330,8 @@ Xbyak::Label EmitX64::EmitCond(IR::Cond cond) {
|
|||
code.jle(pass);
|
||||
break;
|
||||
default:
|
||||
ASSERT_MSG(false, "Unknown cond {}", static_cast<size_t>(cond));
|
||||
break;
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
|
|
|
@ -992,7 +992,6 @@ static void EmitAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst, int bit
|
|||
code.seto(overflow);
|
||||
ctx.reg_alloc.DefineValue(overflow_inst, overflow);
|
||||
}
|
||||
|
||||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,23 @@
|
|||
#include "dynarmic/ir/basic_block.h"
|
||||
#include "dynarmic/ir/microinstruction.h"
|
||||
|
||||
#define FCODE(NAME) \
|
||||
[&code](auto... args) { \
|
||||
if constexpr (fsize == 32) { \
|
||||
code.NAME##s(args...); \
|
||||
} else { \
|
||||
code.NAME##d(args...); \
|
||||
} \
|
||||
}
|
||||
#define ICODE(NAME) \
|
||||
[&code](auto... args) { \
|
||||
if constexpr (fsize == 32) { \
|
||||
code.NAME##d(args...); \
|
||||
} else { \
|
||||
code.NAME##q(args...); \
|
||||
} \
|
||||
}
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
using namespace Xbyak::util;
|
||||
|
@ -60,23 +77,6 @@ constexpr u64 f64_max_s32 = 0x41dfffffffc00000u; // 2147483647 as a double
|
|||
constexpr u64 f64_max_u32 = 0x41efffffffe00000u; // 4294967295 as a double
|
||||
constexpr u64 f64_max_s64_lim = 0x43e0000000000000u; // 2^63 as a double (actual maximum unrepresentable)
|
||||
|
||||
#define FCODE(NAME) \
|
||||
[&code](auto... args) { \
|
||||
if constexpr (fsize == 32) { \
|
||||
code.NAME##s(args...); \
|
||||
} else { \
|
||||
code.NAME##d(args...); \
|
||||
} \
|
||||
}
|
||||
#define ICODE(NAME) \
|
||||
[&code](auto... args) { \
|
||||
if constexpr (fsize == 32) { \
|
||||
code.NAME##d(args...); \
|
||||
} else { \
|
||||
code.NAME##q(args...); \
|
||||
} \
|
||||
}
|
||||
|
||||
template<size_t fsize>
|
||||
void ForceDenormalsToZero(BlockOfCode& code, std::initializer_list<Xbyak::Xmm> to_daz) {
|
||||
if (code.HasHostFeature(HostFeature::AVX512_OrthoFloat)) {
|
||||
|
@ -473,7 +473,7 @@ static void EmitFPMinMax(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
template<size_t fsize, bool is_max>
|
||||
static void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
||||
static inline void EmitFPMinMaxNumeric(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) noexcept {
|
||||
using FPT = mcl::unsigned_integer_of_size<fsize>;
|
||||
constexpr FPT default_nan = FP::FPInfo<FPT>::DefaultNaN();
|
||||
|
||||
|
@ -701,15 +701,14 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
// x64 rounds before flushing to zero
|
||||
// AArch64 rounds after flushing to zero
|
||||
// This difference of behaviour is noticable if something would round to a smallest normalized number
|
||||
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
code.movq(code.ABI_PARAM1, operand1);
|
||||
code.movq(code.ABI_PARAM2, operand2);
|
||||
code.movq(code.ABI_PARAM3, operand3);
|
||||
code.mov(code.ABI_PARAM4.cvt32(), ctx.FPCR().Value());
|
||||
#ifdef _WIN32
|
||||
code.sub(rsp, 16 + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (16 + ABI_SHADOW_SPACE)]);
|
||||
code.lea(rax, code.ptr[code.r15 + code.GetJitStateInfo().offsetof_fpsr_exc]);
|
||||
code.mov(qword[rsp + ABI_SHADOW_SPACE], rax);
|
||||
code.CallFunction(fallback_fn);
|
||||
|
@ -735,13 +734,13 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
code.vmovaps(xmm0, code.Const(xword, FP::FPInfo<FPT>::mantissa_msb));
|
||||
|
||||
FCODE(ucomis)(operand2, operand3);
|
||||
code.jp(has_nan);
|
||||
code.jp(has_nan, code.T_NEAR);
|
||||
FCODE(ucomis)(operand1, operand1);
|
||||
code.jnp(indeterminate);
|
||||
code.jnp(indeterminate, code.T_NEAR);
|
||||
|
||||
// AArch64 specifically emits a default NaN for the case when the addend is a QNaN and the two other arguments are {inf, zero}
|
||||
code.ptest(operand1, xmm0);
|
||||
code.jz(op1_snan);
|
||||
code.jz(op1_snan, code.T_NEAR);
|
||||
FCODE(vmuls)(xmm0, operand2, operand3); // check if {op2, op3} are {inf, zero}/{zero, inf}
|
||||
FCODE(ucomis)(xmm0, xmm0);
|
||||
code.jnp(*end);
|
||||
|
@ -753,10 +752,10 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
code.L(has_nan);
|
||||
|
||||
FCODE(ucomis)(operand1, operand1);
|
||||
code.jnp(op1_done);
|
||||
code.jnp(op1_done, code.T_NEAR);
|
||||
code.movaps(result, operand1); // this is done because of NaN behavior of vfmadd231s (priority of op2, op3, op1)
|
||||
code.ptest(operand1, xmm0);
|
||||
code.jnz(op1_done);
|
||||
code.jnz(op1_done, code.T_NEAR);
|
||||
code.L(op1_snan);
|
||||
code.vorps(result, operand1, xmm0);
|
||||
code.jmp(*end);
|
||||
|
@ -774,9 +773,9 @@ static void EmitFPMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
code.L(op2_done);
|
||||
|
||||
FCODE(ucomis)(operand3, operand3);
|
||||
code.jnp(op3_done);
|
||||
code.jnp(op3_done, code.T_NEAR);
|
||||
code.ptest(operand3, xmm0);
|
||||
code.jnz(op3_done);
|
||||
code.jnz(op3_done, code.T_NEAR);
|
||||
code.vorps(result, operand3, xmm0);
|
||||
code.jmp(*end);
|
||||
code.L(op3_done);
|
||||
|
@ -1019,7 +1018,7 @@ static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst*
|
|||
ctx.deferred_emits.emplace_back([=, &code, &ctx] {
|
||||
code.L(*fallback);
|
||||
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
code.movq(code.ABI_PARAM1, operand1);
|
||||
code.movq(code.ABI_PARAM2, operand2);
|
||||
|
@ -1204,9 +1203,9 @@ static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* i
|
|||
}
|
||||
|
||||
// a > 0 && a < 0x00800000;
|
||||
code.sub(tmp, 1);
|
||||
code.dec(tmp);
|
||||
code.cmp(tmp, 0x007FFFFF);
|
||||
code.jb(fallback);
|
||||
code.jb(fallback, code.T_NEAR); //within -127,128
|
||||
needs_fallback = true;
|
||||
}
|
||||
|
||||
|
@ -1235,17 +1234,17 @@ static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* i
|
|||
|
||||
code.ucomisd(value, result);
|
||||
if (ctx.FPCR().DN()) {
|
||||
code.jc(default_nan);
|
||||
code.je(zero);
|
||||
code.jc(default_nan, code.T_NEAR);
|
||||
code.je(zero, code.T_NEAR);
|
||||
} else {
|
||||
code.jp(nan);
|
||||
code.je(zero);
|
||||
code.jc(default_nan);
|
||||
code.jp(nan, code.T_NEAR);
|
||||
code.je(zero, code.T_NEAR);
|
||||
code.jc(default_nan, code.T_NEAR);
|
||||
}
|
||||
|
||||
if (!ctx.FPCR().FZ()) {
|
||||
needs_fallback = true;
|
||||
code.jmp(fallback);
|
||||
code.jmp(fallback, code.T_NEAR);
|
||||
} else {
|
||||
// result = 0
|
||||
code.jmp(*end, code.T_NEAR);
|
||||
|
@ -1278,7 +1277,7 @@ static void EmitFPRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* i
|
|||
|
||||
code.L(fallback);
|
||||
if (needs_fallback) {
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
code.movq(code.ABI_PARAM1, operand);
|
||||
code.mov(code.ABI_PARAM2.cvt32(), ctx.FPCR().Value());
|
||||
|
@ -1361,7 +1360,7 @@ static void EmitFPRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst*
|
|||
ctx.deferred_emits.emplace_back([=, &code, &ctx] {
|
||||
code.L(*fallback);
|
||||
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
code.movq(code.ABI_PARAM1, operand1);
|
||||
code.movq(code.ABI_PARAM2, operand2);
|
||||
|
@ -2132,3 +2131,6 @@ void EmitX64::EmitFPFixedU64ToSingle(EmitContext& ctx, IR::Inst* inst) {
|
|||
ctx.reg_alloc.DefineValue(inst, result);
|
||||
}
|
||||
} // namespace Dynarmic::Backend::X64
|
||||
|
||||
#undef FCODE
|
||||
#undef ICODE
|
||||
|
|
|
@ -161,8 +161,7 @@ template<>
|
|||
|
||||
template<>
|
||||
[[maybe_unused]] Xbyak::RegExp EmitFastmemVAddr<A64EmitContext>(BlockOfCode& code, A64EmitContext& ctx, Xbyak::Label& abort, Xbyak::Reg64 vaddr, bool& require_abort_handling, std::optional<Xbyak::Reg64> tmp) {
|
||||
const size_t unused_top_bits = 64 - ctx.conf.fastmem_address_space_bits;
|
||||
|
||||
auto const unused_top_bits = 64 - ctx.conf.fastmem_address_space_bits;
|
||||
if (unused_top_bits == 0) {
|
||||
return r13 + vaddr;
|
||||
} else if (ctx.conf.silently_mirror_fastmem) {
|
||||
|
@ -306,7 +305,7 @@ const void* EmitWriteMemoryMov(BlockOfCode& code, const Xbyak::RegExp& addr, int
|
|||
code.L(loop);
|
||||
code.lock();
|
||||
code.cmpxchg16b(xword[addr]);
|
||||
code.jnz(loop);
|
||||
code.jnz(loop, code.T_NEAR);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -373,7 +372,7 @@ void EmitExclusiveTestAndClear(BlockOfCode& code, const UserConfig& conf, Xbyak:
|
|||
Xbyak::Label ok;
|
||||
code.mov(pointer, mcl::bit_cast<u64>(GetExclusiveMonitorAddressPointer(conf.global_monitor, processor_index)));
|
||||
code.cmp(qword[pointer], vaddr);
|
||||
code.jne(ok);
|
||||
code.jne(ok, code.T_NEAR);
|
||||
code.mov(qword[pointer], tmp);
|
||||
code.L(ok);
|
||||
}
|
||||
|
|
|
@ -33,13 +33,6 @@
|
|||
#include "dynarmic/ir/basic_block.h"
|
||||
#include "dynarmic/ir/microinstruction.h"
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
using namespace Xbyak::util;
|
||||
namespace mp = mcl::mp;
|
||||
|
||||
namespace {
|
||||
|
||||
#define FCODE(NAME) \
|
||||
[&code](auto... args) { \
|
||||
if constexpr (fsize == 32) { \
|
||||
|
@ -57,6 +50,13 @@ namespace {
|
|||
} \
|
||||
}
|
||||
|
||||
namespace Dynarmic::Backend::X64 {
|
||||
|
||||
using namespace Xbyak::util;
|
||||
namespace mp = mcl::mp;
|
||||
|
||||
namespace {
|
||||
|
||||
template<typename Lambda>
|
||||
void MaybeStandardFPSCRValue(BlockOfCode& code, EmitContext& ctx, bool fpcr_controlled, Lambda lambda) {
|
||||
const bool switch_mxcsr = ctx.FPCR(fpcr_controlled) != ctx.FPCR();
|
||||
|
@ -122,11 +122,11 @@ void HandleNaNs(BlockOfCode& code, EmitContext& ctx, bool fpcr_controlled, std::
|
|||
|
||||
const Xbyak::Xmm result = xmms[0];
|
||||
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
|
||||
const size_t stack_space = xmms.size() * 16;
|
||||
code.sub(rsp, static_cast<u32>(stack_space + ABI_SHADOW_SPACE));
|
||||
code.lea(rsp, ptr[rsp - static_cast<u32>(stack_space + ABI_SHADOW_SPACE)]);
|
||||
for (size_t i = 0; i < xmms.size(); ++i) {
|
||||
code.movaps(xword[rsp + ABI_SHADOW_SPACE + i * 16], xmms[i]);
|
||||
}
|
||||
|
@ -443,7 +443,7 @@ void EmitTwoOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbyak
|
|||
const u32 fpcr = ctx.FPCR(fpcr_controlled).Value();
|
||||
|
||||
constexpr u32 stack_space = 2 * 16;
|
||||
code.sub(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (stack_space + ABI_SHADOW_SPACE)]);
|
||||
code.lea(code.ABI_PARAM1, ptr[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
||||
code.lea(code.ABI_PARAM2, ptr[rsp + ABI_SHADOW_SPACE + 1 * 16]);
|
||||
code.mov(code.ABI_PARAM3.cvt32(), fpcr);
|
||||
|
@ -479,7 +479,7 @@ void EmitThreeOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xby
|
|||
|
||||
#ifdef _WIN32
|
||||
constexpr u32 stack_space = 4 * 16;
|
||||
code.sub(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (stack_space + ABI_SHADOW_SPACE)]);
|
||||
code.lea(code.ABI_PARAM1, ptr[rsp + ABI_SHADOW_SPACE + 1 * 16]);
|
||||
code.lea(code.ABI_PARAM2, ptr[rsp + ABI_SHADOW_SPACE + 2 * 16]);
|
||||
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE + 3 * 16]);
|
||||
|
@ -488,7 +488,7 @@ void EmitThreeOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xby
|
|||
code.mov(qword[rsp + ABI_SHADOW_SPACE + 0], rax);
|
||||
#else
|
||||
constexpr u32 stack_space = 3 * 16;
|
||||
code.sub(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (stack_space + ABI_SHADOW_SPACE)]);
|
||||
code.lea(code.ABI_PARAM1, ptr[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
||||
code.lea(code.ABI_PARAM2, ptr[rsp + ABI_SHADOW_SPACE + 1 * 16]);
|
||||
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE + 2 * 16]);
|
||||
|
@ -536,7 +536,7 @@ void EmitFourOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbya
|
|||
|
||||
#ifdef _WIN32
|
||||
constexpr u32 stack_space = 5 * 16;
|
||||
code.sub(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (stack_space + ABI_SHADOW_SPACE)]);
|
||||
code.lea(code.ABI_PARAM1, ptr[rsp + ABI_SHADOW_SPACE + 1 * 16]);
|
||||
code.lea(code.ABI_PARAM2, ptr[rsp + ABI_SHADOW_SPACE + 2 * 16]);
|
||||
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE + 3 * 16]);
|
||||
|
@ -546,7 +546,7 @@ void EmitFourOpFallbackWithoutRegAlloc(BlockOfCode& code, EmitContext& ctx, Xbya
|
|||
code.mov(qword[rsp + ABI_SHADOW_SPACE + 8], rax);
|
||||
#else
|
||||
constexpr u32 stack_space = 4 * 16;
|
||||
code.sub(rsp, stack_space + ABI_SHADOW_SPACE);
|
||||
code.lea(rsp, ptr[rsp - (stack_space + ABI_SHADOW_SPACE)]);
|
||||
code.lea(code.ABI_PARAM1, ptr[rsp + ABI_SHADOW_SPACE + 0 * 16]);
|
||||
code.lea(code.ABI_PARAM2, ptr[rsp + ABI_SHADOW_SPACE + 1 * 16]);
|
||||
code.lea(code.ABI_PARAM3, ptr[rsp + ABI_SHADOW_SPACE + 2 * 16]);
|
||||
|
@ -1371,7 +1371,7 @@ void EmitFPVectorMulAdd(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) {
|
|||
|
||||
ctx.deferred_emits.emplace_back([=, &code, &ctx] {
|
||||
code.L(*fallback);
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
if (needs_rounding_correction && needs_nan_correction) {
|
||||
EmitFourOpFallbackWithoutRegAlloc<LoadPreviousResult::Yes>(code, ctx, result, xmm_a, xmm_b, xmm_c, EmitFPVectorMulAddFallback<FPT, true, true>, fpcr_controlled);
|
||||
|
@ -1635,7 +1635,7 @@ static void EmitRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
|
|||
|
||||
ctx.deferred_emits.emplace_back([=, &code, &ctx] {
|
||||
code.L(*fallback);
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
EmitThreeOpFallbackWithoutRegAlloc(code, ctx, result, operand1, operand2, fallback_fn, fpcr_controlled);
|
||||
ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
|
@ -1812,7 +1812,7 @@ static void EmitRSqrtEstimate(BlockOfCode& code, EmitContext& ctx, IR::Inst* ins
|
|||
|
||||
ctx.deferred_emits.emplace_back([=, &code, &ctx] {
|
||||
code.L(*bad_values);
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
EmitTwoOpFallbackWithoutRegAlloc(code, ctx, result, operand, fallback_fn, fpcr_controlled);
|
||||
ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
|
@ -1898,7 +1898,7 @@ static void EmitRSqrtStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* in
|
|||
|
||||
ctx.deferred_emits.emplace_back([=, &code, &ctx] {
|
||||
code.L(*fallback);
|
||||
code.sub(rsp, 8);
|
||||
code.lea(rsp, ptr[rsp - 8]);
|
||||
ABI_PushCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
EmitThreeOpFallbackWithoutRegAlloc(code, ctx, result, operand1, operand2, fallback_fn, fpcr_controlled);
|
||||
ABI_PopCallerSaveRegistersAndAdjustStackExcept(code, HostLocXmmIdx(result.getIdx()));
|
||||
|
@ -2180,3 +2180,6 @@ void EmitX64::EmitFPVectorToUnsignedFixed64(EmitContext& ctx, IR::Inst* inst) {
|
|||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::X64
|
||||
|
||||
#undef FCODE
|
||||
#undef ICODE
|
||||
|
|
|
@ -338,3 +338,6 @@ void EmitX64::EmitVectorUnsignedSaturatedSub64(EmitContext& ctx, IR::Inst* inst)
|
|||
}
|
||||
|
||||
} // namespace Dynarmic::Backend::X64
|
||||
|
||||
#undef FCODE
|
||||
#undef ICODE
|
||||
|
|
|
@ -186,7 +186,7 @@ struct ExceptionHandler::Impl final {
|
|||
code.cmp(code.rax, static_cast<u32>(code.GetTotalCodeSize()));
|
||||
code.ja(exception_handler_without_cb);
|
||||
|
||||
code.sub(code.rsp, 8);
|
||||
code.lea(code.rsp, code.ptr[code.rsp - 8]);
|
||||
code.mov(code.ABI_PARAM1, mcl::bit_cast<u64>(&cb));
|
||||
code.mov(code.ABI_PARAM2, code.ABI_PARAM3);
|
||||
code.CallLambda(
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
enum class ArchVersion;
|
||||
enum class ArchVersion : std::uint8_t;
|
||||
enum class CoprocReg;
|
||||
enum class Exception;
|
||||
enum class ExtReg;
|
||||
|
@ -27,12 +27,11 @@ enum class Reg;
|
|||
* The user of this class updates `current_location` as appropriate.
|
||||
*/
|
||||
class IREmitter : public IR::IREmitter {
|
||||
IR::U64 ImmCurrentLocationDescriptor();
|
||||
public:
|
||||
IREmitter(IR::Block& block, LocationDescriptor descriptor, ArchVersion arch_version)
|
||||
: IR::IREmitter(block), current_location(descriptor), arch_version(arch_version) {}
|
||||
|
||||
LocationDescriptor current_location;
|
||||
|
||||
size_t ArchVersion() const;
|
||||
|
||||
u32 PC() const;
|
||||
|
@ -107,10 +106,9 @@ public:
|
|||
IR::U64 CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, CoprocReg CRm);
|
||||
void CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, CoprocReg CRd, const IR::U32& address, bool has_option, u8 option);
|
||||
void CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, CoprocReg CRd, const IR::U32& address, bool has_option, u8 option);
|
||||
|
||||
private:
|
||||
public:
|
||||
LocationDescriptor current_location;
|
||||
enum ArchVersion arch_version;
|
||||
IR::U64 ImmCurrentLocationDescriptor();
|
||||
};
|
||||
|
||||
} // namespace Dynarmic::A32
|
||||
|
|
|
@ -33,13 +33,11 @@ inline size_t ToFastLookupIndexArm(u32 instruction) {
|
|||
} // namespace detail
|
||||
|
||||
template<typename V>
|
||||
ArmDecodeTable<V> GetArmDecodeTable() {
|
||||
constexpr ArmDecodeTable<V> GetArmDecodeTable() {
|
||||
std::vector<ArmMatcher<V>> list = {
|
||||
|
||||
#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(ArmMatcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)),
|
||||
#include "./arm.inc"
|
||||
#undef INST
|
||||
|
||||
};
|
||||
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
|
@ -62,9 +60,10 @@ ArmDecodeTable<V> GetArmDecodeTable() {
|
|||
|
||||
template<typename V>
|
||||
std::optional<std::reference_wrapper<const ArmMatcher<V>>> DecodeArm(u32 instruction) {
|
||||
static const auto table = GetArmDecodeTable<V>();
|
||||
|
||||
const auto matches_instruction = [instruction](const auto& matcher) { return matcher.Matches(instruction); };
|
||||
alignas(64) static const auto table = GetArmDecodeTable<V>();
|
||||
const auto matches_instruction = [instruction](const auto& matcher) {
|
||||
return matcher.Matches(instruction);
|
||||
};
|
||||
|
||||
const auto& subtable = table[detail::ToFastLookupIndexArm(instruction)];
|
||||
auto iter = std::find_if(subtable.begin(), subtable.end(), matches_instruction);
|
||||
|
|
|
@ -25,3 +25,51 @@ bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor,
|
|||
}
|
||||
|
||||
} // namespace Dynarmic::A32
|
||||
|
||||
// ls -l | awk '{print "#include \"dynarmic/frontend/A32/translate/impl/" $9 "\""}'
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_branch.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_crc32.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_exception_generating.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.cpp"
|
||||
//#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/asimd_load_store_structures.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/asimd_misc.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/asimd_one_reg_modified_immediate.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/asimd_three_regs.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/asimd_two_regs_misc.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/asimd_two_regs_scalar.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/asimd_two_regs_shift.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/barrier.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/coprocessor.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/data_processing.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/divide.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/extension.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/hint.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/load_store.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/misc.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/multiply.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/packing.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/parallel.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/reversal.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/saturated.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/status_register_access.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/synchronization.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb16.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_branch.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_control.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_coprocessor.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_data_processing_modified_immediate.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_data_processing_plain_binary_immediate.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_data_processing_register.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_data_processing_shifted_register.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_load_byte.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_load_halfword.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_load_store_dual.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_load_store_multiple.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_load_word.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_long_multiply.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_misc.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_multiply.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_parallel.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/thumb32_store_single_data_item.cpp"
|
||||
#include "dynarmic/frontend/A32/translate/impl/vfp.cpp"
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
bool TranslatorVisitor::arm_NOP() {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::ArmConditionPassed(Cond cond) {
|
||||
return IsConditionPassed(*this, cond);
|
||||
}
|
||||
|
|
|
@ -258,7 +258,7 @@ struct TranslatorVisitor final {
|
|||
bool arm_CLZ(Cond cond, Reg d, Reg m);
|
||||
bool arm_MOVT(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12);
|
||||
bool arm_MOVW(Cond cond, Imm<4> imm4, Reg d, Imm<12> imm12);
|
||||
bool arm_NOP() { return true; }
|
||||
bool arm_NOP();
|
||||
bool arm_RBIT(Cond cond, Reg d, Reg m);
|
||||
bool arm_SBFX(Cond cond, Imm<5> widthm1, Reg d, Imm<5> lsb, Reg n);
|
||||
bool arm_SEL(Cond cond, Reg n, Reg d, Reg m);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <mcl/bit/bit_field.hpp>
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
namespace {
|
||||
|
@ -17,11 +18,6 @@ enum class Comparison {
|
|||
AbsoluteGT,
|
||||
};
|
||||
|
||||
enum class AccumulateBehavior {
|
||||
None,
|
||||
Accumulate,
|
||||
};
|
||||
|
||||
enum class WidenBehaviour {
|
||||
Second,
|
||||
Both,
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
#include <mcl/bit/bit_field.hpp>
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
namespace {
|
||||
enum class Comparison {
|
||||
enum class ComparisonATRM {
|
||||
EQ,
|
||||
GE,
|
||||
GT,
|
||||
|
@ -19,7 +20,7 @@ enum class Comparison {
|
|||
LT,
|
||||
};
|
||||
|
||||
bool CompareWithZero(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm, Comparison type) {
|
||||
bool CompareWithZero(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm, ComparisonATRM type) {
|
||||
if (sz == 0b11 || (F && sz != 0b10)) {
|
||||
return v.UndefinedInstruction();
|
||||
}
|
||||
|
@ -36,15 +37,15 @@ bool CompareWithZero(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool F,
|
|||
|
||||
if (F) {
|
||||
switch (type) {
|
||||
case Comparison::EQ:
|
||||
case ComparisonATRM::EQ:
|
||||
return v.ir.FPVectorEqual(32, reg_m, zero, false);
|
||||
case Comparison::GE:
|
||||
case ComparisonATRM::GE:
|
||||
return v.ir.FPVectorGreaterEqual(32, reg_m, zero, false);
|
||||
case Comparison::GT:
|
||||
case ComparisonATRM::GT:
|
||||
return v.ir.FPVectorGreater(32, reg_m, zero, false);
|
||||
case Comparison::LE:
|
||||
case ComparisonATRM::LE:
|
||||
return v.ir.FPVectorGreaterEqual(32, zero, reg_m, false);
|
||||
case Comparison::LT:
|
||||
case ComparisonATRM::LT:
|
||||
return v.ir.FPVectorGreater(32, zero, reg_m, false);
|
||||
}
|
||||
|
||||
|
@ -67,11 +68,6 @@ bool CompareWithZero(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool F,
|
|||
return true;
|
||||
}
|
||||
|
||||
enum class AccumulateBehavior {
|
||||
None,
|
||||
Accumulate,
|
||||
};
|
||||
|
||||
bool PairedAddOperation(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm, AccumulateBehavior accumulate) {
|
||||
if (sz == 0b11) {
|
||||
return v.UndefinedInstruction();
|
||||
|
@ -385,23 +381,23 @@ bool TranslatorVisitor::asimd_VQNEG(bool D, size_t sz, size_t Vd, bool Q, bool M
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VCGT_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::GT);
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, ComparisonATRM::GT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VCGE_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::GE);
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, ComparisonATRM::GE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VCEQ_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::EQ);
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, ComparisonATRM::EQ);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VCLE_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::LE);
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, ComparisonATRM::LE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VCLT_zero(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, Comparison::LT);
|
||||
return CompareWithZero(*this, D, sz, Vd, F, Q, M, Vm, ComparisonATRM::LT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VABS(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
|
||||
|
|
|
@ -16,7 +16,7 @@ enum class Accumulating {
|
|||
Accumulate
|
||||
};
|
||||
|
||||
enum class Rounding {
|
||||
enum class RoundingATRS {
|
||||
None,
|
||||
Round,
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ enum class Signedness {
|
|||
Unsigned
|
||||
};
|
||||
|
||||
IR::U128 PerformRoundingCorrection(TranslatorVisitor& v, size_t esize, u64 round_value, IR::U128 original, IR::U128 shifted) {
|
||||
IR::U128 PerformRoundingATRSCorrection(TranslatorVisitor& v, size_t esize, u64 round_value, IR::U128 original, IR::U128 shifted) {
|
||||
const auto round_const = v.ir.VectorBroadcast(esize, v.I(esize, round_value));
|
||||
const auto round_correction = v.ir.VectorEqual(esize, v.ir.VectorAnd(original, round_const), round_const);
|
||||
return v.ir.VectorSub(esize, shifted, round_correction);
|
||||
|
@ -58,7 +58,7 @@ std::pair<size_t, size_t> ElementSizeAndShiftAmount(bool right_shift, bool L, si
|
|||
}
|
||||
}
|
||||
|
||||
bool ShiftRight(TranslatorVisitor& v, bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm, Accumulating accumulate, Rounding rounding) {
|
||||
bool ShiftRight(TranslatorVisitor& v, bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm, Accumulating accumulate, RoundingATRS RoundingATRS) {
|
||||
if (!L && mcl::bit::get_bits<3, 5>(imm6) == 0) {
|
||||
return v.DecodeError();
|
||||
}
|
||||
|
@ -75,9 +75,9 @@ bool ShiftRight(TranslatorVisitor& v, bool U, bool D, size_t imm6, size_t Vd, bo
|
|||
auto result = U ? v.ir.VectorLogicalShiftRight(esize, reg_m, static_cast<u8>(shift_amount))
|
||||
: v.ir.VectorArithmeticShiftRight(esize, reg_m, static_cast<u8>(shift_amount));
|
||||
|
||||
if (rounding == Rounding::Round) {
|
||||
if (RoundingATRS == RoundingATRS::Round) {
|
||||
const u64 round_value = 1ULL << (shift_amount - 1);
|
||||
result = PerformRoundingCorrection(v, esize, round_value, reg_m, result);
|
||||
result = PerformRoundingATRSCorrection(v, esize, round_value, reg_m, result);
|
||||
}
|
||||
|
||||
if (accumulate == Accumulating::Accumulate) {
|
||||
|
@ -89,7 +89,7 @@ bool ShiftRight(TranslatorVisitor& v, bool U, bool D, size_t imm6, size_t Vd, bo
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ShiftRightNarrowing(TranslatorVisitor& v, bool D, size_t imm6, size_t Vd, bool M, size_t Vm, Rounding rounding, Narrowing narrowing, Signedness signedness) {
|
||||
bool ShiftRightNarrowing(TranslatorVisitor& v, bool D, size_t imm6, size_t Vd, bool M, size_t Vm, RoundingATRS RoundingATRS, Narrowing narrowing, Signedness signedness) {
|
||||
if (mcl::bit::get_bits<3, 5>(imm6) == 0) {
|
||||
return v.DecodeError();
|
||||
}
|
||||
|
@ -113,9 +113,9 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, bool D, size_t imm6, size_t Vd, b
|
|||
return v.ir.VectorLogicalShiftRight(source_esize, reg_m, shift_amount);
|
||||
}();
|
||||
|
||||
if (rounding == Rounding::Round) {
|
||||
if (RoundingATRS == RoundingATRS::Round) {
|
||||
const u64 round_value = 1ULL << (shift_amount - 1);
|
||||
wide_result = PerformRoundingCorrection(v, source_esize, round_value, reg_m, wide_result);
|
||||
wide_result = PerformRoundingATRSCorrection(v, source_esize, round_value, reg_m, wide_result);
|
||||
}
|
||||
|
||||
const auto result = [&] {
|
||||
|
@ -141,22 +141,22 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, bool D, size_t imm6, size_t Vd, b
|
|||
|
||||
bool TranslatorVisitor::asimd_SHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
|
||||
return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm,
|
||||
Accumulating::None, Rounding::None);
|
||||
Accumulating::None, RoundingATRS::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_SRA(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
|
||||
return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm,
|
||||
Accumulating::Accumulate, Rounding::None);
|
||||
Accumulating::Accumulate, RoundingATRS::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VRSHR(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
|
||||
return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm,
|
||||
Accumulating::None, Rounding::Round);
|
||||
Accumulating::None, RoundingATRS::Round);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VRSRA(bool U, bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
|
||||
return ShiftRight(*this, U, D, imm6, Vd, L, Q, M, Vm,
|
||||
Accumulating::Accumulate, Rounding::Round);
|
||||
Accumulating::Accumulate, RoundingATRS::Round);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VSRI(bool D, size_t imm6, size_t Vd, bool L, bool Q, bool M, size_t Vm) {
|
||||
|
@ -271,32 +271,32 @@ bool TranslatorVisitor::asimd_VSHL(bool D, size_t imm6, size_t Vd, bool L, bool
|
|||
|
||||
bool TranslatorVisitor::asimd_VSHRN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
|
||||
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
|
||||
Rounding::None, Narrowing::Truncation, Signedness::Unsigned);
|
||||
RoundingATRS::None, Narrowing::Truncation, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VRSHRN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
|
||||
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
|
||||
Rounding::Round, Narrowing::Truncation, Signedness::Unsigned);
|
||||
RoundingATRS::Round, Narrowing::Truncation, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VQRSHRUN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
|
||||
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
|
||||
Rounding::Round, Narrowing::SaturateToUnsigned, Signedness::Signed);
|
||||
RoundingATRS::Round, Narrowing::SaturateToUnsigned, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VQSHRUN(bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
|
||||
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
|
||||
Rounding::None, Narrowing::SaturateToUnsigned, Signedness::Signed);
|
||||
RoundingATRS::None, Narrowing::SaturateToUnsigned, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VQSHRN(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
|
||||
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
|
||||
Rounding::None, U ? Narrowing::SaturateToUnsigned : Narrowing::SaturateToSigned, U ? Signedness::Unsigned : Signedness::Signed);
|
||||
RoundingATRS::None, U ? Narrowing::SaturateToUnsigned : Narrowing::SaturateToSigned, U ? Signedness::Unsigned : Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VQRSHRN(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
|
||||
return ShiftRightNarrowing(*this, D, imm6, Vd, M, Vm,
|
||||
Rounding::Round, U ? Narrowing::SaturateToUnsigned : Narrowing::SaturateToSigned, U ? Signedness::Unsigned : Signedness::Signed);
|
||||
RoundingATRS::Round, U ? Narrowing::SaturateToUnsigned : Narrowing::SaturateToSigned, U ? Signedness::Unsigned : Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::asimd_VSHLL(bool U, bool D, size_t imm6, size_t Vd, bool M, size_t Vm) {
|
||||
|
|
31
externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/common.h
vendored
Normal file
31
externals/dynarmic/src/dynarmic/frontend/A32/translate/impl/common.h
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
static inline IR::U32 Pack2x16To1x32(A32::IREmitter& ir, IR::U32 lo, IR::U32 hi) noexcept {
|
||||
return ir.Or(ir.And(lo, ir.Imm32(0xFFFF)), ir.LogicalShiftLeft(hi, ir.Imm8(16), ir.Imm1(0)).result);
|
||||
}
|
||||
|
||||
static inline IR::U16 MostSignificantHalf(A32::IREmitter& ir, IR::U32 value) noexcept {
|
||||
return ir.LeastSignificantHalf(ir.LogicalShiftRight(value, ir.Imm8(16), ir.Imm1(0)).result);
|
||||
}
|
||||
|
||||
static inline IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) noexcept {
|
||||
const u8 rotate_by = static_cast<u8>(static_cast<size_t>(rotate) * 8);
|
||||
return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result;
|
||||
}
|
||||
|
||||
static inline bool ITBlockCheck(const A32::IREmitter& ir) noexcept {
|
||||
return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock();
|
||||
}
|
||||
|
||||
using ExtensionFunctionU16 = IR::U32 (IREmitter::*)(const IR::U16&);
|
||||
|
||||
enum class AccumulateBehavior {
|
||||
None,
|
||||
Accumulate,
|
||||
};
|
||||
|
||||
}
|
|
@ -4,14 +4,10 @@
|
|||
*/
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
static IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) {
|
||||
const u8 rotate_by = static_cast<u8>(static_cast<size_t>(rotate) * 8);
|
||||
return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result;
|
||||
}
|
||||
|
||||
// SXTAB<c> <Rd>, <Rn>, <Rm>{, <rotation>}
|
||||
bool TranslatorVisitor::arm_SXTAB(Cond cond, Reg n, Reg d, SignExtendRotation rotate, Reg m) {
|
||||
if (d == Reg::PC || m == Reg::PC) {
|
||||
|
|
|
@ -4,17 +4,10 @@
|
|||
*/
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
static IR::U32 Pack2x16To1x32(A32::IREmitter& ir, IR::U32 lo, IR::U32 hi) {
|
||||
return ir.Or(ir.And(lo, ir.Imm32(0xFFFF)), ir.LogicalShiftLeft(hi, ir.Imm8(16), ir.Imm1(0)).result);
|
||||
}
|
||||
|
||||
static IR::U16 MostSignificantHalf(A32::IREmitter& ir, IR::U32 value) {
|
||||
return ir.LeastSignificantHalf(ir.LogicalShiftRight(value, ir.Imm8(16), ir.Imm1(0)).result);
|
||||
}
|
||||
|
||||
// Saturation instructions
|
||||
|
||||
// SSAT<c> <Rd>, #<imm>, <Rn>{, <shift>}
|
||||
|
|
|
@ -7,15 +7,9 @@
|
|||
#include <mcl/bitsizeof.hpp>
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
static IR::U32 Pack2x16To1x32(A32::IREmitter& ir, IR::U32 lo, IR::U32 hi) {
|
||||
return ir.Or(ir.And(lo, ir.Imm32(0xFFFF)), ir.LogicalShiftLeft(hi, ir.Imm8(16), ir.Imm1(0)).result);
|
||||
}
|
||||
|
||||
static IR::U16 MostSignificantHalf(A32::IREmitter& ir, IR::U32 value) {
|
||||
return ir.LeastSignificantHalf(ir.LogicalShiftRight(value, ir.Imm8(16), ir.Imm1(0)).result);
|
||||
}
|
||||
|
||||
using SaturationFunction = IR::ResultAndOverflow<IR::U32> (IREmitter::*)(const IR::U32&, size_t);
|
||||
|
||||
|
|
|
@ -4,13 +4,10 @@
|
|||
*/
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
namespace {
|
||||
IR::U32 Rotate(A32::IREmitter& ir, Reg m, SignExtendRotation rotate) {
|
||||
const u8 rotate_by = static_cast<u8>(static_cast<size_t>(rotate) * 8);
|
||||
return ir.RotateRight(ir.GetRegister(m), ir.Imm8(rotate_by), ir.Imm1(0)).result;
|
||||
}
|
||||
|
||||
using ShiftFunction = IR::ResultAndCarry<IR::U32> (IREmitter::*)(const IR::U32&, const IR::U8&, const IR::U1&);
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@ static bool PLIHandler(TranslatorVisitor& v) {
|
|||
return v.RaiseException(Exception::PreloadInstruction);
|
||||
}
|
||||
|
||||
using ExtensionFunction = IR::U32 (IREmitter::*)(const IR::U8&);
|
||||
using ExtensionFunctionU8 = IR::U32 (IREmitter::*)(const IR::U8&);
|
||||
|
||||
static bool LoadByteLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12, ExtensionFunction ext_fn) {
|
||||
static bool LoadByteLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12, ExtensionFunctionU8 ext_fn) {
|
||||
const u32 imm32 = imm12.ZeroExtend();
|
||||
const u32 base = v.ir.AlignPC(4);
|
||||
const u32 address = U ? (base + imm32) : (base - imm32);
|
||||
|
@ -37,7 +37,7 @@ static bool LoadByteLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool LoadByteRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m, ExtensionFunction ext_fn) {
|
||||
static bool LoadByteRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m, ExtensionFunctionU8 ext_fn) {
|
||||
if (m == Reg::PC) {
|
||||
return v.UnpredictableInstruction();
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ static bool LoadByteRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Re
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool LoadByteImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12, ExtensionFunction ext_fn) {
|
||||
static bool LoadByteImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12, ExtensionFunctionU8 ext_fn) {
|
||||
const u32 imm32 = imm12.ZeroExtend();
|
||||
const IR::U32 reg_n = v.ir.GetRegister(n);
|
||||
const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm32))
|
||||
|
|
|
@ -4,12 +4,11 @@
|
|||
*/
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
|
||||
using ExtensionFunction = IR::U32 (IREmitter::*)(const IR::U16&);
|
||||
|
||||
static bool LoadHalfLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12, ExtensionFunction ext_fn) {
|
||||
static bool LoadHalfLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12, ExtensionFunctionU16 ext_fn) {
|
||||
const auto imm32 = imm12.ZeroExtend();
|
||||
const auto base = v.ir.AlignPC(4);
|
||||
const auto address = U ? (base + imm32) : (base - imm32);
|
||||
|
@ -19,7 +18,7 @@ static bool LoadHalfLiteral(TranslatorVisitor& v, bool U, Reg t, Imm<12> imm12,
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool LoadHalfRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m, ExtensionFunction ext_fn) {
|
||||
static bool LoadHalfRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Reg m, ExtensionFunctionU16 ext_fn) {
|
||||
if (m == Reg::PC) {
|
||||
return v.UnpredictableInstruction();
|
||||
}
|
||||
|
@ -34,7 +33,7 @@ static bool LoadHalfRegister(TranslatorVisitor& v, Reg n, Reg t, Imm<2> imm2, Re
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool LoadHalfImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12, ExtensionFunction ext_fn) {
|
||||
static bool LoadHalfImmediate(TranslatorVisitor& v, Reg n, Reg t, bool P, bool U, bool W, Imm<12> imm12, ExtensionFunctionU16 ext_fn) {
|
||||
const u32 imm32 = imm12.ZeroExtend();
|
||||
const IR::U32 reg_n = v.ir.GetRegister(n);
|
||||
const IR::U32 offset_address = U ? v.ir.Add(reg_n, v.ir.Imm32(imm32))
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
#include <mcl/bit/bit_field.hpp>
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
static bool ITBlockCheck(const A32::IREmitter& ir) {
|
||||
return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock();
|
||||
}
|
||||
|
||||
static bool TableBranch(TranslatorVisitor& v, Reg n, Reg m, bool half) {
|
||||
if (m == Reg::PC) {
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
#include <mcl/bit/bit_count.hpp>
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
static bool ITBlockCheck(const A32::IREmitter& ir) {
|
||||
return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock();
|
||||
}
|
||||
|
||||
static bool LDMHelper(A32::IREmitter& ir, bool W, Reg n, u32 list, const IR::U32& start_address, const IR::U32& writeback_address) {
|
||||
auto address = start_address;
|
||||
|
|
|
@ -4,11 +4,9 @@
|
|||
*/
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
static bool ITBlockCheck(const A32::IREmitter& ir) {
|
||||
return ir.current_location.IT().IsInITBlock() && !ir.current_location.IT().IsLastInITBlock();
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::thumb32_LDR_lit(bool U, Reg t, Imm<12> imm12) {
|
||||
if (t == Reg::PC && ITBlockCheck(ir)) {
|
||||
|
|
|
@ -4,15 +4,9 @@
|
|||
*/
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/impl/a32_translate_impl.h"
|
||||
#include "dynarmic/frontend/A32/translate/impl/common.h"
|
||||
|
||||
namespace Dynarmic::A32 {
|
||||
static IR::U32 Pack2x16To1x32(A32::IREmitter& ir, IR::U32 lo, IR::U32 hi) {
|
||||
return ir.Or(ir.And(lo, ir.Imm32(0xFFFF)), ir.LogicalShiftLeft(hi, ir.Imm8(16), ir.Imm1(0)).result);
|
||||
}
|
||||
|
||||
static IR::U16 MostSignificantHalf(A32::IREmitter& ir, IR::U32 value) {
|
||||
return ir.LeastSignificantHalf(ir.LogicalShiftRight(value, ir.Imm8(16), ir.Imm1(0)).result);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::thumb32_SADD8(Reg n, Reg d, Reg m) {
|
||||
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
|
||||
|
|
|
@ -5,261 +5,7 @@
|
|||
|
||||
#include "dynarmic/frontend/A64/a64_ir_emitter.h"
|
||||
|
||||
#include <mcl/assert.hpp>
|
||||
|
||||
#include "dynarmic/ir/opcodes.h"
|
||||
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
using Opcode = IR::Opcode;
|
||||
|
||||
u64 IREmitter::PC() const {
|
||||
return current_location->PC();
|
||||
}
|
||||
|
||||
u64 IREmitter::AlignPC(size_t alignment) const {
|
||||
const u64 pc = PC();
|
||||
return static_cast<u64>(pc - pc % alignment);
|
||||
}
|
||||
|
||||
void IREmitter::SetCheckBit(const IR::U1& value) {
|
||||
Inst(Opcode::A64SetCheckBit, value);
|
||||
}
|
||||
|
||||
IR::U1 IREmitter::GetCFlag() {
|
||||
return Inst<IR::U1>(Opcode::A64GetCFlag);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetNZCVRaw() {
|
||||
return Inst<IR::U32>(Opcode::A64GetNZCVRaw);
|
||||
}
|
||||
|
||||
void IREmitter::SetNZCVRaw(IR::U32 value) {
|
||||
Inst(Opcode::A64SetNZCVRaw, value);
|
||||
}
|
||||
|
||||
void IREmitter::SetNZCV(const IR::NZCV& nzcv) {
|
||||
Inst(Opcode::A64SetNZCV, nzcv);
|
||||
}
|
||||
|
||||
void IREmitter::CallSupervisor(u32 imm) {
|
||||
Inst(Opcode::A64CallSupervisor, Imm32(imm));
|
||||
}
|
||||
|
||||
void IREmitter::ExceptionRaised(Exception exception) {
|
||||
Inst(Opcode::A64ExceptionRaised, Imm64(PC()), Imm64(static_cast<u64>(exception)));
|
||||
}
|
||||
|
||||
void IREmitter::DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value) {
|
||||
Inst(Opcode::A64DataCacheOperationRaised, ImmCurrentLocationDescriptor(), Imm64(static_cast<u64>(op)), value);
|
||||
}
|
||||
|
||||
void IREmitter::InstructionCacheOperationRaised(InstructionCacheOperation op, const IR::U64& value) {
|
||||
Inst(Opcode::A64InstructionCacheOperationRaised, Imm64(static_cast<u64>(op)), value);
|
||||
}
|
||||
|
||||
void IREmitter::DataSynchronizationBarrier() {
|
||||
Inst(Opcode::A64DataSynchronizationBarrier);
|
||||
}
|
||||
|
||||
void IREmitter::DataMemoryBarrier() {
|
||||
Inst(Opcode::A64DataMemoryBarrier);
|
||||
}
|
||||
|
||||
void IREmitter::InstructionSynchronizationBarrier() {
|
||||
Inst(Opcode::A64InstructionSynchronizationBarrier);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetCNTFRQ() {
|
||||
return Inst<IR::U32>(Opcode::A64GetCNTFRQ);
|
||||
}
|
||||
|
||||
IR::U64 IREmitter::GetCNTPCT() {
|
||||
return Inst<IR::U64>(Opcode::A64GetCNTPCT);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetCTR() {
|
||||
return Inst<IR::U32>(Opcode::A64GetCTR);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetDCZID() {
|
||||
return Inst<IR::U32>(Opcode::A64GetDCZID);
|
||||
}
|
||||
|
||||
IR::U64 IREmitter::GetTPIDR() {
|
||||
return Inst<IR::U64>(Opcode::A64GetTPIDR);
|
||||
}
|
||||
|
||||
void IREmitter::SetTPIDR(const IR::U64& value) {
|
||||
Inst(Opcode::A64SetTPIDR, value);
|
||||
}
|
||||
|
||||
IR::U64 IREmitter::GetTPIDRRO() {
|
||||
return Inst<IR::U64>(Opcode::A64GetTPIDRRO);
|
||||
}
|
||||
|
||||
void IREmitter::ClearExclusive() {
|
||||
Inst(Opcode::A64ClearExclusive);
|
||||
}
|
||||
|
||||
IR::U8 IREmitter::ReadMemory8(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U8>(Opcode::A64ReadMemory8, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U16 IREmitter::ReadMemory16(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U16>(Opcode::A64ReadMemory16, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::ReadMemory32(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U32>(Opcode::A64ReadMemory32, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U64 IREmitter::ReadMemory64(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U64>(Opcode::A64ReadMemory64, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U128 IREmitter::ReadMemory128(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U128>(Opcode::A64ReadMemory128, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U8 IREmitter::ExclusiveReadMemory8(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U8>(Opcode::A64ExclusiveReadMemory8, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U16 IREmitter::ExclusiveReadMemory16(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U16>(Opcode::A64ExclusiveReadMemory16, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::ExclusiveReadMemory32(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveReadMemory32, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U64 IREmitter::ExclusiveReadMemory64(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U64>(Opcode::A64ExclusiveReadMemory64, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U128 IREmitter::ExclusiveReadMemory128(const IR::U64& vaddr, IR::AccType acc_type) {
|
||||
return Inst<IR::U128>(Opcode::A64ExclusiveReadMemory128, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccType acc_type) {
|
||||
Inst(Opcode::A64WriteMemory8, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccType acc_type) {
|
||||
Inst(Opcode::A64WriteMemory16, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccType acc_type) {
|
||||
Inst(Opcode::A64WriteMemory32, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccType acc_type) {
|
||||
Inst(Opcode::A64WriteMemory64, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccType acc_type) {
|
||||
Inst(Opcode::A64WriteMemory128, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::ExclusiveWriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccType acc_type) {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory8, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::ExclusiveWriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccType acc_type) {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory16, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::ExclusiveWriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccType acc_type) {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory32, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::ExclusiveWriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccType acc_type) {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory64, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::ExclusiveWriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccType acc_type) {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory128, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetW(Reg reg) {
|
||||
if (reg == Reg::ZR)
|
||||
return Imm32(0);
|
||||
return Inst<IR::U32>(Opcode::A64GetW, IR::Value(reg));
|
||||
}
|
||||
|
||||
IR::U64 IREmitter::GetX(Reg reg) {
|
||||
if (reg == Reg::ZR)
|
||||
return Imm64(0);
|
||||
return Inst<IR::U64>(Opcode::A64GetX, IR::Value(reg));
|
||||
}
|
||||
|
||||
IR::U128 IREmitter::GetS(Vec vec) {
|
||||
return Inst<IR::U128>(Opcode::A64GetS, IR::Value(vec));
|
||||
}
|
||||
|
||||
IR::U128 IREmitter::GetD(Vec vec) {
|
||||
return Inst<IR::U128>(Opcode::A64GetD, IR::Value(vec));
|
||||
}
|
||||
|
||||
IR::U128 IREmitter::GetQ(Vec vec) {
|
||||
return Inst<IR::U128>(Opcode::A64GetQ, IR::Value(vec));
|
||||
}
|
||||
|
||||
IR::U64 IREmitter::GetSP() {
|
||||
return Inst<IR::U64>(Opcode::A64GetSP);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetFPCR() {
|
||||
return Inst<IR::U32>(Opcode::A64GetFPCR);
|
||||
}
|
||||
|
||||
IR::U32 IREmitter::GetFPSR() {
|
||||
return Inst<IR::U32>(Opcode::A64GetFPSR);
|
||||
}
|
||||
|
||||
void IREmitter::SetW(const Reg reg, const IR::U32& value) {
|
||||
if (reg == Reg::ZR)
|
||||
return;
|
||||
Inst(Opcode::A64SetW, IR::Value(reg), value);
|
||||
}
|
||||
|
||||
void IREmitter::SetX(const Reg reg, const IR::U64& value) {
|
||||
if (reg == Reg::ZR)
|
||||
return;
|
||||
Inst(Opcode::A64SetX, IR::Value(reg), value);
|
||||
}
|
||||
|
||||
void IREmitter::SetS(const Vec vec, const IR::U128& value) {
|
||||
Inst(Opcode::A64SetS, IR::Value(vec), value);
|
||||
}
|
||||
|
||||
void IREmitter::SetD(const Vec vec, const IR::U128& value) {
|
||||
Inst(Opcode::A64SetD, IR::Value(vec), value);
|
||||
}
|
||||
|
||||
void IREmitter::SetQ(const Vec vec, const IR::U128& value) {
|
||||
Inst(Opcode::A64SetQ, IR::Value(vec), value);
|
||||
}
|
||||
|
||||
void IREmitter::SetSP(const IR::U64& value) {
|
||||
Inst(Opcode::A64SetSP, value);
|
||||
}
|
||||
|
||||
void IREmitter::SetFPCR(const IR::U32& value) {
|
||||
Inst(Opcode::A64SetFPCR, value);
|
||||
}
|
||||
|
||||
void IREmitter::SetFPSR(const IR::U32& value) {
|
||||
Inst(Opcode::A64SetFPSR, value);
|
||||
}
|
||||
|
||||
void IREmitter::SetPC(const IR::U64& value) {
|
||||
Inst(Opcode::A64SetPC, value);
|
||||
}
|
||||
|
||||
IR::U64 IREmitter::ImmCurrentLocationDescriptor() {
|
||||
return Imm64(IR::LocationDescriptor{*current_location}.Value());
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
#include <optional>
|
||||
|
||||
#include <mcl/stdint.hpp>
|
||||
#include <mcl/assert.hpp>
|
||||
|
||||
#include "dynarmic/frontend/A64/a64_location_descriptor.h"
|
||||
#include "dynarmic/frontend/A64/a64_types.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
#include "dynarmic/ir/ir_emitter.h"
|
||||
#include "dynarmic/ir/value.h"
|
||||
#include "dynarmic/ir/opcodes.h"
|
||||
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
|
@ -24,79 +26,262 @@ namespace Dynarmic::A64 {
|
|||
*/
|
||||
class IREmitter : public IR::IREmitter {
|
||||
public:
|
||||
explicit IREmitter(IR::Block& block)
|
||||
: IR::IREmitter(block) {}
|
||||
explicit IREmitter(IR::Block& block, LocationDescriptor descriptor)
|
||||
: IR::IREmitter(block), current_location(descriptor) {}
|
||||
explicit IREmitter(IR::Block& block) : IR::IREmitter(block) {}
|
||||
explicit IREmitter(IR::Block& block, LocationDescriptor descriptor) : IR::IREmitter(block), current_location(descriptor) {}
|
||||
|
||||
std::optional<LocationDescriptor> current_location;
|
||||
|
||||
u64 PC() const;
|
||||
u64 AlignPC(size_t alignment) const;
|
||||
using Opcode = IR::Opcode;
|
||||
|
||||
void SetCheckBit(const IR::U1& value);
|
||||
IR::U1 GetCFlag();
|
||||
IR::U32 GetNZCVRaw();
|
||||
void SetNZCVRaw(IR::U32 value);
|
||||
void SetNZCV(const IR::NZCV& nzcv);
|
||||
u64 PC() const noexcept {
|
||||
return current_location->PC();
|
||||
}
|
||||
|
||||
void CallSupervisor(u32 imm);
|
||||
void ExceptionRaised(Exception exception);
|
||||
void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value);
|
||||
void InstructionCacheOperationRaised(InstructionCacheOperation op, const IR::U64& value);
|
||||
void DataSynchronizationBarrier();
|
||||
void DataMemoryBarrier();
|
||||
void InstructionSynchronizationBarrier();
|
||||
IR::U32 GetCNTFRQ();
|
||||
IR::U64 GetCNTPCT(); // TODO: Ensure sub-basic-block cycle counts are updated before this.
|
||||
IR::U32 GetCTR();
|
||||
IR::U32 GetDCZID();
|
||||
IR::U64 GetTPIDR();
|
||||
IR::U64 GetTPIDRRO();
|
||||
void SetTPIDR(const IR::U64& value);
|
||||
u64 AlignPC(size_t alignment) const noexcept {
|
||||
const u64 pc = PC();
|
||||
return static_cast<u64>(pc - pc % alignment);
|
||||
}
|
||||
|
||||
void ClearExclusive();
|
||||
IR::U8 ReadMemory8(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U16 ReadMemory16(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U32 ReadMemory32(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U64 ReadMemory64(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U128 ReadMemory128(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U8 ExclusiveReadMemory8(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U16 ExclusiveReadMemory16(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U32 ExclusiveReadMemory32(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U64 ExclusiveReadMemory64(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
IR::U128 ExclusiveReadMemory128(const IR::U64& vaddr, IR::AccType acc_type);
|
||||
void WriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccType acc_type);
|
||||
void WriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccType acc_type);
|
||||
void WriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccType acc_type);
|
||||
void WriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccType acc_type);
|
||||
void WriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccType acc_type);
|
||||
IR::U32 ExclusiveWriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccType acc_type);
|
||||
IR::U32 ExclusiveWriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccType acc_type);
|
||||
IR::U32 ExclusiveWriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccType acc_type);
|
||||
IR::U32 ExclusiveWriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccType acc_type);
|
||||
IR::U32 ExclusiveWriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccType acc_type);
|
||||
void SetCheckBit(const IR::U1& value) noexcept {
|
||||
Inst(Opcode::A64SetCheckBit, value);
|
||||
}
|
||||
|
||||
IR::U32 GetW(Reg source_reg);
|
||||
IR::U64 GetX(Reg source_reg);
|
||||
IR::U128 GetS(Vec source_vec);
|
||||
IR::U128 GetD(Vec source_vec);
|
||||
IR::U128 GetQ(Vec source_vec);
|
||||
IR::U64 GetSP();
|
||||
IR::U32 GetFPCR();
|
||||
IR::U32 GetFPSR();
|
||||
void SetW(Reg dest_reg, const IR::U32& value);
|
||||
void SetX(Reg dest_reg, const IR::U64& value);
|
||||
void SetS(Vec dest_vec, const IR::U128& value);
|
||||
void SetD(Vec dest_vec, const IR::U128& value);
|
||||
void SetQ(Vec dest_vec, const IR::U128& value);
|
||||
void SetSP(const IR::U64& value);
|
||||
void SetFPCR(const IR::U32& value);
|
||||
void SetFPSR(const IR::U32& value);
|
||||
void SetPC(const IR::U64& value);
|
||||
IR::U1 GetCFlag() noexcept {
|
||||
return Inst<IR::U1>(Opcode::A64GetCFlag);
|
||||
}
|
||||
|
||||
IR::U32 GetNZCVRaw() noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64GetNZCVRaw);
|
||||
}
|
||||
|
||||
void SetNZCVRaw(IR::U32 value) noexcept {
|
||||
Inst(Opcode::A64SetNZCVRaw, value);
|
||||
}
|
||||
|
||||
void SetNZCV(const IR::NZCV& nzcv) noexcept {
|
||||
Inst(Opcode::A64SetNZCV, nzcv);
|
||||
}
|
||||
|
||||
void CallSupervisor(u32 imm) noexcept {
|
||||
Inst(Opcode::A64CallSupervisor, Imm32(imm));
|
||||
}
|
||||
|
||||
void ExceptionRaised(Exception exception) noexcept {
|
||||
Inst(Opcode::A64ExceptionRaised, Imm64(PC()), Imm64(static_cast<u64>(exception)));
|
||||
}
|
||||
|
||||
void DataCacheOperationRaised(DataCacheOperation op, const IR::U64& value) noexcept {
|
||||
Inst(Opcode::A64DataCacheOperationRaised, ImmCurrentLocationDescriptor(), Imm64(static_cast<u64>(op)), value);
|
||||
}
|
||||
|
||||
void InstructionCacheOperationRaised(InstructionCacheOperation op, const IR::U64& value) noexcept {
|
||||
Inst(Opcode::A64InstructionCacheOperationRaised, Imm64(static_cast<u64>(op)), value);
|
||||
}
|
||||
|
||||
void DataSynchronizationBarrier() noexcept {
|
||||
Inst(Opcode::A64DataSynchronizationBarrier);
|
||||
}
|
||||
|
||||
void DataMemoryBarrier() noexcept {
|
||||
Inst(Opcode::A64DataMemoryBarrier);
|
||||
}
|
||||
|
||||
void InstructionSynchronizationBarrier() noexcept {
|
||||
Inst(Opcode::A64InstructionSynchronizationBarrier);
|
||||
}
|
||||
|
||||
IR::U32 GetCNTFRQ() noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64GetCNTFRQ);
|
||||
}
|
||||
|
||||
IR::U64 GetCNTPCT() noexcept {
|
||||
return Inst<IR::U64>(Opcode::A64GetCNTPCT);
|
||||
}
|
||||
|
||||
IR::U32 GetCTR() noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64GetCTR);
|
||||
}
|
||||
|
||||
IR::U32 GetDCZID() noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64GetDCZID);
|
||||
}
|
||||
|
||||
IR::U64 GetTPIDR() noexcept {
|
||||
return Inst<IR::U64>(Opcode::A64GetTPIDR);
|
||||
}
|
||||
|
||||
void SetTPIDR(const IR::U64& value) noexcept {
|
||||
Inst(Opcode::A64SetTPIDR, value);
|
||||
}
|
||||
|
||||
IR::U64 GetTPIDRRO() noexcept {
|
||||
return Inst<IR::U64>(Opcode::A64GetTPIDRRO);
|
||||
}
|
||||
|
||||
void ClearExclusive() noexcept {
|
||||
Inst(Opcode::A64ClearExclusive);
|
||||
}
|
||||
|
||||
IR::U8 ReadMemory8(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U8>(Opcode::A64ReadMemory8, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U16 ReadMemory16(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U16>(Opcode::A64ReadMemory16, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 ReadMemory32(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64ReadMemory32, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U64 ReadMemory64(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U64>(Opcode::A64ReadMemory64, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U128 ReadMemory128(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U128>(Opcode::A64ReadMemory128, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U8 ExclusiveReadMemory8(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U8>(Opcode::A64ExclusiveReadMemory8, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U16 ExclusiveReadMemory16(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U16>(Opcode::A64ExclusiveReadMemory16, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 ExclusiveReadMemory32(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveReadMemory32, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U64 ExclusiveReadMemory64(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U64>(Opcode::A64ExclusiveReadMemory64, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U128 ExclusiveReadMemory128(const IR::U64& vaddr, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U128>(Opcode::A64ExclusiveReadMemory128, ImmCurrentLocationDescriptor(), vaddr, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void WriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccType acc_type) noexcept {
|
||||
Inst(Opcode::A64WriteMemory8, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void WriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccType acc_type) noexcept {
|
||||
Inst(Opcode::A64WriteMemory16, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void WriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccType acc_type) noexcept {
|
||||
Inst(Opcode::A64WriteMemory32, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void WriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccType acc_type) noexcept {
|
||||
Inst(Opcode::A64WriteMemory64, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
void WriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccType acc_type) noexcept {
|
||||
Inst(Opcode::A64WriteMemory128, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 ExclusiveWriteMemory8(const IR::U64& vaddr, const IR::U8& value, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory8, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 ExclusiveWriteMemory16(const IR::U64& vaddr, const IR::U16& value, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory16, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 ExclusiveWriteMemory32(const IR::U64& vaddr, const IR::U32& value, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory32, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 ExclusiveWriteMemory64(const IR::U64& vaddr, const IR::U64& value, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory64, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 ExclusiveWriteMemory128(const IR::U64& vaddr, const IR::U128& value, IR::AccType acc_type) noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64ExclusiveWriteMemory128, ImmCurrentLocationDescriptor(), vaddr, value, IR::Value{acc_type});
|
||||
}
|
||||
|
||||
IR::U32 GetW(Reg reg) noexcept {
|
||||
if (reg == Reg::ZR)
|
||||
return Imm32(0);
|
||||
return Inst<IR::U32>(Opcode::A64GetW, IR::Value(reg));
|
||||
}
|
||||
|
||||
IR::U64 GetX(Reg reg) noexcept {
|
||||
if (reg == Reg::ZR)
|
||||
return Imm64(0);
|
||||
return Inst<IR::U64>(Opcode::A64GetX, IR::Value(reg));
|
||||
}
|
||||
|
||||
IR::U128 GetS(Vec vec) noexcept {
|
||||
return Inst<IR::U128>(Opcode::A64GetS, IR::Value(vec));
|
||||
}
|
||||
|
||||
IR::U128 GetD(Vec vec) noexcept {
|
||||
return Inst<IR::U128>(Opcode::A64GetD, IR::Value(vec));
|
||||
}
|
||||
|
||||
IR::U128 GetQ(Vec vec) noexcept {
|
||||
return Inst<IR::U128>(Opcode::A64GetQ, IR::Value(vec));
|
||||
}
|
||||
|
||||
IR::U64 GetSP() noexcept {
|
||||
return Inst<IR::U64>(Opcode::A64GetSP);
|
||||
}
|
||||
|
||||
IR::U32 GetFPCR() noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64GetFPCR);
|
||||
}
|
||||
|
||||
IR::U32 GetFPSR() noexcept {
|
||||
return Inst<IR::U32>(Opcode::A64GetFPSR);
|
||||
}
|
||||
|
||||
void SetW(const Reg reg, const IR::U32& value) noexcept {
|
||||
if (reg == Reg::ZR)
|
||||
return;
|
||||
Inst(Opcode::A64SetW, IR::Value(reg), value);
|
||||
}
|
||||
|
||||
void SetX(const Reg reg, const IR::U64& value) noexcept {
|
||||
if (reg == Reg::ZR)
|
||||
return;
|
||||
Inst(Opcode::A64SetX, IR::Value(reg), value);
|
||||
}
|
||||
|
||||
void SetS(const Vec vec, const IR::U128& value) noexcept {
|
||||
Inst(Opcode::A64SetS, IR::Value(vec), value);
|
||||
}
|
||||
|
||||
void SetD(const Vec vec, const IR::U128& value) noexcept {
|
||||
Inst(Opcode::A64SetD, IR::Value(vec), value);
|
||||
}
|
||||
|
||||
void SetQ(const Vec vec, const IR::U128& value) noexcept {
|
||||
Inst(Opcode::A64SetQ, IR::Value(vec), value);
|
||||
}
|
||||
|
||||
void SetSP(const IR::U64& value) noexcept {
|
||||
Inst(Opcode::A64SetSP, value);
|
||||
}
|
||||
|
||||
void SetFPCR(const IR::U32& value) noexcept {
|
||||
Inst(Opcode::A64SetFPCR, value);
|
||||
}
|
||||
|
||||
void SetFPSR(const IR::U32& value) noexcept {
|
||||
Inst(Opcode::A64SetFPSR, value);
|
||||
}
|
||||
|
||||
void SetPC(const IR::U64& value) noexcept {
|
||||
Inst(Opcode::A64SetPC, value);
|
||||
}
|
||||
|
||||
private:
|
||||
IR::U64 ImmCurrentLocationDescriptor();
|
||||
IR::U64 ImmCurrentLocationDescriptor() noexcept {
|
||||
return Imm64(IR::LocationDescriptor{*current_location}.Value());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
|
@ -33,27 +33,26 @@ inline size_t ToFastLookupIndex(u32 instruction) {
|
|||
} // namespace detail
|
||||
|
||||
template<typename V>
|
||||
DecodeTable<V> GetDecodeTable() {
|
||||
constexpr DecodeTable<V> GetDecodeTable() {
|
||||
std::vector<Matcher<V>> list = {
|
||||
#define INST(fn, name, bitstring) DYNARMIC_DECODER_GET_MATCHER(Matcher, fn, name, Decoder::detail::StringToArray<32>(bitstring)),
|
||||
#include "./a64.inc"
|
||||
#undef INST
|
||||
};
|
||||
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
std::stable_sort(list.begin(), list.end(), [](const auto& matcher1, const auto& matcher2) {
|
||||
// If a matcher has more bits in its mask it is more specific, so it should come first.
|
||||
return mcl::bit::count_ones(matcher1.GetMask()) > mcl::bit::count_ones(matcher2.GetMask());
|
||||
});
|
||||
|
||||
// Exceptions to the above rule of thumb.
|
||||
const std::set<std::string> comes_first{
|
||||
"MOVI, MVNI, ORR, BIC (vector, immediate)",
|
||||
"FMOV (vector, immediate)",
|
||||
"Unallocated SIMD modified immediate",
|
||||
};
|
||||
|
||||
std::stable_partition(list.begin(), list.end(), [&](const auto& matcher) {
|
||||
return comes_first.count(matcher.GetName()) > 0;
|
||||
return std::set<std::string>{
|
||||
"MOVI, MVNI, ORR, BIC (vector, immediate)",
|
||||
"FMOV (vector, immediate)",
|
||||
"Unallocated SIMD modified immediate",
|
||||
}.count(matcher.GetName()) > 0;
|
||||
});
|
||||
|
||||
DecodeTable<V> table{};
|
||||
|
@ -75,7 +74,6 @@ std::optional<std::reference_wrapper<const Matcher<V>>> Decode(u32 instruction)
|
|||
const auto matches_instruction = [instruction](const auto& matcher) {
|
||||
return matcher.Matches(instruction);
|
||||
};
|
||||
|
||||
const auto& subtable = table[detail::ToFastLookupIndex(instruction)];
|
||||
auto iter = std::find_if(subtable.begin(), subtable.end(), matches_instruction);
|
||||
return iter != subtable.end() ? std::optional<std::reference_wrapper<const Matcher<V>>>(*iter) : std::nullopt;
|
||||
|
|
|
@ -67,3 +67,64 @@ bool TranslateSingleInstruction(IR::Block& block, LocationDescriptor descriptor,
|
|||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
||||
// ls -l | awk '{print "#include \"dynarmic/frontend/A64/translate/impl/" $9 "\""}'
|
||||
#include "dynarmic/frontend/A64/translate/impl/a64_branch.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/a64_exception_generating.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_addsub.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_bitfield.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_conditional_compare.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_conditional_select.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_crc32.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_logical.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_multiply.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_pcrel.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_register.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/data_processing_shift.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/floating_point_compare.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/floating_point_conditional_compare.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/floating_point_conditional_select.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/floating_point_conversion_fixed_point.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/floating_point_conversion_integer.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/floating_point_data_processing_one_register.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/floating_point_data_processing_three_register.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/floating_point_data_processing_two_register.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/impl.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/impl.h"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_exclusive.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_load_literal.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_multiple_structures.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_no_allocate_pair.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_register_immediate.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_register_pair.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_register_register_offset.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_register_unprivileged.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/load_store_single_structure.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/move_wide.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_across_lanes.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_aes.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_copy.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_crypto_four_register.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_crypto_three_register.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_extract.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_modified_immediate.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_permute.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_scalar_pairwise.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_scalar_three_same.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_scalar_x_indexed_element.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_sha512.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_sha.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_shift_by_immediate.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_table_lookup.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_three_different.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_three_same.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_three_same_extra.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_two_register_misc.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/sys_dc.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/sys_ic.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/system.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/system_flag_format.cpp"
|
||||
#include "dynarmic/frontend/A64/translate/impl/system_flag_manipulation.cpp"
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
|
||||
namespace Dynarmic::A64 {
|
||||
namespace {
|
||||
enum class MinMaxOperation {
|
||||
enum class MinMaxOperationSSPW {
|
||||
Max,
|
||||
MaxNumeric,
|
||||
Min,
|
||||
MinNumeric,
|
||||
};
|
||||
|
||||
bool FPPairwiseMinMax(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, MinMaxOperation operation) {
|
||||
bool FPPairwiseMinMax(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, MinMaxOperationSSPW operation) {
|
||||
const size_t esize = sz ? 64 : 32;
|
||||
|
||||
const IR::U128 operand = v.V(128, Vn);
|
||||
|
@ -22,13 +22,13 @@ bool FPPairwiseMinMax(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, MinMaxOpera
|
|||
const IR::U32U64 element2 = v.ir.VectorGetElement(esize, operand, 1);
|
||||
const IR::U32U64 result = [&] {
|
||||
switch (operation) {
|
||||
case MinMaxOperation::Max:
|
||||
case MinMaxOperationSSPW::Max:
|
||||
return v.ir.FPMax(element1, element2);
|
||||
case MinMaxOperation::MaxNumeric:
|
||||
case MinMaxOperationSSPW::MaxNumeric:
|
||||
return v.ir.FPMaxNumeric(element1, element2);
|
||||
case MinMaxOperation::Min:
|
||||
case MinMaxOperationSSPW::Min:
|
||||
return v.ir.FPMin(element1, element2);
|
||||
case MinMaxOperation::MinNumeric:
|
||||
case MinMaxOperationSSPW::MinNumeric:
|
||||
return v.ir.FPMinNumeric(element1, element2);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
@ -63,18 +63,18 @@ bool TranslatorVisitor::FADDP_pair_2(bool size, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FMAXNMP_pair_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return FPPairwiseMinMax(*this, sz, Vn, Vd, MinMaxOperation::MaxNumeric);
|
||||
return FPPairwiseMinMax(*this, sz, Vn, Vd, MinMaxOperationSSPW::MaxNumeric);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMAXP_pair_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return FPPairwiseMinMax(*this, sz, Vn, Vd, MinMaxOperation::Max);
|
||||
return FPPairwiseMinMax(*this, sz, Vn, Vd, MinMaxOperationSSPW::Max);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMINNMP_pair_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return FPPairwiseMinMax(*this, sz, Vn, Vd, MinMaxOperation::MinNumeric);
|
||||
return FPPairwiseMinMax(*this, sz, Vn, Vd, MinMaxOperationSSPW::MinNumeric);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMINP_pair_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return FPPairwiseMinMax(*this, sz, Vn, Vd, MinMaxOperation::Min);
|
||||
return FPPairwiseMinMax(*this, sz, Vn, Vd, MinMaxOperationSSPW::Min);
|
||||
}
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
|
@ -27,7 +27,7 @@ enum class ShiftExtraBehavior {
|
|||
Accumulate,
|
||||
};
|
||||
|
||||
enum class Signedness {
|
||||
enum class SignednessSSSBI {
|
||||
Signed,
|
||||
Unsigned,
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ bool SaturatingShiftLeft(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, ShiftExtraBehavior behavior, Signedness signedness) {
|
||||
bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, ShiftExtraBehavior behavior, SignednessSSSBI SignednessSSSBI) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
|||
|
||||
const IR::U64 operand = v.V_scalar(esize, Vn);
|
||||
IR::U64 result = [&]() -> IR::U64 {
|
||||
if (signedness == Signedness::Signed) {
|
||||
if (SignednessSSSBI == SignednessSSSBI::Signed) {
|
||||
return v.ir.ArithmeticShiftRight(operand, v.ir.Imm8(shift_amount));
|
||||
}
|
||||
return v.ir.LogicalShiftRight(operand, v.ir.Imm8(shift_amount));
|
||||
|
@ -88,7 +88,7 @@ bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, ShiftExtraBehavior behavior, Signedness signedness) {
|
||||
bool RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, ShiftExtraBehavior behavior, SignednessSSSBI SignednessSSSBI) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ bool RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn,
|
|||
const IR::U64 round_bit = v.ir.LogicalShiftRight(v.ir.LogicalShiftLeft(operand, v.ir.Imm8(64 - shift_amount)), v.ir.Imm8(63));
|
||||
const IR::U64 result = [&] {
|
||||
const IR::U64 shifted = [&]() -> IR::U64 {
|
||||
if (signedness == Signedness::Signed) {
|
||||
if (SignednessSSSBI == SignednessSSSBI::Signed) {
|
||||
return v.ir.ArithmeticShiftRight(operand, v.ir.Imm8(shift_amount));
|
||||
}
|
||||
return v.ir.LogicalShiftRight(operand, v.ir.Imm8(shift_amount));
|
||||
|
@ -163,7 +163,7 @@ bool ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ShiftRightNarrowing(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Narrowing narrowing, Signedness signedness) {
|
||||
bool ShiftRightNarrowing(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Narrowing narrowing, SignednessSSSBI SignednessSSSBI) {
|
||||
if (immh == 0b0000) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn,
|
|||
const IR::U128 operand = v.ir.ZeroExtendToQuad(v.ir.VectorGetElement(source_esize, v.V(128, Vn), 0));
|
||||
|
||||
IR::U128 wide_result = [&] {
|
||||
if (signedness == Signedness::Signed) {
|
||||
if (SignednessSSSBI == SignednessSSSBI::Signed) {
|
||||
return v.ir.VectorArithmeticShiftRight(source_esize, operand, shift_amount);
|
||||
}
|
||||
return v.ir.VectorLogicalShiftRight(source_esize, operand, shift_amount);
|
||||
|
@ -190,12 +190,12 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn,
|
|||
case Narrowing::Truncation:
|
||||
return v.ir.VectorNarrow(source_esize, wide_result);
|
||||
case Narrowing::SaturateToUnsigned:
|
||||
if (signedness == Signedness::Signed) {
|
||||
if (SignednessSSSBI == SignednessSSSBI::Signed) {
|
||||
return v.ir.VectorSignedSaturatedNarrowToUnsigned(source_esize, wide_result);
|
||||
}
|
||||
return v.ir.VectorUnsignedSaturatedNarrow(source_esize, wide_result);
|
||||
case Narrowing::SaturateToSigned:
|
||||
ASSERT(signedness == Signedness::Signed);
|
||||
ASSERT(SignednessSSSBI == SignednessSSSBI::Signed);
|
||||
return v.ir.VectorSignedSaturatedNarrowToSigned(source_esize, wide_result);
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
@ -206,7 +206,7 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign, FloatConversionDirection direction, FP::RoundingMode rounding_mode) {
|
||||
bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, SignednessSSSBI sign, FloatConversionDirection direction, FP::RoundingMode rounding_mode) {
|
||||
const u32 immh_value = immh.ZeroExtend();
|
||||
|
||||
if ((immh_value & 0b1110) == 0b0000) {
|
||||
|
@ -227,23 +227,23 @@ bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Ve
|
|||
switch (direction) {
|
||||
case FloatConversionDirection::FloatToFixed:
|
||||
if (esize == 64) {
|
||||
return sign == Signedness::Signed
|
||||
return sign == SignednessSSSBI::Signed
|
||||
? v.ir.FPToFixedS64(operand, fbits, rounding_mode)
|
||||
: v.ir.FPToFixedU64(operand, fbits, rounding_mode);
|
||||
}
|
||||
|
||||
return sign == Signedness::Signed
|
||||
return sign == SignednessSSSBI::Signed
|
||||
? v.ir.FPToFixedS32(operand, fbits, rounding_mode)
|
||||
: v.ir.FPToFixedU32(operand, fbits, rounding_mode);
|
||||
|
||||
case FloatConversionDirection::FixedToFloat:
|
||||
if (esize == 64) {
|
||||
return sign == Signedness::Signed
|
||||
return sign == SignednessSSSBI::Signed
|
||||
? v.ir.FPSignedFixedToDouble(operand, fbits, rounding_mode)
|
||||
: v.ir.FPUnsignedFixedToDouble(operand, fbits, rounding_mode);
|
||||
}
|
||||
|
||||
return sign == Signedness::Signed
|
||||
return sign == SignednessSSSBI::Signed
|
||||
? v.ir.FPSignedFixedToSingle(operand, fbits, rounding_mode)
|
||||
: v.ir.FPUnsignedFixedToSingle(operand, fbits, rounding_mode);
|
||||
}
|
||||
|
@ -257,19 +257,19 @@ bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Ve
|
|||
} // Anonymous namespace
|
||||
|
||||
bool TranslatorVisitor::FCVTZS_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Signed, FloatConversionDirection::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, SignednessSSSBI::Signed, FloatConversionDirection::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTZU_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Unsigned, FloatConversionDirection::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, SignednessSSSBI::Unsigned, FloatConversionDirection::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SCVTF_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Signed, FloatConversionDirection::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, SignednessSSSBI::Signed, FloatConversionDirection::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UCVTF_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Unsigned, FloatConversionDirection::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, SignednessSSSBI::Unsigned, FloatConversionDirection::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SLI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
|
@ -289,27 +289,27 @@ bool TranslatorVisitor::SQSHLU_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SQSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, immh, immb, Vn, Vd, Narrowing::SaturateToSigned, Signedness::Signed);
|
||||
return ShiftRightNarrowing(*this, immh, immb, Vn, Vd, Narrowing::SaturateToSigned, SignednessSSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQSHRUN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, immh, immb, Vn, Vd, Narrowing::SaturateToUnsigned, Signedness::Signed);
|
||||
return ShiftRightNarrowing(*this, immh, immb, Vn, Vd, Narrowing::SaturateToUnsigned, SignednessSSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, SignednessSSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, SignednessSSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, SignednessSSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, SignednessSSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
|
@ -332,23 +332,23 @@ bool TranslatorVisitor::UQSHL_imm_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::UQSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, immh, immb, Vn, Vd, Narrowing::SaturateToUnsigned, Signedness::Unsigned);
|
||||
return ShiftRightNarrowing(*this, immh, immb, Vn, Vd, Narrowing::SaturateToUnsigned, SignednessSSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, SignednessSSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, SignednessSSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, SignednessSSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, SignednessSSSBI::Unsigned);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
|
@ -26,12 +26,12 @@ enum class ComparisonVariant {
|
|||
Zero,
|
||||
};
|
||||
|
||||
enum class Signedness {
|
||||
enum class SignednessSSTS {
|
||||
Signed,
|
||||
Unsigned,
|
||||
};
|
||||
|
||||
bool RoundingShiftLeft(TranslatorVisitor& v, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Signedness sign) {
|
||||
bool RoundingShiftLeft(TranslatorVisitor& v, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, SignednessSSTS sign) {
|
||||
if (size != 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ bool RoundingShiftLeft(TranslatorVisitor& v, Imm<2> size, Vec Vm, Vec Vn, Vec Vd
|
|||
const IR::U128 operand1 = v.V(64, Vn);
|
||||
const IR::U128 operand2 = v.V(64, Vm);
|
||||
const IR::U128 result = [&] {
|
||||
if (sign == Signedness::Signed) {
|
||||
if (sign == SignednessSSTS::Signed) {
|
||||
return v.ir.VectorRoundingShiftLeftSigned(64, operand1, operand2);
|
||||
}
|
||||
|
||||
|
@ -369,7 +369,7 @@ bool TranslatorVisitor::SQSHL_reg_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SRSHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return RoundingShiftLeft(*this, size, Vm, Vn, Vd, Signedness::Signed);
|
||||
return RoundingShiftLeft(*this, size, Vm, Vn, Vd, SignednessSSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -411,7 +411,7 @@ bool TranslatorVisitor::UQSHL_reg_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::URSHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return RoundingShiftLeft(*this, size, Vm, Vn, Vd, Signedness::Unsigned);
|
||||
return RoundingShiftLeft(*this, size, Vm, Vn, Vd, SignednessSSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USHL_1(Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace Dynarmic::A64 {
|
||||
namespace {
|
||||
enum class ComparisonType {
|
||||
enum class ComparisonTypeSSTRM {
|
||||
EQ,
|
||||
GE,
|
||||
GT,
|
||||
|
@ -15,12 +15,12 @@ enum class ComparisonType {
|
|||
LT
|
||||
};
|
||||
|
||||
enum class Signedness {
|
||||
enum class SignednessSSTRM {
|
||||
Signed,
|
||||
Unsigned
|
||||
};
|
||||
|
||||
bool ScalarFPCompareAgainstZero(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, ComparisonType type) {
|
||||
bool ScalarFPCompareAgainstZero(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, ComparisonTypeSSTRM type) {
|
||||
const size_t esize = sz ? 64 : 32;
|
||||
const size_t datasize = esize;
|
||||
|
||||
|
@ -28,15 +28,15 @@ bool ScalarFPCompareAgainstZero(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, C
|
|||
const IR::U128 zero = v.ir.ZeroVector();
|
||||
const IR::U128 result = [&] {
|
||||
switch (type) {
|
||||
case ComparisonType::EQ:
|
||||
case ComparisonTypeSSTRM::EQ:
|
||||
return v.ir.FPVectorEqual(esize, operand, zero);
|
||||
case ComparisonType::GE:
|
||||
case ComparisonTypeSSTRM::GE:
|
||||
return v.ir.FPVectorGreaterEqual(esize, operand, zero);
|
||||
case ComparisonType::GT:
|
||||
case ComparisonTypeSSTRM::GT:
|
||||
return v.ir.FPVectorGreater(esize, operand, zero);
|
||||
case ComparisonType::LE:
|
||||
case ComparisonTypeSSTRM::LE:
|
||||
return v.ir.FPVectorGreaterEqual(esize, zero, operand);
|
||||
case ComparisonType::LT:
|
||||
case ComparisonTypeSSTRM::LT:
|
||||
return v.ir.FPVectorGreater(esize, zero, operand);
|
||||
}
|
||||
|
||||
|
@ -47,18 +47,18 @@ bool ScalarFPCompareAgainstZero(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, C
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ScalarFPConvertWithRound(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, FP::RoundingMode rmode, Signedness sign) {
|
||||
bool ScalarFPConvertWithRound(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, FP::RoundingMode rmode, SignednessSSTRM sign) {
|
||||
const size_t esize = sz ? 64 : 32;
|
||||
|
||||
const IR::U32U64 operand = v.V_scalar(esize, Vn);
|
||||
const IR::U32U64 result = [&]() -> IR::U32U64 {
|
||||
if (sz) {
|
||||
return sign == Signedness::Signed
|
||||
return sign == SignednessSSTRM::Signed
|
||||
? v.ir.FPToFixedS64(operand, 0, rmode)
|
||||
: v.ir.FPToFixedU64(operand, 0, rmode);
|
||||
}
|
||||
|
||||
return sign == Signedness::Signed
|
||||
return sign == SignednessSSTRM::Signed
|
||||
? v.ir.FPToFixedS32(operand, 0, rmode)
|
||||
: v.ir.FPToFixedU32(operand, 0, rmode);
|
||||
}();
|
||||
|
@ -107,55 +107,55 @@ bool TranslatorVisitor::FCMEQ_zero_1(Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FCMEQ_zero_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::EQ);
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonTypeSSTRM::EQ);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMGE_zero_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::GE);
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonTypeSSTRM::GE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMGT_zero_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::GT);
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonTypeSSTRM::GT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMLE_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::LE);
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonTypeSSTRM::LE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMLT_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::LT);
|
||||
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonTypeSSTRM::LT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTAS_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieAwayFromZero, Signedness::Signed);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieAwayFromZero, SignednessSSTRM::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTAU_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieAwayFromZero, Signedness::Unsigned);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieAwayFromZero, SignednessSSTRM::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTMS_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsMinusInfinity, Signedness::Signed);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsMinusInfinity, SignednessSSTRM::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTMU_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsMinusInfinity, Signedness::Unsigned);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsMinusInfinity, SignednessSSTRM::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTNS_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieEven, Signedness::Signed);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieEven, SignednessSSTRM::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTNU_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieEven, Signedness::Unsigned);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::ToNearest_TieEven, SignednessSSTRM::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTPS_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsPlusInfinity, Signedness::Signed);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsPlusInfinity, SignednessSSTRM::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTPU_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsPlusInfinity, Signedness::Unsigned);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsPlusInfinity, SignednessSSTRM::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTXN_1(bool sz, Vec Vn, Vec Vd) {
|
||||
|
@ -171,11 +171,11 @@ bool TranslatorVisitor::FCVTXN_1(bool sz, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTZS_int_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsZero, Signedness::Signed);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsZero, SignednessSSTRM::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTZU_int_2(bool sz, Vec Vn, Vec Vd) {
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsZero, Signedness::Unsigned);
|
||||
return ScalarFPConvertWithRound(*this, sz, Vn, Vd, FP::RoundingMode::TowardsZero, SignednessSSTRM::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FRECPE_1(Vec Vn, Vec Vd) {
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
namespace Dynarmic::A64 {
|
||||
namespace {
|
||||
std::pair<size_t, Vec> Combine(Imm<2> size, Imm<1> H, Imm<1> L, Imm<1> M, Imm<4> Vmlo) {
|
||||
std::pair<size_t, Vec> CombineScalar(Imm<2> size, Imm<1> H, Imm<1> L, Imm<1> M, Imm<4> Vmlo) {
|
||||
if (size == 0b01) {
|
||||
return {concatenate(H, L, M).ZeroExtend(), Vmlo.ZeroExtend<Vec>()};
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ bool TranslatorVisitor::SQDMULH_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vm
|
|||
}
|
||||
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const auto [index, Vm] = CombineScalar(size, H, L, M, Vmlo);
|
||||
|
||||
const IR::UAny operand1 = V_scalar(esize, Vn);
|
||||
const IR::UAny operand2 = ir.VectorGetElement(esize, V(128, Vm), index);
|
||||
|
@ -137,7 +137,7 @@ bool TranslatorVisitor::SQRDMULH_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> V
|
|||
}
|
||||
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const auto [index, Vm] = CombineScalar(size, H, L, M, Vmlo);
|
||||
|
||||
const IR::U128 operand1 = ir.ZeroExtendToQuad(ir.VectorGetElement(esize, V(128, Vn), 0));
|
||||
const IR::U128 operand2 = V(128, Vm);
|
||||
|
@ -154,7 +154,7 @@ bool TranslatorVisitor::SQDMULL_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vm
|
|||
}
|
||||
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const auto [index, Vm] = CombineScalar(size, H, L, M, Vmlo);
|
||||
|
||||
const IR::U128 operand1 = ir.ZeroExtendToQuad(ir.VectorGetElement(esize, V(128, Vn), 0));
|
||||
const IR::U128 operand2 = V(128, Vm);
|
||||
|
|
|
@ -20,24 +20,24 @@ enum class Accumulating {
|
|||
Accumulate
|
||||
};
|
||||
|
||||
enum class Signedness {
|
||||
enum class SignednessSSBI {
|
||||
Signed,
|
||||
Unsigned
|
||||
};
|
||||
|
||||
enum class Narrowing {
|
||||
enum class NarrowingSSBI {
|
||||
Truncation,
|
||||
SaturateToUnsigned,
|
||||
SaturateToSigned,
|
||||
};
|
||||
|
||||
enum class SaturatingShiftLeftType {
|
||||
enum class SaturatingShiftLeftTypeSSBI {
|
||||
Signed,
|
||||
Unsigned,
|
||||
SignedWithUnsignedSaturation,
|
||||
};
|
||||
|
||||
enum class FloatConversionDirection {
|
||||
enum class FloatConversionDirectionSSBI {
|
||||
FixedToFloat,
|
||||
FloatToFixed,
|
||||
};
|
||||
|
@ -48,7 +48,7 @@ IR::U128 PerformRoundingCorrection(TranslatorVisitor& v, size_t esize, u64 round
|
|||
return v.ir.VectorSub(esize, shifted, round_correction);
|
||||
}
|
||||
|
||||
bool ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Rounding rounding, Accumulating accumulating, Signedness signedness) {
|
||||
bool ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Rounding rounding, Accumulating accumulating, SignednessSSBI SignednessSSBI) {
|
||||
if (immh == 0b0000) {
|
||||
return v.DecodeError();
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ bool ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn,
|
|||
const IR::U128 operand = v.V(datasize, Vn);
|
||||
|
||||
IR::U128 result = [&] {
|
||||
if (signedness == Signedness::Signed) {
|
||||
if (SignednessSSBI == SignednessSSBI::Signed) {
|
||||
return v.ir.VectorArithmeticShiftRight(esize, operand, shift_amount);
|
||||
}
|
||||
return v.ir.VectorLogicalShiftRight(esize, operand, shift_amount);
|
||||
|
@ -85,7 +85,7 @@ bool ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Rounding rounding, Narrowing narrowing, Signedness signedness) {
|
||||
bool ShiftRightNarrowingSSBI(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Rounding rounding, NarrowingSSBI NarrowingSSBI, SignednessSSBI SignednessSSBI) {
|
||||
if (immh == 0b0000) {
|
||||
return v.DecodeError();
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb,
|
|||
const IR::U128 operand = v.V(128, Vn);
|
||||
|
||||
IR::U128 wide_result = [&] {
|
||||
if (signedness == Signedness::Signed) {
|
||||
if (SignednessSSBI == SignednessSSBI::Signed) {
|
||||
return v.ir.VectorArithmeticShiftRight(source_esize, operand, shift_amount);
|
||||
}
|
||||
return v.ir.VectorLogicalShiftRight(source_esize, operand, shift_amount);
|
||||
|
@ -115,16 +115,16 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb,
|
|||
}
|
||||
|
||||
const IR::U128 result = [&] {
|
||||
switch (narrowing) {
|
||||
case Narrowing::Truncation:
|
||||
switch (NarrowingSSBI) {
|
||||
case NarrowingSSBI::Truncation:
|
||||
return v.ir.VectorNarrow(source_esize, wide_result);
|
||||
case Narrowing::SaturateToUnsigned:
|
||||
if (signedness == Signedness::Signed) {
|
||||
case NarrowingSSBI::SaturateToUnsigned:
|
||||
if (SignednessSSBI == SignednessSSBI::Signed) {
|
||||
return v.ir.VectorSignedSaturatedNarrowToUnsigned(source_esize, wide_result);
|
||||
}
|
||||
return v.ir.VectorUnsignedSaturatedNarrow(source_esize, wide_result);
|
||||
case Narrowing::SaturateToSigned:
|
||||
ASSERT(signedness == Signedness::Signed);
|
||||
case NarrowingSSBI::SaturateToSigned:
|
||||
ASSERT(SignednessSSBI == SignednessSSBI::Signed);
|
||||
return v.ir.VectorSignedSaturatedNarrowToSigned(source_esize, wide_result);
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
@ -134,7 +134,7 @@ bool ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness signedness) {
|
||||
bool ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, SignednessSSBI SignednessSSBI) {
|
||||
if (immh == 0b0000) {
|
||||
return v.DecodeError();
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ bool ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec V
|
|||
|
||||
const IR::U128 operand = v.Vpart(datasize, Vn, part);
|
||||
const IR::U128 expanded_operand = [&] {
|
||||
if (signedness == Signedness::Signed) {
|
||||
if (SignednessSSBI == SignednessSSBI::Signed) {
|
||||
return v.ir.VectorSignExtend(esize, operand);
|
||||
}
|
||||
return v.ir.VectorZeroExtend(esize, operand);
|
||||
|
@ -162,7 +162,7 @@ bool ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec V
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, SaturatingShiftLeftType type) {
|
||||
bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, SaturatingShiftLeftTypeSSBI type) {
|
||||
if (!Q && immh.Bit<3>()) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -174,11 +174,11 @@ bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb,
|
|||
const IR::U128 operand = v.V(datasize, Vn);
|
||||
const IR::U128 shift_vec = v.ir.VectorBroadcast(esize, v.I(esize, shift));
|
||||
const IR::U128 result = [&] {
|
||||
if (type == SaturatingShiftLeftType::Signed) {
|
||||
if (type == SaturatingShiftLeftTypeSSBI::Signed) {
|
||||
return v.ir.VectorSignedSaturatedShiftLeft(esize, operand, shift_vec);
|
||||
}
|
||||
|
||||
if (type == SaturatingShiftLeftType::Unsigned) {
|
||||
if (type == SaturatingShiftLeftTypeSSBI::Unsigned) {
|
||||
return v.ir.VectorUnsignedSaturatedShiftLeft(esize, operand, shift_vec);
|
||||
}
|
||||
|
||||
|
@ -189,7 +189,7 @@ bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ConvertFloat(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness signedness, FloatConversionDirection direction, FP::RoundingMode rounding_mode) {
|
||||
bool ConvertFloat(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, SignednessSSBI SignednessSSBI, FloatConversionDirectionSSBI direction, FP::RoundingMode rounding_mode) {
|
||||
if (immh == 0b0000) {
|
||||
return v.DecodeError();
|
||||
}
|
||||
|
@ -210,12 +210,12 @@ bool ConvertFloat(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn
|
|||
const IR::U128 operand = v.V(datasize, Vn);
|
||||
const IR::U128 result = [&] {
|
||||
switch (direction) {
|
||||
case FloatConversionDirection::FixedToFloat:
|
||||
return signedness == Signedness::Signed
|
||||
case FloatConversionDirectionSSBI::FixedToFloat:
|
||||
return SignednessSSBI == SignednessSSBI::Signed
|
||||
? v.ir.FPVectorFromSignedFixed(esize, operand, fbits, rounding_mode)
|
||||
: v.ir.FPVectorFromUnsignedFixed(esize, operand, fbits, rounding_mode);
|
||||
case FloatConversionDirection::FloatToFixed:
|
||||
return signedness == Signedness::Signed
|
||||
case FloatConversionDirectionSSBI::FloatToFixed:
|
||||
return SignednessSSBI == SignednessSSBI::Signed
|
||||
? v.ir.FPVectorToSignedFixed(esize, operand, fbits, rounding_mode)
|
||||
: v.ir.FPVectorToUnsignedFixed(esize, operand, fbits, rounding_mode);
|
||||
}
|
||||
|
@ -229,19 +229,19 @@ bool ConvertFloat(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn
|
|||
} // Anonymous namespace
|
||||
|
||||
bool TranslatorVisitor::SSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::None, Accumulating::None, Signedness::Signed);
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::None, Accumulating::None, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Accumulating::None, Signedness::Signed);
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Accumulating::None, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Accumulating::Accumulate, Signedness::Signed);
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Accumulating::Accumulate, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::None, Accumulating::Accumulate, Signedness::Signed);
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::None, Accumulating::Accumulate, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
|
@ -264,71 +264,71 @@ bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd)
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, Rounding::None, Narrowing::Truncation, Signedness::Unsigned);
|
||||
return ShiftRightNarrowingSSBI(*this, Q, immh, immb, Vn, Vd, Rounding::None, NarrowingSSBI::Truncation, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::RSHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Narrowing::Truncation, Signedness::Unsigned);
|
||||
return ShiftRightNarrowingSSBI(*this, Q, immh, immb, Vn, Vd, Rounding::Round, NarrowingSSBI::Truncation, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQSHL_imm_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftType::Signed);
|
||||
return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftTypeSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQSHLU_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftType::SignedWithUnsignedSaturation);
|
||||
return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftTypeSSBI::SignedWithUnsignedSaturation);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, Rounding::None, Narrowing::SaturateToSigned, Signedness::Signed);
|
||||
return ShiftRightNarrowingSSBI(*this, Q, immh, immb, Vn, Vd, Rounding::None, NarrowingSSBI::SaturateToSigned, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQRSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Narrowing::SaturateToSigned, Signedness::Signed);
|
||||
return ShiftRightNarrowingSSBI(*this, Q, immh, immb, Vn, Vd, Rounding::Round, NarrowingSSBI::SaturateToSigned, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, Rounding::None, Narrowing::SaturateToUnsigned, Signedness::Signed);
|
||||
return ShiftRightNarrowingSSBI(*this, Q, immh, immb, Vn, Vd, Rounding::None, NarrowingSSBI::SaturateToUnsigned, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQRSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Narrowing::SaturateToUnsigned, Signedness::Signed);
|
||||
return ShiftRightNarrowingSSBI(*this, Q, immh, immb, Vn, Vd, Rounding::Round, NarrowingSSBI::SaturateToUnsigned, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UQSHL_imm_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftType::Unsigned);
|
||||
return SaturatingShiftLeft(*this, Q, immh, immb, Vn, Vd, SaturatingShiftLeftTypeSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, Rounding::None, Narrowing::SaturateToUnsigned, Signedness::Unsigned);
|
||||
return ShiftRightNarrowingSSBI(*this, Q, immh, immb, Vn, Vd, Rounding::None, NarrowingSSBI::SaturateToUnsigned, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UQRSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Narrowing::SaturateToUnsigned, Signedness::Unsigned);
|
||||
return ShiftRightNarrowingSSBI(*this, Q, immh, immb, Vn, Vd, Rounding::Round, NarrowingSSBI::SaturateToUnsigned, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Signed);
|
||||
return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, SignednessSSBI::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Accumulating::None, Signedness::Unsigned);
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Accumulating::None, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Accumulating::Accumulate, Signedness::Unsigned);
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::Round, Accumulating::Accumulate, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::None, Accumulating::None, Signedness::Unsigned);
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::None, Accumulating::None, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::None, Accumulating::Accumulate, Signedness::Unsigned);
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, Rounding::None, Accumulating::Accumulate, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned);
|
||||
return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, SignednessSSBI::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
|
@ -384,19 +384,19 @@ bool TranslatorVisitor::SLI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd)
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SCVTF_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ConvertFloat(*this, Q, immh, immb, Vn, Vd, Signedness::Signed, FloatConversionDirection::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||
return ConvertFloat(*this, Q, immh, immb, Vn, Vd, SignednessSSBI::Signed, FloatConversionDirectionSSBI::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UCVTF_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ConvertFloat(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned, FloatConversionDirection::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||
return ConvertFloat(*this, Q, immh, immb, Vn, Vd, SignednessSSBI::Unsigned, FloatConversionDirectionSSBI::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTZS_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ConvertFloat(*this, Q, immh, immb, Vn, Vd, Signedness::Signed, FloatConversionDirection::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||
return ConvertFloat(*this, Q, immh, immb, Vn, Vd, SignednessSSBI::Signed, FloatConversionDirectionSSBI::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTZU_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
return ConvertFloat(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned, FloatConversionDirection::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||
return ConvertFloat(*this, Q, immh, immb, Vn, Vd, SignednessSSBI::Unsigned, FloatConversionDirectionSSBI::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
|
@ -12,12 +12,12 @@ enum class AbsoluteDifferenceBehavior {
|
|||
Accumulate
|
||||
};
|
||||
|
||||
enum class Signedness {
|
||||
enum class SignednessSTD {
|
||||
Signed,
|
||||
Unsigned
|
||||
};
|
||||
|
||||
bool AbsoluteDifferenceLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, AbsoluteDifferenceBehavior behavior, Signedness sign) {
|
||||
bool AbsoluteDifferenceLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, AbsoluteDifferenceBehavior behavior, SignednessSTD sign) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ bool AbsoluteDifferenceLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, V
|
|||
|
||||
const IR::U128 operand1 = v.ir.VectorZeroExtend(esize, v.Vpart(datasize, Vn, Q));
|
||||
const IR::U128 operand2 = v.ir.VectorZeroExtend(esize, v.Vpart(datasize, Vm, Q));
|
||||
IR::U128 result = sign == Signedness::Signed ? v.ir.VectorSignedAbsoluteDifference(esize, operand1, operand2)
|
||||
IR::U128 result = sign == SignednessSTD::Signed ? v.ir.VectorSignedAbsoluteDifference(esize, operand1, operand2)
|
||||
: v.ir.VectorUnsignedAbsoluteDifference(esize, operand1, operand2);
|
||||
|
||||
if (behavior == AbsoluteDifferenceBehavior::Accumulate) {
|
||||
|
@ -45,7 +45,7 @@ enum class MultiplyLongBehavior {
|
|||
Subtract
|
||||
};
|
||||
|
||||
bool MultiplyLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, MultiplyLongBehavior behavior, Signedness sign) {
|
||||
bool MultiplyLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, MultiplyLongBehavior behavior, SignednessSTD sign) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ bool MultiplyLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec
|
|||
const auto reg_n = v.Vpart(datasize, Vn, Q);
|
||||
const auto reg_m = v.Vpart(datasize, Vm, Q);
|
||||
|
||||
return sign == Signedness::Signed
|
||||
return sign == SignednessSTD::Signed
|
||||
? v.ir.VectorMultiplySignedWiden(esize, reg_n, reg_m)
|
||||
: v.ir.VectorMultiplyUnsignedWiden(esize, reg_n, reg_m);
|
||||
}();
|
||||
|
@ -81,7 +81,7 @@ enum class LongOperationBehavior {
|
|||
Subtraction
|
||||
};
|
||||
|
||||
bool LongOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, LongOperationBehavior behavior, Signedness sign) {
|
||||
bool LongOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, LongOperationBehavior behavior, SignednessSTD sign) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ bool LongOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Ve
|
|||
const auto get_operand = [&](Vec vec) {
|
||||
const IR::U128 tmp = v.Vpart(64, vec, part);
|
||||
|
||||
if (sign == Signedness::Signed) {
|
||||
if (sign == SignednessSTD::Signed) {
|
||||
return v.ir.VectorSignExtend(esize, tmp);
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ enum class WideOperationBehavior {
|
|||
Subtraction
|
||||
};
|
||||
|
||||
bool WideOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, WideOperationBehavior behavior, Signedness sign) {
|
||||
bool WideOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, WideOperationBehavior behavior, SignednessSTD sign) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -130,7 +130,7 @@ bool WideOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Ve
|
|||
const IR::U128 operand2 = [&] {
|
||||
const IR::U128 tmp = v.Vpart(64, Vm, part);
|
||||
|
||||
if (sign == Signedness::Signed) {
|
||||
if (sign == SignednessSTD::Signed) {
|
||||
return v.ir.VectorSignExtend(esize, tmp);
|
||||
}
|
||||
|
||||
|
@ -166,75 +166,75 @@ bool TranslatorVisitor::PMULL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SABAL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return AbsoluteDifferenceLong(*this, Q, size, Vm, Vn, Vd, AbsoluteDifferenceBehavior::Accumulate, Signedness::Signed);
|
||||
return AbsoluteDifferenceLong(*this, Q, size, Vm, Vn, Vd, AbsoluteDifferenceBehavior::Accumulate, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SABDL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return AbsoluteDifferenceLong(*this, Q, size, Vm, Vn, Vd, AbsoluteDifferenceBehavior::None, Signedness::Signed);
|
||||
return AbsoluteDifferenceLong(*this, Q, size, Vm, Vn, Vd, AbsoluteDifferenceBehavior::None, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SADDL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Addition, Signedness::Signed);
|
||||
return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Addition, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SADDW(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return WideOperation(*this, Q, size, Vm, Vn, Vd, WideOperationBehavior::Addition, Signedness::Signed);
|
||||
return WideOperation(*this, Q, size, Vm, Vn, Vd, WideOperationBehavior::Addition, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMLAL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::Accumulate, Signedness::Signed);
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::Accumulate, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMLSL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::Subtract, Signedness::Signed);
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::Subtract, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMULL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::None, Signedness::Signed);
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::None, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSUBW(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return WideOperation(*this, Q, size, Vm, Vn, Vd, WideOperationBehavior::Subtraction, Signedness::Signed);
|
||||
return WideOperation(*this, Q, size, Vm, Vn, Vd, WideOperationBehavior::Subtraction, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSUBL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Subtraction, Signedness::Signed);
|
||||
return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Subtraction, SignednessSTD::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UADDL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Addition, Signedness::Unsigned);
|
||||
return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Addition, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UABAL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return AbsoluteDifferenceLong(*this, Q, size, Vm, Vn, Vd, AbsoluteDifferenceBehavior::Accumulate, Signedness::Unsigned);
|
||||
return AbsoluteDifferenceLong(*this, Q, size, Vm, Vn, Vd, AbsoluteDifferenceBehavior::Accumulate, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UABDL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return AbsoluteDifferenceLong(*this, Q, size, Vm, Vn, Vd, AbsoluteDifferenceBehavior::None, Signedness::Unsigned);
|
||||
return AbsoluteDifferenceLong(*this, Q, size, Vm, Vn, Vd, AbsoluteDifferenceBehavior::None, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UADDW(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return WideOperation(*this, Q, size, Vm, Vn, Vd, WideOperationBehavior::Addition, Signedness::Unsigned);
|
||||
return WideOperation(*this, Q, size, Vm, Vn, Vd, WideOperationBehavior::Addition, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UMLAL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::Accumulate, Signedness::Unsigned);
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::Accumulate, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UMLSL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::Subtract, Signedness::Unsigned);
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::Subtract, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UMULL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::None, Signedness::Unsigned);
|
||||
return MultiplyLong(*this, Q, size, Vm, Vn, Vd, MultiplyLongBehavior::None, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USUBW(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return WideOperation(*this, Q, size, Vm, Vn, Vd, WideOperationBehavior::Subtraction, Signedness::Unsigned);
|
||||
return WideOperation(*this, Q, size, Vm, Vn, Vd, WideOperationBehavior::Subtraction, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USUBL(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Subtraction, Signedness::Unsigned);
|
||||
return LongOperation(*this, Q, size, Vm, Vn, Vd, LongOperationBehavior::Subtraction, SignednessSTD::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQDMULL_vec_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
|
|
@ -12,12 +12,12 @@ enum class Operation {
|
|||
Subtract,
|
||||
};
|
||||
|
||||
enum class ExtraBehavior {
|
||||
enum class ExtraBehaviorSTS {
|
||||
None,
|
||||
Round
|
||||
};
|
||||
|
||||
bool HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Operation op, ExtraBehavior behavior) {
|
||||
bool HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Operation op, ExtraBehaviorSTS behavior) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ bool HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, V
|
|||
return v.ir.VectorSub(doubled_esize, operand1, operand2);
|
||||
}();
|
||||
|
||||
if (behavior == ExtraBehavior::Round) {
|
||||
if (behavior == ExtraBehaviorSTS::Round) {
|
||||
const u64 round_const = 1ULL << (esize - 1);
|
||||
const IR::U128 round_operand = v.ir.VectorBroadcast(doubled_esize, v.I(doubled_esize, round_const));
|
||||
wide = v.ir.VectorAdd(doubled_esize, wide, round_operand);
|
||||
|
@ -48,12 +48,12 @@ bool HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, V
|
|||
return true;
|
||||
}
|
||||
|
||||
enum class AbsDiffExtraBehavior {
|
||||
enum class AbsDiffExtraBehaviorSTS {
|
||||
None,
|
||||
Accumulate
|
||||
};
|
||||
|
||||
bool SignedAbsoluteDifference(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, AbsDiffExtraBehavior behavior) {
|
||||
bool SignedAbsoluteDifference(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, AbsDiffExtraBehaviorSTS behavior) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ bool SignedAbsoluteDifference(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm,
|
|||
const IR::U128 result = [&] {
|
||||
const IR::U128 tmp = v.ir.VectorSignedAbsoluteDifference(esize, operand1, operand2);
|
||||
|
||||
if (behavior == AbsDiffExtraBehavior::Accumulate) {
|
||||
if (behavior == AbsDiffExtraBehaviorSTS::Accumulate) {
|
||||
const IR::U128 d = v.V(datasize, Vd);
|
||||
return v.ir.VectorAdd(esize, d, tmp);
|
||||
}
|
||||
|
@ -78,12 +78,12 @@ bool SignedAbsoluteDifference(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm,
|
|||
return true;
|
||||
}
|
||||
|
||||
enum class Signedness {
|
||||
enum class SignednessSTS {
|
||||
Signed,
|
||||
Unsigned
|
||||
};
|
||||
|
||||
bool RoundingHalvingAdd(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Signedness sign) {
|
||||
bool RoundingHalvingAdd(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, SignednessSTS sign) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -93,14 +93,14 @@ bool RoundingHalvingAdd(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec V
|
|||
|
||||
const IR::U128 operand1 = v.V(datasize, Vm);
|
||||
const IR::U128 operand2 = v.V(datasize, Vn);
|
||||
const IR::U128 result = sign == Signedness::Signed ? v.ir.VectorRoundingHalvingAddSigned(esize, operand1, operand2)
|
||||
const IR::U128 result = sign == SignednessSTS::Signed ? v.ir.VectorRoundingHalvingAddSigned(esize, operand1, operand2)
|
||||
: v.ir.VectorRoundingHalvingAddUnsigned(esize, operand1, operand2);
|
||||
|
||||
v.V(datasize, Vd, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RoundingShiftLeft(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Signedness sign) {
|
||||
bool RoundingShiftLeft(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, SignednessSTS sign) {
|
||||
if (size == 0b11 && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ bool RoundingShiftLeft(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn
|
|||
const IR::U128 operand1 = v.V(datasize, Vn);
|
||||
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||
const IR::U128 result = [&] {
|
||||
if (sign == Signedness::Signed) {
|
||||
if (sign == SignednessSTS::Signed) {
|
||||
return v.ir.VectorRoundingShiftLeftSigned(esize, operand1, operand2);
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ bool RoundingShiftLeft(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn
|
|||
return true;
|
||||
}
|
||||
|
||||
enum class ComparisonType {
|
||||
enum class ComparisonTypeSTS {
|
||||
EQ,
|
||||
GE,
|
||||
AbsoluteGE,
|
||||
|
@ -130,7 +130,7 @@ enum class ComparisonType {
|
|||
AbsoluteGT
|
||||
};
|
||||
|
||||
bool FPCompareRegister(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd, ComparisonType type) {
|
||||
bool FPCompareRegister(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd, ComparisonTypeSTS type) {
|
||||
if (sz && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -142,17 +142,17 @@ bool FPCompareRegister(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Ve
|
|||
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||
const IR::U128 result = [&] {
|
||||
switch (type) {
|
||||
case ComparisonType::EQ:
|
||||
case ComparisonTypeSTS::EQ:
|
||||
return v.ir.FPVectorEqual(esize, operand1, operand2);
|
||||
case ComparisonType::GE:
|
||||
case ComparisonTypeSTS::GE:
|
||||
return v.ir.FPVectorGreaterEqual(esize, operand1, operand2);
|
||||
case ComparisonType::AbsoluteGE:
|
||||
case ComparisonTypeSTS::AbsoluteGE:
|
||||
return v.ir.FPVectorGreaterEqual(esize,
|
||||
v.ir.FPVectorAbs(esize, operand1),
|
||||
v.ir.FPVectorAbs(esize, operand2));
|
||||
case ComparisonType::GT:
|
||||
case ComparisonTypeSTS::GT:
|
||||
return v.ir.FPVectorGreater(esize, operand1, operand2);
|
||||
case ComparisonType::AbsoluteGT:
|
||||
case ComparisonTypeSTS::AbsoluteGT:
|
||||
return v.ir.FPVectorGreater(esize,
|
||||
v.ir.FPVectorAbs(esize, operand1),
|
||||
v.ir.FPVectorAbs(esize, operand2));
|
||||
|
@ -165,12 +165,12 @@ bool FPCompareRegister(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Ve
|
|||
return true;
|
||||
}
|
||||
|
||||
enum class MinMaxOperation {
|
||||
enum class MinMaxOperationSTS {
|
||||
Min,
|
||||
Max,
|
||||
};
|
||||
|
||||
bool VectorMinMaxOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, MinMaxOperation operation, Signedness sign) {
|
||||
bool VectorMinMaxOperationSTS(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, MinMaxOperationSTS operation, SignednessSTS sign) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -182,14 +182,14 @@ bool VectorMinMaxOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Ve
|
|||
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||
const IR::U128 result = [&] {
|
||||
switch (operation) {
|
||||
case MinMaxOperation::Max:
|
||||
if (sign == Signedness::Signed) {
|
||||
case MinMaxOperationSTS::Max:
|
||||
if (sign == SignednessSTS::Signed) {
|
||||
return v.ir.VectorMaxSigned(esize, operand1, operand2);
|
||||
}
|
||||
return v.ir.VectorMaxUnsigned(esize, operand1, operand2);
|
||||
|
||||
case MinMaxOperation::Min:
|
||||
if (sign == Signedness::Signed) {
|
||||
case MinMaxOperationSTS::Min:
|
||||
if (sign == SignednessSTS::Signed) {
|
||||
return v.ir.VectorMinSigned(esize, operand1, operand2);
|
||||
}
|
||||
return v.ir.VectorMinUnsigned(esize, operand1, operand2);
|
||||
|
@ -203,7 +203,7 @@ bool VectorMinMaxOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Ve
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FPMinMaxOperation(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd, MinMaxOperation operation) {
|
||||
bool FPMinMaxOperationSTS(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd, MinMaxOperationSTS operation) {
|
||||
if (sz && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ bool FPMinMaxOperation(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Ve
|
|||
const IR::U128 operand1 = v.V(datasize, Vn);
|
||||
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||
const IR::U128 result = [&] {
|
||||
if (operation == MinMaxOperation::Min) {
|
||||
if (operation == MinMaxOperationSTS::Min) {
|
||||
return v.ir.FPVectorMin(esize, operand1, operand2);
|
||||
}
|
||||
|
||||
|
@ -225,7 +225,7 @@ bool FPMinMaxOperation(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Ve
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FPMinMaxNumericOperation(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd, MinMaxOperation operation) {
|
||||
bool FPMinMaxNumericOperation(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd, MinMaxOperationSTS operation) {
|
||||
if (sz && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ bool FPMinMaxNumericOperation(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec
|
|||
const IR::U128 operand1 = v.V(datasize, Vn);
|
||||
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||
const IR::U128 result = [&] {
|
||||
if (operation == MinMaxOperation::Min) {
|
||||
if (operation == MinMaxOperationSTS::Min) {
|
||||
return v.ir.FPVectorMinNumeric(esize, operand1, operand2);
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ bool FPMinMaxNumericOperation(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec
|
|||
return true;
|
||||
}
|
||||
|
||||
bool PairedMinMaxOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, MinMaxOperation operation, Signedness sign) {
|
||||
bool PairedMinMaxOperationSTS(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, MinMaxOperationSTS operation, SignednessSTS sign) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -259,14 +259,14 @@ bool PairedMinMaxOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Ve
|
|||
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||
IR::U128 result = [&] {
|
||||
switch (operation) {
|
||||
case MinMaxOperation::Max:
|
||||
if (sign == Signedness::Signed) {
|
||||
case MinMaxOperationSTS::Max:
|
||||
if (sign == SignednessSTS::Signed) {
|
||||
return Q ? v.ir.VectorPairedMaxSigned(esize, operand1, operand2) : v.ir.VectorPairedMaxSignedLower(esize, operand1, operand2);
|
||||
}
|
||||
return Q ? v.ir.VectorPairedMaxUnsigned(esize, operand1, operand2) : v.ir.VectorPairedMaxUnsignedLower(esize, operand1, operand2);
|
||||
|
||||
case MinMaxOperation::Min:
|
||||
if (sign == Signedness::Signed) {
|
||||
case MinMaxOperationSTS::Min:
|
||||
if (sign == SignednessSTS::Signed) {
|
||||
return Q ? v.ir.VectorPairedMinSigned(esize, operand1, operand2) : v.ir.VectorPairedMinSignedLower(esize, operand1, operand2);
|
||||
}
|
||||
return Q ? v.ir.VectorPairedMinUnsigned(esize, operand1, operand2) : v.ir.VectorPairedMinUnsignedLower(esize, operand1, operand2);
|
||||
|
@ -311,7 +311,7 @@ bool FPPairedMinMax(TranslatorVisitor& v, bool Q, bool sz, Vec Vm, Vec Vn, Vec V
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SaturatingArithmeticOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Operation op, Signedness sign) {
|
||||
bool SaturatingArithmeticOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Operation op, SignednessSTS sign) {
|
||||
if (size == 0b11 && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -323,7 +323,7 @@ bool SaturatingArithmeticOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Ve
|
|||
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||
|
||||
const IR::U128 result = [&] {
|
||||
if (sign == Signedness::Signed) {
|
||||
if (sign == SignednessSTS::Signed) {
|
||||
if (op == Operation::Add) {
|
||||
return v.ir.VectorSignedSaturatedAdd(esize, operand1, operand2);
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ bool SaturatingArithmeticOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Ve
|
|||
return true;
|
||||
}
|
||||
|
||||
bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, Signedness sign) {
|
||||
bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, SignednessSTS sign) {
|
||||
if (size == 0b11 && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ bool SaturatingShiftLeft(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec
|
|||
const IR::U128 operand1 = v.V(datasize, Vn);
|
||||
const IR::U128 operand2 = v.V(datasize, Vm);
|
||||
const IR::U128 result = [&] {
|
||||
if (sign == Signedness::Signed) {
|
||||
if (sign == SignednessSTS::Signed) {
|
||||
return v.ir.VectorSignedSaturatedShiftLeft(esize, operand1, operand2);
|
||||
}
|
||||
|
||||
|
@ -401,27 +401,27 @@ bool TranslatorVisitor::CMGE_reg_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd)
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SABA(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return SignedAbsoluteDifference(*this, Q, size, Vm, Vn, Vd, AbsDiffExtraBehavior::Accumulate);
|
||||
return SignedAbsoluteDifference(*this, Q, size, Vm, Vn, Vd, AbsDiffExtraBehaviorSTS::Accumulate);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SABD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return SignedAbsoluteDifference(*this, Q, size, Vm, Vn, Vd, AbsDiffExtraBehavior::None);
|
||||
return SignedAbsoluteDifference(*this, Q, size, Vm, Vn, Vd, AbsDiffExtraBehaviorSTS::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMAX(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return VectorMinMaxOperation(*this, Q, size, Vm, Vn, Vd, MinMaxOperation::Max, Signedness::Signed);
|
||||
return VectorMinMaxOperationSTS(*this, Q, size, Vm, Vn, Vd, MinMaxOperationSTS::Max, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMAXP(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return PairedMinMaxOperation(*this, Q, size, Vm, Vn, Vd, MinMaxOperation::Max, Signedness::Signed);
|
||||
return PairedMinMaxOperationSTS(*this, Q, size, Vm, Vn, Vd, MinMaxOperationSTS::Max, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMIN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return VectorMinMaxOperation(*this, Q, size, Vm, Vn, Vd, MinMaxOperation::Min, Signedness::Signed);
|
||||
return VectorMinMaxOperationSTS(*this, Q, size, Vm, Vn, Vd, MinMaxOperationSTS::Min, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMINP(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return PairedMinMaxOperation(*this, Q, size, Vm, Vn, Vd, MinMaxOperation::Min, Signedness::Signed);
|
||||
return PairedMinMaxOperationSTS(*this, Q, size, Vm, Vn, Vd, MinMaxOperationSTS::Min, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQDMULH_vec_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -506,19 +506,19 @@ bool TranslatorVisitor::MUL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::ADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, Operation::Add, ExtraBehavior::None);
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, Operation::Add, ExtraBehaviorSTS::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::RADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, Operation::Add, ExtraBehavior::Round);
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, Operation::Add, ExtraBehaviorSTS::Round);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, Operation::Subtract, ExtraBehavior::None);
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, Operation::Subtract, ExtraBehaviorSTS::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::RSUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, Operation::Subtract, ExtraBehavior::Round);
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, Operation::Subtract, ExtraBehaviorSTS::Round);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -554,15 +554,15 @@ bool TranslatorVisitor::SHSUB(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SQADD_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return SaturatingArithmeticOperation(*this, Q, size, Vm, Vn, Vd, Operation::Add, Signedness::Signed);
|
||||
return SaturatingArithmeticOperation(*this, Q, size, Vm, Vn, Vd, Operation::Add, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQSUB_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return SaturatingArithmeticOperation(*this, Q, size, Vm, Vn, Vd, Operation::Subtract, Signedness::Signed);
|
||||
return SaturatingArithmeticOperation(*this, Q, size, Vm, Vn, Vd, Operation::Subtract, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return RoundingHalvingAdd(*this, Q, size, Vm, Vn, Vd, Signedness::Signed);
|
||||
return RoundingHalvingAdd(*this, Q, size, Vm, Vn, Vd, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -598,15 +598,15 @@ bool TranslatorVisitor::UHSUB(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::UQADD_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return SaturatingArithmeticOperation(*this, Q, size, Vm, Vn, Vd, Operation::Add, Signedness::Unsigned);
|
||||
return SaturatingArithmeticOperation(*this, Q, size, Vm, Vn, Vd, Operation::Add, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UQSUB_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return SaturatingArithmeticOperation(*this, Q, size, Vm, Vn, Vd, Operation::Subtract, Signedness::Unsigned);
|
||||
return SaturatingArithmeticOperation(*this, Q, size, Vm, Vn, Vd, Operation::Subtract, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return RoundingHalvingAdd(*this, Q, size, Vm, Vn, Vd, Signedness::Unsigned);
|
||||
return RoundingHalvingAdd(*this, Q, size, Vm, Vn, Vd, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::ADDP_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -642,11 +642,11 @@ bool TranslatorVisitor::FABD_4(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FACGE_4(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonType::AbsoluteGE);
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonTypeSTS::AbsoluteGE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FACGT_4(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonType::AbsoluteGT);
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonTypeSTS::AbsoluteGT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FADD_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -737,15 +737,15 @@ bool TranslatorVisitor::FCMEQ_reg_3(bool Q, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FCMEQ_reg_4(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonType::EQ);
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonTypeSTS::EQ);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMGE_reg_4(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonType::GE);
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonTypeSTS::GE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMGT_reg_4(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonType::GT);
|
||||
return FPCompareRegister(*this, Q, sz, Vm, Vn, Vd, ComparisonTypeSTS::GT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::AND_asimd(bool Q, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -827,11 +827,11 @@ bool TranslatorVisitor::CMTST_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SQSHL_reg_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return SaturatingShiftLeft(*this, Q, size, Vm, Vn, Vd, Signedness::Signed);
|
||||
return SaturatingShiftLeft(*this, Q, size, Vm, Vn, Vd, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return RoundingShiftLeft(*this, Q, size, Vm, Vn, Vd, Signedness::Signed);
|
||||
return RoundingShiftLeft(*this, Q, size, Vm, Vn, Vd, SignednessSTS::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -851,11 +851,11 @@ bool TranslatorVisitor::SSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::UQSHL_reg_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return SaturatingShiftLeft(*this, Q, size, Vm, Vn, Vd, Signedness::Unsigned);
|
||||
return SaturatingShiftLeft(*this, Q, size, Vm, Vn, Vd, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return RoundingShiftLeft(*this, Q, size, Vm, Vn, Vd, Signedness::Unsigned);
|
||||
return RoundingShiftLeft(*this, Q, size, Vm, Vn, Vd, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -875,11 +875,11 @@ bool TranslatorVisitor::USHL_2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::UMAX(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return VectorMinMaxOperation(*this, Q, size, Vm, Vn, Vd, MinMaxOperation::Max, Signedness::Unsigned);
|
||||
return VectorMinMaxOperationSTS(*this, Q, size, Vm, Vn, Vd, MinMaxOperationSTS::Max, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UMAXP(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return PairedMinMaxOperation(*this, Q, size, Vm, Vn, Vd, MinMaxOperation::Max, Signedness::Unsigned);
|
||||
return PairedMinMaxOperationSTS(*this, Q, size, Vm, Vn, Vd, MinMaxOperationSTS::Max, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UABA(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -918,11 +918,11 @@ bool TranslatorVisitor::UABD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::UMIN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return VectorMinMaxOperation(*this, Q, size, Vm, Vn, Vd, MinMaxOperation::Min, Signedness::Unsigned);
|
||||
return VectorMinMaxOperationSTS(*this, Q, size, Vm, Vn, Vd, MinMaxOperationSTS::Min, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UMINP(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return PairedMinMaxOperation(*this, Q, size, Vm, Vn, Vd, MinMaxOperation::Min, Signedness::Unsigned);
|
||||
return PairedMinMaxOperationSTS(*this, Q, size, Vm, Vn, Vd, MinMaxOperationSTS::Min, SignednessSTS::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FSUB_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -1104,11 +1104,11 @@ bool TranslatorVisitor::EOR_asimd(bool Q, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FMAX_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPMinMaxOperation(*this, Q, sz, Vm, Vn, Vd, MinMaxOperation::Max);
|
||||
return FPMinMaxOperationSTS(*this, Q, sz, Vm, Vn, Vd, MinMaxOperationSTS::Max);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMAXNM_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPMinMaxNumericOperation(*this, Q, sz, Vm, Vn, Vd, MinMaxOperation::Max);
|
||||
return FPMinMaxNumericOperation(*this, Q, sz, Vm, Vn, Vd, MinMaxOperationSTS::Max);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMAXNMP_vec_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
@ -1120,11 +1120,11 @@ bool TranslatorVisitor::FMAXP_vec_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FMIN_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPMinMaxOperation(*this, Q, sz, Vm, Vn, Vd, MinMaxOperation::Min);
|
||||
return FPMinMaxOperationSTS(*this, Q, sz, Vm, Vn, Vd, MinMaxOperationSTS::Min);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMINNM_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
return FPMinMaxNumericOperation(*this, Q, sz, Vm, Vn, Vd, MinMaxOperation::Min);
|
||||
return FPMinMaxNumericOperation(*this, Q, sz, Vm, Vn, Vd, MinMaxOperationSTS::Min);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMINNMP_vec_2(bool Q, bool sz, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
namespace Dynarmic::A64 {
|
||||
namespace {
|
||||
enum class ComparisonType {
|
||||
enum class ComparisonTypeSTRM {
|
||||
EQ,
|
||||
GE,
|
||||
GT,
|
||||
|
@ -16,7 +16,7 @@ enum class ComparisonType {
|
|||
LT,
|
||||
};
|
||||
|
||||
bool CompareAgainstZero(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, ComparisonType type) {
|
||||
bool CompareAgainstZero(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, ComparisonTypeSTRM type) {
|
||||
if (size == 0b11 && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -28,15 +28,15 @@ bool CompareAgainstZero(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec V
|
|||
const IR::U128 zero = v.ir.ZeroVector();
|
||||
IR::U128 result = [&] {
|
||||
switch (type) {
|
||||
case ComparisonType::EQ:
|
||||
case ComparisonTypeSTRM::EQ:
|
||||
return v.ir.VectorEqual(esize, operand, zero);
|
||||
case ComparisonType::GE:
|
||||
case ComparisonTypeSTRM::GE:
|
||||
return v.ir.VectorGreaterEqualSigned(esize, operand, zero);
|
||||
case ComparisonType::GT:
|
||||
case ComparisonTypeSTRM::GT:
|
||||
return v.ir.VectorGreaterSigned(esize, operand, zero);
|
||||
case ComparisonType::LE:
|
||||
case ComparisonTypeSTRM::LE:
|
||||
return v.ir.VectorLessEqualSigned(esize, operand, zero);
|
||||
case ComparisonType::LT:
|
||||
case ComparisonTypeSTRM::LT:
|
||||
default:
|
||||
return v.ir.VectorLessSigned(esize, operand, zero);
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ bool CompareAgainstZero(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec V
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FPCompareAgainstZero(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, ComparisonType type) {
|
||||
bool FPCompareAgainstZero(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, ComparisonTypeSTRM type) {
|
||||
if (sz && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -62,15 +62,15 @@ bool FPCompareAgainstZero(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd,
|
|||
const IR::U128 zero = v.ir.ZeroVector();
|
||||
const IR::U128 result = [&] {
|
||||
switch (type) {
|
||||
case ComparisonType::EQ:
|
||||
case ComparisonTypeSTRM::EQ:
|
||||
return v.ir.FPVectorEqual(esize, operand, zero);
|
||||
case ComparisonType::GE:
|
||||
case ComparisonTypeSTRM::GE:
|
||||
return v.ir.FPVectorGreaterEqual(esize, operand, zero);
|
||||
case ComparisonType::GT:
|
||||
case ComparisonTypeSTRM::GT:
|
||||
return v.ir.FPVectorGreater(esize, operand, zero);
|
||||
case ComparisonType::LE:
|
||||
case ComparisonTypeSTRM::LE:
|
||||
return v.ir.FPVectorGreaterEqual(esize, zero, operand);
|
||||
case ComparisonType::LT:
|
||||
case ComparisonTypeSTRM::LT:
|
||||
return v.ir.FPVectorGreater(esize, zero, operand);
|
||||
}
|
||||
|
||||
|
@ -81,12 +81,12 @@ bool FPCompareAgainstZero(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd,
|
|||
return true;
|
||||
}
|
||||
|
||||
enum class Signedness {
|
||||
enum class SignednessSTRM {
|
||||
Signed,
|
||||
Unsigned
|
||||
};
|
||||
|
||||
bool IntegerConvertToFloat(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, Signedness signedness) {
|
||||
bool IntegerConvertToFloat(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, SignednessSTRM SignednessSTRM) {
|
||||
if (sz && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -96,7 +96,7 @@ bool IntegerConvertToFloat(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd
|
|||
const FP::RoundingMode rounding_mode = v.ir.current_location->FPCR().RMode();
|
||||
|
||||
const IR::U128 operand = v.V(datasize, Vn);
|
||||
const IR::U128 result = signedness == Signedness::Signed
|
||||
const IR::U128 result = SignednessSTRM == SignednessSTRM::Signed
|
||||
? v.ir.FPVectorFromSignedFixed(esize, operand, 0, rounding_mode)
|
||||
: v.ir.FPVectorFromUnsignedFixed(esize, operand, 0, rounding_mode);
|
||||
|
||||
|
@ -104,7 +104,7 @@ bool IntegerConvertToFloat(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FloatConvertToInteger(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, Signedness signedness, FP::RoundingMode rounding_mode) {
|
||||
bool FloatConvertToInteger(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, SignednessSTRM SignednessSTRM, FP::RoundingMode rounding_mode) {
|
||||
if (sz && !Q) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ bool FloatConvertToInteger(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd
|
|||
const size_t esize = sz ? 64 : 32;
|
||||
|
||||
const IR::U128 operand = v.V(datasize, Vn);
|
||||
const IR::U128 result = signedness == Signedness::Signed
|
||||
const IR::U128 result = SignednessSTRM == SignednessSTRM::Signed
|
||||
? v.ir.FPVectorToSignedFixed(esize, operand, 0, rounding_mode)
|
||||
: v.ir.FPVectorToUnsignedFixed(esize, operand, 0, rounding_mode);
|
||||
|
||||
|
@ -168,7 +168,7 @@ enum class PairedAddLongExtraBehavior {
|
|||
Accumulate,
|
||||
};
|
||||
|
||||
bool PairedAddLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, Signedness sign, PairedAddLongExtraBehavior behavior) {
|
||||
bool PairedAddLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, SignednessSTRM sign, PairedAddLongExtraBehavior behavior) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ bool PairedAddLong(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, Si
|
|||
|
||||
const IR::U128 operand = v.V(datasize, Vn);
|
||||
IR::U128 result = [&] {
|
||||
if (sign == Signedness::Signed) {
|
||||
if (sign == SignednessSTRM::Signed) {
|
||||
return v.ir.VectorPairedAddSignedWiden(esize, operand);
|
||||
}
|
||||
|
||||
|
@ -254,23 +254,23 @@ bool TranslatorVisitor::CNT(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::CMGE_zero_2(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonType::GE);
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonTypeSTRM::GE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::CMGT_zero_2(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonType::GT);
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonTypeSTRM::GT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::CMEQ_zero_2(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonType::EQ);
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonTypeSTRM::EQ);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::CMLE_2(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonType::LE);
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonTypeSTRM::LE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::CMLT_2(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonType::LT);
|
||||
return CompareAgainstZero(*this, Q, size, Vn, Vd, ComparisonTypeSTRM::LT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::ABS_2(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
|
@ -341,23 +341,23 @@ bool TranslatorVisitor::FCMEQ_zero_3(bool Q, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FCMEQ_zero_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::EQ);
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonTypeSTRM::EQ);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMGE_zero_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::GE);
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonTypeSTRM::GE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMGT_zero_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::GT);
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonTypeSTRM::GT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMLE_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::LE);
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonTypeSTRM::LE);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMLT_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::LT);
|
||||
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonTypeSTRM::LT);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTL(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
|
@ -411,19 +411,19 @@ bool TranslatorVisitor::FCVTN(bool Q, bool sz, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTNS_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::ToNearest_TieEven);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Signed, FP::RoundingMode::ToNearest_TieEven);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTMS_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsMinusInfinity);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Signed, FP::RoundingMode::TowardsMinusInfinity);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTAS_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::ToNearest_TieAwayFromZero);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Signed, FP::RoundingMode::ToNearest_TieAwayFromZero);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTPS_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsPlusInfinity);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Signed, FP::RoundingMode::TowardsPlusInfinity);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTXN_2(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
|
@ -447,27 +447,27 @@ bool TranslatorVisitor::FCVTXN_2(bool Q, bool sz, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTZS_int_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsZero);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Signed, FP::RoundingMode::TowardsZero);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTNU_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::ToNearest_TieEven);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Unsigned, FP::RoundingMode::ToNearest_TieEven);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTMU_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsMinusInfinity);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Unsigned, FP::RoundingMode::TowardsMinusInfinity);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTAU_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::ToNearest_TieAwayFromZero);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Unsigned, FP::RoundingMode::ToNearest_TieAwayFromZero);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTPU_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsPlusInfinity);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Unsigned, FP::RoundingMode::TowardsPlusInfinity);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCVTZU_int_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsZero);
|
||||
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, SignednessSTRM::Unsigned, FP::RoundingMode::TowardsZero);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FRINTN_1(bool Q, Vec Vn, Vec Vd) {
|
||||
|
@ -780,19 +780,19 @@ bool TranslatorVisitor::USQADD_2(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SADALP(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return PairedAddLong(*this, Q, size, Vn, Vd, Signedness::Signed, PairedAddLongExtraBehavior::Accumulate);
|
||||
return PairedAddLong(*this, Q, size, Vn, Vd, SignednessSTRM::Signed, PairedAddLongExtraBehavior::Accumulate);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SADDLP(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return PairedAddLong(*this, Q, size, Vn, Vd, Signedness::Signed, PairedAddLongExtraBehavior::None);
|
||||
return PairedAddLong(*this, Q, size, Vn, Vd, SignednessSTRM::Signed, PairedAddLongExtraBehavior::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UADALP(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return PairedAddLong(*this, Q, size, Vn, Vd, Signedness::Unsigned, PairedAddLongExtraBehavior::Accumulate);
|
||||
return PairedAddLong(*this, Q, size, Vn, Vd, SignednessSTRM::Unsigned, PairedAddLongExtraBehavior::Accumulate);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UADDLP(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
return PairedAddLong(*this, Q, size, Vn, Vd, Signedness::Unsigned, PairedAddLongExtraBehavior::None);
|
||||
return PairedAddLong(*this, Q, size, Vn, Vd, SignednessSTRM::Unsigned, PairedAddLongExtraBehavior::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URECPE(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
|
@ -824,11 +824,11 @@ bool TranslatorVisitor::URSQRTE(bool Q, bool sz, Vec Vn, Vec Vd) {
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::SCVTF_int_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return IntegerConvertToFloat(*this, Q, sz, Vn, Vd, Signedness::Signed);
|
||||
return IntegerConvertToFloat(*this, Q, sz, Vn, Vd, SignednessSTRM::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UCVTF_int_4(bool Q, bool sz, Vec Vn, Vec Vd) {
|
||||
return IntegerConvertToFloat(*this, Q, sz, Vn, Vd, Signedness::Unsigned);
|
||||
return IntegerConvertToFloat(*this, Q, sz, Vn, Vd, SignednessSTRM::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SHLL(bool Q, Imm<2> size, Vec Vn, Vec Vd) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
namespace Dynarmic::A64 {
|
||||
namespace {
|
||||
std::pair<size_t, Vec> Combine(Imm<2> size, Imm<1> H, Imm<1> L, Imm<1> M, Imm<4> Vmlo) {
|
||||
std::pair<size_t, Vec> CombineVector(Imm<2> size, Imm<1> H, Imm<1> L, Imm<1> M, Imm<4> Vmlo) {
|
||||
if (size == 0b01) {
|
||||
return {concatenate(H, L, M).ZeroExtend(), Vmlo.ZeroExtend<Vec>()};
|
||||
}
|
||||
|
@ -19,19 +19,19 @@ std::pair<size_t, Vec> Combine(Imm<2> size, Imm<1> H, Imm<1> L, Imm<1> M, Imm<4>
|
|||
return {concatenate(H, L).ZeroExtend(), concatenate(M, Vmlo).ZeroExtend<Vec>()};
|
||||
}
|
||||
|
||||
enum class ExtraBehavior {
|
||||
enum class ExtraBehaviorSVXIE {
|
||||
None,
|
||||
Extended,
|
||||
Accumulate,
|
||||
Subtract,
|
||||
};
|
||||
|
||||
bool MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior) {
|
||||
bool MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehaviorSVXIE extra_behavior) {
|
||||
if (size != 0b01 && size != 0b10) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const auto [index, Vm] = CombineVector(size, H, L, M, Vmlo);
|
||||
const size_t idxdsize = H == 1 ? 128 : 64;
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const size_t datasize = Q ? 128 : 64;
|
||||
|
@ -41,9 +41,9 @@ bool MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<
|
|||
const IR::U128 operand3 = v.V(datasize, Vd);
|
||||
|
||||
IR::U128 result = v.ir.VectorMultiply(esize, operand1, operand2);
|
||||
if (extra_behavior == ExtraBehavior::Accumulate) {
|
||||
if (extra_behavior == ExtraBehaviorSVXIE::Accumulate) {
|
||||
result = v.ir.VectorAdd(esize, operand3, result);
|
||||
} else if (extra_behavior == ExtraBehavior::Subtract) {
|
||||
} else if (extra_behavior == ExtraBehaviorSVXIE::Subtract) {
|
||||
result = v.ir.VectorSub(esize, operand3, result);
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ bool MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FPMultiplyByElement(TranslatorVisitor& v, bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior) {
|
||||
bool FPMultiplyByElement(TranslatorVisitor& v, bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehaviorSVXIE extra_behavior) {
|
||||
if (sz && L == 1) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -71,13 +71,13 @@ bool FPMultiplyByElement(TranslatorVisitor& v, bool Q, bool sz, Imm<1> L, Imm<1>
|
|||
|
||||
const IR::U128 result = [&] {
|
||||
switch (extra_behavior) {
|
||||
case ExtraBehavior::None:
|
||||
case ExtraBehaviorSVXIE::None:
|
||||
return v.ir.FPVectorMul(esize, operand1, operand2);
|
||||
case ExtraBehavior::Extended:
|
||||
case ExtraBehaviorSVXIE::Extended:
|
||||
return v.ir.FPVectorMulX(esize, operand1, operand2);
|
||||
case ExtraBehavior::Accumulate:
|
||||
case ExtraBehaviorSVXIE::Accumulate:
|
||||
return v.ir.FPVectorMulAdd(esize, operand3, operand1, operand2);
|
||||
case ExtraBehavior::Subtract:
|
||||
case ExtraBehaviorSVXIE::Subtract:
|
||||
return v.ir.FPVectorMulAdd(esize, operand3, v.ir.FPVectorNeg(esize, operand1), operand2);
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
@ -86,7 +86,7 @@ bool FPMultiplyByElement(TranslatorVisitor& v, bool Q, bool sz, Imm<1> L, Imm<1>
|
|||
return true;
|
||||
}
|
||||
|
||||
bool FPMultiplyByElementHalfPrecision(TranslatorVisitor& v, bool Q, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior) {
|
||||
bool FPMultiplyByElementHalfPrecision(TranslatorVisitor& v, bool Q, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehaviorSVXIE extra_behavior) {
|
||||
const size_t idxdsize = H == 1 ? 128 : 64;
|
||||
const size_t index = concatenate(H, L, M).ZeroExtend();
|
||||
const Vec Vm = Vmlo.ZeroExtend<Vec>();
|
||||
|
@ -101,13 +101,13 @@ bool FPMultiplyByElementHalfPrecision(TranslatorVisitor& v, bool Q, Imm<1> L, Im
|
|||
// regular multiplies and extended multiplies.
|
||||
const IR::U128 result = [&] {
|
||||
switch (extra_behavior) {
|
||||
case ExtraBehavior::None:
|
||||
case ExtraBehaviorSVXIE::None:
|
||||
break;
|
||||
case ExtraBehavior::Extended:
|
||||
case ExtraBehaviorSVXIE::Extended:
|
||||
break;
|
||||
case ExtraBehavior::Accumulate:
|
||||
case ExtraBehaviorSVXIE::Accumulate:
|
||||
return v.ir.FPVectorMulAdd(esize, operand3, operand1, operand2);
|
||||
case ExtraBehavior::Subtract:
|
||||
case ExtraBehaviorSVXIE::Subtract:
|
||||
return v.ir.FPVectorMulAdd(esize, operand3, v.ir.FPVectorNeg(esize, operand1), operand2);
|
||||
}
|
||||
UNREACHABLE();
|
||||
|
@ -151,12 +151,12 @@ bool DotProduct(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, I
|
|||
return true;
|
||||
}
|
||||
|
||||
enum class Signedness {
|
||||
enum class SignednessSVXIE {
|
||||
Signed,
|
||||
Unsigned
|
||||
};
|
||||
|
||||
bool MultiplyLong(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior, Signedness sign) {
|
||||
bool MultiplyLong(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehaviorSVXIE extra_behavior, SignednessSVXIE sign) {
|
||||
if (size == 0b00 || size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
@ -164,23 +164,23 @@ bool MultiplyLong(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M,
|
|||
const size_t idxsize = H == 1 ? 128 : 64;
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const size_t datasize = 64;
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const auto [index, Vm] = CombineVector(size, H, L, M, Vmlo);
|
||||
|
||||
const IR::U128 operand1 = v.Vpart(datasize, Vn, Q);
|
||||
const IR::U128 operand2 = v.V(idxsize, Vm);
|
||||
const IR::U128 index_vector = v.ir.VectorBroadcastElement(esize, operand2, index);
|
||||
|
||||
const IR::U128 result = [&] {
|
||||
const IR::U128 product = sign == Signedness::Signed
|
||||
const IR::U128 product = sign == SignednessSVXIE::Signed
|
||||
? v.ir.VectorMultiplySignedWiden(esize, operand1, index_vector)
|
||||
: v.ir.VectorMultiplyUnsignedWiden(esize, operand1, index_vector);
|
||||
|
||||
if (extra_behavior == ExtraBehavior::None) {
|
||||
if (extra_behavior == ExtraBehaviorSVXIE::None) {
|
||||
return product;
|
||||
}
|
||||
|
||||
const IR::U128 operand3 = v.V(2 * datasize, Vd);
|
||||
if (extra_behavior == ExtraBehavior::Accumulate) {
|
||||
if (extra_behavior == ExtraBehaviorSVXIE::Accumulate) {
|
||||
return v.ir.VectorAdd(2 * esize, operand3, product);
|
||||
}
|
||||
|
||||
|
@ -193,15 +193,15 @@ bool MultiplyLong(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M,
|
|||
} // Anonymous namespace
|
||||
|
||||
bool TranslatorVisitor::MLA_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate);
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Accumulate);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::MLS_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract);
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Subtract);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::MUL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None);
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FCMLA_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<2> rot, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
|
@ -292,39 +292,39 @@ bool TranslatorVisitor::FCMLA_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::FMLA_elt_3(bool Q, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return FPMultiplyByElementHalfPrecision(*this, Q, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate);
|
||||
return FPMultiplyByElementHalfPrecision(*this, Q, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Accumulate);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMLA_elt_4(bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return FPMultiplyByElement(*this, Q, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate);
|
||||
return FPMultiplyByElement(*this, Q, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Accumulate);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMLS_elt_3(bool Q, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return FPMultiplyByElementHalfPrecision(*this, Q, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract);
|
||||
return FPMultiplyByElementHalfPrecision(*this, Q, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Subtract);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMLS_elt_4(bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return FPMultiplyByElement(*this, Q, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract);
|
||||
return FPMultiplyByElement(*this, Q, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Subtract);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMUL_elt_4(bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return FPMultiplyByElement(*this, Q, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None);
|
||||
return FPMultiplyByElement(*this, Q, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::FMULX_elt_4(bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return FPMultiplyByElement(*this, Q, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Extended);
|
||||
return FPMultiplyByElement(*this, Q, sz, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Extended);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMLAL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate, Signedness::Signed);
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Accumulate, SignednessSVXIE::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMLSL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract, Signedness::Signed);
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Subtract, SignednessSVXIE::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SMULL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None, Signedness::Signed);
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::None, SignednessSVXIE::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SQDMULL_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
|
@ -336,7 +336,7 @@ bool TranslatorVisitor::SQDMULL_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, I
|
|||
const size_t idxsize = H == 1 ? 128 : 64;
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const size_t datasize = 64;
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const auto [index, Vm] = CombineVector(size, H, L, M, Vmlo);
|
||||
|
||||
const IR::U128 operand1 = Vpart(datasize, Vn, part);
|
||||
const IR::U128 operand2 = V(idxsize, Vm);
|
||||
|
@ -355,7 +355,7 @@ bool TranslatorVisitor::SQDMULH_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, I
|
|||
const size_t idxsize = H == 1 ? 128 : 64;
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const size_t datasize = Q ? 128 : 64;
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const auto [index, Vm] = CombineVector(size, H, L, M, Vmlo);
|
||||
|
||||
const IR::U128 operand1 = V(datasize, Vn);
|
||||
const IR::U128 operand2 = V(idxsize, Vm);
|
||||
|
@ -374,7 +374,7 @@ bool TranslatorVisitor::SQRDMULH_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M,
|
|||
const size_t idxsize = H == 1 ? 128 : 64;
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
const size_t datasize = Q ? 128 : 64;
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const auto [index, Vm] = CombineVector(size, H, L, M, Vmlo);
|
||||
|
||||
const IR::U128 operand1 = V(datasize, Vn);
|
||||
const IR::U128 operand2 = V(idxsize, Vm);
|
||||
|
@ -394,15 +394,15 @@ bool TranslatorVisitor::UDOT_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4>
|
|||
}
|
||||
|
||||
bool TranslatorVisitor::UMLAL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Accumulate, SignednessSVXIE::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UMLSL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract, Signedness::Unsigned);
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::Subtract, SignednessSVXIE::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UMULL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None, Signedness::Unsigned);
|
||||
return MultiplyLong(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehaviorSVXIE::None, SignednessSVXIE::Unsigned);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Dynarmic {
|
||||
namespace A32 {
|
||||
|
||||
enum class ArchVersion {
|
||||
enum class ArchVersion : std::uint8_t {
|
||||
v3,
|
||||
v4,
|
||||
v4T,
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2016 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
@ -120,14 +123,32 @@ struct UserCallbacks : public TranslateCallbacks {
|
|||
};
|
||||
|
||||
struct UserConfig {
|
||||
bool HasOptimization(OptimizationFlag f) const {
|
||||
if (!unsafe_optimizations) {
|
||||
f &= all_safe_optimizations;
|
||||
}
|
||||
return (f & optimizations) != no_optimizations;
|
||||
}
|
||||
|
||||
UserCallbacks* callbacks;
|
||||
|
||||
size_t processor_id = 0;
|
||||
ExclusiveMonitor* global_monitor = nullptr;
|
||||
|
||||
/// Select the architecture version to use.
|
||||
/// There are minor behavioural differences between versions.
|
||||
ArchVersion arch_version = ArchVersion::v8;
|
||||
// Page Table
|
||||
// The page table is used for faster memory access. If an entry in the table is nullptr,
|
||||
// the JIT will fallback to calling the MemoryRead*/MemoryWrite* callbacks.
|
||||
static constexpr std::size_t PAGE_BITS = 12;
|
||||
static constexpr std::size_t NUM_PAGE_TABLE_ENTRIES = 1 << (32 - PAGE_BITS);
|
||||
std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>* page_table = nullptr;
|
||||
|
||||
/// Coprocessors
|
||||
std::array<std::shared_ptr<Coprocessor>, 16> coprocessors{};
|
||||
|
||||
/// Fastmem Pointer
|
||||
/// This should point to the beginning of a 4GB address space which is in arranged just like
|
||||
/// what you wish for emulated memory to be. If the host page faults on an address, the JIT
|
||||
/// will fallback to calling the MemoryRead*/MemoryWrite* callbacks.
|
||||
std::optional<uintptr_t> fastmem_pointer = std::nullopt;
|
||||
|
||||
/// This selects other optimizations than can't otherwise be disabled by setting other
|
||||
/// configuration options. This includes:
|
||||
|
@ -137,12 +158,29 @@ struct UserConfig {
|
|||
/// This is intended to be used for debugging.
|
||||
OptimizationFlag optimizations = all_safe_optimizations;
|
||||
|
||||
bool HasOptimization(OptimizationFlag f) const {
|
||||
if (!unsafe_optimizations) {
|
||||
f &= all_safe_optimizations;
|
||||
}
|
||||
return (f & optimizations) != no_optimizations;
|
||||
}
|
||||
/// Minimum size is about 8MiB. Maximum size is about 128MiB (arm64 host) or 2GiB (x64 host).
|
||||
/// Maximum size is limited by the maximum length of a x86_64 / arm64 jump.
|
||||
std::uint32_t code_cache_size = 128 * 1024 * 1024; // bytes
|
||||
|
||||
/// Masks out the first N bits in host pointers from the page table.
|
||||
/// The intention behind this is to allow users of Dynarmic to pack attributes in the
|
||||
/// same integer and update the pointer attribute pair atomically.
|
||||
/// If the configured value is 3, all pointers will be forcefully aligned to 8 bytes.
|
||||
std::int32_t page_table_pointer_mask_bits = 0;
|
||||
|
||||
/// Select the architecture version to use.
|
||||
/// There are minor behavioural differences between versions.
|
||||
ArchVersion arch_version = ArchVersion::v8;
|
||||
|
||||
/// Processor ID
|
||||
std::uint8_t processor_id = 0;
|
||||
|
||||
/// Determines if we should detect memory accesses via page_table that straddle are
|
||||
/// misaligned. Accesses that straddle page boundaries will fallback to the relevant
|
||||
/// memory callback.
|
||||
/// This value should be the required access sizes this applies to ORed together.
|
||||
/// To detect any access, use: 8 | 16 | 32 | 64.
|
||||
std::uint8_t detect_misaligned_access_via_page_table = 0;
|
||||
|
||||
/// This enables unsafe optimizations that reduce emulation accuracy in favour of speed.
|
||||
/// For safety, in order to enable unsafe optimizations you have to set BOTH this flag
|
||||
|
@ -150,12 +188,6 @@ struct UserConfig {
|
|||
/// The prefered and tested mode for this library is with unsafe optimizations disabled.
|
||||
bool unsafe_optimizations = false;
|
||||
|
||||
// Page Table
|
||||
// The page table is used for faster memory access. If an entry in the table is nullptr,
|
||||
// the JIT will fallback to calling the MemoryRead*/MemoryWrite* callbacks.
|
||||
static constexpr std::size_t PAGE_BITS = 12;
|
||||
static constexpr std::size_t NUM_PAGE_TABLE_ENTRIES = 1 << (32 - PAGE_BITS);
|
||||
std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>* page_table = nullptr;
|
||||
/// Determines if the pointer in the page_table shall be offseted locally or globally.
|
||||
/// 'false' will access page_table[addr >> bits][addr & mask]
|
||||
/// 'true' will access page_table[addr >> bits][addr]
|
||||
|
@ -163,26 +195,11 @@ struct UserConfig {
|
|||
/// So there might be wrongly faulted pages which maps to nullptr.
|
||||
/// This can be avoided by carefully allocating the memory region.
|
||||
bool absolute_offset_page_table = false;
|
||||
/// Masks out the first N bits in host pointers from the page table.
|
||||
/// The intention behind this is to allow users of Dynarmic to pack attributes in the
|
||||
/// same integer and update the pointer attribute pair atomically.
|
||||
/// If the configured value is 3, all pointers will be forcefully aligned to 8 bytes.
|
||||
int page_table_pointer_mask_bits = 0;
|
||||
/// Determines if we should detect memory accesses via page_table that straddle are
|
||||
/// misaligned. Accesses that straddle page boundaries will fallback to the relevant
|
||||
/// memory callback.
|
||||
/// This value should be the required access sizes this applies to ORed together.
|
||||
/// To detect any access, use: 8 | 16 | 32 | 64.
|
||||
std::uint8_t detect_misaligned_access_via_page_table = 0;
|
||||
|
||||
/// Determines if the above option only triggers when the misalignment straddles a
|
||||
/// page boundary.
|
||||
bool only_detect_misalignment_via_page_table_on_page_boundary = false;
|
||||
|
||||
// Fastmem Pointer
|
||||
// This should point to the beginning of a 4GB address space which is in arranged just like
|
||||
// what you wish for emulated memory to be. If the host page faults on an address, the JIT
|
||||
// will fallback to calling the MemoryRead*/MemoryWrite* callbacks.
|
||||
std::optional<uintptr_t> fastmem_pointer = std::nullopt;
|
||||
/// Determines if instructions that pagefault should cause recompilation of that block
|
||||
/// with fastmem disabled.
|
||||
/// Recompiled code will use the page_table if this is available, otherwise memory
|
||||
|
@ -198,9 +215,6 @@ struct UserConfig {
|
|||
/// callbacks.
|
||||
bool recompile_on_exclusive_fastmem_failure = true;
|
||||
|
||||
// Coprocessors
|
||||
std::array<std::shared_ptr<Coprocessor>, 16> coprocessors{};
|
||||
|
||||
/// When set to true, UserCallbacks::InstructionSynchronizationBarrierRaised will be
|
||||
/// called when an ISB instruction is executed.
|
||||
/// When set to false, ISB will be treated as a NOP instruction.
|
||||
|
@ -234,10 +248,6 @@ struct UserConfig {
|
|||
/// in unusual behavior.
|
||||
bool always_little_endian = false;
|
||||
|
||||
// Minimum size is about 8MiB. Maximum size is about 128MiB (arm64 host) or 2GiB (x64 host).
|
||||
// Maximum size is limited by the maximum length of a x86_64 / arm64 jump.
|
||||
size_t code_cache_size = 128 * 1024 * 1024; // bytes
|
||||
|
||||
/// Internal use only
|
||||
bool very_verbose_debugging_output = false;
|
||||
};
|
||||
|
|
|
@ -136,11 +136,30 @@ struct UserCallbacks {
|
|||
};
|
||||
|
||||
struct UserConfig {
|
||||
/// Fastmem Pointer
|
||||
/// This should point to the beginning of a 2^page_table_address_space_bits bytes
|
||||
/// address space which is in arranged just like what you wish for emulated memory to
|
||||
/// be. If the host page faults on an address, the JIT will fallback to calling the
|
||||
/// MemoryRead*/MemoryWrite* callbacks.
|
||||
std::optional<std::uintptr_t> fastmem_pointer = std::nullopt;
|
||||
|
||||
UserCallbacks* callbacks;
|
||||
|
||||
size_t processor_id = 0;
|
||||
ExclusiveMonitor* global_monitor = nullptr;
|
||||
|
||||
/// Pointer to where TPIDRRO_EL0 is stored. This pointer will be inserted into
|
||||
/// emitted code.
|
||||
const std::uint64_t* tpidrro_el0 = nullptr;
|
||||
|
||||
/// Pointer to where TPIDR_EL0 is stored. This pointer will be inserted into
|
||||
/// emitted code.
|
||||
std::uint64_t* tpidr_el0 = nullptr;
|
||||
|
||||
/// Pointer to the page table which we can use for direct page table access.
|
||||
/// If an entry in page_table is null, the relevant memory callback will be called.
|
||||
/// If page_table is nullptr, all memory accesses hit the memory callbacks.
|
||||
void** page_table = nullptr;
|
||||
|
||||
/// This selects other optimizations than can't otherwise be disabled by setting other
|
||||
/// configuration options. This includes:
|
||||
/// - IR optimizations
|
||||
|
@ -149,12 +168,50 @@ struct UserConfig {
|
|||
/// This is intended to be used for debugging.
|
||||
OptimizationFlag optimizations = all_safe_optimizations;
|
||||
|
||||
bool HasOptimization(OptimizationFlag f) const {
|
||||
if (!unsafe_optimizations) {
|
||||
f &= all_safe_optimizations;
|
||||
}
|
||||
return (f & optimizations) != no_optimizations;
|
||||
}
|
||||
/// Declares how many valid address bits are there in virtual addresses.
|
||||
/// Determines the size of page_table. Valid values are between 12 and 64 inclusive.
|
||||
/// This is only used if page_table is not nullptr.
|
||||
std::uint32_t page_table_address_space_bits = 36;
|
||||
|
||||
/// Masks out the first N bits in host pointers from the page table.
|
||||
/// The intention behind this is to allow users of Dynarmic to pack attributes in the
|
||||
/// same integer and update the pointer attribute pair atomically.
|
||||
/// If the configured value is 3, all pointers will be forcefully aligned to 8 bytes.
|
||||
std::int32_t page_table_pointer_mask_bits = 0;
|
||||
|
||||
/// Counter-timer frequency register. The value of the register is not interpreted by
|
||||
/// dynarmic.
|
||||
std::uint32_t cntfrq_el0 = 600000000;
|
||||
|
||||
/// CTR_EL0<27:24> is log2 of the cache writeback granule in words.
|
||||
/// CTR_EL0<23:20> is log2 of the exclusives reservation granule in words.
|
||||
/// CTR_EL0<19:16> is log2 of the smallest data/unified cacheline in words.
|
||||
/// CTR_EL0<15:14> is the level 1 instruction cache policy.
|
||||
/// CTR_EL0<3:0> is log2 of the smallest instruction cacheline in words.
|
||||
std::uint32_t ctr_el0 = 0x8444c004;
|
||||
|
||||
/// DCZID_EL0<3:0> is log2 of the block size in words
|
||||
/// DCZID_EL0<4> is 0 if the DC ZVA instruction is permitted.
|
||||
std::uint32_t dczid_el0 = 4;
|
||||
|
||||
/// Declares how many valid address bits are there in virtual addresses.
|
||||
/// Determines the size of fastmem arena. Valid values are between 12 and 64 inclusive.
|
||||
/// This is only used if fastmem_pointer is set.
|
||||
std::uint32_t fastmem_address_space_bits = 36;
|
||||
|
||||
// Minimum size is about 8MiB. Maximum size is about 128MiB (arm64 host) or 2GiB (x64 host).
|
||||
// Maximum size is limited by the maximum length of a x86_64 / arm64 jump.
|
||||
std::uint32_t code_cache_size = 128 * 1024 * 1024; // bytes
|
||||
|
||||
/// Determines if we should detect memory accesses via page_table that straddle are
|
||||
/// misaligned. Accesses that straddle page boundaries will fallback to the relevant
|
||||
/// memory callback.
|
||||
/// This value should be the required access sizes this applies to ORed together.
|
||||
/// To detect any access, use: 8 | 16 | 32 | 64 | 128.
|
||||
std::uint8_t detect_misaligned_access_via_page_table = 0;
|
||||
|
||||
/// Processor ID
|
||||
std::uint8_t processor_id = 0;
|
||||
|
||||
/// This enables unsafe optimizations that reduce emulation accuracy in favour of speed.
|
||||
/// For safety, in order to enable unsafe optimizations you have to set BOTH this flag
|
||||
|
@ -177,48 +234,13 @@ struct UserConfig {
|
|||
/// instruction is executed.
|
||||
bool hook_hint_instructions = false;
|
||||
|
||||
/// Counter-timer frequency register. The value of the register is not interpreted by
|
||||
/// dynarmic.
|
||||
std::uint32_t cntfrq_el0 = 600000000;
|
||||
|
||||
/// CTR_EL0<27:24> is log2 of the cache writeback granule in words.
|
||||
/// CTR_EL0<23:20> is log2 of the exclusives reservation granule in words.
|
||||
/// CTR_EL0<19:16> is log2 of the smallest data/unified cacheline in words.
|
||||
/// CTR_EL0<15:14> is the level 1 instruction cache policy.
|
||||
/// CTR_EL0<3:0> is log2 of the smallest instruction cacheline in words.
|
||||
std::uint32_t ctr_el0 = 0x8444c004;
|
||||
|
||||
/// DCZID_EL0<3:0> is log2 of the block size in words
|
||||
/// DCZID_EL0<4> is 0 if the DC ZVA instruction is permitted.
|
||||
std::uint32_t dczid_el0 = 4;
|
||||
|
||||
/// Pointer to where TPIDRRO_EL0 is stored. This pointer will be inserted into
|
||||
/// emitted code.
|
||||
const std::uint64_t* tpidrro_el0 = nullptr;
|
||||
|
||||
/// Pointer to where TPIDR_EL0 is stored. This pointer will be inserted into
|
||||
/// emitted code.
|
||||
std::uint64_t* tpidr_el0 = nullptr;
|
||||
|
||||
/// Pointer to the page table which we can use for direct page table access.
|
||||
/// If an entry in page_table is null, the relevant memory callback will be called.
|
||||
/// If page_table is nullptr, all memory accesses hit the memory callbacks.
|
||||
void** page_table = nullptr;
|
||||
/// Declares how many valid address bits are there in virtual addresses.
|
||||
/// Determines the size of page_table. Valid values are between 12 and 64 inclusive.
|
||||
/// This is only used if page_table is not nullptr.
|
||||
size_t page_table_address_space_bits = 36;
|
||||
/// Masks out the first N bits in host pointers from the page table.
|
||||
/// The intention behind this is to allow users of Dynarmic to pack attributes in the
|
||||
/// same integer and update the pointer attribute pair atomically.
|
||||
/// If the configured value is 3, all pointers will be forcefully aligned to 8 bytes.
|
||||
int page_table_pointer_mask_bits = 0;
|
||||
/// Determines what happens if the guest accesses an entry that is off the end of the
|
||||
/// page table. If true, Dynarmic will silently mirror page_table's address space. If
|
||||
/// false, accessing memory outside of page_table bounds will result in a call to the
|
||||
/// relevant memory callback.
|
||||
/// This is only used if page_table is not nullptr.
|
||||
bool silently_mirror_page_table = true;
|
||||
|
||||
/// Determines if the pointer in the page_table shall be offseted locally or globally.
|
||||
/// 'false' will access page_table[addr >> bits][addr & mask]
|
||||
/// 'true' will access page_table[addr >> bits][addr]
|
||||
|
@ -226,31 +248,17 @@ struct UserConfig {
|
|||
/// So there might be wrongly faulted pages which maps to nullptr.
|
||||
/// This can be avoided by carefully allocating the memory region.
|
||||
bool absolute_offset_page_table = false;
|
||||
/// Determines if we should detect memory accesses via page_table that straddle are
|
||||
/// misaligned. Accesses that straddle page boundaries will fallback to the relevant
|
||||
/// memory callback.
|
||||
/// This value should be the required access sizes this applies to ORed together.
|
||||
/// To detect any access, use: 8 | 16 | 32 | 64 | 128.
|
||||
std::uint8_t detect_misaligned_access_via_page_table = 0;
|
||||
|
||||
/// Determines if the above option only triggers when the misalignment straddles a
|
||||
/// page boundary.
|
||||
bool only_detect_misalignment_via_page_table_on_page_boundary = false;
|
||||
|
||||
/// Fastmem Pointer
|
||||
/// This should point to the beginning of a 2^page_table_address_space_bits bytes
|
||||
/// address space which is in arranged just like what you wish for emulated memory to
|
||||
/// be. If the host page faults on an address, the JIT will fallback to calling the
|
||||
/// MemoryRead*/MemoryWrite* callbacks.
|
||||
std::optional<uintptr_t> fastmem_pointer = std::nullopt;
|
||||
/// Determines if instructions that pagefault should cause recompilation of that block
|
||||
/// with fastmem disabled.
|
||||
/// Recompiled code will use the page_table if this is available, otherwise memory
|
||||
/// accesses will hit the memory callbacks.
|
||||
bool recompile_on_fastmem_failure = true;
|
||||
/// Declares how many valid address bits are there in virtual addresses.
|
||||
/// Determines the size of fastmem arena. Valid values are between 12 and 64 inclusive.
|
||||
/// This is only used if fastmem_pointer is set.
|
||||
size_t fastmem_address_space_bits = 36;
|
||||
|
||||
/// Determines what happens if the guest accesses an entry that is off the end of the
|
||||
/// fastmem arena. If true, Dynarmic will silently mirror fastmem's address space. If
|
||||
/// false, accessing memory outside of fastmem bounds will result in a call to the
|
||||
|
@ -285,12 +293,15 @@ struct UserConfig {
|
|||
/// AddTicks and GetTicksRemaining are never called, and no cycle counting is done.
|
||||
bool enable_cycle_counting = true;
|
||||
|
||||
// Minimum size is about 8MiB. Maximum size is about 128MiB (arm64 host) or 2GiB (x64 host).
|
||||
// Maximum size is limited by the maximum length of a x86_64 / arm64 jump.
|
||||
size_t code_cache_size = 128 * 1024 * 1024; // bytes
|
||||
|
||||
/// Internal use only
|
||||
bool very_verbose_debugging_output = false;
|
||||
|
||||
inline bool HasOptimization(OptimizationFlag f) const {
|
||||
if (!unsafe_optimizations) {
|
||||
f &= all_safe_optimizations;
|
||||
}
|
||||
return (f & optimizations) != no_optimizations;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace A64
|
||||
|
|
2872
externals/dynarmic/src/dynarmic/ir/ir_emitter.cpp
vendored
2872
externals/dynarmic/src/dynarmic/ir/ir_emitter.cpp
vendored
File diff suppressed because it is too large
Load diff
3176
externals/dynarmic/src/dynarmic/ir/ir_emitter.h
vendored
3176
externals/dynarmic/src/dynarmic/ir/ir_emitter.h
vendored
File diff suppressed because it is too large
Load diff
2
externals/sirit/CMakeLists.txt
vendored
2
externals/sirit/CMakeLists.txt
vendored
|
@ -1,6 +1,6 @@
|
|||
# This file has been adapted from dynarmic
|
||||
|
||||
cmake_minimum_required(VERSION 3.8)
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
project(sirit CXX)
|
||||
|
||||
# Determine if we're built as a subproject (using add_subdirectory)
|
||||
|
|
|
@ -58,7 +58,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
// TODO If this is ever modified, change application_id in strings.xml
|
||||
applicationId = "dev.eden.eden_emulator"
|
||||
applicationId = "dev.legacy.eden_emulator"
|
||||
minSdk = 30
|
||||
targetSdk = 35
|
||||
versionName = getGitVersion()
|
||||
|
@ -103,7 +103,7 @@ android {
|
|||
signingConfigs.getByName("default")
|
||||
}
|
||||
|
||||
resValue("string", "app_name_suffixed", "Eden")
|
||||
resValue("string", "app_name_suffixed", "Eden Legacy")
|
||||
isMinifyEnabled = true
|
||||
isDebuggable = false
|
||||
proguardFiles(
|
||||
|
|
|
@ -15,6 +15,7 @@ import android.view.Surface
|
|||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.Keep
|
||||
import androidx.core.net.toUri
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import net.swiftzer.semver.SemVer
|
||||
import java.lang.ref.WeakReference
|
||||
|
@ -27,6 +28,7 @@ import org.yuzu.yuzu_emu.model.InstallResult
|
|||
import org.yuzu.yuzu_emu.model.Patch
|
||||
import org.yuzu.yuzu_emu.model.GameVerificationResult
|
||||
import org.yuzu.yuzu_emu.network.NetPlayManager
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Class which contains methods that interact
|
||||
|
@ -102,6 +104,21 @@ object NativeLibrary {
|
|||
FileUtil.getFilename(Uri.parse(path))
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun copyFileToStorage(source: String, destdir: String): Boolean {
|
||||
return FileUtil.copyUriToInternalStorage(
|
||||
source.toUri(),
|
||||
destdir
|
||||
) != null
|
||||
}
|
||||
|
||||
@Keep
|
||||
@JvmStatic
|
||||
fun getFileExtension(source: String): String {
|
||||
return FileUtil.getExtension(source.toUri())
|
||||
}
|
||||
|
||||
external fun setAppDirectory(directory: String)
|
||||
|
||||
/**
|
||||
|
@ -415,18 +432,29 @@ object NativeLibrary {
|
|||
*/
|
||||
external fun firmwareVersion(): String
|
||||
|
||||
fun isFirmwareSupported(): Boolean {
|
||||
var version: SemVer
|
||||
/**
|
||||
* Verifies installed firmware.
|
||||
*
|
||||
* @return The result code.
|
||||
*/
|
||||
external fun verifyFirmware(): Int
|
||||
|
||||
try {
|
||||
version = SemVer.parse(firmwareVersion())
|
||||
} catch (_: Exception) {
|
||||
return false
|
||||
}
|
||||
val max = SemVer(19, 0, 1)
|
||||
/**
|
||||
* Check if a game requires firmware to be playable.
|
||||
*
|
||||
* @param programId The game's Program ID.
|
||||
* @return Whether or not the game requires firmware to be playable.
|
||||
*/
|
||||
external fun gameRequiresFirmware(programId: String): Boolean
|
||||
|
||||
return version <= max
|
||||
}
|
||||
/**
|
||||
* Installs keys from the specified path.
|
||||
*
|
||||
* @param path The path to install keys from.
|
||||
* @param ext What extension the keys should have.
|
||||
* @return The result code.
|
||||
*/
|
||||
external fun installKeys(path: String, ext: String): Int
|
||||
|
||||
/**
|
||||
* Checks the PatchManager for any addons that are available
|
||||
|
|
|
@ -3,11 +3,16 @@
|
|||
|
||||
package org.yuzu.yuzu_emu.adapters
|
||||
|
||||
import android.content.DialogInterface
|
||||
import android.net.Uri
|
||||
import android.text.Html
|
||||
import android.text.method.LinkMovementMethod
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.pm.ShortcutInfoCompat
|
||||
|
@ -33,6 +38,10 @@ import org.yuzu.yuzu_emu.utils.GameIconUtils
|
|||
import org.yuzu.yuzu_emu.utils.ViewUtils.marquee
|
||||
import org.yuzu.yuzu_emu.viewholder.AbstractViewHolder
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.content.edit
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
|
||||
class GameAdapter(private val activity: AppCompatActivity) :
|
||||
AbstractDiffAdapter<Game, GameAdapter.GameViewHolder>(exact = false) {
|
||||
|
@ -171,8 +180,9 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
|||
fun onClick(game: Game) {
|
||||
val gameExists = DocumentFile.fromSingleUri(
|
||||
YuzuApplication.appContext,
|
||||
Uri.parse(game.path)
|
||||
game.path.toUri()
|
||||
)?.exists() == true
|
||||
|
||||
if (!gameExists) {
|
||||
Toast.makeText(
|
||||
YuzuApplication.appContext,
|
||||
|
@ -184,29 +194,49 @@ class GameAdapter(private val activity: AppCompatActivity) :
|
|||
return
|
||||
}
|
||||
|
||||
val preferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
preferences.edit()
|
||||
.putLong(
|
||||
game.keyLastPlayedTime,
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
.apply()
|
||||
|
||||
activity.lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val shortcut =
|
||||
ShortcutInfoCompat.Builder(YuzuApplication.appContext, game.path)
|
||||
.setShortLabel(game.title)
|
||||
.setIcon(GameIconUtils.getShortcutIcon(activity, game))
|
||||
.setIntent(game.launchIntent)
|
||||
.build()
|
||||
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
|
||||
val launch: () -> Unit = {
|
||||
val preferences =
|
||||
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
|
||||
preferences.edit {
|
||||
putLong(
|
||||
game.keyLastPlayedTime,
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
}
|
||||
|
||||
activity.lifecycleScope.launch {
|
||||
withContext(Dispatchers.IO) {
|
||||
val shortcut =
|
||||
ShortcutInfoCompat.Builder(YuzuApplication.appContext, game.path)
|
||||
.setShortLabel(game.title)
|
||||
.setIcon(GameIconUtils.getShortcutIcon(activity, game))
|
||||
.setIntent(game.launchIntent)
|
||||
.build()
|
||||
ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
|
||||
}
|
||||
}
|
||||
|
||||
val action = HomeNavigationDirections.actionGlobalEmulationActivity(game, true)
|
||||
binding.root.findNavController().navigate(action)
|
||||
}
|
||||
|
||||
val action = HomeNavigationDirections.actionGlobalEmulationActivity(game, true)
|
||||
binding.root.findNavController().navigate(action)
|
||||
if (NativeLibrary.gameRequiresFirmware(game.programId) && !NativeLibrary.isFirmwareAvailable()) {
|
||||
MaterialAlertDialogBuilder(activity)
|
||||
.setTitle(R.string.loader_requires_firmware)
|
||||
.setMessage(
|
||||
Html.fromHtml(
|
||||
activity.getString(R.string.loader_requires_firmware_description),
|
||||
Html.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
)
|
||||
.setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int ->
|
||||
launch()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel) { _,_ -> }
|
||||
.show()
|
||||
} else {
|
||||
launch()
|
||||
}
|
||||
}
|
||||
|
||||
fun onLongClick(game: Game): Boolean {
|
||||
|
|
|
@ -264,8 +264,6 @@ class DriverFetcherFragment : Fragment() {
|
|||
}
|
||||
|
||||
releases.add(release)
|
||||
|
||||
println(release.publishTime)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ class HomeSettingsFragment : Fragment() {
|
|||
binding.root.findNavController()
|
||||
.navigate(R.id.action_homeSettingsFragment_to_appletLauncherFragment)
|
||||
},
|
||||
{ NativeLibrary.isFirmwareAvailable() && NativeLibrary.isFirmwareSupported() },
|
||||
{ NativeLibrary.isFirmwareAvailable() },
|
||||
R.string.applets_error_firmware,
|
||||
R.string.applets_error_description
|
||||
)
|
||||
|
|
|
@ -352,7 +352,7 @@ class SetupFragment : Fragment() {
|
|||
val getProdKey =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
mainActivity.processKey(result)
|
||||
mainActivity.processKey(result, "keys")
|
||||
if (NativeLibrary.areKeysPresent()) {
|
||||
keyCallback.onStepCompleted()
|
||||
}
|
||||
|
|
|
@ -47,9 +47,6 @@ import info.debatty.java.stringsimilarity.Jaccard
|
|||
import info.debatty.java.stringsimilarity.JaroWinkler
|
||||
import java.util.Locale
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||
import android.view.ViewParent
|
||||
import androidx.core.view.doOnNextLayout
|
||||
|
||||
class GamesFragment : Fragment() {
|
||||
|
@ -151,7 +148,7 @@ class GamesFragment : Fragment() {
|
|||
)
|
||||
}
|
||||
gamesViewModel.games.collect(viewLifecycleOwner) {
|
||||
if (it.size > 0) {
|
||||
if (it.isNotEmpty()) {
|
||||
setAdapter(it)
|
||||
}
|
||||
}
|
||||
|
@ -361,7 +358,7 @@ class GamesFragment : Fragment() {
|
|||
|
||||
popup.setOnMenuItemClickListener { item ->
|
||||
currentFilter = item.itemId
|
||||
preferences.edit().putInt(PREF_SORT_TYPE, currentFilter).apply()
|
||||
preferences.edit { putInt(PREF_SORT_TYPE, currentFilter) }
|
||||
filterAndSearch()
|
||||
true
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ package org.yuzu.yuzu_emu.ui.main
|
|||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.ParcelFileDescriptor
|
||||
import android.provider.OpenableColumns
|
||||
import android.view.View
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
import android.view.WindowManager
|
||||
|
@ -47,6 +49,7 @@ import java.io.BufferedOutputStream
|
|||
import java.util.zip.ZipEntry
|
||||
import java.util.zip.ZipInputStream
|
||||
import androidx.core.content.edit
|
||||
import androidx.core.net.toFile
|
||||
|
||||
class MainActivity : AppCompatActivity(), ThemeProvider {
|
||||
private lateinit var binding: ActivityMainBinding
|
||||
|
@ -70,10 +73,12 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
val granted = permissions.entries.all { it.value }
|
||||
if (granted) {
|
||||
// Permissions were granted.
|
||||
Toast.makeText(this, R.string.bluetooth_permissions_granted, Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(this, R.string.bluetooth_permissions_granted, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
} else {
|
||||
// Permissions were denied.
|
||||
Toast.makeText(this, R.string.bluetooth_permissions_denied, Toast.LENGTH_LONG).show()
|
||||
Toast.makeText(this, R.string.bluetooth_permissions_denied, Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,22 +151,16 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
binding.statusBarShade.setBackgroundColor(
|
||||
ThemeHelper.getColorWithOpacity(
|
||||
MaterialColors.getColor(
|
||||
binding.root,
|
||||
com.google.android.material.R.attr.colorSurface
|
||||
),
|
||||
ThemeHelper.SYSTEM_BAR_ALPHA
|
||||
binding.root, com.google.android.material.R.attr.colorSurface
|
||||
), ThemeHelper.SYSTEM_BAR_ALPHA
|
||||
)
|
||||
)
|
||||
if (InsetsHelper.getSystemGestureType(applicationContext) !=
|
||||
InsetsHelper.GESTURE_NAVIGATION
|
||||
) {
|
||||
if (InsetsHelper.getSystemGestureType(applicationContext) != InsetsHelper.GESTURE_NAVIGATION) {
|
||||
binding.navigationBarShade.setBackgroundColor(
|
||||
ThemeHelper.getColorWithOpacity(
|
||||
MaterialColors.getColor(
|
||||
binding.root,
|
||||
com.google.android.material.R.attr.colorSurface
|
||||
),
|
||||
ThemeHelper.SYSTEM_BAR_ALPHA
|
||||
binding.root, com.google.android.material.R.attr.colorSurface
|
||||
), ThemeHelper.SYSTEM_BAR_ALPHA
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -172,9 +171,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
|
||||
homeViewModel.statusBarShadeVisible.collect(this) { showStatusBarShade(it) }
|
||||
homeViewModel.contentToInstall.collect(
|
||||
this,
|
||||
resetState = { homeViewModel.setContentToInstall(null) }
|
||||
) {
|
||||
this, resetState = { homeViewModel.setContentToInstall(null) }) {
|
||||
if (it != null) {
|
||||
installContent(it)
|
||||
}
|
||||
|
@ -183,7 +180,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
if (it) checkKeys()
|
||||
}
|
||||
|
||||
homeViewModel.checkFirmware.collect(this, resetState = { homeViewModel.setCheckFirmware(false) }) {
|
||||
homeViewModel.checkFirmware.collect(
|
||||
this, resetState = { homeViewModel.setCheckFirmware(false) }) {
|
||||
if (it) checkFirmware()
|
||||
}
|
||||
|
||||
|
@ -203,12 +201,10 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
negativeButtonTitleId = R.string.close,
|
||||
showNegativeButton = true,
|
||||
positiveAction = {
|
||||
PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||
.edit() {
|
||||
putBoolean(Settings.PREF_SHOULD_SHOW_PRE_ALPHA_WARNING, false)
|
||||
}
|
||||
}
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
PreferenceManager.getDefaultSharedPreferences(applicationContext).edit() {
|
||||
putBoolean(Settings.PREF_SHOULD_SHOW_PRE_ALPHA_WARNING, false)
|
||||
}
|
||||
}).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -228,15 +224,18 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
private fun checkFirmware() {
|
||||
if (!NativeLibrary.isFirmwareAvailable() || !NativeLibrary.isFirmwareSupported()) {
|
||||
MessageDialogFragment.newInstance(
|
||||
titleId = R.string.firmware_missing,
|
||||
descriptionId = R.string.firmware_missing_description,
|
||||
helpLinkId = R.string.firmware_missing_help
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
}
|
||||
val resultCode: Int = NativeLibrary.verifyFirmware()
|
||||
if (resultCode == 0) return;
|
||||
|
||||
val resultString: String =
|
||||
resources.getStringArray(R.array.verifyFirmwareResults)[resultCode]
|
||||
|
||||
MessageDialogFragment.newInstance(
|
||||
titleId = R.string.firmware_invalid,
|
||||
descriptionString = resultString,
|
||||
helpLinkId = R.string.firmware_missing_help
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
|
@ -283,23 +282,22 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
super.onResume()
|
||||
}
|
||||
|
||||
private fun setInsets() =
|
||||
ViewCompat.setOnApplyWindowInsetsListener(
|
||||
binding.root
|
||||
) { _: View, windowInsets: WindowInsetsCompat ->
|
||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val mlpStatusShade = binding.statusBarShade.layoutParams as MarginLayoutParams
|
||||
mlpStatusShade.height = insets.top
|
||||
binding.statusBarShade.layoutParams = mlpStatusShade
|
||||
private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener(
|
||||
binding.root
|
||||
) { _: View, windowInsets: WindowInsetsCompat ->
|
||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||
val mlpStatusShade = binding.statusBarShade.layoutParams as MarginLayoutParams
|
||||
mlpStatusShade.height = insets.top
|
||||
binding.statusBarShade.layoutParams = mlpStatusShade
|
||||
|
||||
// The only situation where we care to have a nav bar shade is when it's at the bottom
|
||||
// of the screen where scrolling list elements can go behind it.
|
||||
val mlpNavShade = binding.navigationBarShade.layoutParams as MarginLayoutParams
|
||||
mlpNavShade.height = insets.bottom
|
||||
binding.navigationBarShade.layoutParams = mlpNavShade
|
||||
// The only situation where we care to have a nav bar shade is when it's at the bottom
|
||||
// of the screen where scrolling list elements can go behind it.
|
||||
val mlpNavShade = binding.navigationBarShade.layoutParams as MarginLayoutParams
|
||||
mlpNavShade.height = insets.bottom
|
||||
binding.navigationBarShade.layoutParams = mlpNavShade
|
||||
|
||||
windowInsets
|
||||
}
|
||||
windowInsets
|
||||
}
|
||||
|
||||
override fun setTheme(resId: Int) {
|
||||
super.setTheme(resId)
|
||||
|
@ -315,17 +313,14 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
|
||||
fun processGamesDir(result: Uri, calledFromGameFragment: Boolean = false) {
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
result, Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val uriString = result.toString()
|
||||
val folder = gamesViewModel.folders.value.firstOrNull { it.uriString == uriString }
|
||||
if (folder != null) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
R.string.folder_already_added,
|
||||
Toast.LENGTH_SHORT
|
||||
applicationContext, R.string.folder_already_added, Toast.LENGTH_SHORT
|
||||
).show()
|
||||
return
|
||||
}
|
||||
|
@ -334,72 +329,52 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
.show(supportFragmentManager, AddGameFolderDialogFragment.TAG)
|
||||
}
|
||||
|
||||
val getProdKey =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processKey(result)
|
||||
}
|
||||
val getProdKey = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processKey(result, "keys")
|
||||
}
|
||||
|
||||
fun processKey(result: Uri): Boolean {
|
||||
if (FileUtil.getExtension(result) != "keys") {
|
||||
MessageDialogFragment.newInstance(
|
||||
this,
|
||||
titleId = R.string.reading_keys_failure,
|
||||
descriptionId = R.string.install_prod_keys_failure_extension_description
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
return false
|
||||
}
|
||||
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val dstPath = DirectoryInitialization.userDirectory + "/keys/"
|
||||
if (FileUtil.copyUriToInternalStorage(
|
||||
result,
|
||||
dstPath,
|
||||
"prod.keys"
|
||||
) != null
|
||||
) {
|
||||
if (NativeLibrary.reloadKeys()) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
R.string.install_keys_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
homeViewModel.setCheckKeys(true)
|
||||
|
||||
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
|
||||
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
|
||||
if (!firstTimeSetup) {
|
||||
homeViewModel.setCheckFirmware(true)
|
||||
}
|
||||
|
||||
gamesViewModel.reloadGames(true)
|
||||
return true
|
||||
} else {
|
||||
MessageDialogFragment.newInstance(
|
||||
this,
|
||||
titleId = R.string.invalid_keys_error,
|
||||
descriptionId = R.string.install_keys_failure_description,
|
||||
helpLinkId = R.string.dumping_keys_quickstart_link
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
val getFirmware =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result == null) {
|
||||
return@registerForActivityResult
|
||||
}
|
||||
val getAmiiboKey = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processKey(result, "bin")
|
||||
}
|
||||
}
|
||||
|
||||
fun processKey(result: Uri, extension: String = "keys") {
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result, Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val resultCode: Int = NativeLibrary.installKeys(result.toString(), extension);
|
||||
|
||||
if (resultCode == 0) {
|
||||
// TODO(crueter): It may be worth it to switch some of these Toasts to snackbars,
|
||||
// since most of it is foreground-only anyways.
|
||||
Toast.makeText(
|
||||
applicationContext, R.string.keys_install_success, Toast.LENGTH_SHORT
|
||||
).show()
|
||||
|
||||
gamesViewModel.reloadGames(true)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
val resultString: String =
|
||||
resources.getStringArray(R.array.installKeysResults)[resultCode]
|
||||
|
||||
MessageDialogFragment.newInstance(
|
||||
titleId = R.string.keys_failed,
|
||||
descriptionString = resultString,
|
||||
helpLinkId = R.string.keys_missing_help
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
|
||||
val getFirmware = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result != null) {
|
||||
processFirmware(result)
|
||||
}
|
||||
}
|
||||
|
||||
fun processFirmware(result: Uri, onComplete: (() -> Unit)? = null) {
|
||||
val filterNCA = FilenameFilter { _, dirName -> dirName.endsWith(".nca") }
|
||||
|
@ -409,15 +384,12 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
val cacheFirmwareDir = File("${cacheDir.path}/registered/")
|
||||
|
||||
ProgressDialogFragment.newInstance(
|
||||
this,
|
||||
R.string.firmware_installing
|
||||
this, R.string.firmware_installing
|
||||
) { progressCallback, _ ->
|
||||
var messageToShow: Any
|
||||
try {
|
||||
FileUtil.unzipToInternalStorage(
|
||||
result.toString(),
|
||||
cacheFirmwareDir,
|
||||
progressCallback
|
||||
result.toString(), cacheFirmwareDir, progressCallback
|
||||
)
|
||||
val unfilteredNumOfFiles = cacheFirmwareDir.list()?.size ?: -1
|
||||
val filteredNumOfFiles = cacheFirmwareDir.list(filterNCA)?.size ?: -2
|
||||
|
@ -448,10 +420,10 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
fun uninstallFirmware() {
|
||||
val firmwarePath = File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/")
|
||||
val firmwarePath =
|
||||
File(DirectoryInitialization.userDirectory + "/nand/system/Contents/registered/")
|
||||
ProgressDialogFragment.newInstance(
|
||||
this,
|
||||
R.string.firmware_uninstalling
|
||||
this, R.string.firmware_uninstalling
|
||||
) { progressCallback, _ ->
|
||||
var messageToShow: Any
|
||||
try {
|
||||
|
@ -473,49 +445,6 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
messageToShow
|
||||
}.show(supportFragmentManager, ProgressDialogFragment.TAG)
|
||||
}
|
||||
val getAmiiboKey =
|
||||
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
|
||||
if (result == null) {
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
if (FileUtil.getExtension(result) != "bin") {
|
||||
MessageDialogFragment.newInstance(
|
||||
this,
|
||||
titleId = R.string.reading_keys_failure,
|
||||
descriptionId = R.string.install_amiibo_keys_failure_extension_description
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
return@registerForActivityResult
|
||||
}
|
||||
|
||||
contentResolver.takePersistableUriPermission(
|
||||
result,
|
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||
)
|
||||
|
||||
val dstPath = DirectoryInitialization.userDirectory + "/keys/"
|
||||
if (FileUtil.copyUriToInternalStorage(
|
||||
result,
|
||||
dstPath,
|
||||
"key_retail.bin"
|
||||
) != null
|
||||
) {
|
||||
if (NativeLibrary.reloadKeys()) {
|
||||
Toast.makeText(
|
||||
applicationContext,
|
||||
R.string.install_keys_success,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
} else {
|
||||
MessageDialogFragment.newInstance(
|
||||
this,
|
||||
titleId = R.string.invalid_keys_error,
|
||||
descriptionId = R.string.install_keys_failure_description,
|
||||
helpLinkId = R.string.dumping_keys_quickstart_link
|
||||
).show(supportFragmentManager, MessageDialogFragment.TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installGameUpdate = registerForActivityResult(
|
||||
ActivityResultContracts.OpenMultipleDocuments()
|
||||
|
@ -530,15 +459,12 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
ProgressDialogFragment.newInstance(
|
||||
this@MainActivity,
|
||||
R.string.verifying_content,
|
||||
false
|
||||
this@MainActivity, R.string.verifying_content, false
|
||||
) { _, _ ->
|
||||
var updatesMatchProgram = true
|
||||
for (document in documents) {
|
||||
val valid = NativeLibrary.doesUpdateMatchProgram(
|
||||
addonViewModel.game!!.programId,
|
||||
document.toString()
|
||||
addonViewModel.game!!.programId, document.toString()
|
||||
)
|
||||
if (!valid) {
|
||||
updatesMatchProgram = false
|
||||
|
@ -554,16 +480,14 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
titleId = R.string.content_install_notice,
|
||||
descriptionId = R.string.content_install_notice_description,
|
||||
positiveAction = { homeViewModel.setContentToInstall(documents) },
|
||||
negativeAction = {}
|
||||
)
|
||||
negativeAction = {})
|
||||
}
|
||||
}.show(supportFragmentManager, ProgressDialogFragment.TAG)
|
||||
}
|
||||
|
||||
private fun installContent(documents: List<Uri>) {
|
||||
ProgressDialogFragment.newInstance(
|
||||
this@MainActivity,
|
||||
R.string.installing_game_content
|
||||
this@MainActivity, R.string.installing_game_content
|
||||
) { progressCallback, messageCallback ->
|
||||
var installSuccess = 0
|
||||
var installOverwrite = 0
|
||||
|
@ -571,14 +495,11 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
var error = 0
|
||||
documents.forEach {
|
||||
messageCallback.invoke(FileUtil.getFilename(it))
|
||||
when (
|
||||
InstallResult.from(
|
||||
NativeLibrary.installFileToNand(
|
||||
it.toString(),
|
||||
progressCallback
|
||||
)
|
||||
when (InstallResult.from(
|
||||
NativeLibrary.installFileToNand(
|
||||
it.toString(), progressCallback
|
||||
)
|
||||
) {
|
||||
)) {
|
||||
InstallResult.Success -> {
|
||||
installSuccess += 1
|
||||
}
|
||||
|
@ -599,13 +520,12 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
|
||||
addonViewModel.refreshAddons()
|
||||
|
||||
val separator = System.getProperty("line.separator") ?: "\n"
|
||||
val separator = System.lineSeparator() ?: "\n"
|
||||
val installResult = StringBuilder()
|
||||
if (installSuccess > 0) {
|
||||
installResult.append(
|
||||
getString(
|
||||
R.string.install_game_content_success_install,
|
||||
installSuccess
|
||||
R.string.install_game_content_success_install, installSuccess
|
||||
)
|
||||
)
|
||||
installResult.append(separator)
|
||||
|
@ -613,8 +533,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
if (installOverwrite > 0) {
|
||||
installResult.append(
|
||||
getString(
|
||||
R.string.install_game_content_success_overwrite,
|
||||
installOverwrite
|
||||
R.string.install_game_content_success_overwrite, installOverwrite
|
||||
)
|
||||
)
|
||||
installResult.append(separator)
|
||||
|
@ -624,8 +543,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
installResult.append(separator)
|
||||
installResult.append(
|
||||
getString(
|
||||
R.string.install_game_content_failed_count,
|
||||
errorTotal
|
||||
R.string.install_game_content_failed_count, errorTotal
|
||||
)
|
||||
)
|
||||
installResult.append(separator)
|
||||
|
@ -666,9 +584,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
ProgressDialogFragment.newInstance(
|
||||
this,
|
||||
R.string.exporting_user_data,
|
||||
true
|
||||
this, R.string.exporting_user_data, true
|
||||
) { progressCallback, _ ->
|
||||
val zipResult = FileUtil.zipFromInternalStorage(
|
||||
File(DirectoryInitialization.userDirectory!!),
|
||||
|
@ -692,8 +608,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
|
|||
}
|
||||
|
||||
ProgressDialogFragment.newInstance(
|
||||
this,
|
||||
R.string.importing_user_data
|
||||
this, R.string.importing_user_data
|
||||
) { progressCallback, _ ->
|
||||
val checkStream =
|
||||
ZipInputStream(BufferedInputStream(contentResolver.openInputStream(result)))
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
@ -177,6 +180,10 @@ object GpuDriverHelper {
|
|||
* @return A non-null [GpuDriverMetadata] instance that may have null members
|
||||
*/
|
||||
fun getMetadataFromZip(driver: File): GpuDriverMetadata {
|
||||
if (!driver.exists()) {
|
||||
return GpuDriverMetadata()
|
||||
}
|
||||
|
||||
try {
|
||||
ZipFile(driver).use { zf ->
|
||||
val entries = zf.entries()
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "core/hle/service/set/system_settings_server.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "frontend_common/config.h"
|
||||
#include "frontend_common/firmware_manager.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
|
@ -283,6 +284,7 @@ Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string
|
|||
: Service::AM::LaunchType::ApplicationInitiated,
|
||||
.program_index = static_cast<s32>(program_index),
|
||||
};
|
||||
|
||||
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath, params);
|
||||
if (m_load_result != Core::SystemResultStatus::Success) {
|
||||
return m_load_result;
|
||||
|
@ -764,35 +766,19 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_setCabinetMode(JNIEnv* env, jclass cl
|
|||
}
|
||||
|
||||
bool isFirmwarePresent() {
|
||||
auto bis_system =
|
||||
EmulationSession::GetInstance().System().GetFileSystemController().GetSystemNANDContents();
|
||||
if (!bis_system) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Query an applet to see if it's available
|
||||
auto applet_nca =
|
||||
bis_system->GetEntry(0x010000000000100Dull, FileSys::ContentRecordType::Program);
|
||||
if (!applet_nca) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return FirmwareManager::CheckFirmwarePresence(EmulationSession::GetInstance().System());
|
||||
}
|
||||
|
||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_isFirmwareAvailable(JNIEnv* env, jclass clazz) {
|
||||
return isFirmwarePresent();
|
||||
}
|
||||
|
||||
// TODO(crueter): This check is nonfunctional...
|
||||
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_firmwareVersion(JNIEnv* env, jclass clazz) {
|
||||
Service::Set::FirmwareVersionFormat firmware_data{};
|
||||
const auto result = Service::Set::GetFirmwareVersionImpl(
|
||||
firmware_data, EmulationSession::GetInstance().System(),
|
||||
Service::Set::GetFirmwareVersionType::Version2);
|
||||
const auto pair = FirmwareManager::GetFirmwareVersion(EmulationSession::GetInstance().System());
|
||||
const auto firmware_data = pair.first;
|
||||
const auto result = pair.second;
|
||||
|
||||
if (result.IsError() || !isFirmwarePresent()) {
|
||||
LOG_INFO(Frontend, "Installed firmware: No firmware available");
|
||||
|
||||
return Common::Android::ToJString(env, "N/A");
|
||||
}
|
||||
|
||||
|
@ -804,6 +790,23 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_firmwareVersion(JNIEnv* env, jclas
|
|||
return Common::Android::ToJString(env, display_version);
|
||||
}
|
||||
|
||||
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_verifyFirmware(JNIEnv* env, jclass clazz) {
|
||||
return static_cast<int>(FirmwareManager::VerifyFirmware(EmulationSession::GetInstance().System()));
|
||||
}
|
||||
|
||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_gameRequiresFirmware(JNIEnv* env, jclass clazz, jstring jprogramId) {
|
||||
auto program_id = EmulationSession::GetProgramId(env, jprogramId);
|
||||
|
||||
return FirmwareManager::GameRequiresFirmware(program_id);
|
||||
}
|
||||
|
||||
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_installKeys(JNIEnv* env, jclass clazz, jstring jpath, jstring jext) {
|
||||
const auto path = Common::Android::GetJString(env, jpath);
|
||||
const auto ext = Common::Android::GetJString(env, jext);
|
||||
|
||||
return static_cast<int>(FirmwareManager::InstallKeys(path, ext));
|
||||
}
|
||||
|
||||
jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
|
||||
jstring jpath,
|
||||
jstring jprogramId) {
|
||||
|
|
BIN
src/android/app/src/main/res/drawable/ic_icon_bg.png
Normal file
BIN
src/android/app/src/main/res/drawable/ic_icon_bg.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
|
@ -1,952 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:viewportWidth="687.3875"
|
||||
android:viewportHeight="687.3875"
|
||||
android:width="2598dp"
|
||||
android:height="2598dp">
|
||||
<path
|
||||
android:pathData="M-12.54741 -9.487146H695.7068V701.107H-12.54741V-9.487146Z"
|
||||
android:fillColor="#1C1C1C"
|
||||
android:strokeColor="#1C1C1C"
|
||||
android:strokeWidth="11.589"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M494.45889 345.0122l-20.55738 30.02458 -8.65574 -119.82784 67.35244 34.35247 -20.82787 30.56554 70.59835 147.959 -17.04096 22.7213z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M532.19248 289.56141l26.91392 -4.32787 -65.99997 -34.89344 -26.77869 3.92213z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M558.56543 285.63928l-19.7459 30.56557 -26.77869 3.9221 20.42213 -30.7008z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M582.63918 468.22118l27.86066 -4.05736 -71.54506 -148.36471 -26.77869 4.4631z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M610.22935 464.70479l-17.04099 24.74999 -26.91392 2.84017 17.31148 -24.209z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M474.98348 375.98351l26.91392 -3.11065 3.51639 -5.40983 -10.41392 -22.04509z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<group
|
||||
android:rotation="2.320764"
|
||||
android:scaleX="0.7541365"
|
||||
android:scaleY="0.7541365"
|
||||
android:translateX="-141.3355"
|
||||
android:translateY="27.85998">
|
||||
<path
|
||||
android:pathData="M393.01518 281.73251l-20.55738 30.02458 -8.65574 -119.82784 67.35244 34.35247 -20.82787 30.56554 70.59835 147.959 -17.04096 22.7213z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="3.87681"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M430.74877 226.28172l26.91392 -4.32787 -65.99997 -34.89344 -26.77869 3.92213z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="3.87681"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M457.12172 222.35959l-19.7459 30.56557 -26.77869 3.9221 20.42213 -30.7008z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="3.87681"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M481.19547 404.94149l27.86066 -4.05736 -71.54506 -148.36471 -26.77869 4.4631z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="3.87681"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M508.78564 401.4251l-17.04099 24.74999 -26.91392 2.84017 17.31148 -24.209z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="3.87681"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M373.53977 312.70382l26.91392 -3.11065 3.51639 -5.40983 -10.41392 -22.04509z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="3.87681"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<path
|
||||
android:pathData="M331.56055 45.999602l27.82927 8.893895 62.44852 -56.4236293 -37.39261 -1.8170322z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M359.61877 54.909822l11.09014 24.614746 91.29096 -82.0942394 -38.68031 -1.6229503z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M369.89743 79.524568L341.69867 71.00408 330.67615 46.051217 359.61877 54.63933Z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="2.64583"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M635.3851 77.63113A53.01638 53.01638 0 0 1 529.3523 77.63113A53.01638 53.01638 0 0 1 635.3851 77.63113Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M370.3487 589.3373A26.71373 26.71373 0 0 1 316.9212 589.3373A26.71373 26.71373 0 0 1 370.3487 589.3373Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M221.1756 598.8859A62.61387 62.61387 0 0 1 95.94788 598.8859A62.61387 62.61387 0 0 1 221.1756 598.8859Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M439.18345 506.27236l6.64477 47.48313 43.42712 -20.89004 -6.87718 -47.72509z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M250.6585 331.34613l-31.74822 105.78124 89.83779 84.43087 121.44738 -20.93441 32.30276 -105.6426 -90.11504 -85.12406z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M196.88499 433.42193l28.85734 38.86296 -28.78561 38.82713 -28.59435 -38.30115z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M507.61256 173.83179l8.65666 25.9651 -22.30747 15.78891 -8.61435 -25.6169z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M238.54168 139.98243l48.2679 -0.54605 14.49415 45.96882 -47.66037 0.6626z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<group
|
||||
android:rotation="-6.069791"
|
||||
android:scaleX="0.7527306"
|
||||
android:scaleY="0.7038611"
|
||||
android:translateX="450.7954"
|
||||
android:translateY="136.4846">
|
||||
<group
|
||||
android:rotation="8.307879">
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-2.088203"
|
||||
android:translateY="46.2009">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-0.4652534"
|
||||
android:translateY="1.29927">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-1.006237"
|
||||
android:translateY="24.02058">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="42.78186"
|
||||
android:scaleX="1.070914"
|
||||
android:scaleY="1.042189"
|
||||
android:translateX="661.8707"
|
||||
android:translateY="250.1218">
|
||||
<group
|
||||
android:rotation="17.87905">
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-2.088203"
|
||||
android:translateY="46.2009">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-0.4652534"
|
||||
android:translateY="1.29927">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-1.006237"
|
||||
android:translateY="24.02058">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="92.90104"
|
||||
android:scaleX="0.686048"
|
||||
android:scaleY="0.6572564"
|
||||
android:translateX="164.3531"
|
||||
android:translateY="238.4857">
|
||||
<group
|
||||
android:rotation="-0.00002171183">
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-2.088203"
|
||||
android:translateY="46.2009">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-0.4652534"
|
||||
android:translateY="1.29927">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-1.006237"
|
||||
android:translateY="24.02058">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="3.075623"
|
||||
android:scaleX="1.039543"
|
||||
android:scaleY="0.9959163"
|
||||
android:translateX="-242.0844"
|
||||
android:translateY="-115.0889">
|
||||
<group
|
||||
android:rotation="-0.000003860364">
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-2.088203"
|
||||
android:translateY="46.2009">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-0.4652534"
|
||||
android:translateY="1.29927">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-1.006237"
|
||||
android:translateY="24.02058">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-2.088203"
|
||||
android:translateY="46.2009">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-0.4652534"
|
||||
android:translateY="1.29927">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<group
|
||||
android:scaleX="1.004303"
|
||||
android:scaleY="0.9859607"
|
||||
android:translateX="-1.006237"
|
||||
android:translateY="24.02058">
|
||||
<path
|
||||
android:pathData="M189.07372 56.803262c-24.61475 22.721306 43.27868 105.491778 54.90982 115.229478 11.63114 9.7377 66.54097 64.37703 104.4098 48.68851 37.86886 -15.68852 -54.36883 -119.28685 -47.06557 -111.44259 7.3033 7.84426 -74.38521 -76.008178 -112.25405 -52.475398z"
|
||||
android:strokeColor="#232323"
|
||||
android:strokeWidth="4.48315"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
<path
|
||||
android:pathData="M114.027 0.004829188H120.3289V687.4189H114.027V0.004829188Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M222.8384 0.03916146H229.1403V687.4533H222.8384V0.03916146Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M41.36438 -242.1991H46.69247V-99.86517H41.36438V-242.1991Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M127.124 -242.8359H132.452V-100.502H127.124V-242.8359Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M212.4888 -242.8362H217.8169V-100.5023H212.4888V-242.8362Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M298.6423 -242.8366H303.9704V-100.5027H298.6423V-242.8366Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M384.3656 -242.8369H389.6937V-100.5031H384.3656V-242.8369Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M470.2463 -242.8373H475.5743V-100.5034H470.2463V-242.8373Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M556.1945 -242.8377H561.5226V-100.5038H556.1945V-242.8377Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M642.1034 -242.838H647.4315V-100.5042H642.1034V-242.838Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<path
|
||||
android:pathData="M286.371 -0.4009084H292.6729V687.0132H286.371V-0.4009084Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M395.1824 -0.3665761H401.4843V687.0475H395.1824V-0.3665761Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M40.94651 -414.5431H46.2746V-272.2092H40.94651V-414.5431Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M126.7061 -415.1799H132.0342V-272.846H126.7061V-415.1799Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M212.0709 -415.1802H217.399V-272.8464H212.0709V-415.1802Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M298.2244 -415.1806H303.5525V-272.8467H298.2244V-415.1806Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M383.9477 -415.181H389.2758V-272.8471H383.9477V-415.181Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M469.8284 -415.1813H475.1565V-272.8475H469.8284V-415.1813Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M555.7766 -415.1817H561.1047V-272.8478H555.7766V-415.1817Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M641.6855 -415.182H647.0136V-272.8482H641.6855V-415.182Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:translateX="172.7436"
|
||||
android:translateY="-1.445976">
|
||||
<path
|
||||
android:pathData="M286.371 0.004829188H292.6729V687.4189H286.371V0.004829188Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M395.1824 0.03916146H401.4843V687.4533H395.1824V0.03916146Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M41.35225 -414.5431H46.68034V-272.2092H41.35225V-414.5431Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M127.1118 -415.1799H132.4399V-272.846H127.1118V-415.1799Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M212.4766 -415.1802H217.8047V-272.8464H212.4766V-415.1802Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M298.6302 -415.1806H303.9583V-272.8467H298.6302V-415.1806Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M384.3535 -415.181H389.6815V-272.8471H384.3535V-415.181Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M470.2341 -415.1813H475.5622V-272.8475H470.2341V-415.1813Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M556.1824 -415.1817H561.5105V-272.8478H556.1824V-415.1817Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M642.0913 -415.182H647.4193V-272.8482H642.0913V-415.182Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:translateX="345.2804"
|
||||
android:translateY="-1.445976">
|
||||
<path
|
||||
android:pathData="M286.371 0.004829188H292.6729V687.4189H286.371V0.004829188Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M395.1824 0.03916146H401.4843V687.4533H395.1824V0.03916146Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M41.35225 -414.5431H46.68034V-272.2092H41.35225V-414.5431Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M127.1118 -415.1799H132.4399V-272.846H127.1118V-415.1799Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M212.4766 -415.1802H217.8047V-272.8464H212.4766V-415.1802Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M298.6302 -415.1806H303.9583V-272.8467H298.6302V-415.1806Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M384.3535 -415.181H389.6815V-272.8471H384.3535V-415.181Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M470.2341 -415.1813H475.5622V-272.8475H470.2341V-415.1813Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M556.1824 -415.1817H561.5105V-272.8478H556.1824V-415.1817Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M642.0913 -415.182H647.4193V-272.8482H642.0913V-415.182Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:translateX="-343.8918"
|
||||
android:translateY="0.07904825">
|
||||
<path
|
||||
android:pathData="M286.371 0.004829188H292.6729V687.4189H286.371V0.004829188Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<path
|
||||
android:pathData="M395.1824 0.03916146H401.4843V687.4533H395.1824V0.03916146Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M41.35225 -414.5431H46.68034V-272.2092H41.35225V-414.5431Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M127.1118 -415.1799H132.4399V-272.846H127.1118V-415.1799Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M212.4766 -415.1802H217.8047V-272.8464H212.4766V-415.1802Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M298.6302 -415.1806H303.9583V-272.8467H298.6302V-415.1806Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M384.3535 -415.181H389.6815V-272.8471H384.3535V-415.181Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M470.2341 -415.1813H475.5622V-272.8475H470.2341V-415.1813Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M556.1824 -415.1817H561.5105V-272.8478H556.1824V-415.1817Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
<group
|
||||
android:rotation="45.00107"
|
||||
android:scaleX="1.000033"
|
||||
android:scaleY="0.9999669">
|
||||
<group
|
||||
android:rotation="45.00107">
|
||||
<path
|
||||
android:pathData="M642.0913 -415.182H647.4193V-272.8482H642.0913V-415.182Z"
|
||||
android:fillColor="#232323"
|
||||
android:strokeLineCap="round"
|
||||
android:strokeLineJoin="round" />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</vector>
|
BIN
src/android/app/src/main/res/drawable/ic_icon_bg_orig.png
Normal file
BIN
src/android/app/src/main/res/drawable/ic_icon_bg_orig.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 195 KiB |
|
@ -349,13 +349,7 @@
|
|||
<string name="warning_cancel">إلغاء</string>
|
||||
<string name="install_amiibo_keys">تثبيت مفاتيح أميبو</string>
|
||||
<string name="install_amiibo_keys_description">مطلوب لاستخدام أميبو في اللعبة</string>
|
||||
<string name="invalid_keys_file">تم تحديد ملف مفاتيح غير صالح</string>
|
||||
<string name="install_keys_success">تم تثبيت المفاتيح بنجاح</string>
|
||||
<string name="reading_keys_failure">خطأ في قراءة مفاتيح التشفير</string>
|
||||
<string name="install_prod_keys_failure_extension_description">وحاول مرة أخر keys تحقق من أن ملف المفاتيح له امتداد</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">وحاول مرة أخر bin تحقق من أن ملف المفاتيح له امتداد</string>
|
||||
<string name="invalid_keys_error">مفاتيح التشفير غير صالحة</string>
|
||||
<string name="install_keys_failure_description">الملف المحدد غير صحيح أو تالف. يرجى إعادة المفاتيح الخاصة بك</string>
|
||||
<string name="gpu_driver_manager">GPU مدير برنامج تشغيل</string>
|
||||
<string name="install_gpu_driver">GPU تثبيت برنامج تشغيل</string>
|
||||
<string name="install_gpu_driver_description">قم بتثبيت برامج تشغيل بديلة للحصول على أداء أو دقة أفضل</string>
|
||||
|
@ -422,8 +416,6 @@
|
|||
<string name="verify_installed_content_description">فحص المحتوى المثبت بحثًا عن تلف</string>
|
||||
<string name="keys_missing">مفاتيح التشفير مفقودة</string>
|
||||
<string name="keys_missing_description">لا يمكن فك تشفير البرنامج الثابت والألعاب</string>
|
||||
<string name="firmware_missing">البرنامج الثابت مفقود أو جديد جدًا</string>
|
||||
<string name="firmware_missing_description">بعض الألعاب قد لا تعمل بشكل صحيح. يتطلب إيدن البرنامج الثابت 19.0.1 أو أقل.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -344,13 +344,7 @@
|
|||
<string name="warning_cancel">ڕەتکردنەوە</string>
|
||||
<string name="install_amiibo_keys">دامەزراندنی کلیلی Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">پێویستە بۆ بەکارهێنانی Amiibo لە یاریدا</string>
|
||||
<string name="invalid_keys_file">فایلی کلیلێکی نادروست هەڵبژێردرا</string>
|
||||
<string name="install_keys_success">کلیلەکان بە سەرکەوتوویی دامەزران</string>
|
||||
<string name="reading_keys_failure">هەڵە لە خوێندنەوەی کۆدکردنی کلیل</string>
|
||||
<string name="install_prod_keys_failure_extension_description">دڵنیابەوە کە فایلی کلیلەکانت درێژکراوەی .keys ی هەیە و دووبارە هەوڵبدەرەوە.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">دڵنیابە کە فایلی کلیلەکانت درێژکراوەی .bin ی هەیە و دووبارە هەوڵبدەرەوە.</string>
|
||||
<string name="invalid_keys_error">کلیلی کۆدکردنی نادروستە</string>
|
||||
<string name="install_keys_failure_description">فایلە هەڵبژێردراوەکە هەڵەیە یان تێکچووە. تکایە دووبارە کلیلەکانت دەربێنەوە.</string>
|
||||
<string name="install_gpu_driver">دامەزراندنی وەگەڕخەری GPU</string>
|
||||
<string name="install_gpu_driver_description">دامەزراندنی وەگەڕخەری بەدیل بۆ ئەوەی بە ئەگەرێکی زۆرەوە کارایی باشتر یان وردبینی هەبێت</string>
|
||||
<string name="advanced_settings">ڕێکخستنە پێشکەوتووەکان</string>
|
||||
|
@ -416,8 +410,6 @@
|
|||
<string name="verify_installed_content_description">هەموو ناوەڕۆکی دامەزراو پشکنین دەکات بۆ تێکچوون</string>
|
||||
<string name="keys_missing">کلیلە کۆدکراوەکان دیار نییە</string>
|
||||
<string name="keys_missing_description">پتەوواڵا و یارییە تاکەکەسییەکان ناتوانرێت کۆد بکرێنەوە</string>
|
||||
<string name="firmware_missing">فریموێر بوونی نییە یان زۆر نوێە</string>
|
||||
<string name="firmware_missing_description">هەندێ یاری لەوانەیە باش کار نەکەن. ئێدەن پێویستی بە فریموێری ١٩.٠.١ یان کەمترە.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -333,10 +333,6 @@
|
|||
<string name="warning_cancel">Zrušit</string>
|
||||
<string name="install_amiibo_keys">Instalovat Amiibo klíče</string>
|
||||
<string name="install_amiibo_keys_description">Povinné použití Amiibo ve hře</string>
|
||||
<string name="invalid_keys_file">Vybrané klíče jsou neplatné</string>
|
||||
<string name="install_keys_success">Klíče úspěšně nainstalovány</string>
|
||||
<string name="reading_keys_failure">Chyba při čtení šifrovacích klíčů</string>
|
||||
<string name="invalid_keys_error">Neplatné šifrovací klíče</string>
|
||||
<string name="gpu_driver_manager">Správce ovladače GPU</string>
|
||||
<string name="install_gpu_driver">Instalovat GPU ovladač</string>
|
||||
<string name="advanced_settings">Pokročilé nastavení</string>
|
||||
|
@ -380,8 +376,6 @@
|
|||
<string name="verify_installed_content_description">Kontrola poškození obsahu</string>
|
||||
<string name="keys_missing">Chybí šifrovací klíče</string>
|
||||
<string name="keys_missing_description">Firmware a retail hry nelze dešifrovat</string>
|
||||
<string name="firmware_missing">Firmware chybí nebo je příliš nový</string>
|
||||
<string name="firmware_missing_description">Některé hry nemusí fungovat správně. Eden vyžaduje firmware 19.0.1 nebo nižší.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">Abbrechen</string>
|
||||
<string name="install_amiibo_keys">Amiibo-Schlüssel installieren</string>
|
||||
<string name="install_amiibo_keys_description">Benötigt um Amiibos im Spiel zu verwenden</string>
|
||||
<string name="invalid_keys_file">Ungültige Schlüsseldatei ausgewählt</string>
|
||||
<string name="install_keys_success">Schlüssel erfolgreich installiert</string>
|
||||
<string name="reading_keys_failure">Fehler beim Lesen der Schlüssel</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".keys\" hat, und versuchen Sie es erneut.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Überprüfen Sie, ob Ihre Schlüsseldatei die Erweiterung \".bin\" hat, und versuchen Sie es erneut.</string>
|
||||
<string name="invalid_keys_error">Ungültige Schlüssel</string>
|
||||
<string name="install_keys_failure_description">Die ausgewählte Datei ist falsch oder beschädigt. Bitte kopieren Sie Ihre Schlüssel erneut.</string>
|
||||
<string name="gpu_driver_manager">GPU-Treiber Verwaltung</string>
|
||||
<string name="install_gpu_driver">GPU-Treiber installieren</string>
|
||||
<string name="install_gpu_driver_description">Alternative Treiber für eventuell bessere Leistung oder Genauigkeit installieren</string>
|
||||
|
@ -415,8 +409,6 @@ Wirklich fortfahren?</string>
|
|||
<string name="verify_installed_content_description">Überprüft installierte Inhalte auf Fehler</string>
|
||||
<string name="keys_missing">Schlüssel fehlen</string>
|
||||
<string name="keys_missing_description">Firmware und Spiele können nicht entschlüsselt werden</string>
|
||||
<string name="firmware_missing">Firmware fehlt oder ist zu neu</string>
|
||||
<string name="firmware_missing_description">Einige Spiele funktionieren möglicherweise nicht richtig. Eden erfordert Firmware 19.0.1 oder älter.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Cancelar</string>
|
||||
<string name="install_amiibo_keys">Instalar claves de Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Necesario para usar Amiibos en el juego</string>
|
||||
<string name="invalid_keys_file">Archivo de claves seleccionado no válido</string>
|
||||
<string name="install_keys_success">Claves instaladas correctamente</string>
|
||||
<string name="reading_keys_failure">Error al leer las claves de cifrado</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .keys y pruebe otra vez.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Compruebe que el archivo de claves tenga una extensión .bin y pruebe otra vez.</string>
|
||||
<string name="invalid_keys_error">Claves de cifrado no válidas</string>
|
||||
<string name="install_keys_failure_description">El archivo seleccionado es incorrecto o está corrupto. Vuelva a redumpear sus claves.</string>
|
||||
<string name="gpu_driver_manager">Explorador de drivers de GPU</string>
|
||||
<string name="install_gpu_driver">Instalar driver de GPU</string>
|
||||
<string name="install_gpu_driver_description">Instale drivers alternativos para obtener un rendimiento o una precisión potencialmente mejores</string>
|
||||
|
@ -428,8 +422,6 @@
|
|||
<string name="verify_installed_content_description">Comprueba todo el contenido instalado por si hubiese alguno corrupto</string>
|
||||
<string name="keys_missing">Faltan las claves de encriptación</string>
|
||||
<string name="keys_missing_description">El firmware y los juegos no se pueden desencriptar</string>
|
||||
<string name="firmware_missing">Falta el firmware o es demasiado nuevo</string>
|
||||
<string name="firmware_missing_description">Algunos juegos pueden no funcionar correctamente. Eden requiere firmware 19.0.1 o inferior.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">لغو</string>
|
||||
<string name="install_amiibo_keys">کلیدهای Amiibo را نصب کنید</string>
|
||||
<string name="install_amiibo_keys_description">برای استفاده از Amiibo در بازی لازم است</string>
|
||||
<string name="invalid_keys_file">فایل کلیدهای نامعتبر انتخاب شد</string>
|
||||
<string name="install_keys_success">کلیدها با موفقیت نصب شدند</string>
|
||||
<string name="reading_keys_failure">خطا در خواندن کلیدهای رمزگذاری</string>
|
||||
<string name="install_prod_keys_failure_extension_description">بررسی کنید که فایل کلیدهای شما دارای پسوند keys. باشد و دوباره امتحان کنید.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">بررسی کنید که فایل کلیدهای شما دارای پسوند bin. باشد و دوباره امتحان کنید.</string>
|
||||
<string name="invalid_keys_error">کلیدهای رمزگذاری نامعتبر</string>
|
||||
<string name="install_keys_failure_description">فایل انتخابی نادرست یا خراب است. لطفا کلیدهای خود را دوباره استخراج کنید.</string>
|
||||
<string name="gpu_driver_manager">مدیریت درایور پردازنده گرافیکی</string>
|
||||
<string name="install_gpu_driver">نصب درایور پردازنده گرافیکی</string>
|
||||
<string name="install_gpu_driver_description">درایورهای جایگزین را برای عملکرد یا دقت بهتر نصب کنید</string>
|
||||
|
@ -426,8 +420,6 @@
|
|||
<string name="verify_installed_content_description">تمام محتوای نصب شده را از نظر خرابی بررسی میکند</string>
|
||||
<string name="keys_missing">کلیدهای رمزگذاری وجود ندارند</string>
|
||||
<string name="keys_missing_description">ثابتافزار و بازیهای فروشگاهی قابل رمزگشایی نیستند</string>
|
||||
<string name="firmware_missing">فریمور وجود ندارد یا خیلی جدید است</string>
|
||||
<string name="firmware_missing_description">برخی بازیها ممکن است به درستی کار نکنند. ایدن به فریمور نسخه 19.0.1 یا پایینتر نیاز دارد.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Annuler</string>
|
||||
<string name="install_amiibo_keys">Installer les clés Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Nécessaire pour utiliser les Amiibo en jeu</string>
|
||||
<string name="invalid_keys_file">Fichier de clés sélectionné invalide</string>
|
||||
<string name="install_keys_success">Clés installées avec succès</string>
|
||||
<string name="reading_keys_failure">Erreur lors de la lecture des clés de chiffrement</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Vérifiez que votre fichier de clés a une extension .keys et réessayez.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Vérifiez que votre fichier de clés a une extension .bin et réessayez.</string>
|
||||
<string name="invalid_keys_error">Clés de chiffrement invalides</string>
|
||||
<string name="install_keys_failure_description">Le fichier sélectionné est incorrect ou corrompu. Veuillez dumper à nouveau vos clés.</string>
|
||||
<string name="gpu_driver_manager">Gestionnaire de pilotes du GPU</string>
|
||||
<string name="install_gpu_driver">Installer le pilote du GPU</string>
|
||||
<string name="install_gpu_driver_description">Installer des pilotes alternatifs pour des performances ou une précision potentiellement meilleures</string>
|
||||
|
@ -428,8 +422,6 @@
|
|||
<string name="verify_installed_content_description">Vérifie l\'intégrité des contenus installés</string>
|
||||
<string name="keys_missing">Les clés de chiffrement sont manquantes.</string>
|
||||
<string name="keys_missing_description">Le firmware et les jeux commerciaux ne peuvent pas être déchiffrés</string>
|
||||
<string name="firmware_missing">Firmware manquant ou trop récent</string>
|
||||
<string name="firmware_missing_description">Certains jeux peuvent ne pas fonctionner correctement. Eden nécessite le firmware 19.0.1 ou antérieur.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -348,13 +348,7 @@
|
|||
<string name="warning_cancel">ביטול</string>
|
||||
<string name="install_amiibo_keys">התקן מפתחות Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">נחוץ כדי להשתמש ב Amiibo במשחק</string>
|
||||
<string name="invalid_keys_file">קובץ מפתחות לא חוקי נבחר</string>
|
||||
<string name="install_keys_success">מפתחות הותקנו בהצלחה</string>
|
||||
<string name="reading_keys_failure">שגיאה בקריאת מפתחות ההצפנה</string>
|
||||
<string name="install_prod_keys_failure_extension_description">ודא שלקובץ המפתחות שלך יש סיומת של key. ונסה/י שוב.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">ודא/י שלקובץ המפתחות שלך יש סיומת של bin. ונסה/י שוב.</string>
|
||||
<string name="invalid_keys_error">מפתחות הצפנה לא חוקיים</string>
|
||||
<string name="install_keys_failure_description">קבוץ שנבחר מושחת או לא נכון. בבקשה הוצא מחדש את המפתחות שלך.</string>
|
||||
<string name="gpu_driver_manager">מנהל הדרייברים של המעבד הגרפי</string>
|
||||
<string name="install_gpu_driver">התקן דרייבר למעבד הגרפי</string>
|
||||
<string name="install_gpu_driver_description">התקן דרייברים אחרים בשביל סיכוי לביצועים או דיוק גבוההים יותר</string>
|
||||
|
@ -427,8 +421,6 @@
|
|||
<string name="verify_installed_content_description">בודק תוכן מותקן לשגיאות</string>
|
||||
<string name="keys_missing">מפתחות הצפנה חסרים</string>
|
||||
<string name="keys_missing_description">לא ניתן לפענח firmware ומשחקים</string>
|
||||
<string name="firmware_missing">קושחה חסרה או חדשה מדי</string>
|
||||
<string name="firmware_missing_description">חלק מהמשחקים עשויים לא לפעול כראוי. Eden דורש קושחה בגרסה 19.0.1 או נמוכה יותר.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">Mégse</string>
|
||||
<string name="install_amiibo_keys">Amiibo kulcsok telepítése</string>
|
||||
<string name="install_amiibo_keys_description">Amiibo használata szükséges a játékhoz</string>
|
||||
<string name="invalid_keys_file">Érvénytelen titkosítófájlok kiválasztva</string>
|
||||
<string name="install_keys_success">Kulcsok sikeresen telepítve</string>
|
||||
<string name="reading_keys_failure">Hiba történt a titkosítókulcsok olvasása során</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Győződj meg róla, hogy a titkosító fájlod .keys kiterjesztéssel rendelkezik, majd próbáld újra.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Győződj meg róla, hogy a titkosító fájlod .bin kiterjesztéssel rendelkezik, majd próbáld újra.</string>
|
||||
<string name="invalid_keys_error">Érvénytelen titkosítókulcsok</string>
|
||||
<string name="install_keys_failure_description">A kiválasztott fájl helytelen, vagy sérült. Állíts össze egy új kulcsot.</string>
|
||||
<string name="gpu_driver_manager">GPU illesztőprogram-kezelő</string>
|
||||
<string name="install_gpu_driver">GPU illesztőprogram telepítése</string>
|
||||
<string name="install_gpu_driver_description">Alternatív illesztőprogramok telepítése az esetlegesen elérhető teljesítmény és pontosság érdekében</string>
|
||||
|
@ -424,8 +418,6 @@
|
|||
<string name="verify_installed_content_description">A telepített tartalom épségét ellenőrzi</string>
|
||||
<string name="keys_missing">Hiányzó titkosítókulcsok</string>
|
||||
<string name="keys_missing_description">A Firmware és a kiskereskedelmi (retail) játékok nem dekódolhatók</string>
|
||||
<string name="firmware_missing">Hiányzó vagy túl új firmware</string>
|
||||
<string name="firmware_missing_description">Néhány játék nem fog megfelelően működni. Az Eden 19.0.1 vagy régebbi firmware-t igényel.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Batalkan</string>
|
||||
<string name="install_amiibo_keys">Install Amiibo keys</string>
|
||||
<string name="install_amiibo_keys_description">Diperlukan untuk menggunakan Amiibo di dalam game</string>
|
||||
<string name="invalid_keys_file">Keys yang dipilih invalid</string>
|
||||
<string name="install_keys_success">Keys berhasil diinstal</string>
|
||||
<string name="reading_keys_failure">Error saat mengecek enkripsi keys</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Pastikan file keys anda memiliki format .keys dan coba lagi.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Pastikan file keys anda memiliki format .bin dan coba lagi.</string>
|
||||
<string name="invalid_keys_error">Keys enkripsi tidak valid</string>
|
||||
<string name="install_keys_failure_description">File yang dipilih salah atau rusak. Silakan masukkan kembali kunci Anda.</string>
|
||||
<string name="gpu_driver_manager">Manajer driver GPU</string>
|
||||
<string name="install_gpu_driver">Install driver GPU</string>
|
||||
<string name="install_gpu_driver_description">Instal driver lain untuk kinerja atau akurasi yang berpotensi lebih baik</string>
|
||||
|
@ -424,8 +418,6 @@
|
|||
<string name="verify_installed_content_description">Memeriksa semua konten yang terinstal dari kerusakan</string>
|
||||
<string name="keys_missing">Kunci enkripsi hilang</string>
|
||||
<string name="keys_missing_description">Firmware dan game retail tidak dapat didekripsi</string>
|
||||
<string name="firmware_missing">Firmware hilang atau terlalu baru</string>
|
||||
<string name="firmware_missing_description">Beberapa game mungkin tidak berfungsi dengan baik. Eden memerlukan firmware 19.0.1 atau lebih rendah.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -348,13 +348,7 @@
|
|||
<string name="warning_cancel">Annulla</string>
|
||||
<string name="install_amiibo_keys">Installa le chiavi degli Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Necessario per usare gli Amiibo in gioco</string>
|
||||
<string name="invalid_keys_file">Selezionate chiavi non valide</string>
|
||||
<string name="install_keys_success">Chiavi installate correttamente</string>
|
||||
<string name="reading_keys_failure">Errore durante la lettura delle chiavi di crittografia</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Controlla che le tue chiavi abbiano l\'estensione .keys e prova di nuovo.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Controlla che le tue chiavi abbiano l\'estensione .bin e prova di nuovo</string>
|
||||
<string name="invalid_keys_error">Chiavi di crittografia non valide</string>
|
||||
<string name="install_keys_failure_description">Il file selezionato è incorretto o corrotto. Per favore riesegui il dump delle tue chiavi.</string>
|
||||
<string name="gpu_driver_manager">Gestore driver GPU</string>
|
||||
<string name="install_gpu_driver">Installa i driver GPU</string>
|
||||
<string name="install_gpu_driver_description">Installa driver alternativi per potenziali prestazioni migliori o accuratezza.</string>
|
||||
|
@ -427,8 +421,6 @@
|
|||
<string name="verify_installed_content_description">Verifica l\'integrità di tutti i contenuti installati.</string>
|
||||
<string name="keys_missing">Chiavi di crittografia mancanti</string>
|
||||
<string name="keys_missing_description">Impossibile decifrare firmware e giochi retail</string>
|
||||
<string name="firmware_missing">Firmware mancante o troppo recente</string>
|
||||
<string name="firmware_missing_description">Alcuni giochi potrebbero non funzionare correttamente. Eden richiede il firmware 19.0.1 o precedente.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">キャンセル</string>
|
||||
<string name="install_amiibo_keys">Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">ゲーム内での Amiibo の使用に必要です</string>
|
||||
<string name="invalid_keys_file">無効なキーファイルです</string>
|
||||
<string name="install_keys_success">正常にインストールされました</string>
|
||||
<string name="reading_keys_failure">暗号化キーの読み込み失敗</string>
|
||||
<string name="install_prod_keys_failure_extension_description">キーの拡張子が.keysであることを確認し、再度お試しください。</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">キーの拡張子が.binであることを確認し、再度お試しください。</string>
|
||||
<string name="invalid_keys_error">暗号化キーが無効</string>
|
||||
<string name="install_keys_failure_description">ファイルが間違っているか破損しています。キーを再ダンプしてください。</string>
|
||||
<string name="gpu_driver_manager">GPUドライバーの管理</string>
|
||||
<string name="install_gpu_driver">GPUドライバー</string>
|
||||
<string name="install_gpu_driver_description">代替ドライバーをインストールしてパフォーマンスや精度を向上させます</string>
|
||||
|
@ -417,8 +411,6 @@
|
|||
<string name="verify_installed_content_description">すべてのインストール済みコンテンツの整合性を確認</string>
|
||||
<string name="keys_missing">暗号化キーが不足</string>
|
||||
<string name="keys_missing_description">ファームウェアと製品版ゲームを復号化できません</string>
|
||||
<string name="firmware_missing">ファームウェアがないか、バージョンが新しすぎます</string>
|
||||
<string name="firmware_missing_description">一部のゲームが正常に動作しない可能性があります。Edenは19.0.1以下のファームウェアが必要です。</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">취소</string>
|
||||
<string name="install_amiibo_keys">amiibo 키 설치</string>
|
||||
<string name="install_amiibo_keys_description">게임에서 amiibo 사용 시 필요</string>
|
||||
<string name="invalid_keys_file">잘못된 키 파일이 선택됨</string>
|
||||
<string name="install_keys_success">키 값을 설치했습니다.</string>
|
||||
<string name="reading_keys_failure">암호화 키 읽기 오류</string>
|
||||
<string name="install_prod_keys_failure_extension_description">키 파일의 확장자가 .keys인지 확인하고 다시 시도하세요.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">키 파일의 확장자가 .bin인지 확인하고 다시 시도하세요.</string>
|
||||
<string name="invalid_keys_error">암호화 키가 올바르지 않음</string>
|
||||
<string name="install_keys_failure_description">선택한 파일이 잘못되었거나 손상되었습니다. 키를 다시 덤프하세요.</string>
|
||||
<string name="gpu_driver_manager">GPU 드라이버 관리자</string>
|
||||
<string name="install_gpu_driver">GPU 드라이버 설치</string>
|
||||
<string name="install_gpu_driver_description">잠재적인 성능 또는 정확도 개선을 위해 대체 드라이버 설치</string>
|
||||
|
@ -423,8 +417,6 @@
|
|||
<string name="verify_installed_content_description">전체 설치된 콘텐츠의 손상을 확인합니다.</string>
|
||||
<string name="keys_missing">암호화 키를 찾을 수 없음</string>
|
||||
<string name="keys_missing_description">펌웨어 및 패키지 게임을 해독할 수 없음</string>
|
||||
<string name="firmware_missing">펌웨어가 없거나 버전이 너무 높습니다</string>
|
||||
<string name="firmware_missing_description">일부 게임이 제대로 작동하지 않을 수 있습니다. Eden은 19.0.1 이하 버전의 펌웨어가 필요합니다.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -344,13 +344,7 @@
|
|||
<string name="warning_cancel">Avbryt</string>
|
||||
<string name="install_amiibo_keys">Installer Amiibo-nøkler</string>
|
||||
<string name="install_amiibo_keys_description">Kreves for å bruke Amiibo i spillet</string>
|
||||
<string name="invalid_keys_file">Ugyldig nøkkelfil valgt</string>
|
||||
<string name="install_keys_success">Nøkler vellykket installert</string>
|
||||
<string name="reading_keys_failure">Feil ved lesing av krypteringsnøkler</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Kontroller at nøkkelfilen har filtypen .keys, og prøv igjen.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Kontroller at nøkkelfilen har filtypen .bin, og prøv igjen.</string>
|
||||
<string name="invalid_keys_error">Ugyldige krypteringsnøkler</string>
|
||||
<string name="install_keys_failure_description">Den valgte filen er feil eller ødelagt. Vennligst dump nøklene på nytt.</string>
|
||||
<string name="install_gpu_driver">Installer GPU-driver</string>
|
||||
<string name="install_gpu_driver_description">Installer alternative drivere for potensielt bedre ytelse eller nøyaktighet.</string>
|
||||
<string name="advanced_settings">Avanserte innstillinger</string>
|
||||
|
@ -416,8 +410,6 @@
|
|||
<string name="verify_installed_content_description">Sjekk for korrupsjon</string>
|
||||
<string name="keys_missing">Nøkler mangler</string>
|
||||
<string name="keys_missing_description">Kan ikke dekryptere firmware/spill</string>
|
||||
<string name="firmware_missing">Firmware mangler eller er for ny</string>
|
||||
<string name="firmware_missing_description">Noen spill fungerer kanskje ikke skikkelig. Eden krever firmware 19.0.1 eller lavere.</string>
|
||||
|
||||
<!-- Applet-lanseringsstrenger -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -344,13 +344,7 @@
|
|||
<string name="warning_cancel">Anuluj</string>
|
||||
<string name="install_amiibo_keys">Zainstaluj klucze Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Wymagane aby korzystać z Amiibo w grze</string>
|
||||
<string name="invalid_keys_file">Wybrano niepoprawne klucze</string>
|
||||
<string name="install_keys_success">Klucze zainstalowane pomyślnie</string>
|
||||
<string name="reading_keys_failure">Błąd podczas odczytu kluczy</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Upewnij się że twoje klucze mają rozszerzenie .keys i spróbuj ponownie.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Upewnij się że twoje klucze mają rozszerzenie .bin i spróbuj ponownie.</string>
|
||||
<string name="invalid_keys_error">Niepoprawne klucze</string>
|
||||
<string name="install_keys_failure_description">Wybrany plik jest niepoprawny lub uszkodzony. Zrzuć ponownie swoje klucze.</string>
|
||||
<string name="install_gpu_driver">Zainstaluj sterownik GPU</string>
|
||||
<string name="install_gpu_driver_description">Użyj alternatywnych sterowników aby potencjalnie zwiększyć wydajność i naprawić błędy</string>
|
||||
<string name="advanced_settings">Ustawienia zaawansowane</string>
|
||||
|
@ -416,8 +410,6 @@
|
|||
<string name="verify_installed_content_description">Sprawdza integralność zainstalowanych plików.</string>
|
||||
<string name="keys_missing">Brak kluczy</string>
|
||||
<string name="keys_missing_description">Firmware i gry nie mogą być odszyfrowane.</string>
|
||||
<string name="firmware_missing">Brak firmware lub zbyt nowa wersja</string>
|
||||
<string name="firmware_missing_description">Niektóre gry mogą nie działać poprawnie. Eden wymaga firmware w wersji 19.0.1 lub starszej.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Cancelar</string>
|
||||
<string name="install_amiibo_keys">Instalar chaves Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Necessárias para usar Amiibos em um jogo</string>
|
||||
<string name="invalid_keys_file">Arquivo de chaves selecionado inválido</string>
|
||||
<string name="install_keys_success">Chaves instaladas com sucesso</string>
|
||||
<string name="reading_keys_failure">Erro ao ler chaves de encriptação</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Verifique se seu arquivo de chaves possui a extensão .keys e tente novamente.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Verifique se seu arquivo de chaves possui a extensão .bin e tente novamente.</string>
|
||||
<string name="invalid_keys_error">Chaves de encriptação inválidas</string>
|
||||
<string name="install_keys_failure_description">O arquivo selecionado está incorreto ou corrompido. Por favor extraia suas chaves novamente.</string>
|
||||
<string name="gpu_driver_manager">Gerenciador de driver de GPU</string>
|
||||
<string name="install_gpu_driver">Instalar driver para GPU</string>
|
||||
<string name="install_gpu_driver_description">Instale drivers alternativos para desempenho ou precisão potencialmente melhores</string>
|
||||
|
@ -428,8 +422,6 @@
|
|||
<string name="verify_installed_content_description">Verifica todo o conteúdo instalado em busca de dados corrompidos</string>
|
||||
<string name="keys_missing">Faltando chaves de encriptação</string>
|
||||
<string name="keys_missing_description">O firmware e jogos comerciais não poderão ser decriptados</string>
|
||||
<string name="firmware_missing">Firmware ausente ou muito recente</string>
|
||||
<string name="firmware_missing_description">Alguns jogos podem não funcionar corretamente. O Eden requer firmware 19.0.1 ou inferior.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -347,13 +347,7 @@
|
|||
<string name="warning_cancel">Cancelar</string>
|
||||
<string name="install_amiibo_keys">Instala chaves Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Necessário para usares Amiibo no jogo</string>
|
||||
<string name="invalid_keys_file">Ficheiro de chaves inválido</string>
|
||||
<string name="install_keys_success">Chaves instaladas com sucesso</string>
|
||||
<string name="reading_keys_failure">Erro ao ler chaves de encriptação</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .keys e tente novamente.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Verifique se seu arquivo keys possui a extensão .bin e tente novamente.</string>
|
||||
<string name="invalid_keys_error">Chaves de encriptação inválidas</string>
|
||||
<string name="install_keys_failure_description">O ficheiro selecionado está corrompido. Por favor recarrega as tuas chaves.</string>
|
||||
<string name="gpu_driver_manager">Gerenciador de driver de GPU</string>
|
||||
<string name="install_gpu_driver">Instala driver para GPU</string>
|
||||
<string name="install_gpu_driver_description">Instala drivers alternativos para desempenho ou precisão potencialmente melhores</string>
|
||||
|
@ -428,8 +422,6 @@
|
|||
<string name="verify_installed_content_description">Verifica todo o conteúdo instalado em busca de dados corrompidos</string>
|
||||
<string name="keys_missing">Faltando chaves de encriptação</string>
|
||||
<string name="keys_missing_description">O firmware e jogos comerciais não poderão ser decriptados</string>
|
||||
<string name="firmware_missing">Firmware em falta ou demasiado recente</string>
|
||||
<string name="firmware_missing_description">Alguns jogos podem não funcionar corretamente. O Eden requer firmware versão 19.0.1 ou inferior.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">Отмена</string>
|
||||
<string name="install_amiibo_keys">Установить ключи Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Необходимо для использования Amiibo в играх</string>
|
||||
<string name="invalid_keys_file">Выбран неверный файл ключей</string>
|
||||
<string name="install_keys_success">Ключи успешно установлены</string>
|
||||
<string name="reading_keys_failure">Ошибка при чтении ключей шифрования</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Убедитесь, что файл ключей имеет расширение .keys, и повторите попытку.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Убедитесь, что файл ключей имеет расширение .bin, и повторите попытку.</string>
|
||||
<string name="invalid_keys_error">Неверные ключи шифрования</string>
|
||||
<string name="install_keys_failure_description">Выбранный файл неверен или поврежден. Пожалуйста, пере-дампите ваши ключи.</string>
|
||||
<string name="gpu_driver_manager">Менеджер драйверов ГП</string>
|
||||
<string name="install_gpu_driver">Установить драйвер ГП</string>
|
||||
<string name="install_gpu_driver_description">Установите альтернативные драйверы для потенциально лучшей производительности и/или точности</string>
|
||||
|
@ -430,8 +424,6 @@
|
|||
<string name="verify_installed_content_description">Проверяет весь установленный контент на наличие повреждений</string>
|
||||
<string name="keys_missing">Отсутствуют ключи шифрования</string>
|
||||
<string name="keys_missing_description">Прошивка и розничные игры не могут быть расшифрованы</string>
|
||||
<string name="firmware_missing">Прошивка отсутствует или слишком новая</string>
|
||||
<string name="firmware_missing_description">Некоторые игры могут работать некорректно. Eden требует прошивку версии 19.0.1 или ниже.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -298,13 +298,7 @@
|
|||
<string name="warning_cancel">Отказати</string>
|
||||
<string name="install_amiibo_keys">Инсталирајте Амиибо Кеис</string>
|
||||
<string name="install_amiibo_keys_description">Потребно је користити Амиибо у игри</string>
|
||||
<string name="invalid_keys_file">Изабрана је неважећа датотека тастера</string>
|
||||
<string name="install_keys_success">Кључеви су успешно инсталирани</string>
|
||||
<string name="reading_keys_failure">Грешка приликом чишћења кључева за шифровање</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Проверите да датотека кључева има. Екеис Ектенсион и покушајте поново.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Проверите да датотека кључева има .бин екстензију и покушајте поново.</string>
|
||||
<string name="invalid_keys_error">Неважеће кључеве за шифровање</string>
|
||||
<string name="install_keys_failure_description">Изабрана датотека је нетачна или оштећена. Молим вас да вам умањите кључеве.</string>
|
||||
<string name="gpu_driver_fetcher">ГПУ возач фетцхер</string>
|
||||
<string name="gpu_driver_manager">ГПУ управљач возача</string>
|
||||
<string name="install_gpu_driver">Инсталирајте ГПУ драјвер</string>
|
||||
|
@ -380,8 +374,6 @@
|
|||
<string name="keys_missing">Шифра о шифрирањима недостају</string>
|
||||
<string name="keys_missing_description">Фирмваре и малопродајне игре не могу се дешифровати</string>
|
||||
|
||||
<string name="firmware_missing">Фирмвер недостаје или је превише нов</string>
|
||||
<string name="firmware_missing_description">Неке игре можда неће радити исправно. Eden захтева фирмвер верзије 19.0.1 или старији.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Клаунцх</string>
|
||||
|
|
|
@ -344,12 +344,6 @@
|
|||
<string name="warning_cancel">Відміна</string>
|
||||
<string name="install_amiibo_keys">Встановити ключі Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Необхідно для використання Amiibo в іграх</string>
|
||||
<string name="invalid_keys_file">Вибрано неправильний файл ключів</string>
|
||||
<string name="install_keys_success">Ключі успішно встановлено</string>
|
||||
<string name="reading_keys_failure">Помилка під час зчитування ключів шифрування</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Переконайтеся, що файл ключів має розширення .keys, і повторіть спробу.</string>
|
||||
<string name="invalid_keys_error">Невірні ключі шифрування</string>
|
||||
<string name="install_keys_failure_description">Обраний файл невірний або пошкоджений. Будь ласка, зробіть повторний дамп ваших ключів.</string>
|
||||
<string name="install_gpu_driver">Встановити драйвер GPU</string>
|
||||
<string name="install_gpu_driver_description">Встановіть альтернативні драйвери для потенційно кращої продуктивності та/або точності</string>
|
||||
<string name="advanced_settings">Розширені налаштування</string>
|
||||
|
@ -415,8 +409,6 @@
|
|||
<string name="verify_installed_content_description">Перевіряє встановлений вміст на наявність помилок.</string>
|
||||
<string name="keys_missing">Відсутні ключі</string>
|
||||
<string name="keys_missing_description">Прошивку та роздрібні ігри не вдасться розшифрувати.</string>
|
||||
<string name="firmware_missing">Прошивка відсутня або занадто нова</string>
|
||||
<string name="firmware_missing_description">Деякі ігри можуть працювати неправильно. Eden вимагає прошивку версії 19.0.1 або нижче.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -344,13 +344,7 @@
|
|||
<string name="warning_cancel">Huỷ</string>
|
||||
<string name="install_amiibo_keys">Cài đặt Amiibo</string>
|
||||
<string name="install_amiibo_keys_description">Cần thiết để dùng Amiibo trong trò chơi</string>
|
||||
<string name="invalid_keys_file">Chìa khóa không hợp lệ</string>
|
||||
<string name="install_keys_success">Cài đặt chìa khóa thành công</string>
|
||||
<string name="reading_keys_failure">Lỗi đọc keys mã hóa</string>
|
||||
<string name="install_prod_keys_failure_extension_description">Xác minh rằng tệp keys của bạn có đuôi .keys và thử lại.</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">Xác minh rằng tệp keys của bạn có đuôi .bin và thử lại.</string>
|
||||
<string name="invalid_keys_error">Keys mã hoá không hợp lệ</string>
|
||||
<string name="install_keys_failure_description">Chọn file sai hoặc bị hỏng. Hãy xuất chìa khóa khác</string>
|
||||
<string name="install_gpu_driver">Cài đặt driver GPU</string>
|
||||
<string name="install_gpu_driver_description">Cài đặt driver thay thế để có thể có hiệu suất tốt và chính xác hơn</string>
|
||||
<string name="advanced_settings">Cài đặt nâng cao</string>
|
||||
|
@ -416,8 +410,6 @@
|
|||
<string name="verify_installed_content_description">Kiểm tra lỗi nội dung đã cài</string>
|
||||
<string name="keys_missing">Thiếu keys mã hóa</string>
|
||||
<string name="keys_missing_description">Không thể giải mã firmware và game</string>
|
||||
<string name="firmware_missing">Thiếu firmware hoặc phiên bản quá mới</string>
|
||||
<string name="firmware_missing_description">Một số trò chơi có thể không hoạt động bình thường. Eden yêu cầu firmware phiên bản 19.0.1 hoặc thấp hơn.</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -346,13 +346,7 @@
|
|||
<string name="warning_cancel">取消</string>
|
||||
<string name="install_amiibo_keys">安装 Amiibo 密钥文件</string>
|
||||
<string name="install_amiibo_keys_description">在遊戏中使用 Amiibo 时必需</string>
|
||||
<string name="invalid_keys_file">选择的密钥文件无效</string>
|
||||
<string name="install_keys_success">密钥文件已成功安装</string>
|
||||
<string name="reading_keys_failure">读取加密密钥时出错</string>
|
||||
<string name="install_prod_keys_failure_extension_description">请确保您的密钥文件扩展名为 .keys 并重试。</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">请确保您的密钥文件扩展名为 .bin 并重试。</string>
|
||||
<string name="invalid_keys_error">无效的加密密钥</string>
|
||||
<string name="install_keys_failure_description">选择的密钥文件不正确或已损坏。请重新转储密钥文件。</string>
|
||||
<string name="gpu_driver_manager">GPU 驱动管理器</string>
|
||||
<string name="install_gpu_driver">安装 GPU 驱动</string>
|
||||
<string name="install_gpu_driver_description">安装替代的驱动程序以获得更好的性能和精度</string>
|
||||
|
@ -423,8 +417,6 @@
|
|||
<string name="verify_installed_content_description">检查所有安装的内容是否有损坏</string>
|
||||
<string name="keys_missing">密钥缺失</string>
|
||||
<string name="keys_missing_description">无法解密固件和商业游戏</string>
|
||||
<string name="firmware_missing">固件缺失或版本过新</string>
|
||||
<string name="firmware_missing_description">某些游戏可能无法正常运行。Eden需要19.0.1或更低版本的固件。</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
|
@ -350,13 +350,7 @@
|
|||
<string name="warning_cancel">取消</string>
|
||||
<string name="install_amiibo_keys">安裝 Amiibo 金鑰</string>
|
||||
<string name="install_amiibo_keys_description">需要在遊戲中使用 Amiibo</string>
|
||||
<string name="invalid_keys_file">無效的金鑰檔案已選取</string>
|
||||
<string name="install_keys_success">金鑰已成功安裝</string>
|
||||
<string name="reading_keys_failure">讀取加密金鑰時發生錯誤</string>
|
||||
<string name="install_prod_keys_failure_extension_description">驗證您的金鑰檔案是否具有 .keys 副檔名並再試一次。</string>
|
||||
<string name="install_amiibo_keys_failure_extension_description">驗證您的金鑰檔案是否具有 .bin 副檔名並再試一次。</string>
|
||||
<string name="invalid_keys_error">無效的加密金鑰</string>
|
||||
<string name="install_keys_failure_description">選取的檔案不正確或已損毀,請重新傾印您的金鑰。</string>
|
||||
<string name="gpu_driver_manager">GPU 驅動程式管理員</string>
|
||||
<string name="install_gpu_driver">安裝 GPU 驅動程式</string>
|
||||
<string name="install_gpu_driver_description">安裝替代驅動程式以取得潛在的更佳效能或準確度</string>
|
||||
|
@ -427,8 +421,6 @@
|
|||
<string name="verify_installed_content_description">检查所有安装的内容是否有损坏</string>
|
||||
<string name="keys_missing">密钥缺失</string>
|
||||
<string name="keys_missing_description">无法解密固件和商业游戏</string>
|
||||
<string name="firmware_missing">韌體缺失或版本過新</string>
|
||||
<string name="firmware_missing_description">某些遊戲可能無法正常運作。Eden需要19.0.1或更低版本的韌體。</string>
|
||||
|
||||
<!-- Applet launcher strings -->
|
||||
<string name="qlaunch_applet">Qlaunch</string>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue