Compare commits

...

25 commits

Author SHA1 Message Date
Bixthefin
1960804696
[Android] Change app_name to Eden Legacy 2025-07-18 13:17:03 +01:00
Bixthefin
c07df11609
[android] Update applicationId to legacy 2025-07-18 13:05:29 +01:00
Bix
ac89ffae9f revert cd394fc40f
revert revert [android] Snapdragon 865 patches (#23)

revert [android] Snapdragon 865 patches (#23)

Co-authored-by: Aleksandr Popovich <alekpopo@pm.me>
Reviewed-on: https://git.bixed.xyz/Bix/eden/pulls/23

Reverted due to heavy performance hits on Android with higher specifications, will be adjusted to be included in a specific build for older A6XX devices, as 855, 860, 865, 870, meanwhile it does fix critical issues with certain games crashing due to memory and VRAM usage, hits performance on SoC that can do it without this special flags.
2025-07-18 13:58:19 +02:00
Bix
fc8d7004d2 Added "Legacy " to App name on android.
Signed-off-by: Bix <bix@bixed.xyz>
2025-07-18 13:58:19 +02:00
crueter
2aab37b516
[cmake] QuaZip: The Finale (#74)
All checks were successful
eden-build / source (push) Successful in 6m56s
eden-build / linux (push) Successful in 26m27s
eden-build / windows (msvc) (push) Successful in 29m46s
eden-build / android (push) Successful in 32m24s
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/74
2025-07-17 21:00:00 +02:00
crueter
108daeeb39
[cmake] Fix QuaZip once and for all (#71)
Some checks failed
eden-build / source (push) Successful in 6m39s
eden-build / windows (msvc) (push) Successful in 30m35s
eden-build / android (push) Successful in 33m0s
eden-build / linux (push) Failing after 17m53s
(and core5compat)

Signed-off-by: crueter <crueter@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/71
2025-07-16 23:17:34 +02:00
crueter
a538126eb7
[cmake, desktop] Fix <6.9 build error and quazip fetching (#67)
Some checks failed
eden-build / source (push) Successful in 6m37s
eden-build / windows (msvc) (push) Successful in 29m59s
eden-build / android (push) Successful in 33m10s
eden-build / linux (push) Failing after 17m40s
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/67
2025-07-15 22:24:40 +02:00
crueter
d7574b2878
[android] Update app icon background
All checks were successful
eden-build / source (push) Successful in 6m33s
eden-build / linux (push) Successful in 26m40s
eden-build / windows (msvc) (push) Successful in 30m32s
eden-build / android (push) Successful in 33m35s
thx antabaka

Signed-off-by: crueter <crueter@eden-emu.dev>
2025-07-14 20:51:20 -04:00
MaranBr
e9ca3f4c06
[host1x] Fix FFmpeg crash on Linux (#37)
All checks were successful
eden-build / source (push) Successful in 6m44s
eden-build / linux (push) Successful in 26m24s
eden-build / windows (msvc) (push) Successful in 30m47s
eden-build / android (push) Successful in 34m10s
This fixes the FFmpeg crash on Linux / Steam Deck.

Credit to Maufeat for AVERROR_EOF check.

Co-authored-by: MaranBr <maranbr@outlook.com>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/37
Co-authored-by: MaranBr <maranbr@eden-emu.dev>
Co-committed-by: MaranBr <maranbr@eden-emu.dev>
2025-07-14 22:30:54 +02:00
SDK-Chan
a8564a09b7
[host1x] FreeBSD: Fix random crashes due to CUDA/VAAPI check sideeffects (#64)
FreeBSD doesn't support NVDEC, CUDA, and partially supports VAAPI (mostly for firefox).
Implementing VAAPI for other use cases would be a little bit complicated so, I chose to switch it off for FreeBSD.
This PR ensures that FFmpeg will always default to software decoding on FreeBSD, but should remain the same functionalities for other OS's.
The results are slight CPU increases while decoding in software mode, but still neglectable and they don't really harm performance.

Co-authored-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/64
Co-authored-by: SDK-Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK-Chan <sdkchan@eden-emu.dev>
2025-07-14 22:30:07 +02:00
crueter
2e092010e6
[cmake] Disable bzip2 requirement for quazip (#63)
All checks were successful
eden-build / source (push) Successful in 5m57s
eden-build / linux (push) Successful in 26m40s
eden-build / windows (msvc) (push) Successful in 29m57s
eden-build / android (push) Successful in 33m55s
caused windows builds to fail

Signed-off-by: crueter <crueter@crueter.xyz>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/63
Co-authored-by: crueter <crueter@crueter.xyz>
Co-committed-by: crueter <crueter@crueter.xyz>
2025-07-14 06:10:25 +02:00
crueter
be59b4f15f
[cmake] Patch QuaZip for windows fix (#60)
All checks were successful
eden-build / source (push) Successful in 6m7s
eden-build / linux (push) Successful in 26m39s
eden-build / windows (msvc) (push) Successful in 29m54s
eden-build / android (push) Successful in 34m23s
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/60
2025-07-14 04:48:39 +02:00
Aleksandr Popovich
2be7df287a
[android] Fix crash caused by unreferenced driver (#58)
All checks were successful
eden-build / source (push) Successful in 9m44s
eden-build / linux (push) Successful in 30m48s
eden-build / android (push) Successful in 38m17s
eden-build / windows (msvc) (push) Successful in 29m9s
Previously, if the user selected a per-game driver and that driver was
deleted from the global menu, it would cause a crash, it was because of
a mismatch between FileNotFoundException and NoSuchFileException. To
avoid the inconsistency I just made the check for if a file exists or
not to be separate.

Signed-off-by: Aleksandr Popovich <popovich@eden-emu.dev>

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/58
Co-authored-by: Aleksandr Popovich <popovich@eden-emu.dev>
Co-committed-by: Aleksandr Popovich <popovich@eden-emu.dev>
2025-07-14 02:18:33 +02:00
Aleksandr Popovich
492903cc7a
[cmake] force quazip to use qt 6
All checks were successful
eden-build / source (push) Successful in 6m54s
eden-build / windows (msvc) (push) Successful in 31m59s
eden-build / android (push) Successful in 36m34s
eden-build / linux (push) Successful in 26m49s
Signed-off-by: Aleksandr Popovich <popovich@eden-emu.dev>
2025-07-13 20:00:38 -04:00
crueter
f99488fe3e
[desktop] feat: install firmware from ZIP (#52)
Closes #12

Adds a menu option to install firmware from a packed ZIP.

This PR additionally lays the groundwork to add data import/export via ZIP. In the future, a qt_common subproject should be added to handle common Qt tasks such as this.

Furthermore, to decrease dependency complexity, this also introduces CPM, a wrapper around FetchContent. In theory, this should also lay the groundwork for #8 as well.

Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/52
2025-07-14 01:29:57 +02:00
lizzie
7b23cd0df4
[dynarmic] fix userconfig casting warn (#55)
All checks were successful
eden-build / source (push) Successful in 6m55s
eden-build / linux (push) Successful in 28m46s
eden-build / windows (msvc) (push) Successful in 31m32s
eden-build / android (push) Successful in 35m15s
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/55
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-07-14 00:54:00 +02:00
Ghost
fe4f5a3860
[dynarmic] lea over mov and other stuff (#24)
Some checks failed
eden-build / source (push) Successful in 6m48s
eden-build / android (push) Failing after 19m13s
eden-build / windows (msvc) (push) Failing after 23m32s
eden-build / linux (push) Successful in 27m51s
Co-authored-by: Esther1024 <danishreyjavik@outlook.com>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/24
Co-authored-by: Ghost <>
Co-committed-by: Ghost <>
2025-07-13 23:03:26 +02:00
SDK Chan
a0a208db57
[cmake] Fix misplaced comment (#54)
All checks were successful
eden-build / source (push) Successful in 6m50s
eden-build / linux (push) Successful in 27m50s
eden-build / windows (msvc) (push) Successful in 31m55s
eden-build / android (push) Successful in 34m52s
A member of the community notified me that I misplaced a comment so, I corrected it.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/54
Co-authored-by: SDK Chan <sdkchan@eden-emu.dev>
Co-committed-by: SDK Chan <sdkchan@eden-emu.dev>
2025-07-13 20:58:04 +02:00
Ghost
c47f6615d3
[vk, opengl] Prevent GPU draw call if CBUF binding fails (cbuf0 error handling) (#2)
All checks were successful
eden-build / source (push) Successful in 6m50s
eden-build / linux (push) Successful in 28m30s
eden-build / windows (msvc) (push) Successful in 32m22s
eden-build / android (push) Successful in 34m47s
Add defensive checks to cancel draw calls early if any graphics storage buffer (CBUF) fails to bind properly.

- Modified BindGraphicsStorageBuffer to return false on invalid buffer ID.,
- ConfigureImpl (both OpenGL and Vulkan) now propagates binding failure.,
- Pipeline::Configure returns false if CBUF binding fails.,
- PrepareDraw cancels rendering if pipeline configuration fails.,

This avoids undefined GPU behavior, draw corruption, or crashes caused by uninitialized or invalid constant buffer (CBUF0) access, particularly in games with faulty or missing shader bindings.
Eden Collaborator: <edencollaborator@eden-emu.org>
Authored-by: CamilleLaVey <camillelavey@eden-emu.org>
Signed-off-by: Bix <bix@bixed.xyz>

Co-authored-by: Bix <114880614+Bixbr@users.noreply.github.com>
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2
Co-authored-by: Ghost <>
Co-committed-by: Ghost <>
2025-07-13 19:27:39 +02:00
crueter
1cd51d6545
[android] Fix key install and revert to old icon_bg
All checks were successful
eden-build / source (push) Successful in 6m52s
eden-build / linux (push) Successful in 29m5s
eden-build / windows (msvc) (push) Successful in 31m30s
eden-build / android (push) Successful in 34m32s
`312b3d4743`

Signed-off-by: crueter <crueter@eden-emu.dev>
2025-07-13 01:17:32 -04:00
lizzie
5091759a47
[vk, opengl] defer checks to topmost call (avoid unnecessary call) (#40)
All checks were successful
eden-build / source (push) Successful in 7m1s
eden-build / linux (push) Successful in 29m14s
eden-build / windows (msvc) (push) Successful in 32m8s
eden-build / android (push) Successful in 34m51s
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/40
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-07-13 03:40:48 +02:00
crueter
03351a4f8b
[frontend] refactor: extract common firmware & key functions (#38)
Extracts some firmware version/verification functions into
`frontend_common` to reduce duplicate code, especially for the new QML
frontend.

Additionally adds a check for games that are known to require firmware
(e.g. MK8DX) and warns the user if they don't have firmware installed
and attempt to run the game.

Firmware installation is to be in a separate PR.

Signed-off-by: crueter <crueter@eden-emu.dev>
Co-authored-by: Aleksandr Popovich <popovich@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/38
2025-07-13 03:39:19 +02:00
crueter
55a7797378
[desktop] add options to open root, NAND, SDMC, load, and log dirs (#53)
Signed-off-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/53
2025-07-13 03:39:01 +02:00
lizzie
d5c58342e0
[yuzu_cmd] gdbstub option (#43)
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/43
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
2025-07-13 03:25:43 +02:00
crueter
ae02310bdf
optional multimedia/webengine
All checks were successful
eden-build / source (push) Successful in 7m5s
eden-build / linux (push) Successful in 29m17s
eden-build / windows (msvc) (push) Successful in 31m21s
eden-build / android (push) Successful in 34m1s
Signed-off-by: crueter <crueter@eden-emu.dev>
2025-07-12 18:05:37 -04:00
136 changed files with 6142 additions and 6484 deletions

View file

@ -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[@]}"

View file

@ -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
View file

@ -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

View 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;
}
+

View 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 */

View 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;

View 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
+

View file

@ -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)
@ -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)
if (YUZU_USE_QT_MULTIMEDIA)
find_package(Qt6 REQUIRED COMPONENTS Multimedia)
endif()
if (UNIX AND NOT APPLE)

24
CMakeModules/CPM.cmake Normal file
View 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})

View file

@ -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}")

View file

@ -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()

View file

@ -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

View file

@ -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();
}

View file

@ -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

View file

@ -124,9 +124,9 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
EmitCondPrelude(ctx);
for (auto iter = block.begin(); iter != block.end(); ++iter) {
IR::Inst* inst = &*iter;
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, ...) \
@ -142,17 +142,18 @@ A32EmitX64::BlockDescriptor A32EmitX64::Emit(IR::Block& block) {
#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();
if (conf.very_verbose_debugging_output) {
EmitVerboseDebuggingOutput(reg_alloc);
func(reg_alloc);
}
};
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)]);

View file

@ -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());
}

View file

@ -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;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -338,3 +338,6 @@ void EmitX64::EmitVectorUnsignedSaturatedSub64(EmitContext& ctx, IR::Inst* inst)
}
} // namespace Dynarmic::Backend::X64
#undef FCODE
#undef ICODE

View file

@ -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(

View file

@ -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

View file

@ -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);

View file

@ -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"

View file

@ -11,6 +11,10 @@
namespace Dynarmic::A32 {
bool TranslatorVisitor::arm_NOP() {
return true;
}
bool TranslatorVisitor::ArmConditionPassed(Cond cond) {
return IsConditionPassed(*this, cond);
}

View file

@ -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);

View file

@ -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,

View file

@ -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) {

View file

@ -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) {

View 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,
};
}

View file

@ -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) {

View file

@ -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>}

View file

@ -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);

