Compare commits

..

8 Commits

Author SHA1 Message Date
lizzie 17c5325109 i implode 2026-08-18 20:52:42 +00:00
lizzie 2876c4ec52 [hle/service/ssl] remove non-OpenSSL backends, force builds to use OpenSSL and remove passthru backend
Signed-off-by: lizzie <lizzie@eden-emu.dev>
2026-08-18 20:31:12 +00:00
lizzie 0465292a81 [docs] overview doc for newcomers (#4266)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

documents basic stuff about the emu and "hey eden is HLE" (like most yuzu forks!)

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4266
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: Maufeat <sahyno1996@gmail.com>
2026-08-18 19:00:26 +02:00
lizzie a41a98028a [hle/service] stub missing homebrew services, fix NPad/caps crashes (#4264)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

this PR adds various missing services (acc:e, acc:e:u1)
to expand homebrew compatibility
notably this also fixes NPad related crashes due to nullref

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4264
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-08-18 18:11:33 +02:00
xbzk 265c27f391 [cmake] drop invalid c98 warning suppression (#4269)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------
The -Wno-c98-compat breaks clang build on windows.
I believe it's a typo, since i couldn't find about it elsewhere.
The -Wno-c99-compat is in place.
As a bonus removed a doubled -Wno-c99-extensions right after.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4269
Reviewed-by: Samuel <lizzie@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-08-18 00:56:26 +02:00
Eden CI fb2202d69c [dist, android] Update translations from Transifex for Aug 17 (#4267)
Automatic translation update for Aug 17

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4267
2026-08-17 23:02:25 +02:00
CamilleLaVey 2000fdfb7b [vulkan, android] Initial implementation of LSFG-VK (#4263)
Pretty much self explanatory, own implementation based on LSFG-VK available with some additional reverse engineer work for the actual use of shaders inside Lossless.dll, we don't store/ bundle any tools that bypass security and self ownership: to use this feature is required to own your own copy of Lossless Scaling and I encourage to support developers behind this work.

Special thanks:

1.- THS - Original developer behind Lossless Scaling
2.- PancakeTAS - Developer behind LSFG-VK
3.- The Big Smolio The Sleeper (@gidoly)

Co-authored-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4263
2026-08-17 00:30:19 +02:00
xbzk dc95cd09ee [android] Add Samsung DeX fullscreen probes (#4245)
- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------
Shotgun attempt to fix fullscreen issue on samsung dex.

External test mapping:
bit 1, value 2: disable runtime fullscreen attempts
bit 2, value 4: force runtime user-landscape
bit 3, value 8: add legacy sticky system UI flags
bit 4, value 16: add delayed retries
bit 5, value 32: runtime orientation unspecified
bit 6, value 64: add FLAG_LAYOUT_NO_LIMITS
Good smoke masks: 0, 8, 16, 24, 4, 12, 20, 28, 32, 40, 64, 72, 88, 2.

EDIT: 8 (bit 3) did the trick. All cleaned up.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4245
Reviewed-by: Samuel <lizzie@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-15 14:21:52 +02:00
235 changed files with 22133 additions and 24718 deletions
-1
View File
@@ -19,7 +19,6 @@ log.txt
# Generated source files
src/common/scm_rev.cpp
dist/english_plurals/generated_en.ts
*-toolchain.cmake
# Project/editor files
*.swp
+6 -4
View File
@@ -81,6 +81,9 @@ cmake_dependent_option(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSV
option(ENABLE_DEBUG_TOOLS "Enable debugging tools (maxwell disassembler, SPIRV translator, etc)" OFF)
option(ENABLE_WERROR "Enable -Werror diagnostics" ON)
# Lossless Scaling frame generation. Only Android.
cmake_dependent_option(ENABLE_LSFG "Enable Lossless Scaling frame generation" ON "ANDROID" OFF)
# non-linux bundled qt are static
if (YUZU_USE_BUNDLED_QT AND (APPLE OR NOT UNIX))
set(YUZU_STATIC_BUILD ON)
@@ -169,8 +172,6 @@ if (CXX_CLANG_CL)
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++98-compat-pedantic>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c++98-compat>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c99-compat>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c98-compat>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-c99-extensions>
$<$<COMPILE_LANGUAGE:C,CXX>:/EHsc>)
# REQUIRED CPU features IN Windows-amd64
if (ARCHITECTURE_x86_64)
@@ -339,11 +340,12 @@ if (CXX_GCC OR CXX_CLANG)
endif()
elseif(ARCHITECTURE_arm64)
# See https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html
set(YUZU_BUILD_PRESET "custom" CACHE STRING "Build preset to use. One of: custom, generic, armv9, native")
set(YUZU_BUILD_PRESET "custom" CACHE STRING "Build preset to use. One of: custom, generic, optimized, armv9, native")
set(mtune generic)
if (${YUZU_BUILD_PRESET} STREQUAL "generic")
set(march armv8-a)
elseif (${YUZU_BUILD_PRESET} STREQUAL "optimized")
set(march armv8.2-a+lse+rcpc)
elseif (${YUZU_BUILD_PRESET} STREQUAL "armv9")
set(march armv9-a)
endif()
-18
View File
@@ -1,18 +0,0 @@
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
set(CROSS_TARGET "powerpc64le" CACHE STRING "Cross-compilation target (aarch64, powerpc64le, riscv64, etc)")
set(CMAKE_SYSROOT /usr/${CROSS_TARGET}-unknown-linux-gnu)
set(CMAKE_C_COMPILER ${CROSS_TARGET}-unknown-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_TARGET}-unknown-linux-gnu-g++)
# search programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH /usr/${CROSS_TARGET}-unknown-linux-gnu)
+17 -2
View File
@@ -15,8 +15,9 @@
<br>
</h1>
<h4 align="center"><b>Eden</b> is a free and opensource (FOSS) Switch 1 emulator, derived from Yuzu and Sudachi - started by developer Camille LaVey.
It's written in C++ with portability in mind, with builds for Windows, Linux, macOS, Android, FreeBSD and more.
<h4 align="center"><b>Eden</b> is a free and opensource (FOSS) Switch 1 emulator started by developer Camille LaVey.
<br>
Written in C++, with builds for Windows, Linux, macOS, Android, FreeBSD and more.
</h4>
<p align="center">
@@ -73,3 +74,17 @@ Save us some bandwidth! We have [mirrors available](./docs/user/ThirdParty.md#mi
## License
Eden is licensed under the GPLv3 (or any later version). Refer to the [LICENSE.txt](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/LICENSE.txt) file.
## Special thanks
Super special thanks to Cloudflare for preventing the git server from blowing up.
- Yuzu
- Ryujinx
- Sudachi
- Citron
- Torzu
- Suyu
- Ryubing
And everyone who continues or had contributed to the project! <3
+540 -531
View File
File diff suppressed because it is too large Load Diff
+538 -529
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+537 -529
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+533 -525
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+536 -527
View File
File diff suppressed because it is too large Load Diff
+599 -591
View File
File diff suppressed because it is too large Load Diff
+541 -532
View File
File diff suppressed because it is too large Load Diff
+535 -528
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+569 -553
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+539 -531
View File
File diff suppressed because it is too large Load Diff
+539 -532
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+534 -525
View File
File diff suppressed because it is too large Load Diff
+556 -541
View File
File diff suppressed because it is too large Load Diff
+535 -527
View File
File diff suppressed because it is too large Load Diff
+1 -137
View File
@@ -2,122 +2,7 @@
General guide for cross compiling.
## Gentoo
Gentoo's cross-compilation setup is relatively easy, provided you're already familiar with portage.
### Crossdev
First, emerge crossdev via `sudo emerge -a sys-devel/crossdev`.
Now, set up the environment depending on the target architecture; e.g.
```sh
sudo crossdev powerpc64le
sudo crossdev aarch64
```
### QEMU
Installing a qemu user setup is recommended for testing. To do so, you will need the relevant USE flags:
```sh
app-emulation/qemu static-user qemu_user_targets_ppc64le qemu_user_targets_aarch64
```
Note that to use cross-emerged libraries, you will need to tell qemu where the sysroot is. You can do this with an alias:
```sh
alias qemu-ppc64le="qemu-ppc64le -L /usr/powerpc64le-unknown-linux-gnu"
alias qemu-aarch64="qemu-aarch64 -L /usr/aarch64-unknown-linux-gnu"
```
### Dependencies
Some packages have broken USE flags on other architectures; you'll also need to set up python targets. In `/usr/<target>-unknown-linux-gnu/etc/portage/package.use`:
```sh
>=net-misc/curl-8.16.0-r1 ssl
*/* PYTHON_TARGETS: python3_13 PYTHON_SINGLE_TARGET: python3_13
*/* pam
sys-apps/util-linux pam su
app-shells/bash -readline
>=dev-libs/libpcre2-10.47 unicode
>=x11-libs/libxkbcommon-1.12.3 X
>=sys-libs/zlib-1.3.1-r1 minizip
>=app-alternatives/gpg-1-r3 ssl
>=app-crypt/gnupg-2.5.13-r2 ssl
dev-libs/* -introspection
media-libs/harfbuzz -introspection
dev-libs/quazip -qt5 qt6
```
Dependencies should be about the same [as normal Gentoo](./Deps.md), but removing gamemode and renderdoc is recommended. Keep in mind that when emerging, you want to use `emerge-<target>-unknown-linux-gnu`, e.g. `emerge-powerpc64le-unknown-linux-gnu`.
Enable GURU in the cross environment (as root):
```sh
mkdir -p /usr/powerpc64le-unknown-linux-gnu/etc/portage/repos.conf
cat << EOF > /usr/powerpc64le-unknown-linux-gnu/etc/portage/repos.conf/guru.conf
[guru]
location = /var/db/repos/guru
auto-sync = no
priority = 1
EOF
```
Now emerge your dependencies:
```sh
sudo emerge-powerpc64le-unknown-linux-gnu -aU app-arch/lz4 app-arch/zstd app-arch/unzip \
dev-libs/libfmt dev-libs/libusb dev-libs/mcl dev-libs/sirit dev-libs/oaknut \
dev-libs/unordered_dense dev-libs/boost dev-libs/openssl dev-libs/discord-rpc \
dev-util/spirv-tools dev-util/spirv-headers dev-util/vulkan-headers \
dev-util/vulkan-utility-libraries dev-util/glslang \
media-libs/libva media-libs/opus media-video/ffmpeg \
media-libs/VulkanMemoryAllocator media-libs/libsdl2 media-libs/cubeb \
net-libs/enet net-libs/mbedtls \
sys-libs/zlib \
dev-cpp/nlohmann_json dev-cpp/simpleini dev-cpp/cpp-httplib dev-cpp/cpp-jwt dev-cpp/catch \
net-wireless/wireless-tools \
dev-qt/qtbase:6 dev-libs/quazip \
virtual/pkgconfig
```
### Building
A toolchain is provided in `CMakeModules/GentooCross.cmake`. To use it:
```sh
cmake -S . -B build/ppc64 -DCMAKE_TOOLCHAIN_FILE=CMakeModules/GentooCross.cmake -G Ninja -DCROSS_TARGET=powerpc64le -DENABLE_OPENGL=OFF
```
Now build as normal:
```sh
cmake --build build/ppc64 -j$(nproc)
```
### Alternatively
Only emerge the absolute necessities:
```sh
sudo emerge-powerpc64le-unknown-linux-gnu -aU media-video/ffmpeg media-libs/libsdl2 dev-qt/qtbase:6
```
Then set `YUZU_USE_CPM=ON`:
```sh
cmake -S . -B build/ppc64 -DCMAKE_TOOLCHAIN_FILE=CMakeModules/GentooCross.cmake -G Ninja -DCROSS_TARGET=powerpc64le -DENABLE_OPENGL=OFF -DYUZU_USE_CPM=ON
```
## ARM64
### Debian ARM64
## Debian ARM64
A painless guide for cross compilation (or to test NCE) from a x86_64 system without polluting your main.
@@ -203,24 +88,3 @@ And finally, run the compiled executable with QEMU!
```sh
qemu-aarch64 build/aarch64/bin/eden
```
## PowerPC
This is a guide for FreeBSD users mainly.
Now you got a PowerPC sysroot - quickly decompress it somewhere, say `/home/user/opt/powerpc64le`. Create a toolchain file, for example `powerpc64le-toolchain.cmake`; always [consult the manual](https://man.freebsd.org/cgi/man.cgi?query=cmake-toolchains&sektion=7&manpath=FreeBSD+13.2-RELEASE+and+Ports).
There is a script to automatically do all of this under `./tools/setup-cross-sysroot.sh`.
Remember to add `-mabi=elfv1` to `CFLAGS`/`CXXFLAGS` otherwise the program will crash.
Specify:
- `YUZU_USE_CPM`: Set this to `ON` so packages can be found and built if your sysroot doesn't have them.
- `YUZU_USE_EXTERNAL_FFMPEG`: Set this to `ON` as well.
Then run using a program such as QEMU to emulate userland syscalls:
```sh
cmake --build build-ppc64-pc-freebsd -t dynarmic_tests -- -j8 && qemu-ppc64-static -L $HOME/opt/ppc64-freebsd/sysroot ./build-ppc64-pc-freebsd/bin/dynarmic_tests
```
+47
View File
@@ -0,0 +1,47 @@
# Design Overview
Modern game consoles require heavy power to be emulated appropriatedly. This is why the emulator uses an approach known as HLE (High-Level-Emulation), in a nuthsell: Instead of accurately emulating every subsystem that forms part of a component, emulate the resulting visible I/O interface instead.
For example, take a disk write, instead of emulating a proper SD card we instead use the C++ standard library for I/O. Additionally we use the abstractions provided by the `fs` service to "lie" to programs about certain SD card properties. Notably this includes making up sizes for the fake SD card, giving "realistic" values or expected outputs for a given card, and so on. And instead of writing to an actual SD card, the emulator simply writes to a file.
This also means grand part of the emulator consists of just re-implementing firmware but using HLE primitives; for example audio doesn't go to an emulated audio device, but rather gets processed on the fly by a dedicated service and then passed to SDL3/cubeb/etc.
As such, many of the systems implemented are not 100% accurate to the original software, but they're "good enough" to pass as being so. While we do strive to maintain high compatibility (especially with homebrew), there are realistic limitations to these approaches.
No formal fuzzing or formal verification has been done on the emulator as a whole, this means there may be hundreds of bugs hiding in each subsystem. As such, output may also not correctly match due to those aforementioned issues.
## src/android/
Entire Android frontend, written mostly in Kotlin and generally having asinine hacks (thanks Android) due to the particularly horrific (and particular way) to do things.
## src/audio_core/
Handles everything related to audio, this is where most of the filtering and processing occurs (CPU intensive task!).
## src/common/
The [common](../src/common) folder contains just your basic pollyfills for whatever missing functionality. We heavily encourage new PRs to make use of one of the dependencies, or the standard C++ library. Minimizing the amount of things we reinvent the wheel for is always a good thing.
## src/core/
The [core folder](../src/core) is the main heart of the emulator, while we don't officially support having other frontends out of the box (RetroArch, for example); any prospective developer can reuse this library (compiled as one by CMake) to stitch up their own RetroArch core, for example.
## src/dynarmic/
See [Dynarmic](./dynarmic).
## src/hid_core/
Input, joysticks, controllers and everything related to input devices.
## src/shader_recompiler/
Dedicated shader recompiler to translate Maxwell assembly code to either SPIR-V, GLSL or GLASM.
## src/video_core/
Most of the things here have their own dedicated section. In short this is basically the entire Tegra NVIDIA Maxwell GPU emulation. Additionally it includes some [extra effects](../src/video_core/host_ahders) to emulate MSAA, D24 copies or as polyfill.
Available backends are: Null, Vulkan, and OpenGL.
See [NVIDIA GPU](./NvidiaGpu.md).
+1
View File
@@ -20,6 +20,7 @@ This contains documentation created by developers. This contains build instructi
- **[Driver Bugs](./DriverBugs.md)**
- **[Building Older Commits](./build/OlderCommits.md)**
- Subsystems:
- **[Design Overview](./DesignOverview.md)**
- **[Dynarmic](./dynarmic/README.md)**
- **[HOS Kernel](./HosKernel.md)**
- **[Settings](./Settings.md)**
-8
View File
@@ -1,8 +0,0 @@
# PowerPC 64 backend
The ppc64 backend currently only supports the little endian variant, with big endian support being experimental for the time being. Additionally only A32 is supported (for now).
- Flag handling: Flags are emulated via software, while there may be some funny tricks with the CTR, I'd rather not bother - plus it's widely known that those instructions are not nice on real metal - so I would rather take the i-cache cost.
- 128-bit atomics: No 128-bit atomic support is provided, this may cause wrong or erroneous execution in some contexts.
To handle endianess differences all 16/32/64-bit loads and stores to the "emulated memory" are byteswapped beforehand.
-2
View File
@@ -35,7 +35,6 @@ There are no plans to support v1 or v2.
* x86-64
* AArch64
* PowerPC 64 (POWER 4 and up)
There are no plans to support any 32-bit architecture.
@@ -51,7 +50,6 @@ Documentation
-------------
Design documentation can be found at [./Design.md](./Design.md).
PowerPC design documentation can be found at [./PowerPC](./PowerPC.md).
Usage Example
+38
View File
@@ -77,3 +77,41 @@ Use this guide to get starting using the Eden emulator.
8. Double-Click the main window to add the folder containing your games.
9. Go to *Emulation > Configure > Input* and set up your controller. Click **OK** to close the dialog window.
10. Double-Click a game to run it.
## macOS
Current macOS support is still experimental and very reliant on MoltenVK developments, plans have shifted to properly provide support for KosmicKrisp and similar new GPU endeavours, but macOS users still are bound to MoltenVK itself.
Users of macOS may wish to use [Asahi Linux](https://wiki.gentoo.org/wiki/Project:Asahi/Guide) for the rising KosmicKrisp support.
As of writing, neither macOS nor Asahi has support for NCE; additionally Asahi has extraneous paging bugs with fastmem.
### Allowing Eden to Run on MacOS
Use this guide when you need to allow Eden to run on a Mac system, but are being blocked by Apple Security policy.
**Click [Here](https://evilperson1337.notion.site/Allowing-Eden-to-Run-on-MacOS-2b057c2edaf681fea63dc81027efeffd) for a version of this guide with images & visual elements.**
---
##### Pre-Requisites
- Permissions to modify settings in MacOS
---
#### Why am I Seeing This?
Recent versions of MacOS (Catalina & newer) introduced the **Gatekeeper** security functionality, requiring software to be signed by Apple or a trusted (aka - paying) developer. If the signature isn't on the list of trusted ones, it will stop the program from executing and display the message above.
---
#### Steps
1. Open the *System Settings* panel.
2. Navigate to *Privacy & Security*.
3. Scroll down and observe the following message under the **Security** settings.
4. Select **Open Anyway** to tell your Mac that you trust the application.
5. You will now get another window appearing to verify you want to open Eden. Select **Open Anyway**.
6. You will be prompted for your password to authorize the request. Enter the credentials of an account that has permission to modify settings and press **OK**.
7. Eden will now open and any subsequent launches of the program will not prompt this.
+3 -1
View File
@@ -10,13 +10,15 @@ A copy of this handbook is [available online](https://git.eden-emu.dev/eden-emu/
- **[The Basics](Basics.md)**
- **[Quickstart](./QuickStart.md)**
- **[Windows](./QuickStart.md#windows)**
- **[Steamdeck](./QuickStart.md#steamdeck)**
- **[macOS](./QuickStart.md#macos)**
- **[Settings](./Settings.md)**
- **[Controllers](./Controllers.md)**
- **[Controller profiles](./Controllers.md#configuring-controller-profiles)**
- **[Audio](Audio.md)**
- **[Graphics](Graphics.md)**
- **[Installing Mods](./Mods.md)**
- **[Run On macOS](./RunOnMacOS.md)**
- **[Data, Savefiles and Storage](Storage.md)**
- **[Orphaned Profiles](Orphaned.md)**
- **[Troubleshooting](./Troubleshoot.md)**
-37
View File
@@ -1,37 +0,0 @@
# User Handbook - Run on macOS
Current macOS support is still experimental and very reliant on MoltenVK developments, plans have shifted to properly provide support for KosmicKrisp and similar new GPU endeavours, but macOS users still are bound to MoltenVK itself.
Users of macOS may wish to use [Asahi Linux](https://wiki.gentoo.org/wiki/Project:Asahi/Guide) for the rising KosmicKrisp support.
As of writing, neither macOS nor Asahi has support for NCE; additionally Asahi has extraneous paging bugs with fastmem.
## Allowing Eden to Run on MacOS
Use this guide when you need to allow Eden to run on a Mac system, but are being blocked by Apple Security policy.
**Click [Here](https://evilperson1337.notion.site/Allowing-Eden-to-Run-on-MacOS-2b057c2edaf681fea63dc81027efeffd) for a version of this guide with images & visual elements.**
---
#### Pre-Requisites
- Permissions to modify settings in MacOS
---
### Why am I Seeing This?
Recent versions of MacOS (Catalina & newer) introduced the **Gatekeeper** security functionality, requiring software to be signed by Apple or a trusted (aka - paying) developer. If the signature isn't on the list of trusted ones, it will stop the program from executing and display the message above.
---
### Steps
1. Open the *System Settings* panel.
2. Navigate to *Privacy & Security*.
3. Scroll down and observe the following message under the **Security** settings.
4. Select **Open Anyway** to tell your Mac that you trust the application.
5. You will now get another window appearing to verify you want to open Eden. Select **Open Anyway**.
6. You will be prompted for your password to authorize the request. Enter the credentials of an account that has permission to modify settings and press **OK**.
7. Eden will now open and any subsequent launches of the program will not prompt this.
-5
View File
@@ -254,11 +254,6 @@ endif()
# TZDB (Time Zone Database)
add_subdirectory(nx_tzdb)
# PowerPC emitter
if (ARCHITECTURE_powerpc64)
add_subdirectory(powah)
endif()
add_library(tz tz/tz/tz.cpp)
target_include_directories(tz PUBLIC ./tz)
+2 -2
View File
@@ -166,7 +166,7 @@ detect_architecture_symbols(
"_M_MRX000")
detect_architecture_symbols(
ARCH powerpc64
ARCH ppc64
SYMBOLS
"__ppc64__"
"__powerpc64__"
@@ -174,7 +174,7 @@ detect_architecture_symbols(
"_M_PPC64")
detect_architecture_symbols(
ARCH powerpc
ARCH ppc
SYMBOLS
"__ppc__"
"__ppc"
-10
View File
@@ -1,10 +0,0 @@
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
add_library(powah INTERFACE)
target_include_directories(powah INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_options(powah INTERFACE -Wno-unused-parameter)
add_executable(powah_tests tests.cpp)
create_target_directory_groups(powah_tests)
target_link_libraries(powah_tests PRIVATE Catch2::Catch2WithMain)
-145
View File
@@ -1,145 +0,0 @@
vabsdub,VX,04,1027
vabsduh,VX,04,1091
vabsduw,VX,04,1155
vaddcuw,VX,04,384
vaddfp,VX,04,10
vaddsbs,VX,04,768
vaddshs,VX,04,832
vaddsws,VX,04,896
vaddubm,VX,04,0
vaddubs,VX,04,512
vadduhm,VX,04,64
vadduhs,VX,04,576
vadduwm,VX,04,128
vadduws,VX,04,640
vand,VX,04,1028
vandc,VX,04,1092
vavgsb,VX,04,1282
vavgsh,VX,04,1346
vavgsw,VX,04,1410
vavgub,VX,04,1026
vavguh,VX,04,1090
vavguw,VX,04,1154
vcfsx,VDU,04842
vcfux,VDU,04778
vcmpbfp,VXR,04,966
vcmpeqfp,VXR,04,198
vcmpequb,VXR,04,6
vcmpequh,VXR,04,70
vcmpequw,VXR,04,134
vcmpgefp,VXR,04,454
vcmpgtfp,VXR,04,710
vcmpgtsb,VXR,04,774
vcmpgtsh,VXR,04,838
vcmpgtsw,VXR,04,902
vcmpgtub,VXR,04,518
vcmpgtuh,VXR,04,582
vcmpgtuw,VXR,04,646
vctsxs,VDU,04970
vctuxs,VDU,04906
vexptefp,VY,04,394
vlogefp,VY,04,458
vmaddfp,VXC,46
vmaxfp,VX,04,1034
vmaxsb,VX,04,258
vmaxsh,VX,04,322
vmaxsw,VX,04,386
vmaxub,VX,04,2
vmaxuh,VX,04,66
vmaxuw,VX,04,130
vmhaddshs,VXC,32
vmhraddshs,VXC,33
vminfp,VX,04,1098
vminsb,VX,04,770
vminsh,VX,04,834
vminsw,VX,04,898
vminub,VX,04,514
vminuh,VX,04,578
vminuw,VX,04,642
vmladduhm,VXC,34
vmrghb,VX,04,12
vmrghh,VX,04,76
vmrghw,VX,04,140
vmrglb,VX,04,268
vmrglh,VX,04,332
vmrglw,VX,04,396
vmsummbm,VXC,37
vmsumshm,VXC,40
vmsumshs,VXC,41
vmsumubm,VXC,36
vmsumuhm,VXC,38
vmsumuhs,VXC,39
vmulesb,VX,04,776
vmulesh,VX,04,840
vmuleub,VX,04,520
vmuleuh,VX,04,584
vmulosb,VX,04,264
vmulosh,VX,04,328
vmuloub,VX,04,8
vmulouh,VX,04,72
vnmsubfp,VXC,47
vnor,VX,04,1284
vor,VX,04,1156
vperm,VXC,43
vpkpx,VX,04,782
vpkshss,VX,04,398
vpkshus,VX,04,270
vpkswss,VX,04,462
vpkswus,VX,04,334
vpkuhum,VX,04,14
vpkuhus,VX,04,142
vpkuwum,VX,04,78
vpkuwus,VX,04,206
vrefp,VY,04,266
vrfim,VY,04,714
vrfin,VY,04,522
vrfip,VY,04,650
vrfiz,VY,04,586
vrlb,VX,04,4
vrlh,VX,04,68
vrlw,VX,04,132
vrsqrtefp,VY,04,330
vsel,VXC,42
vsl,VX,04,452
vslb,VX,04,260
vsldoi,VX,04,/ SH 44
vslh,VX,04,324
vslo,VX,04,1036
vslw,VX,04,388
vspltb,VU,04,524
vsplth,VU,04,588
vspltisb,VS,04,780
vspltish,VS,04,844
vspltisw,VS,04,908
vspltw,VSU,04,652
vsr,VX,04,708
vsrab,VX,04,772
vsrah,VX,04,836
vsraw,VX,04,900
vsrb,VX,04,516
vsrh,VX,04,580
vsro,VX,04,1100
vsrw,VX,04,644
vsubcuw,VX,04,1408
vsubfp,VX,04,74
vsubsbs,VX,04,1792
vsubshs,VX,04,1856
vsubsws,VX,04,1920
vsububm,VX,04,1024
vsububs,VX,04,1536
vsubuhm,VX,04,1088
vsubuhs,VX,04,1600
vsubuwm,VX,04,1152
vsubuws,VX,04,1664
vsumsws,VX,04,1928
vsum2sws,VX,04,1672
vsum4sbs,VX,04,1800
vsum4shs,VX,04,1608
vsum4ubs,VX,04,1544
vupkhpx,VY,04,846
vupkhsb,VY,04,526
vupkhsh,VY,04,590
vupklpx,VY,04,974
vupklsb,VY,04,654
vupklsh,VY,04,718
vxor,VX,04,122
-6
View File
@@ -1,6 +0,0 @@
#!/bin/sh
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
$CC data2code.c -o data2code && ./data2code data.txt >powah_gen_base.hpp
$CC --target=powerpc64le test.S -c -o test && objdump -SC test
-222
View File
@@ -1,222 +0,0 @@
add[o][.],Add,XO,31,266
addc[o][.],Add Carrying,XO,31,10
adde[o][.],Add Extended,XO,31,138
addi,Add Immediate,D,14,
addic,Add Immediate Carrying,D,12,
addic.,Add Immediate Carrying and Record,D,13,
addis,Add Immediate Shifted,D,15,
addme[o][.],Add to Minus One Extended,XO,31,234
addze[o][.],Add to Zero Extended,XO,31,202
and[.],AND,X,31,28
andc[.],AND with Complement,X,31,60
andi.,AND Immediate,D,28,
andis.,AND Immediate Shifted,D,29,
b[l][a],Branch,I,18,
bc[l][a],Branch Conditional,B,16,
bcctr[l],Branch Conditional to Count Register,XL,19,528
bclr[l],Branch Conditional Link Register,XL,19,16
cmp,Compare,X,31,0
cmpi,Compare Immediate,D,11,
cmpl,Compare Logical,X,31,32
cmpli,Compare Logical Immediate,D,10,
cntlzd,Count Leading Zeros Doubleword,X,31,58
cntlzw[.],Count Leading Zeros Word,X,31,26
crand,Condition Register AND,XL,19,257
crandc,Condition Register AND with Complement,XL,19,129
creqv,Condition Register Equivalent,XL,19,289
crnand,Condition Register NAND,XL,19,225
crnor,Condition Register NOR,XL,19,33
cror,Condition Register OR,XL,19,449
crorc,Condition Register OR with Complement,XL,19,417
crxor,Condition Register XOR,XL,19,193
dcbf,Data Cache Block Flush,X,31,86
dcbi,Data Cache Block Invalidate,X,31,470
dcbst,Data Cache Block Store,X,31,54
dcbt,Data Cache Block Touch,X,31,278
dcbtst,Data Cache Block Touch for Store,X,31,246
dcbz,Data Cache Block Set to Zero,X,31,1014
divd,Divide Doubleword,XO,31,489
divdu,Divide Doubleword Unsigned,XO,31,457
divw[o][.],Divide Word,XO,31,491
divwu[o][.],Divide Word Unsigned,XO,31,459
eciwx,External Control in Word Indexed (opt.),X,31,310
ecowx,External Control out Word Indexed (opt.),X,31,438
eieio,Enforce In-order Execution of I/O,X,31,854
eqv[.],Equivalent,X,31,284
extsb[.],Extend Sign Byte,X,31,954
extsh[.],Extend Sign Halfword,XO,31,922
extsw,Extend Sign Word,X,31,986
fabs[.],Floating Absolute Value,X,63,264
fadd[.],Floating Add,A,63,21
fadds[.],Floating Add Single,A,59,21
fcfid,Floating Convert from Integer Doubleword,X,63,846
fcmpo,Floating Compare Ordered,X,63,32
fcmpu,Floating Compare Unordered,XL,63,0
fctid,Floating Convert to Integer Doubleword,X,63,814
fctidz,Floating Convert to Integer Doubleword with Round Toward Zero,X,63,815
fctiw[.],Floating Convert to Integer Word,X,63,14
fctiwz[.],Floating Convert to Integer Word with Round to Zero,XL,63,15
fdiv[.],Floating Divide,A,63,18
fdivs[.],Floating Divide Single,A,59,18
fmadd[.],Floating Multiply-Add,A,63,29
fmadds[.],Floating Multiply-Add Single,A,59,29
fmr[.],Floating Move Register,X,63,72
fmsub[.],Floating Multiply-Subtract,A,63,28
fmsubs[.],Floating Multiply-Subtract Single,A,59,28
fmul[.],Floating Multiply,A,63,25
fmuls[.],Floating Multiply Single,A,59,25
fnabs[.],Floating Negative Absolute Value,X,63,136
fneg[.],Floating Negate,X,63,40
fnmadd[.],Floating Negative Multiply-Add,A,63,31
fnmadds[.],Floating Negative Multiply-Add Single,A,59,31
fnmsub[.],Floating Negative Multiply-Subtract,A,63,30
fnmsubs[.],Floating Negative Multiply-Subtract Single,A,59,30
fres[.],Floating Reciprocal Estimate Single (optional),A,59,24
frsp[.],Floating Round to Single Precision,X,63,12
frsqrte[.],Floating Reciprocal Square Root Estimate (optional),A,63,26
fsel[.],Floating-Point Select (optional),A,63,23
fsub[.],Floating Subtract,A,63,20
fsubs[.],Floating Subtract Single,A,59,20
icbi,Instruction Cache Block Invalidate,X,31,982
isync,Instruction Synchronize,X,19,150
lbz,Load Byte and Zero,D,34,
lbzu,Load Byte and Zero with Update,D,35,
lbzux,Load Byte and Zero with Update Indexed,X,31,119
lbzx,Load Byte and Zero Indexed,X,31,87
ld,Load Doubleword,DS,58,0
ldarx,Load Doubleword and Reserve Indexed,X,31,84
ldu,Load Doubleword with Update,DS,58,1
ldux,Load Doubleword with Update Indexed,X,31,53
ldx,Load Doubleword Indexed,X,31,21
lfd,Load Floating-Point Double,D,50,
lfdu,Load Floating-Point Double with Update,D,51,
lfdux,Load Floating-Point Double with Update Indexed,X,31,631
lfdx,Load Floating-Point Double Indexed,X,31,599
lfs,Load Floating-Point Single,D,48,
lfsu,Load Floating-Point Single with Update,D,49,
lfsux,Load Floating-Point Single with Update Indexed,X,31,567
lfsx,Load Floating-Point Single Indexed,X,31,535
lha,Load Half Algebraic,D,42,
lhau,Load Half Algebraic with Update,D,43,
lhaux,Load Half Algebraic with Update Indexed,X,31,375
lhax,Load Half Algebraic Indexed,X,31,343
lhbrx,Load Half Byte-Reversed Indexed,X,31,790
lhz,Load Half and Zero,D,40,
lhzu,Load Half and Zero with Update,D,41,
lhzux,Load Half and Zero with Update Indexed,X,31,331
lhzx,Load Half and Zero Indexed,X,31,279
lmw,Load Multiple Word,D,46,
lswi,Load String Word Immediate,X,31,597
lswx,Load String Word Indexed,X,31,533
lwa,Load Word Algebraic,DS,58,2
lwarx,Load Word and Reserve Indexed,X,31,20
lwaux,Load Word Algebraic with Update Indexed,X,31,373
lwax,Load Word Algebraic Indexed,X,31,341
lwbrx,Load Word Byte-Reversed Indexed,X,31,534
lwz,Load Word and Zero,D,32,
lwzu,Load Word with Zero Update,D,33,
lwzux,Load Word and Zero with Update Indexed,X,31,55
lwzx,Load Word and Zero Indexed,X,31,23
mcrf,Move Condition Register Field,XL,19,0
mcrfs,Move to Condition Register from FPSCR,X,63,64
mcrxr,Move to Condition Register from XER,X,31,512
mfcr,Move from Condition Register,X,31,19
mffs[.],Move from FPSCR,X,63,583
mfmsr,Move from Machine State Register,X,31,83
mfspr,Move from Special-Purpose Register,X,31,339
mfsr,Move from Segment Register,X,31,595
mfsrin,Move from Segment Register Indirect,X,31,659
mtcrf,Move to Condition Register Fields,XFX,31,144
mtfsb0[.],Move to FPSCR Bit 0,X,63,70
mtfsb1[.],Move to FPSCR Bit 1,X,63,38
mtfsf[.],Move to FPSCR Fields,XFL,63,711
mtfsfi[.],Move to FPSCR Field Immediate,X,63,134
mtmsr,Move to Machine State Register,X,31,146
mtspr,Move to Special-Purpose Register,X,31,467
mtsr,Move to Segment Register,X,31,210
mtsrin,Move to Segment Register Indirect,X,31,242
mulhd,Multiply High Doubleword,XO,31,73
mulhdu,Multiply High Doubleword Unsigned,XO,31,9
mulhw[.],Multiply High Word,XO,31,75
mulhwu[.],Multiply High Word Unsigned,XO,31,11
mulld,Multiply Low Doubleword,XO,31,233
mulli,Multiply Low Immediate,D,07,
mullw[o][.],Multiply Low Word,XO,31,235
nand[.],NAND,X,31,476
neg[o][.],Negate,XO,31,104
nor[.],NOR,X,31,124
or[.],OR,X,31,444
orc[.],OR with Complement,X,31,412
ori,OR Immediate,D,24,
oris,OR Immediate Shifted,D,25,
rfi,Return from Interrupt,X,19,50
rldcl,Rotate Left Doubleword then Clear Left,MDS,30,8
rldcr,Rotate Left Doubleword then Clear Right,MDS,30,9
rldic,Rotate Left Doubleword Immediate then Clear,MD,30,2
rldicl,Rotate Left Doubleword Immediate then Clear Left,MD,30,0
rldicr,Rotate Left Doubleword Immediate then Clear Right,MD,30,1
rldimi,Rotate Left Doubleword Immediate then Mask Insert,MD,30,3
rlwimi[.],Rotate Left Word Immediate then Mask Insert,M,20,
rlwinm[.],Rotate Left Word Immediate then AND with Mask,M,21,
rlwnm[.],Rotate Left Word then AND with Mask,M,23,
sc,System Call,SC,17,
si,Subtract Immediate,D,12,
si.,Subtract Immediate and Record,D,13,
slbia,SLB Invalidate All,X,31,498
slbie,SLB Invalidate Entry,X,31,434
sld,Shift Left Doubleword,X,31,27
slw[.],Shift Left Word,X,31,24
srad,Shift Right Algebraic Doubleword,X,31,794
sradi,Shift Right Algebraic Doubleword Immediate,XS,31,413
srd,Shift Right Doubleword,X,31,539
sraw[.],Shift Right Algebraic Word,X,31,792
srawi[.],Shift Right Algebraic Word Immediate,X,31,824
srw[.],Shift Right Word,X,31,536
stb,Store Byte,D,38,
stbu,Store Byte with Update,D,39,
stbux,Store Byte with Update Indexed,X,31,247
stbx,Store Byte Indexed,X,31,215
std,Store Doubleword,DS,62,0
stdcx,Store Doubleword Conditional Indexed,X,31,214
stdu,Store Doubleword with Update,DS,62,1
stdux,Store Doubleword with Update Indexed,X,31,181
stdx,Store Doubleword Indexed,X,31,149
stfd,Store Floating-Point Double,D,54,
stfdu,Store Floating-Point Double with Update,D,55,
stfdux,Store Floating-Point Double with Update Indexed,X,31,759
stfdx,Store Floating-Point Double Indexed,X,31,727
stfiwx,Store Floating-Point as Integer Word Indexed (optional),X,31,983
stfs,Store Floating-Point Single,D,52,
stfsu,Store Floating-Point Single with Update,D,53,
stfsux,Store Floating-Point Single with Update Indexed,X,31,695
stfsx,Store Floating-Point Single Indexed,X,31,663
sth,Store Half,D,44,
sthbrx,Store Half Byte-Reverse Indexed,X,31,918
sthu,Store Half with Update,D,45,
sthux,Store Half with Update Indexed,X,31,439
sthx,Store Half Indexed,X,31,407
stmw,Store Multiple Word,D,47,
stswi,Store String Word Immediate,X,31,725
stswx,Store String Word Indexed,X,31,661
stw,Store,D,36,
stwbrx,Store Word Byte-Reversed Indexed,X,31,662
stwcx.,Store Word Conditional Indexed,X,31,150
stwu,Store Word with Update,D,37,
stwux,Store Word with Update Indexed,X,31,183
stwx,Store Word Indexed,X,31,151
subf[o][.],Subtract from,XO,31,40
subfc[o][.],Subtract from Carrying,XO,31,08
subfe[o][.],Subtract from Extended,XO,31,136
subfic,Subtract from Immediate Carrying,D,08,
subfme[o][.],Subtract from Minus One Extended,XO,31,232
subfze[o][.],Subtract from Zero Extended,XO,31,200
sync,Synchronize,X,31,598
td,Trap Doubleword,X,31,68
tdi,Trap Doubleword Immediate,D,2,
tlbie,Translation Look-aside Buffer Invalidate Entry (optional),X,31,306
tlbsync,Translation Look-aside Buffer Synchronize (optional),X,31,566
tw,Trap Word,X,31,04
twi,Trap Word Immediate,D,03,
xor[.],XOR,X,31,316
xori,XOR Immediate,D,26,
xoris,XOR Immediate Shift,D,27,
-343
View File
@@ -1,343 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <ctype.h>
#include <string.h>
int main(int argc, char *argv[]) {
printf(
"// this file is autogenerated DO NOT MODIFY\n"
"#pragma once\n"
);
FILE* fp = fopen(argv[1], "rt");
if (fp) {
char line[80];
while (fgets(line, sizeof line, fp) != NULL) {
bool with_o = strstr(line, "[o]"), with_d = strstr(line, "[.]");
char* p = strchr(line, '\n'), *name = strchr(line, ','), *mem = line;
if (p) *p = '\0';
if (name) {
*name++ = '\0';
char *form = strchr(name, ',');
if (form) {
*form++ = '\0';
char *opc = strchr(form, ',');
if (opc) {
*opc++ = '\0';
char *sec = strchr(opc, ',');
if (sec) {
struct b_info { const char *s; int o; int p; } infos[] = {
{"",1,0},
{"LT",1,12},
{"LE",2,4},
{"NG",2,4},
{"EQ",3,12},
{"GE",1,4},
{"NL",1,4},
{"GT",2,12},
{"NE",3,4},
{"SO",4,12},
{"UN",4,12},
{"NS",4,4},
{"NU",4,4},
};
#define OP_EXT ((i_opcode << 26) | (i_extopc << 1))
if (strchr(mem, '[') != NULL) *strchr(mem, '[') = '\0';
if (strchr(mem, '.') != NULL) *strchr(mem, '.') = '_';
*sec++ = '\0';
for (int i = 0; i < strlen(mem); ++i)
mem[i] = toupper(mem[i]);
int i_opcode = atoi(opc);
int i_extopc = atoi(sec);
//printf("// %s\n", mem);
if (!strcmp(form, "XO")) {
if (!strcmp(mem, "EXTSH")) {
printf(
"void %s(GPR const rt, GPR const ra) {"
" emit_%s(0x%08x, rt, ra, R0, false, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %sC(GPR const rt, GPR const ra) {"
" emit_%s(0x%08x, rt, ra, R0, true, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s_(GPR const rt, GPR const ra) {"
" emit_%s(0x%08x, rt, ra, R0, false, true); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %sC_(GPR const rt, GPR const ra) {"
" emit_%s(0x%08x, rt, ra, R0, true, true); "
"}\n"
, mem, form, OP_EXT);
} else {
printf(
"void %s(GPR const rt, GPR const ra, GPR const rb) {"
" emit_%s(0x%08x, rt, ra, rb, false, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %sO(GPR const rt, GPR const ra, GPR const rb) {"
" emit_%s(0x%08x, rt, ra, rb, true, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s_(GPR const rt, GPR const ra, GPR const rb) {"
" emit_%s(0x%08x, rt, ra, rb, false, true); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %sO_(GPR const rt, GPR const ra, GPR const rb) {"
" emit_%s(0x%08x, rt, ra, rb, true, true); "
"}\n"
, mem, form, OP_EXT);
}
} else if (!strcmp(form, "X")) {
if (!strcmp(mem, "CMPL") || !strcmp(mem, "CMP")) {
printf(
"void %s(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) {"
" emit_%s(0x%08x, GPR{(bf << 2) | l}, ra, rb, false); "
"}\n"
, mem, form, OP_EXT);
} else if (!strcmp(mem, "CNTLZD") || !strcmp(mem, "CNTLZW") || !strcmp(mem, "EXTSB") || !strcmp(mem, "EXTSH") || !strcmp(mem, "EXTSW")) {
printf(
"void %s(GPR const rt, GPR const ra) {"
" emit_%s(0x%08x, ra, rt, R0, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s_(GPR const rt, GPR const ra) {"
" emit_%s(0x%08x, ra, rt, R0, true); "
"}\n"
, mem, form, OP_EXT);
} else {
printf(
"void %s(GPR const rt, GPR const ra, GPR const rb) {"
" emit_%s(0x%08x, ra, rt, rb, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s_(GPR const rt, GPR const ra, GPR const rb) {"
" emit_%s(0x%08x, ra, rt, rb, true); "
"}\n"
, mem, form, OP_EXT);
}
} else if (!strcmp(form, "I")) {
printf(
"void %s(Label const& i) {"
" emit_reloc_%s(0x%08x, i, false); "
"}\n"
, mem, form, i_opcode << 26);
printf(
"void %sL(Label const& i) {"
" emit_reloc_%s(0x%08x, i, true); "
"}\n"
, mem, form, i_opcode << 26);
} else if (!strcmp(form, "B")) {
for (int i = 0; i < 12; ++i) {
printf(
"void %s%s(CPR const cr, Label const& i) {"
" emit_reloc_%s(0x%08x, %i, cr.index + %i, i, false); "
"}\n"
, mem, infos[i].s, form, i_opcode << 26, infos[i].p, infos[i].o - 1);
printf(
"void %s%sL(CPR const cr, Label const& i) {"
" emit_reloc_%s(0x%08x, %i, cr.index + %i, i, true); "
"}\n"
, mem, infos[i].s, form, i_opcode << 26, infos[i].p, infos[i].o - 1);
if (!strcmp(mem, "BC")) mem[1] = '\0';
}
} else if (!strcmp(form, "D")) {
if (!strcmp(mem, "CMPLI") || !strcmp(mem, "CMPI")) {
printf(
"void %s(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) {"
" emit_%s(0x%08x, GPR{(bf << 2) | l}, ra, d); "
"}\n"
, mem, form, i_opcode << 26);
} else if (!strcmp(mem, "ANDIS_") || !strcmp(mem, "ANDI_")
|| !strcmp(mem, "ORI") || !strcmp(mem, "ORIS")
|| !strcmp(mem, "XORI") || !strcmp(mem, "XORIS")) {
printf(
"void %s(GPR const rt, GPR const ra, uint32_t d) {"
" emit_%s(0x%08x, ra, rt, d); "
"}\n"
, mem, form, i_opcode << 26);
} else {
printf(
"void %s(GPR const rt, GPR const ra, uint32_t d) {"
" emit_%s(0x%08x, rt, ra, d); "
"}\n"
, mem, form, i_opcode << 26);
}
} else if (!strcmp(form, "SC")) {
printf(
"void %s(uint32_t lev) {"
" emit_%s(0x%08x, lev); "
"}\n"
, mem, form, i_opcode << 26);
} else if (!strcmp(form, "DS")) {
#define OP_EXT_DS ((i_opcode << 26) | (i_extopc << 0))
printf(
"void %s(GPR const rt, GPR const ra, uint32_t d) {"
" emit_%s(0x%08x, rt, ra, d >> 2); "
"}\n"
, mem, form, OP_EXT_DS);
#undef OP_EXT_DS
} else if (!strcmp(form, "XS")) {
#define OP_EXT_XS ((i_opcode << 26) | (i_extopc << 2))
/* HUGE DIFFERENCE DO NOT REMOVE */
printf(
"void %s(GPR const rt, GPR const ra, uint32_t sh) {"
" emit_%s(0x%08x, rt, ra, sh, false); "
"}\n"
, mem, form, OP_EXT_XS);
printf(
"void %s_(GPR const rt, GPR const ra, uint32_t sh) {"
" emit_%s(0x%08x, rt, ra, sh, true); "
"}\n"
, mem, form, OP_EXT_XS);
#undef OP_EXT_XS
} else if (!strcmp(form, "XL")) {
if (!strcmp(mem, "BCLR")) {
printf(
"void %s(GPR const bt, CPR const ba, GPR const bb) {"
" emit_%s(0x%08x, bt.index, ba.index, bb.index, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %sL(GPR const bt, CPR const ba, GPR const bb) {"
" emit_%s(0x%08x, bt.index, ba.index, bb.index, true); "
"}\n"
, mem, form, OP_EXT);
if (!strcmp(mem, "BCLR")) mem[1] = '\0';
for (int i = 1; i < 12; ++i) {
printf(
"void %s%sLR(CPR const cr) {"
" emit_%s(0x%08x, %i, cr.index + %i, 0, false); "
"}\n"
, mem, infos[i].s, form, OP_EXT, infos[i].p, infos[i].o - 1);
printf(
"void %s%sLRL(CPR const cr) {"
" emit_%s(0x%08x, %i, cr.index + %i, 0, true); "
"}\n"
, mem, infos[i].s, form, OP_EXT, infos[i].p, infos[i].o - 1);
}
} else if (mem[0] == 'B') {
printf(
"void %s(GPR const bt, CPR const ba, GPR const bb) {"
" emit_%s(0x%08x, bt.index, ba.index, bb.index, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %sL(GPR const bt, CPR const ba, GPR const bb) {"
" emit_%s(0x%08x, bt.index, ba.index, bb.index, true); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s(GPR const bt, Cond const ba, GPR const bb) {"
" emit_%s(0x%08x, bt.index, cond2offset(ba), bb.index, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %sL(GPR const bt, Cond const ba, GPR const bb) {"
" emit_%s(0x%08x, bt.index, cond2offset(ba), bb.index, true); "
"}\n"
, mem, form, OP_EXT);
} else {
printf(
"void %s(CPR const bt, CPR const ba, CPR const bb) {"
" emit_%s(0x%08x, bt.index, ba.index, bb.index, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %sL(CPR const bt, CPR const ba, CPR const bb) {"
" emit_%s(0x%08x, bt.index, ba.index, bb.index, true); "
"}\n"
, mem, form, OP_EXT);
}
} else if (!strcmp(form, "M")) {
if (!strcmp(mem, "RLWNM")) {
printf(
"void %s(GPR const rs, GPR const ra, GPR const rb, uint32_t mb, uint32_t me = 0) {"
" emit_%s(0x%08x, ra, rs, rb.index, mb, me, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb, uint32_t me = 0) {"
" emit_%s(0x%08x, ra, rs, rb.index, mb, me, true); "
"}\n"
, mem, form, OP_EXT);
} else {
printf(
"void %s(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) {"
" emit_%s(0x%08x, ra, rs, sh, mb, me, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s_(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) {"
" emit_%s(0x%08x, ra, rs, sh, mb, me, true); "
"}\n"
, mem, form, OP_EXT);
}
} else if (!strcmp(form, "MD")) {
printf(
"void %s(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) {"
" emit_%s(0x%08x, ra, rs, mb, sh, false); "
"}\n"
, mem, form, (i_opcode << 26) | (i_extopc << 2));
printf(
"void %s_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) {"
" emit_%s(0x%08x, ra, rs, mb, sh, true); "
"}\n"
, mem, form, (i_opcode << 26) | (i_extopc << 2));
} else if (!strcmp(form, "MDS")) {
printf(
"void %s(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) {"
" emit_%s(0x%08x, ra, rs, rb, mb, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) {"
" emit_%s(0x%08x, ra, rs, rb, mb, true); "
"}\n"
, mem, form, OP_EXT);
} else if (!strcmp(form, "A")) {
printf(
"void %s(FPR const frt, FPR const fra, FPR const frb, FPR const frc) {"
" emit_%s(0x%08x, frt, fra, frb, frc, false); "
"}\n"
, mem, form, OP_EXT);
printf(
"void %s_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) {"
" emit_%s(0x%08x, frt, fra, frb, frc, true); "
"}\n"
, mem, form, OP_EXT);
} else if (!strcmp(form, "XFX")) {
printf(
"void %s(GPR const rt, uint32_t spr) {"
" emit_%s(0x%08x, rt, spr); "
"}\n"
, mem, form, OP_EXT);
} else {
printf(
"void %s() {"
" emit_%s(0x%08x); "
"}\n"
, mem, form, OP_EXT);
}
}
}
}
}
//printf("%s\n", line);
}
fclose(fp);
return 0;
}
return 1;
}
-401
View File
@@ -1,401 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#undef NDEBUG
#include <cstdint>
#include <cstddef>
#include <cassert>
#include <vector>
#include <utility>
#include <sys/mman.h>
#include <cstdlib>
//#ifndef __cpp_lib_unreachable
namespace std {
[[noreturn]] inline void unreachable() {
#if defined(_MSC_VER) && !defined(__clang__) // MSVC
__assume(false);
#else // GCC, Clang
__builtin_unreachable();
#endif
}
}
//#endif
namespace powah {
// Symbolic conditions
enum class Cond : uint8_t {
LT, LE, NG, EQ, GE, NL, GT, NE, SO, UN, NS, NU
};
struct GPR { uint32_t index; };
struct FPR { uint32_t index; };
struct VPR { uint32_t index; };
struct CPR { uint32_t index; };
struct Label { uint32_t index; };
constexpr inline GPR R0{0};
constexpr inline GPR R1{1};
constexpr inline GPR R2{2};
constexpr inline GPR R3{3};
constexpr inline GPR R4{4};
constexpr inline GPR R5{5};
constexpr inline GPR R6{6};
constexpr inline GPR R7{7};
constexpr inline GPR R8{8};
constexpr inline GPR R9{9};
constexpr inline GPR R10{10};
constexpr inline GPR R11{11};
constexpr inline GPR R12{12};
constexpr inline GPR R13{13};
constexpr inline GPR R14{14};
constexpr inline GPR R15{15};
constexpr inline GPR R16{16};
constexpr inline GPR R17{17};
constexpr inline GPR R18{18};
constexpr inline GPR R19{19};
constexpr inline GPR R20{20};
constexpr inline GPR R21{21};
constexpr inline GPR R22{22};
constexpr inline GPR R23{23};
constexpr inline GPR R24{24};
constexpr inline GPR R25{25};
constexpr inline GPR R26{26};
constexpr inline GPR R27{27};
constexpr inline GPR R28{28};
constexpr inline GPR R29{29};
constexpr inline GPR R30{30};
constexpr inline GPR R31{31};
constexpr inline FPR FR0{0};
constexpr inline FPR FR1{1};
constexpr inline FPR FR2{2};
constexpr inline FPR FR3{3};
constexpr inline FPR FR4{4};
constexpr inline FPR FR5{5};
constexpr inline FPR FR6{6};
constexpr inline FPR FR7{7};
constexpr inline FPR FR8{8};
constexpr inline FPR FR9{9};
constexpr inline FPR FR10{10};
constexpr inline FPR FR11{11};
constexpr inline FPR FR12{12};
constexpr inline FPR FR13{13};
constexpr inline FPR FR14{14};
constexpr inline FPR FR15{15};
constexpr inline FPR FR16{16};
constexpr inline FPR FR17{17};
constexpr inline FPR FR18{18};
constexpr inline FPR FR19{19};
constexpr inline FPR FR20{20};
constexpr inline FPR FR21{21};
constexpr inline FPR FR22{22};
constexpr inline FPR FR23{23};
constexpr inline FPR FR24{24};
constexpr inline FPR FR25{25};
constexpr inline FPR FR26{26};
constexpr inline FPR FR27{27};
constexpr inline FPR FR28{28};
constexpr inline FPR FR29{29};
constexpr inline FPR FR30{30};
constexpr inline FPR FR31{31};
// They call it CPR because when programmers see this code they-
constexpr inline CPR CR0{0};
constexpr inline CPR CR1{4};
constexpr inline CPR CR2{8};
constexpr inline CPR CR3{12};
constexpr inline CPR CR4{16};
constexpr inline CPR CR5{20};
constexpr inline CPR CR6{24};
constexpr inline CPR CR7{28};
constexpr uint32_t XER_SO = 32;
constexpr uint32_t XER_OV = 33;
constexpr uint32_t XER_CA = 34;
enum class RelocKind : uint8_t {
FormB,
FormI,
};
struct RelocInfo {
uint32_t offset;
RelocKind kind;
};
struct Context {
Context() = default;
Context(void* ptr, size_t size)
: base{reinterpret_cast<uint32_t*>(ptr)}
, offset{0}
, size{uint32_t(size)} {
}
~Context() = default;
std::vector<uint32_t> labels;
std::vector<std::pair<uint32_t, RelocInfo>> relocs;
Label DefineLabel() {
labels.push_back(0);
return Label{ uint32_t(labels.size() - 1) };
}
void ApplyRelocs() {
for (auto const &[index, info] : relocs) {
//assert(labels[index] != 0); //label must have an addr
int32_t rel = (int32_t)labels[index] - (int32_t)info.offset;
switch (info.kind) {
case RelocKind::FormB:
base[info.offset] |= bitExt(rel, 16, 14);
break;
case RelocKind::FormI:
base[info.offset] |= bitExt(rel, 6, 24);
break;
}
}
relocs.clear();
}
void LABEL(Label l) {
assert(labels[l.index] == 0);
labels[l.index] = offset;
}
static constexpr uint32_t cond2offset(Cond c) noexcept {
switch (c) {
case Cond::LT: return 1;
case Cond::LE: return 2;
case Cond::NG: return 2;
case Cond::EQ: return 3;
case Cond::GE: return 1;
case Cond::NL: return 1;
case Cond::GT: return 2;
case Cond::NE: return 3;
case Cond::SO: return 4;
case Cond::UN: return 4;
case Cond::NS: return 4;
case Cond::NU: return 4;
default: return 0; //hopefully icc isn't stupid
}
}
uint32_t bitExt(uint32_t value, uint32_t offs, uint32_t n) {
uint32_t mask = (1UL << n) - 1;
return (value & mask) << (32 - (n + offs));
}
void emit_XO(uint32_t op, GPR const rt, GPR const ra, GPR const rb, bool oe, bool rc) {
base[offset++] = (op |
bitExt(rt.index, 6, 5)
| bitExt(ra.index, 11, 5)
| bitExt(rb.index, 16, 5)
| bitExt(oe, 21, 1)
| bitExt(rc, 31, 1)
);
}
void emit_D(uint32_t op, GPR const rt, GPR const ra, uint32_t d) {
base[offset++] = (op |
bitExt(rt.index, 6, 5)
| bitExt(ra.index, 11, 5)
| (d & 0xffff)
);
}
void emit_X(uint32_t op, GPR const rt, GPR const ra, GPR const rb, bool rc) {
base[offset++] = (op |
bitExt(rt.index, 6, 5)
| bitExt(ra.index, 11, 5)
| bitExt(rb.index, 16, 5)
| bitExt(rc, 31, 1)
);
}
void emit_XS(uint32_t op, GPR const rt, GPR const ra, uint32_t sh, bool rc) {
base[offset++] = (op |
((rt.index & 0x1f) << 16)
| ((ra.index & 0x1f) << 21)
| ((sh & 0x1f) << 11)
| ((sh >> 4) & 0x02)
| bitExt(rc, 31, 1)
);
}
void emit_reloc_I(uint32_t op, Label const& l, bool lk) {
relocs.emplace_back(l.index, RelocInfo{ offset, RelocKind::FormI });
base[offset++] = (op |
bitExt(lk, 31, 1)
);
}
void emit_reloc_B(uint32_t op, uint32_t bo, uint32_t cri, Label const& l, bool lk) {
relocs.emplace_back(l.index, RelocInfo{ offset, RelocKind::FormB });
base[offset++] = (op |
bitExt(bo, 6, 5)
| bitExt(cri, 11, 5)
| bitExt(lk, 31, 1)
);
}
void emit_XL(uint32_t op, uint32_t bt, uint32_t ba, uint32_t bb, bool lk) {
base[offset++] = (op |
bitExt(bt, 6, 5)
| bitExt(ba, 11, 5)
| bitExt(bb, 16, 5)
| bitExt(lk, 31, 1)
);
}
void emit_A(uint32_t op, FPR const frt, FPR const fra, FPR const frb, FPR const frc, bool rc) {
base[offset++] = (op |
bitExt(frt.index, 6, 5)
| bitExt(fra.index, 11, 5)
| bitExt(frb.index, 16, 5)
| bitExt(frc.index, 21, 5)
| bitExt(rc, 31, 1)
);
}
void emit_DS(uint32_t op, GPR const rt, GPR const ra, uint32_t d) {
//assert(d & 0x03 == 0);
base[offset++] = (op |
bitExt(rt.index, 6, 5)
| bitExt(ra.index, 11, 5)
| bitExt(d, 16, 14)
);
}
void emit_M(uint32_t op, GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me, bool rc) {
assert(sh <= 0x3f && mb <= 0x3f);
base[offset++] = (op |
bitExt(rs.index, 6, 5)
| bitExt(ra.index, 11, 5)
| ((sh & 0x1f) << 11)
| ((mb & 0x1f) << 6)
| ((me & 0x1f) << 1)
| bitExt(rc, 31, 1)
);
}
void emit_MD(uint32_t op, GPR const rs, GPR const ra, GPR const rb, uint32_t mb, bool rc) {
assert(mb <= 0x3f);
base[offset++] = (op |
bitExt(rs.index, 6, 5)
| bitExt(ra.index, 11, 5)
| bitExt(rb.index, 16, 5)
| ((mb & 0x1f) << 6) | (mb & 0x20)
| bitExt(rc, 31, 1)
);
}
void emit_MD(uint32_t op, GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, bool rc) {
assert(sh <= 0x3f && mb <= 0x3f);
base[offset++] = (op |
bitExt(rs.index, 6, 5)
| bitExt(ra.index, 11, 5)
| ((mb & 0x1f) << 6) | (mb & 0x20)
| ((sh & 0x1f) << 11) | ((sh >> 4) & 0x02)
| bitExt(rc, 31, 1)
);
}
void emit_MDS(uint32_t op, GPR const rs, GPR const ra, GPR const rb, uint32_t mb, bool rc) {
base[offset++] = (op |
bitExt(rs.index, 6, 5)
| bitExt(ra.index, 11, 5)
| bitExt(rb.index, 16, 5)
| ((mb & 0x1f) << 6) | (mb & 0x20)
| bitExt(rc, 31, 1)
);
}
void emit_XFL(uint32_t op) {
(void)op;
std::abort();
}
void emit_XFX(uint32_t op, GPR const rt, uint32_t spr) {
base[offset++] = (op |
(rt.index & 0x1f) << 21
| ((spr & 0xff) << 12)
);
}
void emit_SC(uint32_t op, uint32_t lev) {
(void)op;
(void)lev;
std::abort();
}
// Extended Memmonics, hand coded :)
void MR(GPR const ra, GPR const rs) { OR(ra, rs, rs); }
void NOP() { ORI(R0, R0, 0); }
void NOT(GPR const ra, GPR const rs) { NOR(ra, rs, rs); }
void ROTLDI(GPR const ra, GPR const rs, uint32_t n) { RLDICL(ra, rs, n, 0); }
void ROTRDI(GPR const ra, GPR const rs, uint32_t n) { RLDICL(ra, rs, 64 - n, 0); }
void ROTLWI(GPR const ra, GPR const rs, uint32_t n) { RLWINM(ra, rs, n, 0, 31); }
void ROTRWI(GPR const ra, GPR const rs, uint32_t n) { RLWINM(ra, rs, 32 - n, 0, 31); }
void ROTLW(GPR const ra, GPR const rs, GPR const rb) { RLWNM(ra, rs, rb, 0, 31); }
void ROTLD(GPR const ra, GPR const rs, GPR const rb) { RLDCL(ra, rs, rb, 0); }
void EXTLDI(GPR const ra, GPR const rs, uint32_t n, uint32_t b) { RLDICR(ra, rs, b, n - 1); }
void SLDI(GPR const ra, GPR const rs, uint32_t n) { RLDICR(ra, rs, n, 63 - n); }
void CLRLDI(GPR const ra, GPR const rs, uint32_t n) { RLDICL(ra, rs, 0, n); }
void EXTRDI(GPR const ra, GPR const rs, uint32_t n, uint32_t b) { RLDICL(ra, rs, b + n, 64 - n); }
void SRDI(GPR const ra, GPR const rs, uint32_t n) { RLDICL(ra, rs, 64 - n, n); }
void CLLDI(GPR const ra, GPR const rs, uint32_t n) { RLDICR(ra, rs, 0, n); }
void CLRSLDI(GPR const ra, GPR const rs, uint32_t n, uint32_t b) { RLDICR(ra, rs, n, b - n); }
void EXTLWI(GPR const ra, GPR const rs, uint32_t n, uint32_t b) { RLWINM(ra, rs, b, 0, n - 1); }
void SRWI(GPR const ra, GPR const rs, uint32_t n) { RLWINM(ra, rs, 32 - n, n, 31); }
void CLRRWI(GPR const ra, GPR const rs, uint32_t n) { RLWINM(ra, rs, 0, 0, 31 - n); }
void CRSET(CPR const bx) { CREQV(bx, bx, bx); }
void CRCLR(CPR const bx) { CRXOR(bx, bx, bx); }
void CRMOVE(CPR const bx, CPR const by) { CROR(bx, by, by); }
void CRNOT(CPR const bx, CPR const by) { CRNOR(bx, by, by); }
void CMPLDI(CPR const cr, GPR const rx, uint32_t v) { CMPLI(cr.index, 1, rx, v); }
void CMPLWI(CPR const cr, GPR const rx, uint32_t v) { CMPLI(cr.index, 0, rx, v); }
void CMPLD(CPR const cr, GPR const rx, GPR const ry) { CMPL(cr.index, 1, rx, ry); }
void CMPLW(CPR const cr, GPR const rx, GPR const ry) { CMPL(cr.index, 0, rx, ry); }
void CMPLDI(GPR const rx, uint32_t v) { CMPLI(0, 1, rx, v); }
void CMPLWI(GPR const rx, uint32_t v) { CMPLI(0, 0, rx, v); }
void CMPLD(GPR const rx, GPR const ry) { CMPL(0, 1, rx, ry); }
void CMPLW(GPR const rx, GPR const ry) { CMPL(0, 0, rx, ry); }
void CMPWI(CPR const cr, GPR const rx, uint32_t si) { CMPI(cr.index, 0, rx, si); }
void CMPW(CPR const cr, GPR const rx, GPR const ry) { CMP(cr.index, 0, rx, ry); }
void CMPDI(CPR const cr, GPR const rx, uint32_t si) { CMPI(cr.index, 1, rx, si); }
void CMPD(CPR const cr, GPR const rx, GPR const ry) { CMP(cr.index, 1, rx, ry); }
void CMPWI(GPR const rx, uint32_t si) { CMPI(0, 0, rx, si); }
void CMPW(GPR const rx, GPR const ry) { CMP(0, 0, rx, ry); }
void CMPDI(GPR const rx, uint32_t si) { CMPI(0, 1, rx, si); }
void CMPD(GPR const rx, GPR const ry) { CMP(0, 1, rx, ry); }
void LI(GPR const rx, uint32_t value) { ADDI(rx, R0, value); }
void LIS(GPR const rx, uint32_t value) { ADDIS(rx, R0, value); }
void MFLR(GPR const rt) { MFSPR(powah::GPR{8}, rt, powah::GPR{0}); }
void MTLR(GPR const rt) { MTSPR(powah::GPR{8}, rt, powah::GPR{0}); }
void BLR() { base[offset++] = 0x4e800020; } //BCLR(R0, CR0, R0);
void MFCTR(GPR const rt) { MFSPR(powah::GPR{9}, rt, powah::GPR{0}); }
void MTCTR(GPR const rt) { MTSPR(powah::GPR{9}, rt, powah::GPR{0}); }
void BCTRL() { base[offset++] = 0x4e800421; } //BCCTRL(R0, CR0, R0);
void BCTR() { base[offset++] = 0x4e800420; } //BCCTR(R0, CR0, R0);
// TODO: PowerPC 11 stuff
void ISEL(GPR const rd, GPR const ra, GPR const rb, uint32_t d) {
(void)rd;
(void)ra;
(void)rb;
(void)d;
std::unreachable();
}
void ISELLT(GPR const rd, GPR const ra, GPR const rb) { ISEL(rd, ra, rb, 0); }
void ISELGT(GPR const rd, GPR const ra, GPR const rb) { ISEL(rd, ra, rb, 1); }
void ISELEQ(GPR const rd, GPR const ra, GPR const rb) { ISEL(rd, ra, rb, 2); }
// Rawly pasted because fuck you
#include "powah_gen_base.hpp"
uint32_t* base = nullptr;
uint32_t offset = 0;
uint32_t size = 0;
};
}
-487
View File
@@ -1,487 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// this file is autogenerated DO NOT MODIFY
#pragma once
void ADD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, false, false); }
void ADDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, true, false); }
void ADD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, false, true); }
void ADDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000214, rt, ra, rb, true, true); }
void ADDC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, false, false); }
void ADDCO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, true, false); }
void ADDC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, false, true); }
void ADDCO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000014, rt, ra, rb, true, true); }
void ADDE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, false, false); }
void ADDEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, true, false); }
void ADDE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, false, true); }
void ADDEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000114, rt, ra, rb, true, true); }
void ADDI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x38000000, rt, ra, d); }
void ADDIC(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x30000000, rt, ra, d); }
void ADDIC_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x34000000, rt, ra, d); }
void ADDIS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x3c000000, rt, ra, d); }
void ADDME(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, false, false); }
void ADDMEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, true, false); }
void ADDME_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, false, true); }
void ADDMEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d4, rt, ra, rb, true, true); }
void ADDZE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, false, false); }
void ADDZEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, true, false); }
void ADDZE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, false, true); }
void ADDZEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000194, rt, ra, rb, true, true); }
void AND(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000038, ra, rt, rb, false); }
void AND_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000038, ra, rt, rb, true); }
void ANDC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000078, ra, rt, rb, false); }
void ANDC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000078, ra, rt, rb, true); }
void ANDI_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x70000000, ra, rt, d); }
void ANDIS_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x74000000, ra, rt, d); }
void B(Label const& i) { emit_reloc_I(0x48000000, i, false); }
void BL(Label const& i) { emit_reloc_I(0x48000000, i, true); }
void BC(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 0, cr.index + 0, i, false); }
void BCL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 0, cr.index + 0, i, true); }
void BLT(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 0, i, false); }
void BLTL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 0, i, true); }
void BLE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, false); }
void BLEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, true); }
void BNG(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, false); }
void BNGL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 1, i, true); }
void BEQ(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 2, i, false); }
void BEQL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 2, i, true); }
void BGE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, false); }
void BGEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, true); }
void BNL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, false); }
void BNLL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 0, i, true); }
void BGT(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 1, i, false); }
void BGTL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 1, i, true); }
void BNE(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 2, i, false); }
void BNEL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 2, i, true); }
void BSO(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, false); }
void BSOL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, true); }
void BUN(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, false); }
void BUNL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 12, cr.index + 3, i, true); }
void BNS(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 3, i, false); }
void BNSL(CPR const cr, Label const& i) { emit_reloc_B(0x40000000, 4, cr.index + 3, i, true); }
void BCCTR(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, ba.index, bb.index, false); }
void BCCTRL(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, ba.index, bb.index, true); }
void BCCTR(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, cond2offset(ba), bb.index, false); }
void BCCTRL(GPR const bt, Cond const ba, GPR const bb) { emit_XL(0x4c000420, bt.index, cond2offset(ba), bb.index, true); }
void BCLR(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, ba.index, bb.index, false); }
void BCLRL(GPR const bt, CPR const ba, GPR const bb) { emit_XL(0x4c000020, bt.index, ba.index, bb.index, true); }
void BLTLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 0, 0, false); }
void BLTLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 0, 0, true); }
void BLELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, false); }
void BLELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, true); }
void BNGLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, false); }
void BNGLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 1, 0, true); }
void BEQLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 2, 0, false); }
void BEQLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 2, 0, true); }
void BGELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, false); }
void BGELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, true); }
void BNLLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, false); }
void BNLLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 0, 0, true); }
void BGTLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 1, 0, false); }
void BGTLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 1, 0, true); }
void BNELR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 2, 0, false); }
void BNELRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 2, 0, true); }
void BSOLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, false); }
void BSOLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, true); }
void BUNLR(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, false); }
void BUNLRL(CPR const cr) { emit_XL(0x4c000020, 12, cr.index + 3, 0, true); }
void BNSLR(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 3, 0, false); }
void BNSLRL(CPR const cr) { emit_XL(0x4c000020, 4, cr.index + 3, 0, true); }
void CMP(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000000, GPR{(bf << 2) | l}, ra, rb, false); }
void CMPI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x2c000000, GPR{(bf << 2) | l}, ra, d); }
void CMPL(uint32_t bf, uint32_t l, GPR const ra, GPR const rb) { emit_X(0x7c000040, GPR{(bf << 2) | l}, ra, rb, false); }
void CMPLI(uint32_t bf, uint32_t l, GPR const ra, uint32_t d) { emit_D(0x28000000, GPR{(bf << 2) | l}, ra, d); }
void CNTLZD(GPR const rt, GPR const ra) { emit_X(0x7c000074, ra, rt, R0, false); }
void CNTLZD_(GPR const rt, GPR const ra) { emit_X(0x7c000074, ra, rt, R0, true); }
void CNTLZW(GPR const rt, GPR const ra) { emit_X(0x7c000034, ra, rt, R0, false); }
void CNTLZW_(GPR const rt, GPR const ra) { emit_X(0x7c000034, ra, rt, R0, true); }
void CRAND(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000202, bt.index, ba.index, bb.index, false); }
void CRANDL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000202, bt.index, ba.index, bb.index, true); }
void CRANDC(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000102, bt.index, ba.index, bb.index, false); }
void CRANDCL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000102, bt.index, ba.index, bb.index, true); }
void CREQV(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000242, bt.index, ba.index, bb.index, false); }
void CREQVL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000242, bt.index, ba.index, bb.index, true); }
void CRNAND(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c0001c2, bt.index, ba.index, bb.index, false); }
void CRNANDL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c0001c2, bt.index, ba.index, bb.index, true); }
void CRNOR(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000042, bt.index, ba.index, bb.index, false); }
void CRNORL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000042, bt.index, ba.index, bb.index, true); }
void CROR(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000382, bt.index, ba.index, bb.index, false); }
void CRORL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000382, bt.index, ba.index, bb.index, true); }
void CRORC(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000342, bt.index, ba.index, bb.index, false); }
void CRORCL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000342, bt.index, ba.index, bb.index, true); }
void CRXOR(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000182, bt.index, ba.index, bb.index, false); }
void CRXORL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000182, bt.index, ba.index, bb.index, true); }
void DCBF(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ac, ra, rt, rb, false); }
void DCBF_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ac, ra, rt, rb, true); }
void DCBI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003ac, ra, rt, rb, false); }
void DCBI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003ac, ra, rt, rb, true); }
void DCBST(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006c, ra, rt, rb, false); }
void DCBST_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006c, ra, rt, rb, true); }
void DCBT(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00022c, ra, rt, rb, false); }
void DCBT_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00022c, ra, rt, rb, true); }
void DCBTST(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ec, ra, rt, rb, false); }
void DCBTST_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ec, ra, rt, rb, true); }
void DCBZ(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ec, ra, rt, rb, false); }
void DCBZ_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ec, ra, rt, rb, true); }
void DIVD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, false, false); }
void DIVDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, true, false); }
void DIVD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, false, true); }
void DIVDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d2, rt, ra, rb, true, true); }
void DIVDU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, false, false); }
void DIVDUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, true, false); }
void DIVDU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, false, true); }
void DIVDUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000392, rt, ra, rb, true, true); }
void DIVW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, false, false); }
void DIVWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, true, false); }
void DIVW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, false, true); }
void DIVWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0003d6, rt, ra, rb, true, true); }
void DIVWU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, false, false); }
void DIVWUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, true, false); }
void DIVWU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, false, true); }
void DIVWUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000396, rt, ra, rb, true, true); }
void ECIWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00026c, ra, rt, rb, false); }
void ECIWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00026c, ra, rt, rb, true); }
void ECOWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036c, ra, rt, rb, false); }
void ECOWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036c, ra, rt, rb, true); }
void EIEIO(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0006ac, ra, rt, rb, false); }
void EIEIO_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0006ac, ra, rt, rb, true); }
void EQV(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000238, ra, rt, rb, false); }
void EQV_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000238, ra, rt, rb, true); }
void EXTSB(GPR const rt, GPR const ra) { emit_X(0x7c000774, ra, rt, R0, false); }
void EXTSB_(GPR const rt, GPR const ra) { emit_X(0x7c000774, ra, rt, R0, true); }
void EXTSH(GPR const rt, GPR const ra) { emit_XO(0x7c000734, rt, ra, R0, false, false); }
void EXTSHC(GPR const rt, GPR const ra) { emit_XO(0x7c000734, rt, ra, R0, true, false); }
void EXTSH_(GPR const rt, GPR const ra) { emit_XO(0x7c000734, rt, ra, R0, false, true); }
void EXTSHC_(GPR const rt, GPR const ra) { emit_XO(0x7c000734, rt, ra, R0, true, true); }
void EXTSW(GPR const rt, GPR const ra) { emit_X(0x7c0007b4, ra, rt, R0, false); }
void EXTSW_(GPR const rt, GPR const ra) { emit_X(0x7c0007b4, ra, rt, R0, true); }
void FABS(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000210, ra, rt, rb, false); }
void FABS_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000210, ra, rt, rb, true); }
void FADD(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00002a, frt, fra, frb, frc, false); }
void FADD_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00002a, frt, fra, frb, frc, true); }
void FADDS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00002a, frt, fra, frb, frc, false); }
void FADDS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00002a, frt, fra, frb, frc, true); }
void FCFID(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00069c, ra, rt, rb, false); }
void FCFID_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00069c, ra, rt, rb, true); }
void FCMPO(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000040, ra, rt, rb, false); }
void FCMPO_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000040, ra, rt, rb, true); }
void FCMPU(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0xfc000000, bt.index, ba.index, bb.index, false); }
void FCMPUL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0xfc000000, bt.index, ba.index, bb.index, true); }
void FCTID(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00065c, ra, rt, rb, false); }
void FCTID_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00065c, ra, rt, rb, true); }
void FCTIDZ(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00065e, ra, rt, rb, false); }
void FCTIDZ_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00065e, ra, rt, rb, true); }
void FCTIW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00001c, ra, rt, rb, false); }
void FCTIW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00001c, ra, rt, rb, true); }
void FCTIWZ(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0xfc00001e, bt.index, ba.index, bb.index, false); }
void FCTIWZL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0xfc00001e, bt.index, ba.index, bb.index, true); }
void FDIV(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000024, frt, fra, frb, frc, false); }
void FDIV_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000024, frt, fra, frb, frc, true); }
void FDIVS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000024, frt, fra, frb, frc, false); }
void FDIVS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000024, frt, fra, frb, frc, true); }
void FMADD(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003a, frt, fra, frb, frc, false); }
void FMADD_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003a, frt, fra, frb, frc, true); }
void FMADDS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003a, frt, fra, frb, frc, false); }
void FMADDS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003a, frt, fra, frb, frc, true); }
void FMR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000090, ra, rt, rb, false); }
void FMR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000090, ra, rt, rb, true); }
void FMSUB(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000038, frt, fra, frb, frc, false); }
void FMSUB_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000038, frt, fra, frb, frc, true); }
void FMSUBS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000038, frt, fra, frb, frc, false); }
void FMSUBS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000038, frt, fra, frb, frc, true); }
void FMUL(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000032, frt, fra, frb, frc, false); }
void FMUL_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000032, frt, fra, frb, frc, true); }
void FMULS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000032, frt, fra, frb, frc, false); }
void FMULS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000032, frt, fra, frb, frc, true); }
void FNABS(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000110, ra, rt, rb, false); }
void FNABS_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000110, ra, rt, rb, true); }
void FNEG(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000050, ra, rt, rb, false); }
void FNEG_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000050, ra, rt, rb, true); }
void FNMADD(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003e, frt, fra, frb, frc, false); }
void FNMADD_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003e, frt, fra, frb, frc, true); }
void FNMADDS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003e, frt, fra, frb, frc, false); }
void FNMADDS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003e, frt, fra, frb, frc, true); }
void FNMSUB(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003c, frt, fra, frb, frc, false); }
void FNMSUB_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00003c, frt, fra, frb, frc, true); }
void FNMSUBS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003c, frt, fra, frb, frc, false); }
void FNMSUBS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec00003c, frt, fra, frb, frc, true); }
void FRES(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000030, frt, fra, frb, frc, false); }
void FRES_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000030, frt, fra, frb, frc, true); }
void FRSP(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000018, ra, rt, rb, false); }
void FRSP_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000018, ra, rt, rb, true); }
void FRSQRTE(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000034, frt, fra, frb, frc, false); }
void FRSQRTE_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000034, frt, fra, frb, frc, true); }
void FSEL(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00002e, frt, fra, frb, frc, false); }
void FSEL_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc00002e, frt, fra, frb, frc, true); }
void FSUB(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000028, frt, fra, frb, frc, false); }
void FSUB_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xfc000028, frt, fra, frb, frc, true); }
void FSUBS(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000028, frt, fra, frb, frc, false); }
void FSUBS_(FPR const frt, FPR const fra, FPR const frb, FPR const frc) { emit_A(0xec000028, frt, fra, frb, frc, true); }
void ICBI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ac, ra, rt, rb, false); }
void ICBI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ac, ra, rt, rb, true); }
void ISYNC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x4c00012c, ra, rt, rb, false); }
void ISYNC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x4c00012c, ra, rt, rb, true); }
void LBZ(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x88000000, rt, ra, d); }
void LBZU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x8c000000, rt, ra, d); }
void LBZUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ee, ra, rt, rb, false); }
void LBZUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ee, ra, rt, rb, true); }
void LBZX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ae, ra, rt, rb, false); }
void LBZX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000ae, ra, rt, rb, true); }
void LD(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000000, rt, ra, d >> 2); }
void LDARX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a8, ra, rt, rb, false); }
void LDARX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a8, ra, rt, rb, true); }
void LDU(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000001, rt, ra, d >> 2); }
void LDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006a, ra, rt, rb, false); }
void LDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006a, ra, rt, rb, true); }
void LDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002a, ra, rt, rb, false); }
void LDX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002a, ra, rt, rb, true); }
void LFD(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xc8000000, rt, ra, d); }
void LFDU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xcc000000, rt, ra, d); }
void LFDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ee, ra, rt, rb, false); }
void LFDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ee, ra, rt, rb, true); }
void LFDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ae, ra, rt, rb, false); }
void LFDX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ae, ra, rt, rb, true); }
void LFS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xc0000000, rt, ra, d); }
void LFSU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xc4000000, rt, ra, d); }
void LFSUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00046e, ra, rt, rb, false); }
void LFSUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00046e, ra, rt, rb, true); }
void LFSX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042e, ra, rt, rb, false); }
void LFSX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042e, ra, rt, rb, true); }
void LHA(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xa8000000, rt, ra, d); }
void LHAU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xac000000, rt, ra, d); }
void LHAUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ee, ra, rt, rb, false); }
void LHAUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ee, ra, rt, rb, true); }
void LHAX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ae, ra, rt, rb, false); }
void LHAX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ae, ra, rt, rb, true); }
void LHBRX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00062c, ra, rt, rb, false); }
void LHBRX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00062c, ra, rt, rb, true); }
void LHZ(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xa0000000, rt, ra, d); }
void LHZU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xa4000000, rt, ra, d); }
void LHZUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000296, ra, rt, rb, false); }
void LHZUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000296, ra, rt, rb, true); }
void LHZX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00022e, ra, rt, rb, false); }
void LHZX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00022e, ra, rt, rb, true); }
void LMW(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xb8000000, rt, ra, d); }
void LSWI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004aa, ra, rt, rb, false); }
void LSWI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004aa, ra, rt, rb, true); }
void LSWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042a, ra, rt, rb, false); }
void LSWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042a, ra, rt, rb, true); }
void LWA(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xe8000002, rt, ra, d >> 2); }
void LWARX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000028, ra, rt, rb, false); }
void LWARX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000028, ra, rt, rb, true); }
void LWAUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ea, ra, rt, rb, false); }
void LWAUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002ea, ra, rt, rb, true); }
void LWAX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002aa, ra, rt, rb, false); }
void LWAX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002aa, ra, rt, rb, true); }
void LWBRX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042c, ra, rt, rb, false); }
void LWBRX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00042c, ra, rt, rb, true); }
void LWZ(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x80000000, rt, ra, d); }
void LWZU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x84000000, rt, ra, d); }
void LWZUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006e, ra, rt, rb, false); }
void LWZUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00006e, ra, rt, rb, true); }
void LWZX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002e, ra, rt, rb, false); }
void LWZX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00002e, ra, rt, rb, true); }
void MCRF(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000000, bt.index, ba.index, bb.index, false); }
void MCRFL(CPR const bt, CPR const ba, CPR const bb) { emit_XL(0x4c000000, bt.index, ba.index, bb.index, true); }
void MCRFS(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000080, ra, rt, rb, false); }
void MCRFS_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc000080, ra, rt, rb, true); }
void MCRXR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000400, ra, rt, rb, false); }
void MCRXR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000400, ra, rt, rb, true); }
void MFCR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000026, ra, rt, rb, false); }
void MFCR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000026, ra, rt, rb, true); }
void MFFS(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00048e, ra, rt, rb, false); }
void MFFS_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00048e, ra, rt, rb, true); }
void MFMSR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a6, ra, rt, rb, false); }
void MFMSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000a6, ra, rt, rb, true); }
void MFSPR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002a6, ra, rt, rb, false); }
void MFSPR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0002a6, ra, rt, rb, true); }
void MFSR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004a6, ra, rt, rb, false); }
void MFSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004a6, ra, rt, rb, true); }
void MFSRIN(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000526, ra, rt, rb, false); }
void MFSRIN_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000526, ra, rt, rb, true); }
void MTCRF(GPR const rt, uint32_t spr) { emit_XFX(0x7c000120, rt, spr); }
void MTFSB0(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00008c, ra, rt, rb, false); }
void MTFSB0_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00008c, ra, rt, rb, true); }
void MTFSB1(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00004c, ra, rt, rb, false); }
void MTFSB1_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00004c, ra, rt, rb, true); }
void MTFSF() { emit_XFL(0xfc00058e); }
void MTFSFI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00010c, ra, rt, rb, false); }
void MTFSFI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0xfc00010c, ra, rt, rb, true); }
void MTMSR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000124, ra, rt, rb, false); }
void MTMSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000124, ra, rt, rb, true); }
void MTSPR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003a6, ra, rt, rb, false); }
void MTSPR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003a6, ra, rt, rb, true); }
void MTSR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001a4, ra, rt, rb, false); }
void MTSR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001a4, ra, rt, rb, true); }
void MTSRIN(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001e4, ra, rt, rb, false); }
void MTSRIN_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001e4, ra, rt, rb, true); }
void MULHD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, false, false); }
void MULHDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, true, false); }
void MULHD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, false, true); }
void MULHDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000092, rt, ra, rb, true, true); }
void MULHDU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, false, false); }
void MULHDUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, true, false); }
void MULHDU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, false, true); }
void MULHDUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000012, rt, ra, rb, true, true); }
void MULHW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, false, false); }
void MULHWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, true, false); }
void MULHW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, false, true); }
void MULHWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000096, rt, ra, rb, true, true); }
void MULHWU(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, false, false); }
void MULHWUO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, true, false); }
void MULHWU_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, false, true); }
void MULHWUO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000016, rt, ra, rb, true, true); }
void MULLD(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, false, false); }
void MULLDO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, true, false); }
void MULLD_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, false, true); }
void MULLDO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d2, rt, ra, rb, true, true); }
void MULLI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x1c000000, rt, ra, d); }
void MULLW(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, false, false); }
void MULLWO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, true, false); }
void MULLW_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, false, true); }
void MULLWO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d6, rt, ra, rb, true, true); }
void NAND(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003b8, ra, rt, rb, false); }
void NAND_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003b8, ra, rt, rb, true); }
void NEG(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, false, false); }
void NEGO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, true, false); }
void NEG_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, false, true); }
void NEGO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0000d0, rt, ra, rb, true, true); }
void NOR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000f8, ra, rt, rb, false); }
void NOR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0000f8, ra, rt, rb, true); }
void OR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000378, ra, rt, rb, false); }
void OR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000378, ra, rt, rb, true); }
void ORC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000338, ra, rt, rb, false); }
void ORC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000338, ra, rt, rb, true); }
void ORI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x60000000, ra, rt, d); }
void ORIS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x64000000, ra, rt, d); }
void RFI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x4c000064, ra, rt, rb, false); }
void RFI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x4c000064, ra, rt, rb, true); }
void RLDCL(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) { emit_MDS(0x78000010, ra, rs, rb, mb, false); }
void RLDCL_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) { emit_MDS(0x78000010, ra, rs, rb, mb, true); }
void RLDCR(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) { emit_MDS(0x78000012, ra, rs, rb, mb, false); }
void RLDCR_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb) { emit_MDS(0x78000012, ra, rs, rb, mb, true); }
void RLDIC(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000008, ra, rs, mb, sh, false); }
void RLDIC_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000008, ra, rs, mb, sh, true); }
void RLDICL(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000000, ra, rs, mb, sh, false); }
void RLDICL_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000000, ra, rs, mb, sh, true); }
void RLDICR(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000004, ra, rs, mb, sh, false); }
void RLDICR_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x78000004, ra, rs, mb, sh, true); }
void RLDIMI(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x7800000c, ra, rs, mb, sh, false); }
void RLDIMI_(GPR const rs, GPR const ra, uint32_t mb, uint32_t sh) { emit_MD(0x7800000c, ra, rs, mb, sh, true); }
void RLWIMI(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) { emit_M(0x50000000, ra, rs, sh, mb, me, false); }
void RLWIMI_(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) { emit_M(0x50000000, ra, rs, sh, mb, me, true); }
void RLWINM(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) { emit_M(0x54000000, ra, rs, sh, mb, me, false); }
void RLWINM_(GPR const rs, GPR const ra, uint32_t sh, uint32_t mb, uint32_t me = 0) { emit_M(0x54000000, ra, rs, sh, mb, me, true); }
void RLWNM(GPR const rs, GPR const ra, GPR const rb, uint32_t mb, uint32_t me = 0) { emit_M(0x5c000000, ra, rs, rb.index, mb, me, false); }
void RLWNM_(GPR const rs, GPR const ra, GPR const rb, uint32_t mb, uint32_t me = 0) { emit_M(0x5c000000, ra, rs, rb.index, mb, me, true); }
void SC(uint32_t lev) { emit_SC(0x44000000, lev); }
void SI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x30000000, rt, ra, d); }
void SI_(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x34000000, rt, ra, d); }
void SLBIA(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003e4, ra, rt, rb, false); }
void SLBIA_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0003e4, ra, rt, rb, true); }
void SLBIE(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000364, ra, rt, rb, false); }
void SLBIE_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000364, ra, rt, rb, true); }
void SLD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000036, ra, rt, rb, false); }
void SLD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000036, ra, rt, rb, true); }
void SLW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000030, ra, rt, rb, false); }
void SLW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000030, ra, rt, rb, true); }
void SRAD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000634, ra, rt, rb, false); }
void SRAD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000634, ra, rt, rb, true); }
void SRADI(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, rt, ra, sh, false); }
void SRADI_(GPR const rt, GPR const ra, uint32_t sh) { emit_XS(0x7c000674, rt, ra, sh, true); }
void SRD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000436, ra, rt, rb, false); }
void SRD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000436, ra, rt, rb, true); }
void SRAW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000630, ra, rt, rb, false); }
void SRAW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000630, ra, rt, rb, true); }
void SRAWI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000670, ra, rt, rb, false); }
void SRAWI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000670, ra, rt, rb, true); }
void SRW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000430, ra, rt, rb, false); }
void SRW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000430, ra, rt, rb, true); }
void STB(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x98000000, rt, ra, d); }
void STBU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x9c000000, rt, ra, d); }
void STBUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ee, ra, rt, rb, false); }
void STBUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ee, ra, rt, rb, true); }
void STBX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ae, ra, rt, rb, false); }
void STBX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ae, ra, rt, rb, true); }
void STD(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xf8000000, rt, ra, d >> 2); }
void STDCX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ac, ra, rt, rb, false); }
void STDCX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0001ac, ra, rt, rb, true); }
void STDU(GPR const rt, GPR const ra, uint32_t d) { emit_DS(0xf8000001, rt, ra, d >> 2); }
void STDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016a, ra, rt, rb, false); }
void STDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016a, ra, rt, rb, true); }
void STDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012a, ra, rt, rb, false); }
void STDX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012a, ra, rt, rb, true); }
void STFD(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xd8000000, rt, ra, d); }
void STFDU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xdc000000, rt, ra, d); }
void STFDUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005ee, ra, rt, rb, false); }
void STFDUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005ee, ra, rt, rb, true); }
void STFDX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005ae, ra, rt, rb, false); }
void STFDX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005ae, ra, rt, rb, true); }
void STFIWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ae, ra, rt, rb, false); }
void STFIWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0007ae, ra, rt, rb, true); }
void STFS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xd0000000, rt, ra, d); }
void STFSU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xd4000000, rt, ra, d); }
void STFSUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00056e, ra, rt, rb, false); }
void STFSUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00056e, ra, rt, rb, true); }
void STFSX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052e, ra, rt, rb, false); }
void STFSX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052e, ra, rt, rb, true); }
void STH(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xb0000000, rt, ra, d); }
void STHBRX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00072c, ra, rt, rb, false); }
void STHBRX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00072c, ra, rt, rb, true); }
void STHU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xb4000000, rt, ra, d); }
void STHUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036e, ra, rt, rb, false); }
void STHUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00036e, ra, rt, rb, true); }
void STHX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00032e, ra, rt, rb, false); }
void STHX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00032e, ra, rt, rb, true); }
void STMW(GPR const rt, GPR const ra, uint32_t d) { emit_D(0xbc000000, rt, ra, d); }
void STSWI(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005aa, ra, rt, rb, false); }
void STSWI_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0005aa, ra, rt, rb, true); }
void STSWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052a, ra, rt, rb, false); }
void STSWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052a, ra, rt, rb, true); }
void STW(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x90000000, rt, ra, d); }
void STWBRX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052c, ra, rt, rb, false); }
void STWBRX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00052c, ra, rt, rb, true); }
void STWCX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012c, ra, rt, rb, false); }
void STWCX__(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012c, ra, rt, rb, true); }
void STWU(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x94000000, rt, ra, d); }
void STWUX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016e, ra, rt, rb, false); }
void STWUX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00016e, ra, rt, rb, true); }
void STWX(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012e, ra, rt, rb, false); }
void STWX_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00012e, ra, rt, rb, true); }
void SUBF(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, false, false); }
void SUBFO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, true, false); }
void SUBF_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, false, true); }
void SUBFO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000050, rt, ra, rb, true, true); }
void SUBFC(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, false, false); }
void SUBFCO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, true, false); }
void SUBFC_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, false, true); }
void SUBFCO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000010, rt, ra, rb, true, true); }
void SUBFE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, false, false); }
void SUBFEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, true, false); }
void SUBFE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, false, true); }
void SUBFEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000110, rt, ra, rb, true, true); }
void SUBFIC(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x20000000, rt, ra, d); }
void SUBFME(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, false, false); }
void SUBFMEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, true, false); }
void SUBFME_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, false, true); }
void SUBFMEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c0001d0, rt, ra, rb, true, true); }
void SUBFZE(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, false, false); }
void SUBFZEO(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, true, false); }
void SUBFZE_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, false, true); }
void SUBFZEO_(GPR const rt, GPR const ra, GPR const rb) { emit_XO(0x7c000190, rt, ra, rb, true, true); }
void SYNC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ac, ra, rt, rb, false); }
void SYNC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c0004ac, ra, rt, rb, true); }
void TD(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000088, ra, rt, rb, false); }
void TD_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000088, ra, rt, rb, true); }
void TDI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x08000000, rt, ra, d); }
void TLBIE(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000264, ra, rt, rb, false); }
void TLBIE_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000264, ra, rt, rb, true); }
void TLBSYNC(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00046c, ra, rt, rb, false); }
void TLBSYNC_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c00046c, ra, rt, rb, true); }
void TW(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000008, ra, rt, rb, false); }
void TW_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000008, ra, rt, rb, true); }
void TWI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x0c000000, rt, ra, d); }
void XOR(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000278, ra, rt, rb, false); }
void XOR_(GPR const rt, GPR const ra, GPR const rb) { emit_X(0x7c000278, ra, rt, rb, true); }
void XORI(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x68000000, ra, rt, d); }
void XORIS(GPR const rt, GPR const ra, uint32_t d) { emit_D(0x6c000000, ra, rt, d); }
-340
View File
@@ -1,340 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <catch2/catch_test_macros.hpp>
#include <sys/mman.h>
#include "powah_emit.hpp"
#define EB32(X) __bswap32(X)
TEST_CASE("ppc64: addi", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.ADDI(powah::R2, powah::R2, 0);
ctx.ADDIS(powah::R2, powah::R12, 0);
REQUIRE(data[0] == EB32(0x00004238));
REQUIRE(data[1] == EB32(0x00004c3c));
}
TEST_CASE("ppc64: std/mr", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.STD(powah::R26, powah::R1, 144);
ctx.MR(powah::R26, powah::R4);
ctx.STD(powah::R30, powah::R1, 176);
ctx.MR(powah::R30, powah::R3);
ctx.RLDICR(powah::R4, powah::R5, 25, 6);
ctx.STD(powah::R28, powah::R1, 160);
REQUIRE(data[0] == EB32(0x900041fb));
REQUIRE(data[1] == EB32(0x78239a7c));
REQUIRE(data[2] == EB32(0xb000c1fb));
REQUIRE(data[3] == EB32(0x781b7e7c));
REQUIRE(data[4] == EB32(0x84c9a478));
REQUIRE(data[5] == EB32(0xa00081fb));
}
TEST_CASE("ppc64: sldi", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.SLDI(powah::R3, powah::R5, 37);
REQUIRE(data[0] == EB32(0x862ea378));
}
TEST_CASE("ppc64: rldicr", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.RLDICR(powah::R1, powah::R1, 0, 0);
ctx.RLDICR(powah::R1, powah::R1, 1, 0);
ctx.RLDICR(powah::R1, powah::R1, 0, 1);
ctx.RLDICR(powah::R1, powah::R1, 1, 1);
ctx.RLDICR(powah::R1, powah::R1, 31, 31);
REQUIRE(data[0] == EB32(0x04002178));
REQUIRE(data[1] == EB32(0x04082178));
REQUIRE(data[2] == EB32(0x44002178));
REQUIRE(data[3] == EB32(0x44082178));
REQUIRE(data[4] == EB32(0xc4ff2178));
}
TEST_CASE("ppc64: mr/or/std", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.MR(powah::R27, powah::R7);
ctx.MR(powah::R29, powah::R6);
ctx.OR(powah::R3, powah::R3, powah::R4);
ctx.MR(powah::R4, powah::R28);
ctx.CRMOVE(powah::CPR{8}, powah::CPR{1});
ctx.MR(powah::R25, powah::R5);
ctx.OR(powah::R3, powah::R3, powah::R26);
ctx.STD(powah::R3, powah::R1, 56);
ctx.MR(powah::R3, powah::R30);
REQUIRE(data[0] == EB32(0x783bfb7c));
REQUIRE(data[1] == EB32(0x7833dd7c));
REQUIRE(data[2] == EB32(0x7823637c));
REQUIRE(data[3] == EB32(0x78e3847f));
REQUIRE(data[4] == EB32(0x820b014d));
REQUIRE(data[5] == EB32(0x782bb97c));
REQUIRE(data[6] == EB32(0x78d3637c));
REQUIRE(data[7] == EB32(0x380061f8));
REQUIRE(data[8] == EB32(0x78f3c37f));
}
TEST_CASE("ppc64: ld/crand+addi", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.LD(powah::R4, powah::R1, 72);
ctx.LWZ(powah::R5, powah::R1, 80);
ctx.CRAND(powah::CPR{20}, powah::CPR{10}, powah::CPR{9});
ctx.ADDI(powah::R6, powah::R4, 4);
ctx.ANDIS_(powah::R4, powah::R5, 1992);
ctx.LD(powah::R5, powah::R30, 1984);
ctx.LBZ(powah::R3, powah::R1, 84);
ctx.CLRLDI(powah::R26, powah::R6, 8);
ctx.STW(powah::R4, powah::R1, 80);
ctx.ADDI(powah::R5, powah::R5, 1);
ctx.STD(powah::R26, powah::R1, 72);
ctx.STD(powah::R5, powah::R30, 1984);
REQUIRE(data[0] == EB32(0x480081e8));
REQUIRE(data[1] == EB32(0x5000a180));
REQUIRE(data[2] == EB32(0x024a8a4e));
REQUIRE(data[3] == EB32(0x0400c438));
REQUIRE(data[4] == EB32(0xc807a474));
REQUIRE(data[5] == EB32(0xc007bee8));
REQUIRE(data[6] == EB32(0x54006188));
REQUIRE(data[7] == EB32(0x0002da78));
REQUIRE(data[8] == EB32(0x50008190));
REQUIRE(data[9] == EB32(0x0100a538));
REQUIRE(data[10] == EB32(0x480041fb));
REQUIRE(data[11] == EB32(0xc007bef8));
}
TEST_CASE("ppc64: rotldi", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.ROTLDI(powah::R5, powah::R3, 16);
ctx.ROTLDI(powah::R4, powah::R3, 8);
ctx.RLDIMI(powah::R4, powah::R5, 8, 48);
ctx.ROTLDI(powah::R5, powah::R3, 24);
ctx.RLDIMI(powah::R4, powah::R5, 16, 40);
ctx.ROTLDI(powah::R5, powah::R3, 32);
ctx.RLDIMI(powah::R4, powah::R5, 24, 32);
ctx.ROTLDI(powah::R5, powah::R3, 48);
ctx.RLDIMI(powah::R4, powah::R5, 40, 16);
ctx.ROTLDI(powah::R5, powah::R3, 56);
ctx.RLDIMI(powah::R4, powah::R5, 48, 8);
ctx.RLDIMI(powah::R4, powah::R3, 56, 0);
ctx.MR(powah::R3, powah::R4);
REQUIRE(data[0] == EB32(0x00806578));
REQUIRE(data[1] == EB32(0x00406478));
REQUIRE(data[2] == EB32(0x2c44a478));
REQUIRE(data[3] == EB32(0x00c06578));
REQUIRE(data[4] == EB32(0x2c82a478));
REQUIRE(data[5] == EB32(0x02006578));
REQUIRE(data[6] == EB32(0x2cc0a478));
REQUIRE(data[7] == EB32(0x02806578));
REQUIRE(data[8] == EB32(0x0e44a478));
REQUIRE(data[9] == EB32(0x02c06578));
REQUIRE(data[10] == EB32(0x0e82a478));
REQUIRE(data[11] == EB32(0x0ec06478));
REQUIRE(data[12] == EB32(0x7823837c));
}
TEST_CASE("ppc64: branch-backwards", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
powah::Label l_3 = ctx.DefineLabel();
ctx.LABEL(l_3);
ctx.ADD(powah::R1, powah::R2, powah::R3);
ctx.B(l_3);
ctx.ApplyRelocs();
REQUIRE(data[0] == EB32(0x141a227c));
REQUIRE(data[1] == EB32(0xfcffff4b));
}
TEST_CASE("ppc64: rlwimi madness", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.ROTLWI(powah::R10, powah::R3, 24);
ctx.SRDI(powah::R9, powah::R3, 32);
ctx.RLWIMI(powah::R10, powah::R3, 8, 8, 15);
ctx.RLWIMI(powah::R10, powah::R3, 8, 24, 31);
ctx.ROTLWI(powah::R3, powah::R9, 24);
ctx.RLWIMI(powah::R3, powah::R9, 8, 8, 15);
ctx.RLWIMI(powah::R3, powah::R9, 8, 24, 31);
ctx.RLDIMI(powah::R3, powah::R10, 32, 0);
REQUIRE(data[0] == EB32(0x3ec06a54));
REQUIRE(data[1] == EB32(0x22006978));
REQUIRE(data[2] == EB32(0x1e426a50));
REQUIRE(data[3] == EB32(0x3e466a50));
REQUIRE(data[4] == EB32(0x3ec02355));
REQUIRE(data[5] == EB32(0x1e422351));
REQUIRE(data[6] == EB32(0x3e462351));
REQUIRE(data[7] == EB32(0x0e004379));
}
/*
0: 78 1b 68 7c mr 8, 3
4: 38 28 83 7c and 3, 4, 5
8: 74 00 6a 7c cntlzd 10, 3
c: 76 06 69 7c sradi 9, 3, 32
10: 82 d1 4a 79 rldicl 10, 10, 58, 6
14: 00 00 29 55 rlwinm 9, 9, 0, 0, 0
18: 64 f0 4a 79 sldi 10, 10, 30
1c: 78 53 29 7d or 9, 9, 10
20: 00 00 28 f9 std 9, 0(8)
24: 20 00 80 4e blr
*/
TEST_CASE("ppc64: functor-2", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
ctx.MR(powah::R8, powah::R3);
ctx.AND(powah::R3, powah::R4, powah::R5);
ctx.CNTLZD(powah::R10, powah::R3);
ctx.SRADI(powah::R9, powah::R3, 32);
ctx.RLDICL(powah::R10, powah::R10, 58, 6);
ctx.RLWINM(powah::R9, powah::R9, 0, 0, 0);
ctx.SLDI(powah::R10, powah::R10, 30);
ctx.OR(powah::R9, powah::R9, powah::R10);
ctx.STD(powah::R9, powah::R8, 0);
ctx.BLR();
REQUIRE(data[0] == EB32(0x781b687c));
REQUIRE(data[1] == EB32(0x3828837c));
REQUIRE(data[2] == EB32(0x74006a7c));
REQUIRE(data[3] == EB32(0x7606697c));
REQUIRE(data[4] == EB32(0x82d14a79));
REQUIRE(data[5] == EB32(0x00002955));
REQUIRE(data[6] == EB32(0x64f04a79));
REQUIRE(data[7] == EB32(0x7853297d));
REQUIRE(data[8] == EB32(0x000028f9));
REQUIRE(data[9] == EB32(0x2000804e));
}
TEST_CASE("ppc64: functor-1", "[ppc64]") {
std::vector<uint32_t> data(64);
powah::Context ctx(data.data(), data.size());
powah::Label l_4 = ctx.DefineLabel();
powah::Label l_7 = ctx.DefineLabel();
ctx.CMPLD(powah::CR0, powah::R3, powah::R4);
ctx.MR(powah::R9, powah::R3);
ctx.BGT(powah::CR0, l_7);
ctx.CMPLDI(powah::CR0, powah::R3, 3781);
ctx.LI(powah::R3, 1);
ctx.BGTLR(powah::CR0);
ctx.CMPLD(powah::CR0, powah::R9, powah::R5);
ctx.BLE(powah::CR0, l_4);
ctx.SUBF(powah::R5, powah::R9, powah::R5);
ctx.XOR(powah::R3, powah::R5, powah::R4);
ctx.BLR();
ctx.LABEL(l_4);
ctx.ADD(powah::R5, powah::R4, powah::R5);
ctx.ADD(powah::R3, powah::R5, powah::R9);
ctx.BLR();
ctx.LABEL(l_7);
ctx.ADD(powah::R3, powah::R4, powah::R5);
ctx.BLR();
ctx.ApplyRelocs();
REQUIRE(data[0] == EB32(0x4020237c));
REQUIRE(data[1] == EB32(0x781b697c));
REQUIRE(data[2] == EB32(0x30008141));
REQUIRE(data[3] == EB32(0xc50e2328));
REQUIRE(data[4] == EB32(0x01006038));
REQUIRE(data[5] == EB32(0x2000814d));
REQUIRE(data[6] == EB32(0x4028297c));
REQUIRE(data[7] == EB32(0x10008140));
REQUIRE(data[8] == EB32(0x5028a97c));
REQUIRE(data[9] == EB32(0x7822a37c));
REQUIRE(data[10] == EB32(0x2000804e));
REQUIRE(data[11] == EB32(0x142aa47c));
REQUIRE(data[12] == EB32(0x144a657c));
REQUIRE(data[13] == EB32(0x2000804e));
REQUIRE(data[14] == EB32(0x142a647c));
REQUIRE(data[15] == EB32(0x2000804e));
}
#if defined(ARCHITECTURE_powerpc64)
/*
0: d619637c mullw 3, 3, 3
4: 20006378 clrldi 3, 3, 32
8: 2000804e blr
*/
TEST_CASE("ppc64: live-exec square", "[ppc64]") {
uint32_t* data = (uint32_t*)mmap(nullptr, 4096, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
REQUIRE(data != nullptr);
powah::Context ctx((void*)data, 4096);
ctx.MULLW(powah::R3, powah::R3, powah::R3);
ctx.CLRLDI(powah::R3, powah::R3, 32);
ctx.BLR();
REQUIRE(data[0] == EB32(0xd619637c));
REQUIRE(data[1] == EB32(0x20006378));
REQUIRE(data[2] == EB32(0x2000804e));
auto* fn = (int (*)(int))data;
REQUIRE(fn(4) == 4 * 4);
REQUIRE(fn(8) == 8 * 8);
munmap((void*)data, 4096);
}
/*
int f(int a, int b, int c) {
a += (a > b) ? b - 0xffff : c + 402, b += 2, c &= b*c;
return a * a + b ^ c & b;
}
*/
TEST_CASE("ppc64: live-exec xoralu", "[ppc64]") {
uint32_t* data = (uint32_t*)mmap(nullptr, 4096, PROT_WRITE | PROT_READ | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
REQUIRE(data != nullptr);
powah::Context ctx((void*)data, 4096);
powah::Label l_2 = ctx.DefineLabel();
powah::Label l_3 = ctx.DefineLabel();
ctx.CMPW(powah::R3, powah::R4);
ctx.BGT(powah::CR0, l_2);
ctx.ADDI(powah::R6, powah::R5, 402);
ctx.B(l_3);
ctx.LABEL(l_2);
ctx.ADDI(powah::R6, powah::R4, 1);
ctx.ADDIS(powah::R6, powah::R6, -1);
ctx.LABEL(l_3);
ctx.ADDI(powah::R4, powah::R4, 2);
ctx.ADD(powah::R3, powah::R6, powah::R3);
ctx.MULLW(powah::R6, powah::R4, powah::R5);
ctx.MULLW(powah::R3, powah::R3, powah::R3);
ctx.AND(powah::R5, powah::R5, powah::R6);
ctx.ADD(powah::R3, powah::R3, powah::R4);
ctx.AND(powah::R4, powah::R5, powah::R4);
ctx.XOR(powah::R3, powah::R3, powah::R4);
ctx.EXTSW(powah::R3, powah::R3);
ctx.BLR();
ctx.ApplyRelocs();
REQUIRE(data[0] == EB32(0x0020037c));
REQUIRE(data[1] == EB32(0x0c008141));
REQUIRE(data[2] == EB32(0x9201c538));
REQUIRE(data[3] == EB32(0x0c000048));
REQUIRE(data[4] == EB32(0x0100c438));
REQUIRE(data[5] == EB32(0xffffc63c));
REQUIRE(data[6] == EB32(0x02008438));
REQUIRE(data[7] == EB32(0x141a667c));
REQUIRE(data[8] == EB32(0xd629c47c));
REQUIRE(data[9] == EB32(0xd619637c));
REQUIRE(data[10] == EB32(0x3830a57c));
REQUIRE(data[11] == EB32(0x1422637c));
REQUIRE(data[12] == EB32(0x3820a47c));
REQUIRE(data[13] == EB32(0x7822637c));
REQUIRE(data[14] == EB32(0xb407637c));
REQUIRE(data[15] == EB32(0x2000804e));
auto const orig = [](int a, int b, int c) {
a += (a > b) ? b - 0xffff : c + 402, b += 2, c &= b*c;
return a * a + b ^ c & b;
};
auto* fn = (int (*)(int, int, int))data;
REQUIRE(fn(0, 1, 2) == orig(0, 1, 2));
REQUIRE(fn(6456, 4564, 4564561) == orig(6456, 4564, 4564561));
munmap((void*)data, 4096);
}
#endif
+1 -1
View File
@@ -8,7 +8,7 @@
include_directories(.)
# Dynarmic
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_loongarch64 OR ARCHITECTURE_powerpc64) AND NOT YUZU_STATIC_ROOM)
if ((ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64 OR ARCHITECTURE_riscv64 OR ARCHITECTURE_loongarch64) AND NOT YUZU_STATIC_ROOM)
add_subdirectory(dynarmic)
add_library(dynarmic::dynarmic ALIAS dynarmic)
endif()
@@ -539,6 +539,40 @@ object NativeLibrary {
*/
external fun installKeys(path: String, ext: String): Int
/**
* @return Whether this GPU can run the Lossless Scaling frame generation shaders,
* which are built against the Vulkan memory model.
*/
external fun supportsFrameGeneration(): Boolean
/**
* @return Path the user-supplied Lossless Scaling library is expected at.
*/
external fun getLosslessDllPath(): String
/**
* Parses the installed Lossless Scaling library and checks that every shader the
* frame generation chain needs is present.
*
* @return The result code, matching the losslessDllResults array.
*/
external fun validateLosslessDll(): Int
/**
* Translates the frame generation shaders out of the installed Lossless Scaling library
* and writes them to the SPIR-V cache. Slow, so call it off the main thread.
*
* @return The result code, matching the losslessDllResults array.
*/
external fun prepareLosslessDll(): Int
/**
* Deletes the installed Lossless Scaling library.
*
* @return Whether the library is gone after the call.
*/
external fun removeLosslessDll(): Boolean
/**
* Checks the PatchManager for any addons that are available
*
@@ -559,6 +559,15 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener, InputManager
private fun enableFullscreenImmersive() {
WindowCompat.setDecorFitsSystemWindows(window, false)
@Suppress("DEPRECATION")
window.decorView.systemUiVisibility =
View.SYSTEM_UI_FLAG_FULLSCREEN or
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
controller.hide(WindowInsetsCompat.Type.systemBars())
controller.systemBarsBehavior =
@@ -37,6 +37,10 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
RENDERER_PATCH_OLD_QCOM_DRIVERS("patch_old_qcom_drivers"),
RENDERER_VERTEX_INPUT_DYNAMIC_STATE("vertex_input_dynamic_state"),
RENDERER_SAMPLE_SHADING("sample_shading"),
RENDERER_FRAME_GEN("frame_gen"),
RENDERER_FRAME_GEN_FP16("frame_gen_fp16"),
RENDERER_FRAME_GEN_FLOW_SCALE_AUTO("frame_gen_flow_scale_auto"),
RENDERER_FRAME_GEN_DUMP_FLOW("frame_gen_dump_flow"),
GPU_UNSWIZZLE_ENABLED("gpu_unswizzle_enabled"),
PICTURE_IN_PICTURE("picture_in_picture"),
USE_CUSTOM_RTC("custom_rtc_enabled"),
@@ -19,6 +19,10 @@ enum class IntSetting(override val key: String) : AbstractIntSetting {
RENDERER_ASTC_DECODE_METHOD("accelerate_astc"),
RENDERER_ACCURACY("gpu_accuracy"),
RENDERER_RESOLUTION("resolution_setup"),
RENDERER_FRAME_GEN_MULTIPLIER("frame_gen_multiplier"),
RENDERER_FRAME_GEN_TARGET_RATE("frame_gen_target_rate"),
RENDERER_FRAME_GEN_QUEUE_TARGET("frame_gen_queue_target"),
RENDERER_FRAME_GEN_FLOW_SCALE("frame_gen_flow_scale"),
RENDERER_VSYNC("use_vsync"),
RENDERER_SCALING_FILTER("scaling_filter"),
RENDERER_ANTI_ALIASING("anti_aliasing"),
@@ -11,6 +11,7 @@ object Settings {
SECTION_ROOT(R.string.advanced_settings),
SECTION_SYSTEM(R.string.preferences_system),
SECTION_RENDERER(R.string.preferences_graphics),
SECTION_FRAME_GEN(R.string.frame_gen),
SECTION_PERFORMANCE_STATS(R.string.stats_overlay_options),
SECTION_INPUT_OVERLAY(R.string.input_overlay_options),
SECTION_SOC_OVERLAY(R.string.soc_overlay_options),
@@ -21,6 +21,7 @@ import org.yuzu.yuzu_emu.features.settings.model.LongSetting
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.network.NetDataValidators
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
import org.yuzu.yuzu_emu.utils.NativeConfig
/**
@@ -65,6 +66,19 @@ abstract class SettingsItem(
return NativeLibrary.isFirmwareAvailable()
}
if (setting.key in frameGenKeys &&
!(LosslessScalingHelper.isInstalled() && LosslessScalingHelper.isSupportedByGpu())
) {
return false
}
// A frame rate target moves the multiplier on its own
if (setting.key == IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key &&
frameGenTargetRate != 0
) {
return false
}
// Can't edit settings that aren't saveable in per-game config even if they are switchable
if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) {
return false
@@ -88,7 +102,31 @@ abstract class SettingsItem(
val clearable: Boolean
get() = !setting.global && NativeConfig.isPerGameConfigLoaded()
private val frameGenTargetRate: Int
get() {
val key = IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key
val needsGlobal = if (NativeLibrary.isRunning() &&
!NativeConfig.isPerGameConfigLoaded()
) {
!NativeConfig.usingGlobal(key)
} else {
NativeConfig.usingGlobal(key)
}
return IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.getInt(needsGlobal)
}
companion object {
private val frameGenKeys = setOf(
BooleanSetting.RENDERER_FRAME_GEN.key,
IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key,
IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key,
IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET.key,
BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key,
IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.key,
BooleanSetting.RENDERER_FRAME_GEN_FP16.key,
BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW.key
)
const val TYPE_HEADER = 0
const val TYPE_SWITCH = 1
const val TYPE_SINGLE_CHOICE = 2
@@ -607,6 +645,71 @@ abstract class SettingsItem(
valuesId = R.array.rendererAntiAliasingValues
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_FRAME_GEN,
titleId = R.string.frame_gen,
descriptionId = R.string.frame_gen_description
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_FRAME_GEN_MULTIPLIER,
titleId = R.string.frame_gen_multiplier,
descriptionId = R.string.frame_gen_multiplier_description,
choicesId = R.array.frameGenMultiplierNames,
valuesId = R.array.frameGenMultiplierValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_FRAME_GEN_TARGET_RATE,
titleId = R.string.frame_gen_target_rate,
descriptionId = R.string.frame_gen_target_rate_description,
choicesId = R.array.frameGenTargetRateNames,
valuesId = R.array.frameGenTargetRateValues
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET,
titleId = R.string.frame_gen_queue_target,
descriptionId = R.string.frame_gen_queue_target_description,
choicesId = R.array.frameGenQueueTargetNames,
valuesId = R.array.frameGenQueueTargetValues
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO,
titleId = R.string.frame_gen_flow_scale_auto,
descriptionId = R.string.frame_gen_flow_scale_auto_description
)
)
put(
SliderSetting(
IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE,
titleId = R.string.frame_gen_flow_scale,
descriptionId = R.string.frame_gen_flow_scale_description,
min = 25,
max = 100,
units = "%"
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_FRAME_GEN_FP16,
titleId = R.string.frame_gen_fp16,
descriptionId = R.string.frame_gen_fp16_description
)
)
put(
SwitchSetting(
BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW,
titleId = R.string.frame_gen_dump_flow,
descriptionId = R.string.frame_gen_dump_flow_description
)
)
put(
SingleChoiceSetting(
IntSetting.RENDERER_SCREEN_LAYOUT,
@@ -382,7 +382,9 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
}
scSetting.setSelectedValue(value)
if (scSetting.setting.key == IntSetting.RENDERER_SCALING_FILTER.key) {
if (scSetting.setting.key == IntSetting.RENDERER_SCALING_FILTER.key ||
scSetting.setting.key == IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key
) {
settingsViewModel.setShouldReloadSettingsList(true)
}
@@ -27,6 +27,7 @@ import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
import org.yuzu.yuzu_emu.features.settings.model.view.*
import org.yuzu.yuzu_emu.utils.InputHandler
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
import org.yuzu.yuzu_emu.utils.FullscreenHelper
@@ -76,6 +77,41 @@ class SettingsFragmentPresenter(
}
}
private fun addFrameGenSettings(sl: ArrayList<SettingsItem>) {
sl.apply {
if (!LosslessScalingHelper.isSupportedByGpu()) {
add(
RunnableSetting(
titleId = R.string.frame_gen_unsupported,
descriptionId = R.string.frame_gen_unsupported_description,
isRunnable = false
) {}
)
} else if (!LosslessScalingHelper.isInstalled()) {
add(
RunnableSetting(
titleId = R.string.lossless_scaling_missing,
descriptionId = R.string.lossless_scaling_missing_description,
isRunnable = false
) {}
)
}
add(BooleanSetting.RENDERER_FRAME_GEN.key)
add(IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key)
add(IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key)
add(IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET.key)
add(BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key)
if (!BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.getBoolean(
getNeedsGlobalForKey(BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key)
)
) {
add(IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.key)
}
add(BooleanSetting.RENDERER_FRAME_GEN_FP16.key)
}
}
private fun isSharpnessScalingFilterSelected(): Boolean {
val needsGlobal = getNeedsGlobalForKey(IntSetting.RENDERER_SCALING_FILTER.key)
val selectedFilter = IntSetting.RENDERER_SCALING_FILTER.getInt(needsGlobal)
@@ -120,6 +156,7 @@ class SettingsFragmentPresenter(
MenuTag.SECTION_ROOT -> addConfigSettings(sl)
MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
MenuTag.SECTION_FRAME_GEN -> addFrameGenSettings(sl)
MenuTag.SECTION_PERFORMANCE_STATS -> addPerformanceOverlaySettings(sl)
MenuTag.SECTION_SOC_OVERLAY -> addSocOverlaySettings(sl)
MenuTag.SECTION_INPUT_OVERLAY -> addInputOverlaySettings(sl)
@@ -302,7 +339,6 @@ class SettingsFragmentPresenter(
add(BooleanSetting.SKIP_CPU_INNER_INVALIDATION.key)
add(BooleanSetting.FIX_BLOOM_EFFECTS.key)
add(BooleanSetting.EMULATE_BGR565.key)
add(BooleanSetting.RESCALE_HACK.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
add(IntSetting.ANDROID_PIPELINE_WORKERS.key)
add(BooleanSetting.RENDERER_ASYNCHRONOUS_GPU_EMULATION.key)
@@ -1296,6 +1332,7 @@ class SettingsFragmentPresenter(
add(BooleanSetting.DUMP_GUEST_SHADERS.key)
add(BooleanSetting.GPU_LOG_SHADER_DUMPS.key)
add(BooleanSetting.DUMP_MACROS.key)
add(BooleanSetting.RENDERER_FRAME_GEN_DUMP_FLOW.key)
add(BooleanSetting.GPU_LOG_MEMORY_TRACKING.key)
add(BooleanSetting.GPU_LOG_DRIVER_DEBUG.key)
add(IntSetting.GPU_LOG_RING_BUFFER_SIZE.key)
@@ -29,6 +29,7 @@ enum class SettingsSubscreen {
DRIVER_MANAGER,
DRIVER_FETCHER,
FREEDRENO_SETTINGS,
LOSSLESS_MANAGER,
APPLET_LAUNCHER,
INSTALLABLE,
GAME_FOLDERS,
@@ -126,6 +127,7 @@ class SettingsSubscreenActivity : AppCompatActivity() {
SettingsSubscreen.DRIVER_MANAGER -> R.id.driverManagerFragment
SettingsSubscreen.DRIVER_FETCHER -> R.id.driverFetcherFragment
SettingsSubscreen.FREEDRENO_SETTINGS -> R.id.freedrenoSettingsFragment
SettingsSubscreen.LOSSLESS_MANAGER -> R.id.losslessManagerFragment
SettingsSubscreen.APPLET_LAUNCHER -> R.id.appletLauncherFragment
SettingsSubscreen.INSTALLABLE -> R.id.installableFragment
SettingsSubscreen.GAME_FOLDERS -> R.id.gameFoldersFragment
@@ -369,6 +369,21 @@ class GamePropertiesFragment : Fragment() {
)
)
}
add(
SubmenuProperty(
R.string.frame_gen,
R.string.frame_gen_per_game_description,
R.drawable.ic_duck,
action = {
val action = HomeNavigationDirections.actionGlobalSettingsActivity(
args.game,
Settings.MenuTag.SECTION_FRAME_GEN
)
binding.root.findNavController().navigate(action)
}
)
)
if (GpuDriverHelper.isAdrenoGpu()) {
add(
SubmenuProperty(
@@ -44,6 +44,7 @@ import org.yuzu.yuzu_emu.ui.main.MainActivity
import org.yuzu.yuzu_emu.utils.FileUtil
import org.yuzu.yuzu_emu.utils.GpuDriverHelper
import org.yuzu.yuzu_emu.utils.Log
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
class HomeSettingsFragment : Fragment() {
@@ -170,6 +171,24 @@ class HomeSettingsFragment : Fragment() {
)
)
}
add(
HomeSetting(
R.string.lossless_scaling,
R.string.lossless_scaling_description,
R.drawable.ic_duck,
{
val action = HomeNavigationDirections.actionGlobalSettingsSubscreenActivity(
SettingsSubscreen.LOSSLESS_MANAGER,
null
)
binding.root.findNavController().navigate(action)
},
{ true },
0,
0,
LosslessScalingHelper.statusText
)
)
add(
HomeSetting(
R.string.multiplayer,
@@ -337,6 +356,7 @@ class HomeSettingsFragment : Fragment() {
override fun onResume() {
super.onResume()
driverViewModel.updateDriverNameForGame(null)
LosslessScalingHelper.refreshStatus()
}
override fun onDestroyView() {
@@ -0,0 +1,174 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.fragments
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import com.google.android.material.transition.MaterialSharedAxis
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.adapters.HomeSettingAdapter
import org.yuzu.yuzu_emu.databinding.FragmentLosslessManagerBinding
import org.yuzu.yuzu_emu.features.fetcher.SpacingItemDecoration
import org.yuzu.yuzu_emu.model.HomeSetting
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
import org.yuzu.yuzu_emu.utils.ViewUtils.updateMargins
import org.yuzu.yuzu_emu.utils.collect
class LosslessManagerFragment : Fragment() {
private var _binding: FragmentLosslessManagerBinding? = null
private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentLosslessManagerBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.toolbarLossless.setNavigationOnClickListener {
requireActivity().onBackPressedDispatcher.onBackPressed()
}
binding.losslessOptionsList.apply {
layoutManager =
GridLayoutManager(requireContext(), resources.getInteger(R.integer.grid_columns))
addItemDecoration(
SpacingItemDecoration(resources.getDimensionPixelSize(R.dimen.spacing_small))
)
}
LosslessScalingHelper.statusText.collect(viewLifecycleOwner) { refreshOptions() }
setInsets()
}
private fun refreshOptions() {
binding.losslessOptionsList.adapter = HomeSettingAdapter(
requireActivity() as AppCompatActivity,
viewLifecycleOwner,
buildOptions()
)
}
private fun buildOptions(): List<HomeSetting> {
val installed = LosslessScalingHelper.isInstalled()
return listOf(
HomeSetting(
if (installed) R.string.lossless_scaling_replace else R.string.lossless_scaling_install,
if (installed) {
R.string.lossless_scaling_replace_description
} else {
R.string.lossless_scaling_install_description
},
R.drawable.ic_install,
{ dllPickerLauncher.launch(arrayOf("*/*")) },
{ !NativeLibrary.isRunning() },
R.string.lossless_scaling_locked,
R.string.lossless_scaling_locked_description,
LosslessScalingHelper.statusText
),
HomeSetting(
R.string.lossless_scaling_remove,
R.string.lossless_scaling_remove_description,
R.drawable.ic_delete,
{ confirmRemoval() },
{ installed && !NativeLibrary.isRunning() },
if (installed) {
R.string.lossless_scaling_locked
} else {
R.string.lossless_scaling_remove_unavailable
},
if (installed) {
R.string.lossless_scaling_locked_description
} else {
R.string.lossless_scaling_remove_unavailable_description
}
)
)
}
private fun confirmRemoval() {
MessageDialogFragment.newInstance(
requireActivity(),
titleId = R.string.lossless_scaling_remove,
descriptionId = R.string.lossless_scaling_remove_confirmation,
positiveButtonTitleId = R.string.lossless_scaling_remove,
positiveAction = { LosslessScalingHelper.remove() },
showNegativeButton = true,
negativeAction = {}
).show(parentFragmentManager, MessageDialogFragment.TAG)
}
private val dllPickerLauncher =
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
if (result == null) {
return@registerForActivityResult
}
val resultStrings = resources.getStringArray(R.array.losslessDllResults)
ProgressDialogFragment.newInstance(
requireActivity(),
R.string.lossless_scaling_installing,
false
) { _, _ ->
val installResult = LosslessScalingHelper.install(result)
if (installResult == LosslessScalingHelper.RESULT_OK) {
getString(R.string.lossless_scaling_install_success)
} else {
MessageDialogFragment.newInstance(
titleId = R.string.lossless_scaling_install_failed,
descriptionString = resultStrings[installResult]
)
}
}.show(parentFragmentManager, ProgressDialogFragment.TAG)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun setInsets() =
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _, windowInsets ->
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
binding.appbarLossless.updateMargins(
left = barInsets.left + cutoutInsets.left,
right = barInsets.right + cutoutInsets.right
)
binding.scrollViewLossless.updatePadding(bottom = barInsets.bottom)
binding.losslessOptionsList.updatePadding(
left = barInsets.left + cutoutInsets.left,
right = barInsets.right + cutoutInsets.right
)
windowInsets
}
}
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.fragments
@@ -42,6 +42,7 @@ import org.yuzu.yuzu_emu.model.SetupPage
import org.yuzu.yuzu_emu.model.PageState
import org.yuzu.yuzu_emu.ui.main.MainActivity
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
import org.yuzu.yuzu_emu.utils.LosslessScalingHelper
import org.yuzu.yuzu_emu.utils.NativeConfig
import org.yuzu.yuzu_emu.utils.ViewUtils
import org.yuzu.yuzu_emu.utils.ViewUtils.setVisible
@@ -202,6 +203,24 @@ class SetupFragment : Fragment() {
R.string.install_firmware_warning_help,
)
)
add(
PageButton(
R.drawable.ic_duck,
R.string.lossless_scaling,
R.string.lossless_scaling_setup_description,
{
pageButtonCallback = it
getLosslessDll.launch(arrayOf("*/*"))
},
{
if (LosslessScalingHelper.isInstalled()) {
ButtonState.BUTTON_ACTION_COMPLETE
} else {
ButtonState.BUTTON_ACTION_INCOMPLETE
}
}
)
)
add(
PageButton(
R.drawable.ic_controller,
@@ -446,6 +465,32 @@ class SetupFragment : Fragment() {
}
}
val getLosslessDll =
registerForActivityResult(ActivityResultContracts.OpenDocument()) { result ->
if (result == null) {
return@registerForActivityResult
}
val resultStrings = resources.getStringArray(R.array.losslessDllResults)
ProgressDialogFragment.newInstance(
requireActivity(),
R.string.lossless_scaling_installing,
false
) { _, _ ->
val installResult = LosslessScalingHelper.install(result)
if (installResult == LosslessScalingHelper.RESULT_OK) {
getString(R.string.lossless_scaling_install_success)
} else {
MessageDialogFragment.newInstance(
titleId = R.string.lossless_scaling_install_failed,
descriptionString = resultStrings[installResult]
)
}
}.apply {
onDialogComplete = { checkForButtonState.invoke() }
}.show(parentFragmentManager, ProgressDialogFragment.TAG)
}
val getGamesDirectory =
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { result ->
if (result != null) {
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.fragments
@@ -72,6 +72,18 @@ class SystemInfoDialogFragment : DialogFragment() {
val vulkanDriver = NativeLibrary.getVulkanDriverVersion()
appendLine("${getString(R.string.vulkan_driver_version)}: $vulkanDriver")
val frameGen = NativeLibrary.supportsFrameGeneration()
appendLine(
"${getString(R.string.frame_generation_support)}: " +
getString(
if (frameGen) {
R.string.frame_generation_supported
} else {
R.string.frame_generation_unsupported
}
)
)
} catch (e: Exception) {
appendLine("${getString(R.string.error_getting_emulator_info)}: ${e.message}")
}
@@ -0,0 +1,77 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
package org.yuzu.yuzu_emu.utils
import android.net.Uri
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
import java.io.File
object LosslessScalingHelper {
const val RESULT_OK = 0
const val RESULT_NOT_INSTALLED = 1
private val _statusText = MutableStateFlow("")
val statusText: StateFlow<String> = _statusText.asStateFlow()
private var installed: Boolean? = null
private var gpuSupported: Boolean? = null
fun isInstalled(): Boolean = installed ?: refreshStatus()
fun isSupportedByGpu(): Boolean {
val cached = gpuSupported
if (cached != null) {
return cached
}
val result = NativeLibrary.supportsFrameGeneration()
gpuSupported = result
return result
}
fun refreshStatus(): Boolean {
val result = NativeLibrary.validateLosslessDll() == RESULT_OK
installed = result
val context = YuzuApplication.appContext
_statusText.value = if (result) {
context.getString(R.string.lossless_scaling_installed)
} else {
context.getString(R.string.lossless_scaling_not_installed)
}
return result
}
fun install(source: Uri): Int {
val destination = File(NativeLibrary.getLosslessDllPath())
destination.parentFile?.mkdirs()
val copied = FileUtil.copyUriToInternalStorage(
source,
destination.parent!!,
destination.name
)
if (copied == null) {
refreshStatus()
return RESULT_NOT_INSTALLED
}
val result = NativeLibrary.prepareLosslessDll()
if (result != RESULT_OK) {
NativeLibrary.removeLosslessDll()
}
refreshStatus()
return result
}
fun remove(): Boolean {
val removed = NativeLibrary.removeLosslessDll()
refreshStatus()
return removed
}
}
@@ -33,8 +33,8 @@ void AndroidConfig::SaveAllValues() {
}
void AndroidConfig::ReadAndroidValues() {
ReadAndroidUIValues();
if (global) {
ReadAndroidUIValues();
ReadUIValues();
BeginGroup(Settings::TranslateCategory(Settings::Category::DataStorage));
Settings::values.ext_content_from_game_dirs = ReadBooleanSetting(
@@ -223,8 +223,8 @@ void AndroidConfig::ReadAndroidControlValues() {
}
void AndroidConfig::SaveAndroidValues() {
SaveAndroidUIValues();
if (global) {
SaveAndroidUIValues();
SaveUIValues();
SaveOverlayValues();
}
@@ -147,7 +147,7 @@ namespace AndroidSettings {
&show_performance_overlay};
Settings::Setting<s32> pipeline_worker_count{linkage, 4, "pipeline_worker_count",
Settings::SwitchableSetting<s32> pipeline_worker_count{linkage, 2, "pipeline_worker_count",
Settings::Category::Android,
Settings::Specialization::Default,
true,
@@ -124,9 +124,18 @@ float EmuWindow_Android::GetFrameTimeVerifiedHint() const {
return QuantizeFrameRateHint(verified_rate);
}
float EmuWindow_Android::GetPresentedFrameMultiplier() {
if (!Settings::values.frame_gen.GetValue()) {
return 1.0f;
}
return static_cast<float>(std::clamp<u32>(Settings::values.frame_gen_multiplier.GetValue(), 2, 4));
}
float EmuWindow_Android::GetFrameRateHint() const {
const float observed_rate = std::clamp(m_smoothed_present_rate, 0.0f, 240.0f);
const float frame_time_verified_hint = GetFrameTimeVerifiedHint();
const float presented_multiplier = GetPresentedFrameMultiplier();
const float observed_rate =
std::clamp(m_smoothed_present_rate * presented_multiplier, 0.0f, 240.0f);
const float frame_time_verified_hint = GetFrameTimeVerifiedHint() * presented_multiplier;
if (m_last_frame_rate_hint > 0.0f && observed_rate > 0.0f) {
const float tolerance = std::max(m_last_frame_rate_hint * 0.12f, 4.0f);
@@ -150,9 +159,9 @@ float EmuWindow_Android::GetFrameRateHint() const {
return frame_time_verified_hint;
}
constexpr float NominalFrameRate = 60.0f;
const float nominal_rate = 60.0f * presented_multiplier;
if (!Settings::values.use_speed_limit.GetValue()) {
return NominalFrameRate;
return QuantizeFrameRateHint(nominal_rate);
}
const u16 speed_limit = Settings::SpeedLimit();
@@ -161,7 +170,7 @@ float EmuWindow_Android::GetFrameRateHint() const {
}
const float speed_limited_rate =
NominalFrameRate * (static_cast<float>(std::min<u16>(speed_limit, 100)) / 100.0f);
nominal_rate * (static_cast<float>(std::min<u16>(speed_limit, 100)) / 100.0f);
return QuantizeFrameRateHint(speed_limited_rate);
}
@@ -61,6 +61,7 @@ private:
void UpdateObservedFrameRate();
[[nodiscard]] float GetFrameRateHint() const;
[[nodiscard]] float GetFrameTimeVerifiedHint() const;
[[nodiscard]] static float GetPresentedFrameMultiplier();
[[nodiscard]] static float QuantizeFrameRateHint(float frame_rate);
float m_window_width{};
+92 -1
View File
@@ -44,6 +44,7 @@ extern "C" {
#include "common/android/android_common.h"
#include "common/android/id_cache.h"
#include "common/dynamic_library.h"
#include "common/fs/fs_util.h"
#include "common/fs/path_util.h"
#include "common/logging.h"
#include "common/scm_rev.h"
@@ -90,6 +91,7 @@ extern "C" {
#include "hid_core/hid_types.h"
#include "input_common/drivers/virtual_amiibo.h"
#include "jni/native.h"
#include "video_core/frame_gen/lossless_dll.h"
#include "video_core/renderer_base.h"
#include "video_core/renderer_vulkan/renderer_vulkan.h"
#include "video_core/capture.h"
@@ -998,7 +1000,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuSummary(JNIEnv* env, jobject
FILE* f = std::fopen(CPUINFO_PATH, "r");
if (!f) return Common::Android::ToJString(env, result);
char buf[512];
char buf[4096];
if (f) {
std::set<std::string> feature_set;
@@ -1029,7 +1031,13 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuSummary(JNIEnv* env, jobject
bool has_dotprod = feature_set.count("asimddp") || feature_set.count("dotprod");
bool has_i8mm = feature_set.count("i8mm");
bool has_bf16 = feature_set.count("bf16");
bool has_fp16 = feature_set.count("fphp") || feature_set.count("asimdhp");
bool has_atomics = feature_set.count("atomics") || feature_set.count("lse");
bool has_lse2 = feature_set.count("uscat");
bool has_rcpc = feature_set.count("lrcpc");
bool has_rcpc2 = feature_set.count("ilrcpc");
bool has_flagm = feature_set.count("flagm");
bool has_flagm2 = feature_set.count("flagm2");
std::string features;
if (has_neon || has_fp) {
@@ -1037,6 +1045,7 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuSummary(JNIEnv* env, jobject
if (has_dotprod) features += "+DP";
if (has_i8mm) features += "+I8MM";
if (has_bf16) features += "+BF16";
if (has_fp16) features += "+FP16";
}
if (has_sve) {
@@ -1053,6 +1062,19 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getCpuSummary(JNIEnv* env, jobject
if (has_atomics) {
if (!features.empty()) features += " | ";
features += "LSE";
if (has_lse2) features += "2";
}
if (has_rcpc) {
if (!features.empty()) features += " | ";
features += "RCpc";
if (has_rcpc2) features += "2";
}
if (has_flagm) {
if (!features.empty()) features += " | ";
features += "FlagM";
if (has_flagm2) features += "2";
}
if (!features.empty()) {
@@ -1090,6 +1112,34 @@ VkPhysicalDeviceProperties GetVulkanDeviceProperties() {
const Vulkan::vk::PhysicalDevice physical_device(physical_devices[0], dld);
return physical_device.GetProperties();
}
bool GetVulkanMemoryModelSupport() {
Common::DynamicLibrary library;
if (!library.Open("libvulkan.so")) {
return false;
}
Vulkan::vk::InstanceDispatch dld;
const auto instance = Vulkan::CreateInstance(library, dld, VK_API_VERSION_1_1);
const auto physical_devices = instance.EnumeratePhysicalDevices();
if (physical_devices.empty()) {
return false;
}
const Vulkan::vk::PhysicalDevice physical_device(physical_devices[0], dld);
VkPhysicalDeviceVulkanMemoryModelFeatures memory_model{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES,
.pNext = nullptr,
};
VkPhysicalDeviceFeatures2 features{
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
.pNext = &memory_model,
};
physical_device.GetFeatures2(features);
return memory_model.vulkanMemoryModel == VK_TRUE;
}
} // namespace
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getVulkanDriverVersion(JNIEnv* env, jobject jobj) {
@@ -1165,6 +1215,14 @@ jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getVulkanApiVersion(JNIEnv* env, j
}
}
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_supportsFrameGeneration(JNIEnv* env, jobject jobj) {
try {
return static_cast<jboolean>(GetVulkanMemoryModelSupport());
} catch (...) {
return static_cast<jboolean>(false);
}
}
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getGpuModel(JNIEnv* env, jobject jobj) {
const auto props = GetVulkanDeviceProperties();
if (props.deviceID == 0) {
@@ -1390,6 +1448,39 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_installKeys(JNIEnv* env, jclass clazz
return static_cast<int>(FirmwareManager::InstallKeys(path, ext));
}
jstring Java_org_yuzu_yuzu_1emu_NativeLibrary_getLosslessDllPath(JNIEnv* env, jclass clazz) {
#ifdef HAS_LSFG
const auto path = VideoCore::FrameGen::GetLosslessDllPath();
return Common::Android::ToJString(env, Common::FS::PathToUTF8String(path));
#else
return Common::Android::ToJString(env, "");
#endif
}
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_validateLosslessDll(JNIEnv* env, jclass clazz) {
#ifdef HAS_LSFG
return static_cast<jint>(VideoCore::FrameGen::GetInstalledLosslessStatus());
#else
return static_cast<jint>(VideoCore::FrameGen::LosslessStatus::NotInstalled);
#endif
}
jint Java_org_yuzu_yuzu_1emu_NativeLibrary_prepareLosslessDll(JNIEnv* env, jclass clazz) {
#ifdef HAS_LSFG
return static_cast<jint>(VideoCore::FrameGen::BuildShaderCache());
#else
return static_cast<jint>(VideoCore::FrameGen::LosslessStatus::NotInstalled);
#endif
}
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_removeLosslessDll(JNIEnv* env, jclass clazz) {
#ifdef HAS_LSFG
return static_cast<jboolean>(VideoCore::FrameGen::RemoveInstalledLosslessDll());
#else
return static_cast<jboolean>(false);
#endif
}
jobjectArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPatchesForFile(JNIEnv* env, jobject jobj,
jstring jpath,
jstring jprogramId) {
@@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M11,10.6a8,5.2 0 1,0 0,10.4a8,5.2 0 1,0 0,-10.4z" />
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M4.6,12.6L0.8,10.2L3.2,15.5z" />
<path
android:fillColor="?attr/colorControlNormal"
android:fillType="evenOdd"
android:pathData="M15.3,3.5a4,4 0 1,0 0,8a4,4 0 1,0 0,-8zM16.6,4.9a1,1 0 1,0 0,2a1,1 0 1,0 0,-2z" />
<path
android:fillColor="?attr/colorControlNormal"
android:pathData="M18.6,6.5L23.2,7.8L18.6,9.3z" />
</vector>
@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_lossless"
style="@style/Widget.Eden.TransparentTopAppBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:touchscreenBlocksFocus="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_lossless"
style="@style/Widget.Eden.TransparentTopToolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:touchscreenBlocksFocus="false"
app:navigationIcon="@drawable/ic_back"
app:title="@string/lossless_scaling" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view_lossless"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/transparent"
android:clipToPadding="false"
android:defaultFocusHighlightEnabled="false"
android:fadeScrollbars="false"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar_lossless">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingTop="16dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/lossless_options_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false"
android:nestedScrollingEnabled="false" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -47,6 +47,12 @@
android:defaultValue="@null" />
</fragment>
<fragment
android:id="@+id/losslessManagerFragment"
android:name="org.yuzu.yuzu_emu.fragments.LosslessManagerFragment"
android:label="@string/lossless_scaling"
tools:layout="@layout/fragment_lossless_manager" />
<fragment
android:id="@+id/appletLauncherFragment"
android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment"
@@ -291,6 +291,22 @@
<string name="gpu_driver_fetcher">أداة جلب برامج تشغيل وحدة المعالجة الرسومية</string>
<string name="gpu_driver_manager">إدارة برامج تشغيل وحدة معالجة الرسومات</string>
<string name="install_gpu_driver_description">تثبيت برامج تشغيل بديلة لأداء أو دقة أفضل</string>
<string name="frame_gen">توليد الإطار</string>
<string name="frame_gen_per_game_description">تكوين إعدادات إنشاء الإطارات لهذه اللعبة</string>
<string name="frame_gen_description">قم بإدراج الإطارات المُستكملة بين الإطارات المُعالجة باستخدام تقنية التحجيم بدون فقدان الجودة. يُفرض هذا الخيار عرض الإطارات وفقًا لترتيب FIFO عند تفعيله.</string>
<string name="frame_gen_multiplier">مضاعف الإطارات</string>
<string name="frame_gen_multiplier_description">عدد الإطارات المطلوب عرضها لكل إطار مُعالَج. تتطلب القيم الأعلى وقت معالجة رسوميات أكبر. طلب عدد إطارات يفوق قدرة الشاشة على عرضه سيؤدي إلى إبطاء المحاكاة.</string>
<string name="frame_gen_multiplier_2x">2x</string>
<string name="frame_gen_multiplier_3x">3x</string>
<string name="frame_gen_multiplier_4x">4x</string>
<string name="frame_gen_target_rate">معدل الإطارات المستهدف</string>
<string name="frame_gen_target_rate_off">استخدم مضاعفًا ثابتًا</string>
<string name="frame_gen_target_rate_60">60 إطارًا في الثانية</string>
<string name="frame_gen_target_rate_90">90 إطارًا في الثانية</string>
<string name="frame_gen_target_rate_120">120 إطارًا في الثانية</string>
<string name="frame_gen_target_rate_144">144 إطارًا في الثانية</string>
<string name="frame_gen_target_rate_165">165 إطارًا في الثانية</string>
<string name="frame_gen_queue_target">هدف قائمة انتظار الإطارات</string>
<string name="advanced_settings">الإعدادات المتقدمة</string>
<string name="settings_description">ضبط إعدادات المحاكي</string>
<string name="search_recently_played">تم تشغيلها مؤخرًا</string>
@@ -444,8 +460,8 @@
<string name="set_custom_rtc">تعيين ساعة مخصصة في الوقت الحقيقي</string>
<!-- CPU -->
<string name="fast_cpu_time">رفع تردد المعالج</string>
<string name="fast_cpu_time_description">يجبر وحدة المعالجة المركزية المحاكاة على العمل بتردد أعلى، مما يقلل بعض محددات معدل الإطارات. استخدم وضع التعزيز (1700 ميجاهرتز) لتشغيلها عند أعلى تردد أصلي لجهاز Switch، أو وضع السرعة (2000 ميجاهرتز) لتشغيلها بتردد مضاعف.</string>
<string name="fast_cpu_time">ترددات وحدة المعالجة المركزية</string>
<string name="fast_cpu_time_description">يرفع هذا الإعداد تردد المعالج المُحاكى، مما يُزيل بعض مُحددات معدل الإطارات. قد تُلاحظ المعالجات الأضعف انخفاضًا في الأداء، وقد تعمل بعض الألعاب بشكل غير صحيح.</string>
<string name="custom_cpu_ticks">تخصيص دورات المعالج</string>
<string name="custom_cpu_ticks_description">قم بتعيين قيمة مخصصة لدورات المعالج. القيم الأعلى يمكن أن تزيد من الأداء، ولكنها قد تتسبب أيضًا في تجميد اللعبة. يوصى باستخدام نطاق 77-21000.</string>
<string name="cpu_ticks">دورات</string>
@@ -506,8 +522,8 @@
<string name="hacks">اختراقات</string>
<string name="fast_gpu_time">وقت معالجة الرسومات السريع</string>
<string name="fast_gpu_time_description">يُجبر هذا الخيار معظم الألعاب على العمل بأعلى دقة عرض أصلية. استخدم 256 للحصول على أقصى أداء و512 للحصول على أعلى جودة رسومات.</string>
<string name="fast_gpu_time">سرعات معالج الرسوميات</string>
<string name="fast_gpu_time_description">يجعل اللعبة تعتقد أن عمل وحدة معالجة الرسومات ينتهي بشكل أسرع مما هو عليه في الواقع، لذلك تتوقف عن خفض الدقة ومسافة العرض لتتناسب مع سرعات جهاز Switch.</string>
<string name="skip_cpu_inner_invalidation">تخطي إبطال صلاحية وحدة المعالجة المركزية الداخلية</string>
<string name="skip_cpu_inner_invalidation_description">يتخطى بعض عمليات إبطال ذاكرة التخزين المؤقتة من جانب وحدة المعالجة المركزية أثناء تحديثات الذاكرة، مما يقلل من استخدام وحدة المعالجة المركزية ويحسن أداءها. قد يتسبب ذلك في حدوث أعطال أو تعطل في بعض الألعاب.</string>
<string name="fix_bloom_effects">إصلاح تأثيرات التوهج</string>
@@ -554,6 +570,7 @@
<!-- Debug settings strings -->
<string name="cpu">وحدة المعالج المركزية</string>
<string name="clocks">ترددات</string>
<string name="use_auto_stub">استخدم الملحق التلقائي</string>
<string name="use_auto_stub_description">استبدال الخدمات والوظائف المفقودة تلقائيًا. قد يؤدي ذلك إلى تحسين التوافق، ولكنه قد يتسبب في حدوث أعطال ومشكلات في الاستقرار.</string>
@@ -953,13 +970,15 @@
<string name="memory_6gb">6 جيجابايت (غير آمن)</string>
<string name="memory_8gb">8 جيجابايت (غير آمن)</string>
<!--CPU clock speeds-->
<string name="clock_boost">تعزيز (1700MHz)</string>
<string name="clock_fast">سريع (2000MHz)</string>
<!-- CPU clock levels -->
<string name="clock_normal">طبيعي</string>
<string name="clock_boost">طبيعي</string>
<string name="clock_fast">كسر السرعة</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">متوسط (256)</string>
<string name="fast_gpu_high">مرتفع (512)</string>
<!-- GPU clock levels -->
<string name="fast_gpu_normal">طبيعي</string>
<string name="fast_gpu_medium">تعزيز</string>
<string name="fast_gpu_high">كسر السرعة</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">صغير جدًا (16 ميغابايت)</string>
@@ -553,10 +553,6 @@
<string name="memory_6gb">6GB (نائاسایش)</string>
<string name="memory_8gb">8GB (نائاسایش)</string>
<!--CPU clock speeds-->
<string name="clock_boost">زۆرکردن (1700MHz)</string>
<string name="clock_fast">خێرا (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">سیلیزی</string>
<string name="temperature_fahrenheit">فارینهایت</string>
@@ -417,9 +417,6 @@
<string name="use_custom_rtc_description">Umožňuje nastavit vlastní hodiny reálného času nezávisle na systému.</string>
<string name="set_custom_rtc">Nastavit vlastní RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">Přetaktování CPU</string>
<string name="fast_cpu_time_description">Vynutí běh CPU na vyšší frekvenci, což může pomoci obejít některé omezovače FPS. Režim Boost (1700 MHz) odpovídá maximální taktu konzole Switch, režim Fast (2000 MHz) je dvojnásobek základního taktu konzole.</string>
<string name="custom_cpu_ticks">Vlastní hodnota CPU cyků</string>
<string name="custom_cpu_ticks_description">Nastavte vlastní hodnotu cyklů CPU. Vyšší hodnoty mohou zvýšit výkon, ale mohou také způsobit zamrznutí hry. Doporučený rozsah hodnot je 7721000.</string>
<string name="cpu_ticks">Cykly</string>
@@ -466,8 +463,6 @@
<string name="enable_buffer_history_description">Umožňuje přístup k předchozím stavům bufferu. Tato volba může u některých her zvýšit kvalitu vykreslování a zlepšit stabilitu výkonu.</string>
<string name="hacks">Hacky</string>
<string name="fast_gpu_time">Rychlé časování GPU</string>
<string name="fast_gpu_time_description">Nutí většinu her běžet v nejvyšším nativním rozlišení. Použijte hodnotu 256 pro maximální výkon a 512 pro nejlepší kvalitu.</string>
<string name="skip_cpu_inner_invalidation">Přeskočit vnitřní invalidaci CPU</string>
<string name="skip_cpu_inner_invalidation_description">Přeskočí určité invalidace mezipaměti procesoru při aktualizacích paměti, čímž snižuje vytížení CPU a zvyšuje jeho výkon. Může způsobit chyby nebo pády některých hrách.</string>
<string name="renderer_asynchronous_shaders">Asynchronní kompilace shaderů</string>
@@ -694,10 +689,6 @@
<string name="memory_6gb">6GB (Nebezpečné)</string>
<string name="memory_8gb">8GB (Nebezpečné)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rychlé (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsia</string>
<string name="temperature_fahrenheit">Fahrenheita</string>
@@ -429,9 +429,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="use_custom_rtc_description">Ermöglicht Ihnen, eine benutzerdefinierte Echtzeituhr unabhängig von Ihrer aktuellen Systemzeit einzustellen.</string>
<string name="set_custom_rtc">Legen Sie eine benutzerdefinierte Echtzeituhr fest</string>
<!-- CPU -->
<string name="fast_cpu_time">CPU-Übertaktung</string>
<string name="fast_cpu_time_description">Zwingt die emulierte CPU, mit höherer Taktrate zu laufen, wodurch bestimmte FPS-Begrenzungen reduziert werden. Verwende Boost (1700MHz), um mit der höchsten nativen Taktrate der Switch zu laufen, oder Fast (2000MHz), um mit der doppelten Taktrate zu laufen.</string>
<string name="custom_cpu_ticks">Benutzerdefinierte CPU-Ticks</string>
<string name="custom_cpu_ticks_description">Legen Sie einen benutzerdefinierten Wert für CPU-Ticks fest. Höhere Werte können die Leistung steigern, aber auch zum Einfrieren des Spiels führen. Ein Bereich von 7721000 wird empfohlen.</string>
<string name="cpu_ticks">Ticks</string>
@@ -476,8 +473,6 @@ Wird der Handheld-Modus verwendet, verringert es die Auflösung und erhöht die
<string name="renderer_reactive_flushing_description">Verbessert die Genauigkeit in einigen Spielen.</string>
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">Schnelle GPU-Zeit</string>
<string name="fast_gpu_time_description">Erzwingt bei den meisten Spielen die höchste native Auflösung. Verwende 256 für maximale Leistung und 512 für maximale Grafikqualität</string>
<string name="skip_cpu_inner_invalidation">CPU-interne Invalidierung überspringen</string>
<string name="skip_cpu_inner_invalidation_description">Überspringt bestimmte Cache-Invalidierungen auf CPU-Seite während Speicherupdates, reduziert die CPU-Auslastung und verbessert die Leistung. Kann in einigen Spielen zu Fehlern oder Abstürzen führen.</string>
<string name="renderer_asynchronous_shaders">Asynchrone Shader</string>
@@ -879,14 +874,6 @@ Wirklich fortfahren?</string>
<string name="memory_6gb">6 GB (Unsicher)</string>
<string name="memory_8gb">8 GB (Unsicher)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Schnell (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Mittel (256)</string>
<string name="fast_gpu_high">Hoch (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Sehr klein (16 MB)</string>
<string name="gpu_texturesizeswizzle_small">Klein (32 MB)</string>
@@ -291,6 +291,23 @@
<string name="gpu_driver_fetcher">Obtenedor de controladores de la GPU</string>
<string name="gpu_driver_manager">Gestor de controladores de la GPU</string>
<string name="install_gpu_driver_description">Instale los controladores alternativos para obtener un posible mejor rendimiento o precisión</string>
<string name="frame_gen">Generación de fotograma</string>
<string name="frame_gen_multiplier">Multiplicador de fotograma</string>
<string name="frame_gen_multiplier_2x">2x</string>
<string name="frame_gen_multiplier_3x">3x</string>
<string name="frame_gen_multiplier_4x">4x</string>
<string name="frame_gen_target_rate_60">60 FPS</string>
<string name="frame_gen_target_rate_90">90 FPS</string>
<string name="frame_gen_target_rate_120">120 FPS</string>
<string name="frame_gen_target_rate_144">144 FPS</string>
<string name="frame_gen_target_rate_165">165 FPS</string>
<string name="frame_gen_queue_target_1">Equilibrado (1 fotograma)</string>
<string name="frame_generation_support">Generación de fotograma</string>
<string name="frame_generation_supported">Soportado</string>
<string name="lossless_scaling">Escalado sin pérdidas</string>
<string name="lossless_scaling_installed">Instalado</string>
<string name="lossless_scaling_not_installed">No instalado</string>
<string name="lossless_scaling_missing">Lossless.dll no instalado</string>
<string name="advanced_settings">Ajustes avanzados</string>
<string name="settings_description">Configurar los ajustes del emulador</string>
<string name="search_recently_played">Jugado recientemente</string>
@@ -437,9 +454,6 @@
<string name="use_custom_rtc_description">Le permite tener un reloj personalizado en tiempo real diferente de la hora de su sistema.</string>
<string name="set_custom_rtc">Configurar RTC personalizado</string>
<!-- CPU -->
<string name="fast_cpu_time">Overclock de la CPU</string>
<string name="fast_cpu_time_description">Fuerza a la CPU emulada a ejecutarser a una velocidad de reloj más alta, lo cual reduce ciertos limitadores de fotogramas por segundo. Usa Boost (1700 MHz) para ejecutar a la velocidad de reloj nativa más alta de la Switch, o Fast (2000 MHz) para ejecutar a una velocidad doble de reloj.</string>
<string name="custom_cpu_ticks">Ticks de CPU personalizados</string>
<string name="custom_cpu_ticks_description">Establezca un valor personalizado de los ciclos de la CPU. Los valores más altos pueden aumentar el rendimiento, pero también pueden hacer que el juego se congele. Se recomienda un rango de 7721000.</string>
<string name="cpu_ticks">Ciclos</string>
@@ -498,8 +512,6 @@
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">Tiempo rápido de la GPU</string>
<string name="fast_gpu_time_description">Fuerza a la mayoría de los juegos a ejecutarse a su resolución nativa más alta. Usa 256 para un máximo rendimiento y 512 para una fidelidad gráfica óptima.</string>
<string name="skip_cpu_inner_invalidation">Omitir invalidación interna de la CPU</string>
<string name="skip_cpu_inner_invalidation_description">Omite ciertas invalidaciones de caché de la CPU durante las actualizaciones de memoria, lo que reduce el uso de la CPU y mejora su rendimiento. Esto puede causar fallos o bloqueos en algunos juegos.</string>
<string name="fix_bloom_effects">Arreglar los efectos de resplandor</string>
@@ -945,13 +957,13 @@
<string name="memory_6gb">6GB (Inseguro)</string>
<string name="memory_8gb">8GB (Inseguro)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Impulsado (1700MHz)</string>
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- CPU clock levels -->
<string name="clock_normal">Normal</string>
<string name="clock_fast">Overclock</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Medio (256)</string>
<string name="fast_gpu_high">Alto (512)</string>
<!-- GPU clock levels -->
<string name="fast_gpu_normal">Normal</string>
<string name="fast_gpu_high">Overclock</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Muy pequeño (16 MB)</string>
@@ -432,9 +432,6 @@
<string name="use_custom_rtc_description">Vous permet de définir une horloge en temps réel personnalisée distincte de l\'heure actuelle de votre système.</string>
<string name="set_custom_rtc">Définir l\'horloge RTC personnalisée</string>
<!-- CPU -->
<string name="fast_cpu_time">Overclock du CPU</string>
<string name="fast_cpu_time_description">Force le CPU émulé à fonctionner à une fréquence plus élevée, en contournant certaines limitations de FPS. Utilisez Boost (1700MHz) pour atteindre la fréquence native maximale de la Nintendo Switch, ou Fast (2000MHz) pour doubler la fréquence. Cest un “hack”. Certains chipsets moins puissants peuvent voir leurs performances réduites et les jeux peuvent se comporter différemment.</string>
<string name="custom_cpu_ticks">Ticks CPU personnalisés</string>
<string name="custom_cpu_ticks_description">Définissez une valeur personnalisée de ticks CPU. Des valeurs plus élevées peuvent améliorer les performances, mais peuvent aussi provoquer des gels du jeu. Une plage de 77 à 21000 est recommandée.</string>
<string name="cpu_ticks">Ticks</string>
@@ -482,7 +479,6 @@
<string name="enable_buffer_history">Activer l\'historique du tampon</string>
<string name="hacks">Contournements</string>
<string name="fast_gpu_time">Temps GPU rapide</string>
<string name="skip_cpu_inner_invalidation">Ignorer l\'invalidation interne du CPU</string>
<string name="skip_cpu_inner_invalidation_description">Ignore certaines invalidations de cache côté CPU lors des mises à jour mémoire, réduisant l\'utilisation du CPU et améliorant ses performances. Peut causer des bugs ou plantages sur certains jeux.</string>
<string name="emulate_bgr565">Emuler BGR565</string>
@@ -892,14 +888,6 @@
<string name="memory_6gb">6 Go (Dangereux)</string>
<string name="memory_8gb">8 Go (Dangereux)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rapide (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Moyen (256)</string>
<string name="fast_gpu_high">Élevé (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Très petit (16 Mo)</string>
<string name="gpu_texturesizeswizzle_small">Petit (32 Mo)</string>
@@ -592,10 +592,6 @@
<string name="memory_6gb">6GB (לא בטוח)</string>
<string name="memory_8gb">8GB (לא בטוח)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">מהיר (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">צלזיוס</string>
<string name="temperature_fahrenheit">פרנהייט</string>
@@ -681,10 +681,6 @@
<string name="memory_6gb">6GB (Nem biztonságos)</string>
<string name="memory_8gb">8GB (Nem biztonságos)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Gyors (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -727,10 +727,6 @@
<string name="memory_6gb">6GB (Tidak Aman)</string>
<string name="memory_8gb">8GB (Tidak Aman)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Cepat (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -764,10 +764,6 @@
<string name="memory_6gb">6GB (Non sicuro)</string>
<string name="memory_8gb">8GB (Non sicuro)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Veloce (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -590,10 +590,6 @@
<string name="memory_6gb">6GB (安全でない)</string>
<string name="memory_8gb">8GB (安全でない)</string>
<!--CPU clock speeds-->
<string name="clock_boost">ブースト (1700MHz)</string>
<string name="clock_fast">高速 (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">摂氏</string>
<string name="temperature_fahrenheit">華氏</string>
@@ -642,10 +642,6 @@
<string name="memory_6gb">6GB (안전하지 않음)</string>
<string name="memory_8gb">8GB (안전하지 않음)</string>
<!--CPU clock speeds-->
<string name="clock_boost">부스트 (1700MHz)</string>
<string name="clock_fast">빠름 (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">섭씨</string>
<string name="temperature_fahrenheit">화씨</string>
@@ -566,10 +566,6 @@
<string name="memory_6gb">6GB (Usikkert)</string>
<string name="memory_8gb">8GB (Usikkert)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rask (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -417,9 +417,6 @@
<string name="use_custom_rtc_description">Ta opcja pozwala na wybranie własnych ustawień czasu używanych w czasie emulacji, innych niż czas systemu Android.</string>
<string name="set_custom_rtc">Ustaw niestandardowy czas RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">Podkręcanie CPU</string>
<string name="fast_cpu_time_description">Wymusza działanie emulowanego CPU z wyższym taktowaniem, ograniczając niektóre blokady FPS. Użyj Boost (1700 MHz), aby działać z najwyższym natywnym taktowaniem Switcha, lub Fast (2000 MHz), aby działać z taktowaniem 2×.</string>
<string name="custom_cpu_ticks">Niestandardowe takty CPU</string>
<string name="custom_cpu_ticks_description">Ustaw niestandardową wartość taktów CPU. Wyższe wartości mogą zwiększyć wydajność, ale mogą też powodować zawieszanie się gry. Zalecany zakres to 7721000.</string>
<string name="cpu_ticks">Takty</string>
@@ -464,8 +461,6 @@
<string name="renderer_reactive_flushing_description">Poprawia jakość renderowania w kilku grach, kosztem wydajności.</string>
<string name="hacks">Hacki</string>
<string name="fast_gpu_time">Szybki czas GPU</string>
<string name="fast_gpu_time_description">Wymusza działanie większości gier w ich najwyższej natywnej rozdzielczości. Ustaw 256 dla maksymalnej wydajności, a 512 dla maksymalnej jakości grafiki.</string>
<string name="skip_cpu_inner_invalidation">Pomiń wewnętrzne unieważnienie CPU</string>
<string name="skip_cpu_inner_invalidation_description">Pomija niektóre unieważnienia pamięci podręcznej po stronie CPU podczas aktualizacji pamięci, zmniejszając użycie CPU i poprawiając jego wydajność. Może powodować błędy lub awarie w niektórych grach.</string>
<string name="renderer_asynchronous_shaders">Wyłącz synchronizację shaderów</string>
@@ -866,14 +861,6 @@
<string name="memory_6gb">6GB (Niebezpieczne)</string>
<string name="memory_8gb">8GB (Niebezpieczne)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Szybkie (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Średnie (256)</string>
<string name="fast_gpu_high">Wysokie (512)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsjusza</string>
<string name="temperature_fahrenheit">Fahrenheita</string>
@@ -409,8 +409,6 @@
<string name="use_custom_rtc_description">Permite a você configurar um relógio em tempo real separado do relógio do seu dispositivo.</string>
<string name="set_custom_rtc">Definir um relógio em tempo real personalizado</string>
<!-- CPU -->
<string name="fast_cpu_time">Overclock da CPU</string>
<string name="custom_cpu_ticks">Ciclos da CPU Personalizados</string>
<string name="custom_cpu_ticks_description">Defina um valor personalizado de ciclos da CPU. Valores mais altos podem aumentar o desempenho, mas também podem fazer o jogo travar. Recomenda-se usar valores entre 77 e 21000.</string>
<string name="cpu_ticks">Ciclos</string>
@@ -821,10 +819,6 @@
<string name="memory_6gb">6GB (Inseguro)</string>
<string name="memory_8gb">8GB (Inseguro)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -693,10 +693,6 @@ uma tentativa de mapeamento automático</string>
<string name="memory_6gb">6GB (Inseguro)</string>
<string name="memory_8gb">8GB (Inseguro)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Rápido (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -439,9 +439,6 @@
<string name="use_custom_rtc_description">Позволяет установить пользовательские часы реального времени отдельно от текущего системного времени.</string>
<string name="set_custom_rtc">Установить пользовательский RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">Разгон ЦП</string>
<string name="fast_cpu_time_description">Принудительно повышает тактовую частоту эмулируемого ЦП, снижая влияние некоторых ограничителей FPS. Используйте Разгон (1700 МГц) для работы на максимальной штатной частоте Switch или Быстрая (2000 МГц) для удвоенной частоты.</string>
<string name="custom_cpu_ticks">Пользовательские такты ЦП</string>
<string name="custom_cpu_ticks_description">Установите пользовательское значение тактов ЦП. Более высокие значения могут увеличить производительность, но также могут вызвать зависание игры. Рекомендуется диапазон 77–21000.</string>
<string name="cpu_ticks">Такты</string>
@@ -502,8 +499,6 @@
<string name="hacks">Хаки</string>
<string name="fast_gpu_time">Быстрое время ГПУ</string>
<string name="fast_gpu_time_description">Принудительно запускает большинство игр в их максимальном нативном разрешении. Используйте значение 256 для максимальной производительности и 512 для максимального качества графики.</string>
<string name="skip_cpu_inner_invalidation">Пропустить внутреннюю инвалидацию ЦП</string>
<string name="skip_cpu_inner_invalidation_description">Пропускает некоторые инвалидации кэша на стороне ЦП при обновлениях памяти, уменьшая нагрузку на процессор и повышая производительность. Может вызывать сбои в некоторых играх.</string>
<string name="fix_bloom_effects">Исправить эффекты размытия</string>
@@ -949,14 +944,6 @@
<string name="memory_6gb">6 ГБ (Небезопасно)</string>
<string name="memory_8gb">8 ГБ (Небезопасно)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Разгон (1700MHz)</string>
<string name="clock_fast">Быстрая (2000MHz)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Среднее (256)</string>
<string name="fast_gpu_high">Высокое (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Очень малый (16 МБ)</string>
<string name="gpu_texturesizeswizzle_small">Малый (32 МБ)</string>
@@ -690,10 +690,6 @@
<string name="memory_6gb">6ГБ (несигуран)</string>
<string name="memory_8gb">8ГБ (несигурно)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Боост (1700МХз)</string>
<string name="clock_fast">Брзи (2000МХз)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Целзијус</string>
<string name="temperature_fahrenheit">Фаренхајт</string>
@@ -439,9 +439,6 @@
<string name="use_custom_rtc_description">Дозволяє встановити власний час (Real-time clock, або RTC), відмінний від системного.</string>
<string name="set_custom_rtc">Встановити RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">Розгін ЦП</string>
<string name="fast_cpu_time_description">Примушує емульований ЦП працювати з вищою тактовою частотою, послаблюючи деякі обмежувачі частоти кадрів. Використовуйте «Підвищення (1700 МГц)», щоб емулювати максимальну тактову частоту справжнього Switch, або «Швидко (2000 МГц)», щоб подвоїти частоту.</string>
<string name="custom_cpu_ticks">Користувацькі такти CPU</string>
<string name="custom_cpu_ticks_description">Встановіть користувацьке значення тактів CPU. Вищі значення можуть покращити продуктивність, але також можуть спричинити зависання гри. Рекомендується діапазон 77–21000.</string>
<string name="cpu_ticks">Такти</string>
@@ -497,8 +494,6 @@
<string name="hacks">Обхідні рішення</string>
<string name="fast_gpu_time">Швидкий час роботи ГП</string>
<string name="fast_gpu_time_description">Примушує більшість ігор працювати на їхній максимальній нативній роздільності. Використовуйте 256 для максимальної продуктивності та 512 для найкращої якості.</string>
<string name="skip_cpu_inner_invalidation">Пропустити внутрішнє інвалідування CPU</string>
<string name="skip_cpu_inner_invalidation_description">Пропускає деякі інвалідації кешу на стороні CPU під час оновлення пам\'яті, зменшуючи навантаження на процесор і покращуючи продуктивність. Може спричинити збої в деяких іграх.</string>
<string name="fix_bloom_effects">Виправити ефекти світіння</string>
@@ -938,14 +933,6 @@
<string name="memory_6gb">6 ГБ (Небезпечно)</string>
<string name="memory_8gb">8 ГБ (Небезпечно)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Підвищення (1700 МГц)</string>
<string name="clock_fast">Швидко (2000 МГц)</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">Середньо (256)</string>
<string name="fast_gpu_high">Високо (512)</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">Дуже малий (16 МБ)</string>
<string name="gpu_texturesizeswizzle_small">Малий (32 МБ)</string>
@@ -562,10 +562,6 @@
<string name="memory_6gb">6GB (Không an toàn)</string>
<string name="memory_8gb">8GB (Không an toàn)</string>
<!--CPU clock speeds-->
<string name="clock_boost">Boost (1700MHz)</string>
<string name="clock_fast">Nhanh (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">Celsius</string>
<string name="temperature_fahrenheit">Fahrenheit</string>
@@ -434,8 +434,8 @@
<string name="set_custom_rtc">设置自定义系统时间</string>
<!-- CPU -->
<string name="fast_cpu_time">CPU 超频</string>
<string name="fast_cpu_time_description">强制模拟 CPU 以更高的时钟频率运行,从而消除某些帧率限制。使用“升频”(1700MHz)以在 Switch 的最高原生时钟频率运行,或使用“快速”(2000MHz)以 2 倍时钟频率运行</string>
<string name="fast_cpu_time">CPU 时钟频率</string>
<string name="fast_cpu_time_description">提高模拟 CPU 报告的时钟频率,从而消除部分帧率限制。性能较弱的 CPU 可能会出现可见性能下降,甚至会导致某些游戏运行异常</string>
<string name="custom_cpu_ticks">自定义 CPU 时钟周期</string>
<string name="custom_cpu_ticks_description">设定自定义的 CPU 时钟周期值。更高的值可以提升性能,但也可能导致游戏冻结卡死。建议的赋值范围为77-21000。</string>
<string name="cpu_ticks">时钟周期</string>
@@ -496,8 +496,8 @@
<string name="hacks">Hacks</string>
<string name="fast_gpu_time">快速 GPU 时</string>
<string name="fast_gpu_time_description">强制大多数游戏以其最高原生分辨率运行。设置为 256 可获得最佳性能,设置为 512 可获得最佳画面保真度</string>
<string name="fast_gpu_time">GPU 时钟频率</string>
<string name="fast_gpu_time_description">通过让游戏误以为 GPU 的处理速度比实际更快,以避免游戏为了适应 Switch 的时钟频率而降低分辨率和渲染距离</string>
<string name="skip_cpu_inner_invalidation">跳过CPU内部无效化</string>
<string name="skip_cpu_inner_invalidation_description">在更新内存时跳过某些 CPU 端的缓存失效操作,从而降低 CPU 占用率并提升性能。可能会在某些游戏中引发故障点或崩溃。</string>
<string name="fix_bloom_effects">修复 Bloom 效果</string>
@@ -544,6 +544,7 @@
<!-- Debug settings strings -->
<string name="cpu">CPU</string>
<string name="clocks">时钟频率</string>
<string name="use_auto_stub">使用自动占位处理</string>
<string name="use_auto_stub_description">自动为缺失的服务和功能生成占位代码。这可能会提高兼容性,但也可能导致崩溃和稳定性问题</string>
@@ -943,13 +944,15 @@
<string name="memory_6gb">6GB (不安全)</string>
<string name="memory_8gb">8GB (不安全)</string>
<!--CPU clock speeds-->
<string name="clock_boost">加速 (1700MHz)</string>
<string name="clock_fast">快速 (2000MHz)</string>
<!-- CPU clock levels -->
<string name="clock_normal">正常</string>
<string name="clock_boost">升频</string>
<string name="clock_fast">超频</string>
<!-- GPU overclock factors -->
<string name="fast_gpu_medium">中 (256)</string>
<string name="fast_gpu_high">高 (512)</string>
<!-- GPU clock levels -->
<string name="fast_gpu_normal">正常</string>
<string name="fast_gpu_medium">升频</string>
<string name="fast_gpu_high">超频</string>
<!-- GPU swizzle texture size -->
<string name="gpu_texturesizeswizzle_verysmall">极小 (16 MB)</string>
@@ -99,7 +99,7 @@
<string name="use_sync_core">同步核心速度</string>
<string name="use_sync_core_description">將核心速度與最大速度百分比同步,在不改變遊戲實際速度的情況下提高效能</string>
<string name="cpuopt_unsafe_host_mmu">啟用主機 MMU 模擬</string>
<string name="cpuopt_unsafe_host_mmu_description">此最佳化可加速來賓程式的記憶體存取。啟用後,來賓記憶體讀取/寫入將直接在記憶體中執行並利用主機的 MMU。停用此功能將強制所有記憶體存取使用軟體 MMU 模擬。</string>
<string name="cpuopt_unsafe_host_mmu_description">此最佳化可加速客體程式的記憶體存取。啟用後,客體記憶體讀取/寫入將直接在記憶體中執行並利用主機的 MMU。停用此功能將強制所有記憶體存取使用軟體 MMU 模擬。</string>
<string name="debug_knobs">偵錯開關</string>
<string name="debug_knobs_description">僅限開發用途</string>
<string name="debug_knobs_hint">0到65535</string>
@@ -192,7 +192,7 @@
<string name="multiplayer_nickname_invalid">使用者名稱無效,請在系統→網路中檢查設定</string>
<string name="multiplayer_token_error">必須為48個字元,且僅包含小寫字母a-z</string>
<string name="multiplayer_port_error">埠號需為1-65535</string>
<string name="cancel">略過</string>
<string name="cancel">取消</string>
<string name="ok">確定</string>
<string name="refresh">重新整理</string>
<string name="room_list">房間列表</string>
@@ -302,7 +302,7 @@
<string name="notification_no_directory_link">無法開啟 Eden 目錄</string>
<string name="notification_no_directory_link_description">請使用檔案管理員的側邊面板手動定位到使用者資料夾</string>
<string name="manage_save_data">管理儲存資料</string>
<string name="manage_save_data_description">導入/導出遊戲的儲存資料\n\n壓縮檔中首個子資料夾名稱必須為遊戲 ID</string>
<string name="manage_save_data_description">導入/導出遊戲的儲存資料\n壓縮檔必須為.zip格式\n壓縮檔中首個子資料夾名稱必須為遊戲 ID</string>
<string name="import_save_warning">導入儲存資料</string>
<string name="import_save_warning_description">這將會以提供的檔案覆寫現有的該遊戲儲存資料,您確定要繼續嗎?</string>
<string name="save_files_importing">正在導入儲存資料…</string>
@@ -434,8 +434,8 @@
<string name="set_custom_rtc">設定自訂 RTC</string>
<!-- CPU -->
<string name="fast_cpu_time">CPU 超頻</string>
<string name="fast_cpu_time_description">強制模擬 CPU 以更高的時脈運作,減少某些 FPS 限制。使用 加速 (1700MHz) 以 Switch 的最高原生時脈執行,或 高速 (2000MHz) 以雙倍時脈執行</string>
<string name="fast_cpu_time">CPU 時脈</string>
<string name="fast_cpu_time_description">提高模擬 CPU 回報的時脈,可以減少某些 FPS 限制。較弱的 CPU 可能會出現效能下降的情況,部分遊戲可能會出現異常</string>
<string name="custom_cpu_ticks">自訂CPU時脈</string>
<string name="custom_cpu_ticks_description">自訂CPU時脈。更高的值可能提高效能,但也可能導致遊戲卡死。建議範圍為77-21000。</string>
<string name="cpu_ticks">時脈</string>
@@ -481,15 +481,57 @@
<string name="use_disk_shader_cache_description">將產生的著色器快取儲存至硬碟以減少中斷</string>
<string name="renderer_force_max_clock">強制使用最大時脈 (僅限Adreno)</string>
<string name="renderer_force_max_clock_description">強制 GPU 以可能的最大時脈執行 (熱溫限制仍會被套用)</string>
<string name="renderer_asynchronous_gpu_emulation">GPU 非同步模擬</string>
<string name="renderer_asynchronous_gpu_emulation_description">此修改可透過使用 GPU 非同步模擬來提升性能,不過可能會導致圖形問題且會提高在進行時序相關操作時當機的機率</string>
<string name="renderer_async_presentation">非同步呈現</string>
<string name="renderer_async_presentation_description">此修改可以透過將渲染移至單獨的 CPU 執行緒來提升性能,但可能會導致圖形問題</string>
<string name="renderer_reactive_flushing">使用重新啟用排清</string>
<string name="renderer_reactive_flushing_description">犧牲效能,以改善部分遊戲的轉譯準確度。</string>
<string name="enable_buffer_history">啟用緩衝區歷史</string>
<string name="enable_buffer_history_description">允許存取先前的緩衝區狀態。此選項可能會改善部分遊戲的渲染品質與效能穩定性</string>
<string name="enable_gpu_buffer_readback">啟用 GPU 緩衝區讀回</string>
<string name="enable_gpu_buffer_readback_description">透過在上傳之前先將 GPU 修改過的緩衝區資料讀回來保存資料,部分遊戲需要啟用此功能才能正常渲染遊戲特效。如果硬體無法負荷可能會導致錯誤</string>
<string name="use_optimized_vertex_buffers">最佳化頂點緩衝區</string>
<string name="use_optimized_vertex_buffers_description">啟用最佳化的頂點緩衝區綁定。需要安裝 Mesa 26.0+ Turnip drivers/Qualcomm drivers。使用舊版 Turnip drivers 會導致當機 (25.3版和更低的版本)</string>
<string name="hacks">修改</string>
<string name="fast_gpu_time">GPU 時脈</string>
<string name="fast_gpu_time_description">讓遊戲誤以為 GPU 工作能更快完成,避免遊戲為了配合 Switch 的時脈而降低解析度與渲染距離</string>
<string name="skip_cpu_inner_invalidation">跳過CPU內部失效處理</string>
<string name="skip_cpu_inner_invalidation_description">在記憶體更新期間跳過某些CPU端快取的失效處理,減少CPU使用率並提高其性能。可能會導致某些遊戲出現故障或崩潰</string>
<string name="skip_cpu_inner_invalidation_description">在記憶體更新期間跳過某些CPU端快取的失效處理,減少CPU使用率並提高其性能。可能會導致某些遊戲出現故障或當機</string>
<string name="fix_bloom_effects">修正光暈特效</string>
<string name="fix_bloom_effects_description">在 薩爾達傳說:織夢島 和 薩爾達傳說:智慧的再現 中 減少光暈模糊的問題並移除 橫衝直撞:狂飆樂園重製版 中的光暈效果 (Adreno A6XX - A7XX/ Turnip)。警告:可能會在其它遊戲中導致圖形異常</string>
<string name="emulate_bgr565">模擬 BGR565</string>
<string name="emulate_bgr565_description">修正遊戲中出現的顏色反轉、圖形異常或陰影異常</string>
<string name="rescale_hack">啟用舊版重新縮放處理</string>
<string name="rescale_hack_description">透過快速重新縮放處理來啟用遊戲重新縮放設定階段的舊版處理方式</string>
<string name="renderer_asynchronous_shaders">使用非同步著色器</string>
<string name="renderer_asynchronous_shaders_description">非同步編譯著色器。這可能會減少卡頓,但也可能導致圖形錯誤。</string>
<string name="renderer_asynchronous_shaders_description">使用非同步編譯著色器。這可能會減少卡頓,但也可能導致圖形錯誤。</string>
<string name="gpu_unswizzle_settings">GPU Unswizzle 設定</string>
<string name="gpu_unswizzle_settings_description">設定基於 GPU 的 Unswizzling 參數或完全停用此功能。調整此設定以在性能與紋理載入品質中取得平衡</string>
<string name="gpu_unswizzle_enable">啟用 GPU Unswizzle</string>
<string name="gpu_unswizzle_disabled">停用</string>
<string name="gpu_unswizzle_texture_size">GPU Unswizzle 最大紋理尺寸</string>
<string name="gpu_unswizzle_texture_size_description">設定 GPU 紋理 Unswizzling 的最大值 (MB)。雖然 GPU 處理中型和大型紋理的速度較快,但 CPU 處理非常小的紋理可能更有效率。整此設定以在 GPU 加速與 CPU 負載之間取得平衡</string>
<string name="gpu_unswizzle_stream_size">GPU Unswizzle 流大小</string>
<string name="gpu_unswizzle_stream_size_description">設定每個影格處理大型紋理 Unswizzling 的資料上限。數值越高載入紋理的速度越快,但會增加畫面延遲;數值較低則能降低 GPU 負載,不過有可能導致至紋理載入不完全甚至突然出現</string>
<string name="gpu_unswizzle_chunk_size">GPU Unswizzle 塊大小</string>
<string name="gpu_unswizzle_chunk_size_description">設定 3D 紋理每批次處理的深度切片數量。增加此數值可提升規格較佳 GPU 的處理效率,但在較低規格的硬體上可能導致卡頓或驅動程式逾時</string>
<string name="gpu_unswizzle_default_button">預設</string>
<string name="extensions">擴充功能</string>
<string name="dyna_state">擴展動態狀態</string>
<string name="disabled">已停用</string>
<string name="dyna_state_description">控制擴展動態狀態中可使用的功能數量。較高的數值可根據驅動程式支援的動態狀態減少管線編譯的次數。</string>
<string name="disabled">停用</string>
<string name="vertex_input_dynamic_state">頂點輸入動態狀態</string>
<string name="vertex_input_dynamic_state_description">啟用此功能可提供更彈性的頂點輸入處理方式,並可能減少頂點/緩衝區的管線編譯時間</string>
<string name="sample_shading_fraction">取樣著色</string>
<string name="sample_shading_fraction_description">讓片段著色器在多重取樣片段中針對每個取樣執行,而不是每個片段只執行一次。可提升圖形品質但會降低部分效能</string>
<string name="display">顯示</string>
<string name="renderer_screen_layout">方向</string>
@@ -498,32 +540,55 @@
<string name="picture_in_picture">子母畫面</string>
<string name="picture_in_picture_description">位於背景時最小化視窗</string>
<string name="warning_resolution">解析度縮放到2倍或更高可能會導致問題,並可能顯著降低設備速度</string>
<string name="warning_resolution">解析度縮放到2倍或更高可能會導致問題,並可能顯著降低設備速度</string>
<!-- Debug settings strings -->
<string name="cpu">CPU</string>
<string name="clocks">時脈</string>
<string name="use_auto_stub">使用自動存根</string>
<string name="use_auto_stub_description">自動補上缺少的服務和功能。可提高相容性但可能導致崩潰和穩定性問題。</string>
<string name="use_auto_stub_description">自動補上缺少的服務和功能。可提高相容性但可能導致當機和穩定性問題。</string>
<string name="gpu">GPU</string>
<string name="renderer_api">API</string>
<string name="renderer_debug">圖形偵錯</string>
<string name="renderer_debug_description">將圖形 API 設為慢速偵錯模式</string>
<string name="renderer_debug_description">將圖形 API 設為慢速偵錯模式</string>
<string name="patch_old_qcom_drivers">BCn 區塊壓縮紋理修補</string>
<string name="patch_old_qcom_drivers_description">覆寫 Adreno GPU 的 BCn 紋理格式自動偵測。通常會根據 Android 版本自動偵測(會在API 28 以上自動啟用)</string>
<string name="fastmem">Fastmem</string>
<string name="log">日誌記錄</string>
<string name="log">日誌</string>
<string name="flush_by_line">按行寫入偵錯日誌</string>
<string name="flush_by_line_description">在每行寫入時重新整理偵錯日誌,讓程式在崩潰或當機時更容易偵錯。</string>
<string name="flush_by_line_description">在每行寫入時重新整理偵錯日誌,讓程式在當機或閃退時更容易偵錯。</string>
<!-- GPU Logging strings -->
<string name="gpu_logging_header">GPU 日誌</string>
<string name="gpu_log_level">記錄層級</string>
<string name="gpu_log_level_description">GPU 日誌的詳細層級 (越高日誌越詳細,不過會更容易過熱)</string>
<string name="gpu_log_vulkan_calls">記錄 Vulkan API 呼叫</string>
<string name="gpu_log_vulkan_calls_description">在環形緩衝區中記錄所有 Vulkan API 呼叫</string>
<string name="gpu_log_shader_dumps">傾印 SPIR-V 著色器</string>
<string name="gpu_log_shader_dumps_description">將重新編譯後的 SPIR-V 二進位檔案 (.spv) 儲存至 Eden 資料夾裡的 dump 資料夾中。可使用 spirv-dis/spirv-cross/spirv-val 進行檢查</string>
<string name="dump_guest_shaders">傾印客體(Maxwell)著色器</string>
<string name="dump_guest_shaders_description">將 Maxwell 客體著色器位元組碼檔案 (.ash) 儲存至 Eden 資料夾裡的 dump 資料夾中。可使用 nvdisasm 進行檢查</string>
<string name="dump_macros">傾印 Maxwell 巨集</string>
<string name="dump_macros_description">將 Maxwell 巨集程式檔案 (.macro) 儲存至 Eden 資料夾裡的 dump 資料夾中。可使用 envydis 進行檢查</string>
<string name="gpu_log_memory_tracking">追蹤 GPU 記憶體</string>
<string name="gpu_log_memory_tracking_description">監控 GPU 記憶體的分配和釋放</string>
<string name="gpu_log_driver_debug">驅動程式偵錯資料</string>
<string name="gpu_log_driver_debug_description">擷取驅動程式的特定偵錯資料(例如 Turnip breadcrumbs</string>
<string name="gpu_log_ring_buffer_size">環形緩衝區大小</string>
<string name="gpu_log_ring_buffer_size_description">追蹤的近期 Vulkan 呼叫數量(預設為 512 )</string>
<string name="gpu_log_ring_buffer_size_hint">64 至 4096 個項目</string>
<string name="general">一般</string>
<!-- Audio settings strings -->
<string name="audio_output_engine">輸出引擎</string>
<string name="audio_volume">音量</string>
<string name="audio_volume_description">指定音訊輸出音量</string>
<string name="audio_volume_description">指定音訊輸出音量</string>
<!-- Input strings -->
<string name="buttons"></string>
<string name="buttons"></string>
<string name="button_plus"></string>
<string name="button_minus"></string>
<string name="button_home">HOME</string>
@@ -592,19 +657,20 @@
<string name="button_map_description">按下一個按鈕或肩部按鍵/移動搖桿</string>
<string name="map_dpad_direction">將方向鍵配對到 %1$s</string>
<string name="map_control">配對到 %1$s</string>
<string name="failed_to_load_profile">入設定檔失敗</string>
<string name="failed_to_load_profile">入設定檔失敗</string>
<string name="failed_to_save_profile">儲存設定檔失敗</string>
<string name="reset_mapping">重設控制器配對</string>
<string name="reset_mapping_description">您確定要將此控制器的所有配對重設為預設值?此動作無法復原</string>
<!-- Miscellaneous -->
<string name="slider_default">預設</string>
<string name="default_string">預設</string>
<string name="loading">正在載入…</string>
<string name="shutting_down">正在關閉…</string>
<string name="reset_setting_confirmation">要將此設定重設回預設值嗎?</string>
<string name="reset_to_default">重設為預設值</string>
<string name="reset_to_default_description">重設所有進階設定</string>
<string name="reset_all_settings">重設所有設定?</string>
<string name="reset_all_settings">確定要重設所有設定</string>
<string name="reset_all_settings_description">所有進階設定將被重設,此動作無法復原</string>
<string name="settings_reset">設定已重設</string>
<string name="close">關閉</string>
@@ -624,8 +690,8 @@
<string name="import_success">已成功導入</string>
<string name="export_success">已成功導出</string>
<string name="start">開始</string>
<string name="global">全域</string>
<string name="custom">自定義</string>
<string name="global">全域設定</string>
<string name="custom">個別遊戲設定</string>
<string name="import_complete">導入完成</string>
<string name="use_global_setting">使用全域設定</string>
<string name="operation_completed_successfully">操作已成功完成</string>
@@ -637,6 +703,7 @@
<string name="select_gpu_driver_default">預設</string>
<string name="select_gpu_driver_error">選擇的驅動程式無效</string>
<string name="driver_already_installed">驅動程式已安裝</string>
<string name="installed_label">%1$s(已安裝)</string>
<string name="system_gpu_driver">系統 GPU 驅動程式</string>
<string name="installing_driver">正在安裝驅動程式…</string>
@@ -666,6 +733,9 @@
<string name="preferences_system_description">底座模式、區域及語言</string>
<string name="preferences_graphics">圖形</string>
<string name="preferences_graphics_description">準確度層級、解析度及著色器快取</string>
<string name="quick_settings">快捷設定</string>
<string name="enable_quick_settings">啟用快捷設定</string>
<string name="enable_quick_settings_description">允許透過滑動和選單按鈕存取快捷設定選單</string>
<string name="preferences_audio">音訊</string>
<string name="preferences_audio_description">輸出引擎及音量</string>
<string name="preferences_controls">控制</string>
@@ -673,12 +743,26 @@
<string name="preferences_player">玩家 %d</string>
<string name="preferences_debug">偵錯</string>
<string name="preferences_debug_description">CPU/GPU 偵錯、圖形 API 及 fastmem</string>
<string name="preferences_custom_paths">自訂路徑</string>
<string name="preferences_custom_paths_description">自訂檔案的存放路徑</string>
<!-- Custom Paths settings -->
<string name="custom_save_directory">遊戲儲存資料路徑</string>
<string name="custom_save_directory_description">設定遊戲儲存資料的自訂路徑</string>
<string name="reset_to_nand">重設為預設值</string>
<string name="migrate_save_data">遷移儲存資料</string>
<string name="migrate_save_data_question">您要將現有的儲存資料移至新位置嗎?</string>
<string name="save_migration_complete">成功遷移儲存資料</string>
<string name="save_migration_failed">儲存資料遷移失敗</string>
<string name="save_directory_set">存檔目錄設定完成</string>
<string name="skip_migration">跳過</string>
<!-- Game properties -->
<string name="info">資訊</string>
<string name="info_description">程式 ID、開發人員及版本資訊</string>
<string name="per_game_settings">個別遊戲設定</string>
<string name="per_game_settings_description">編輯此遊戲的特定設定</string>
<string name="launch_options">啟動組態</string>
<string name="launch_options">啟動設定</string>
<string name="path">路徑</string>
<string name="program_id">程式 ID</string>
<string name="developer">開發商</string>
@@ -784,7 +868,7 @@
<string name="driver_missing_title">需要GPU驅動程式</string>
<string name="driver_missing_message">這個遊戲的設定需要 \"%s\"驅動程式,而它並沒有安裝在您的裝置上\n\n要下載並安裝此驅動程式嗎?</string>
<string name="driver_download_cancelled">驅動程式下載已取消。沒有所需的驅動程式無法啟動遊戲。</string>
<string name="download">下載</string>
<string name="download">遷移</string>
<!-- Emulation Menu -->
<string name="emulation_exit">結束模擬</string>
@@ -827,11 +911,11 @@
<string name="abort_button">中止</string>
<string name="continue_button">繼續</string>
<string name="system_archive_not_found">找不到系統存檔</string>
<string name="system_archive_not_found_message">缺少%s,請轉儲您的系統存檔\n繼續模擬可能會導致崩潰</string>
<string name="system_archive_not_found_message">缺少%s,請轉儲您的系統存檔\n繼續模擬可能會導致當機</string>
<string name="system_archive_general">系統存檔</string>
<string name="save_load_error">儲存/載入時發生錯誤</string>
<string name="fatal_error">嚴重錯誤</string>
<string name="fatal_error_message">發生嚴重錯誤。請查看日誌以取得詳細資料\n繼續模擬可能會導致崩潰</string>
<string name="fatal_error_message">發生嚴重錯誤。請查看日誌以取得詳細資料\n繼續模擬可能會導致當機</string>
<string name="device_memory_inadequate">裝置記憶體大小:%1$s\n推薦記憶體大小:%2$s</string>
<string name="memory_formatted">%1$s%2$s</string>
<string name="no_game_present">目前沒有可啟動的遊戲!</string>
@@ -850,10 +934,6 @@
<string name="memory_6gb">6GB (不穩定)</string>
<string name="memory_8gb">8GB (不穩定)</string>
<!--CPU clock speeds-->
<string name="clock_boost">加速 (1700MHz)</string>
<string name="clock_fast">快速 (2000MHz)</string>
<!-- Temperature Units -->
<string name="temperature_celsius">攝氏度</string>
<string name="temperature_fahrenheit">華氏度</string>
@@ -162,6 +162,48 @@
<item>@string/resolution_four</item>
</string-array>
<string-array name="frameGenMultiplierNames">
<item>@string/frame_gen_multiplier_2x</item>
<item>@string/frame_gen_multiplier_3x</item>
<item>@string/frame_gen_multiplier_4x</item>
</string-array>
<integer-array name="frameGenMultiplierValues">
<item>2</item>
<item>3</item>
<item>4</item>
</integer-array>
<string-array name="frameGenTargetRateNames">
<item>@string/frame_gen_target_rate_off</item>
<item>@string/frame_gen_target_rate_60</item>
<item>@string/frame_gen_target_rate_90</item>
<item>@string/frame_gen_target_rate_120</item>
<item>@string/frame_gen_target_rate_144</item>
<item>@string/frame_gen_target_rate_165</item>
</string-array>
<integer-array name="frameGenTargetRateValues">
<item>0</item>
<item>60</item>
<item>90</item>
<item>120</item>
<item>144</item>
<item>165</item>
</integer-array>
<string-array name="frameGenQueueTargetNames">
<item>@string/frame_gen_queue_target_0</item>
<item>@string/frame_gen_queue_target_1</item>
<item>@string/frame_gen_queue_target_2</item>
</string-array>
<integer-array name="frameGenQueueTargetValues">
<item>0</item>
<item>1</item>
<item>2</item>
</integer-array>
<string-array name="rendererVSyncNames">
<item>@string/renderer_vsync_immediate</item>
<item>@string/renderer_vsync_mailbox</item>
@@ -638,6 +680,16 @@
<item>@string/error_keys_failed_init</item>
</string-array>
<string-array name="losslessDllResults">
<item>""</item>
<item>@string/error_lossless_copy_failed</item>
<item>@string/error_lossless_unreadable</item>
<item>@string/error_lossless_not_pe</item>
<item>@string/error_lossless_missing_shaders</item>
<item>@string/error_lossless_translation_failed</item>
<item>@string/error_lossless_cache_failed</item>
</string-array>
<!-- GPU Logging Arrays -->
<string-array name="gpuLogLevelEntries">
<item>Off</item>
@@ -298,6 +298,67 @@
<string name="gpu_driver_fetcher">GPU driver fetcher</string>
<string name="gpu_driver_manager">GPU driver manager</string>
<string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
<string name="frame_gen">Frame generation</string>
<string name="frame_gen_per_game_description">Configure frame generation for this game</string>
<string name="frame_gen_description">Insert interpolated frames between rendered ones using Lossless Scaling. Forces FIFO presentation while enabled.</string>
<string name="frame_gen_multiplier">Frame multiplier</string>
<string name="frame_gen_multiplier_description">How many frames to display for each rendered frame. Higher values cost proportionally more GPU time. Asking for more than your display can present will slow emulation down.</string>
<string name="frame_gen_multiplier_2x">2x</string>
<string name="frame_gen_multiplier_3x">3x</string>
<string name="frame_gen_multiplier_4x">4x</string>
<string name="frame_gen_target_rate">Target frame rate</string>
<string name="frame_gen_target_rate_description">Pick the rate your display can actually show. The multiplier then rises or falls on its own to hold it, and rolls back any step that makes the game itself run slower.</string>
<string name="frame_gen_target_rate_off">Use a fixed multiplier</string>
<string name="frame_gen_target_rate_60">60 FPS</string>
<string name="frame_gen_target_rate_90">90 FPS</string>
<string name="frame_gen_target_rate_120">120 FPS</string>
<string name="frame_gen_target_rate_144">144 FPS</string>
<string name="frame_gen_target_rate_165">165 FPS</string>
<string name="frame_gen_queue_target">Frame queue target</string>
<string name="frame_gen_queue_target_description">How many finished frames may wait ahead of the display. Larger queues absorb GPU spikes at the cost of input latency.</string>
<string name="frame_gen_queue_target_0">Lowest latency (Unbuffered)</string>
<string name="frame_gen_queue_target_1">Balanced (1 frame)</string>
<string name="frame_gen_queue_target_2">Smoothest (2 frames)</string>
<string name="frame_gen_flow_scale_auto">Match motion estimation to the game</string>
<string name="frame_gen_flow_scale_auto_description">Estimate motion at the resolution the game actually renders instead of the upscaled output. Costs nothing in accuracy, since upscaling adds no motion detail.</string>
<string name="frame_gen_flow_scale">Motion estimation resolution</string>
<string name="frame_gen_flow_scale_description">Resolution of the optical flow pass, as a fraction of the output. Lowering it is the cheapest way to reclaim performance.</string>
<string name="frame_gen_fp16">Half precision shaders</string>
<string name="frame_gen_fp16_description">Use the 16-bit shader variant. Falls back automatically if the driver or the file lacks it.</string>
<string name="frame_gen_dump_flow">Dump generated frame</string>
<string name="frame_gen_dump_flow_description">Write the optical flow mip levels and the interpolated frame to the lossless/debug folder once, for troubleshooting</string>
<string name="frame_gen_unsupported">Frame generation unavailable</string>
<string name="frame_gen_unsupported_description">This GPU driver does not support the Vulkan memory model, which the Lossless Scaling shaders require.</string>
<string name="lossless_scaling_setup_description">Optional. Provide your own Lossless.dll to enable frame generation later</string>
<string name="lossless_scaling_install">Install Lossless.dll</string>
<string name="lossless_scaling_install_description">Frame generation needs your own legal copy of Lossless.dll from Lossless Scaling</string>
<string name="lossless_scaling_replace_description">Select a different copy of Lossless.dll</string>
<string name="frame_generation_support">Frame generation</string>
<string name="frame_generation_supported">Supported</string>
<string name="frame_generation_unsupported">Unsupported (no Vulkan memory model)</string>
<string name="lossless_scaling">Lossless Scaling</string>
<string name="lossless_scaling_description">Provide your own copy of Lossless.dll to enable frame generation</string>
<string name="lossless_scaling_installed">Installed</string>
<string name="lossless_scaling_not_installed">Not installed</string>
<string name="lossless_scaling_replace">Replace</string>
<string name="lossless_scaling_remove">Remove</string>
<string name="lossless_scaling_remove_description">Delete the installed Lossless.dll and its prepared shaders</string>
<string name="lossless_scaling_remove_confirmation">Frame generation will stop working until you install Lossless.dll again. Your original file is not affected.</string>
<string name="lossless_scaling_missing">Lossless.dll not installed</string>
<string name="lossless_scaling_missing_description">Install it from Settings Lossless Scaling to use frame generation.</string>
<string name="lossless_scaling_locked">Close the game first</string>
<string name="lossless_scaling_locked_description">Lossless.dll cannot be changed while a game is running.</string>
<string name="lossless_scaling_remove_unavailable">Nothing to remove</string>
<string name="lossless_scaling_remove_unavailable_description">Lossless.dll is not installed yet.</string>
<string name="lossless_scaling_installing">Preparing frame generation shaders…</string>
<string name="lossless_scaling_install_success">Lossless.dll installed successfully</string>
<string name="lossless_scaling_install_failed">Could not install Lossless.dll</string>
<string name="error_lossless_copy_failed">The selected file could not be copied.</string>
<string name="error_lossless_unreadable">The selected file could not be read.</string>
<string name="error_lossless_not_pe">The selected file is not a Windows library. Select Lossless.dll from your Lossless Scaling installation.</string>
<string name="error_lossless_missing_shaders">This copy of Lossless.dll does not contain the frame generation shaders. Update Lossless Scaling and try again.</string>
<string name="error_lossless_translation_failed">The frame generation shaders could not be translated. This version of Lossless Scaling is not supported yet.</string>
<string name="error_lossless_cache_failed">The translated shaders could not be written to storage. Check that there is free space available.</string>
<string name="advanced_settings">Advanced settings</string>
<string name="settings_description">Configure emulator settings</string>
<string name="search_recently_played">Recently played</string>
+4 -1
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -20,6 +20,7 @@
#define KEYS_DIR "keys"
#define LOAD_DIR "load"
#define LOG_DIR "log"
#define LOSSLESS_DIR "lossless"
#define NAND_DIR "nand"
#define PLAY_TIME_DIR "play_time"
#define SCREENSHOTS_DIR "screenshots"
@@ -37,3 +38,5 @@
// yuzu-specific files
#define LOG_FILE "eden_log.txt"
#define LOSSLESS_DLL_FILE "Lossless.dll"
#define LOSSLESS_CACHE_FILE "lsfg_spirv.cache"
+1
View File
@@ -157,6 +157,7 @@ public:
GenerateEdenPath(EdenPath::KeysDir, eden_path / KEYS_DIR);
GenerateEdenPath(EdenPath::LoadDir, eden_path / LOAD_DIR);
GenerateEdenPath(EdenPath::LogDir, eden_path / LOG_DIR);
GenerateEdenPath(EdenPath::LosslessDir, eden_path / LOSSLESS_DIR);
GenerateEdenPath(EdenPath::NANDDir, eden_path / NAND_DIR);
GenerateEdenPath(EdenPath::PlayTimeDir, eden_path / PLAY_TIME_DIR);
GenerateEdenPath(EdenPath::SaveDir, eden_path / NAND_DIR);
+2 -1
View File
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -23,6 +23,7 @@ enum class EdenPath {
KeysDir, // Where key files are stored.
LoadDir, // Where cheat/mod files are stored.
LogDir, // Where log files are stored.
LosslessDir, // Where the user-supplied Lossless Scaling library is stored.
NANDDir, // Where the emulated NAND is stored.
PlayTimeDir, // Where play time data is stored.
SaveDir, // Where save data is stored.

Some files were not shown because too many files have changed in this diff Show More