View file

@ -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&);

View file

@ -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))

View file

@ -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))

View file

@ -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) {

View file

@ -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;

View file

@ -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)) {

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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{
std::stable_partition(list.begin(), list.end(), [&](const auto& matcher) {
return std::set<std::string>{
"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;
}.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;

View file

@ -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"

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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) {

View file

@ -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);

View file

@ -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

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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

View file

@ -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,

View file

@ -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;
};

View file

@ -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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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)

View file

@ -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(

View file

@ -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

View file

@ -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,14 +194,15 @@ class GameAdapter(private val activity: AppCompatActivity) :
return
}
val launch: () -> Unit = {
val preferences =
PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
preferences.edit()
.putLong(
preferences.edit {
putLong(
game.keyLastPlayedTime,
System.currentTimeMillis()
)
.apply()
}
activity.lifecycleScope.launch {
withContext(Dispatchers.IO) {
@ -209,6 +220,25 @@ class GameAdapter(private val activity: AppCompatActivity) :
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 {
val action = HomeNavigationDirections.actionGlobalPerGamePropertiesFragment(game)
binding.root.findNavController().navigate(action)

View file

@ -264,8 +264,6 @@ class DriverFetcherFragment : Fragment() {
}
releases.add(release)
println(release.publishTime)
}
}

View file

@ -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
)

View file

@ -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()
}

View file

@ -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
}

View file

@ -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() {
PreferenceManager.getDefaultSharedPreferences(applicationContext).edit() {
putBoolean(Settings.PREF_SHOULD_SHOW_PRE_ALPHA_WARNING, false)
}
}
).show(supportFragmentManager, MessageDialogFragment.TAG)
}).show(supportFragmentManager, MessageDialogFragment.TAG)
}
}
@ -228,15 +224,18 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
}
private fun checkFirmware() {
if (!NativeLibrary.isFirmwareAvailable() || !NativeLibrary.isFirmwareSupported()) {
val resultCode: Int = NativeLibrary.verifyFirmware()
if (resultCode == 0) return;
val resultString: String =
resources.getStringArray(R.array.verifyFirmwareResults)[resultCode]
MessageDialogFragment.newInstance(
titleId = R.string.firmware_missing,
descriptionId = R.string.firmware_missing_description,
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,8 +282,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
super.onResume()
}
private fun setInsets() =
ViewCompat.setOnApplyWindowInsetsListener(
private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener(
binding.root
) { _: View, windowInsets: WindowInsetsCompat ->
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
@ -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 ->
val getProdKey = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
if (result != null) {
processKey(result)
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
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
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 resultCode: Int = NativeLibrary.installKeys(result.toString(), extension);
val firstTimeSetup = PreferenceManager.getDefaultSharedPreferences(applicationContext)
.getBoolean(Settings.PREF_FIRST_APP_LAUNCH, true)
if (!firstTimeSetup) {
homeViewModel.setCheckFirmware(true)
}
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 true
} else {
return
}
val resultString: String =
resources.getStringArray(R.array.installKeysResults)[resultCode]
MessageDialogFragment.newInstance(
this,
titleId = R.string.invalid_keys_error,
descriptionId = R.string.install_keys_failure_description,
helpLinkId = R.string.dumping_keys_quickstart_link
titleId = R.string.keys_failed,
descriptionString = resultString,
helpLinkId = R.string.keys_missing_help
).show(supportFragmentManager, MessageDialogFragment.TAG)
return false
}
}
return false
}
val getFirmware =
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
if (result == null) {
return@registerForActivityResult
}
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(
when (InstallResult.from(
NativeLibrary.installFileToNand(
it.toString(),
progressCallback
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)))

View file

@ -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()

View file

@ -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) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View file

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 195 KiB

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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